aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/modem_if/modem_link_device_pld.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/modem_if/modem_link_device_pld.h')
-rw-r--r--drivers/misc/modem_if/modem_link_device_pld.h532
1 files changed, 532 insertions, 0 deletions
diff --git a/drivers/misc/modem_if/modem_link_device_pld.h b/drivers/misc/modem_if/modem_link_device_pld.h
new file mode 100644
index 0000000..2656110
--- /dev/null
+++ b/drivers/misc/modem_if/modem_link_device_pld.h
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __MODEM_LINK_DEVICE_DPRAM_H__
+#define __MODEM_LINK_DEVICE_DPRAM_H__
+
+#include <linux/spinlock.h>
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+#include <linux/platform_data/modem.h>
+
+#include "modem_prj.h"
+
+#define DPRAM_MAGIC_CODE 0xAA
+
+/* interrupt masks.*/
+#define INT_MASK_VALID 0x0080
+#define INT_MASK_CMD 0x0040
+#define INT_VALID(x) ((x) & INT_MASK_VALID)
+#define INT_CMD_VALID(x) ((x) & INT_MASK_CMD)
+#define INT_NON_CMD(x) (INT_MASK_VALID | (x))
+#define INT_CMD(x) (INT_MASK_VALID | INT_MASK_CMD | (x))
+
+#define EXT_UDL_MASK 0xF000
+#define EXT_UDL_CMD(x) ((x) & EXT_UDL_MASK)
+#define EXT_INT_VALID_MASK 0x8000
+#define EXT_CMD_VALID_MASK 0x4000
+#define UDL_CMD_VALID_MASK 0x2000
+#define EXT_INT_VALID(x) ((x) & EXT_INT_VALID_MASK)
+#define EXT_CMD_VALID(x) ((x) & EXT_CMD_VALID_MASK)
+#define UDL_CMD_VALID(x) ((x) & UDL_CMD_VALID_MASK)
+#define INT_EXT_CMD(x) (EXT_INT_VALID_MASK | EXT_CMD_VALID_MASK | (x))
+
+#define EXT_CMD_MASK(x) ((x) & 0x0FFF)
+#define EXT_CMD_SET_SPEED_LOW 0x0011
+#define EXT_CMD_SET_SPEED_MID 0x0012
+#define EXT_CMD_SET_SPEED_HIGH 0x0013
+
+#define UDL_RESULT_SUCCESS 0x1
+#define UDL_RESULT_FAIL 0x2
+
+#define UDL_CMD_MASK(x) (((x) >> 8) & 0xF)
+#define UDL_CMD_RECV_READY 0x1
+#define UDL_CMD_DL_START_REQ 0x2
+#define UDL_CMD_DL_START_RESP 0x3
+#define UDL_CMD_IMAGE_SEND_REQ 0x4
+#define UDL_CMD_SEND_DONE_RESP 0x5
+#define UDL_CMD_SEND_DONE_REQ 0x6
+#define UDL_CMD_UPDATE_DONE 0x7
+#define UDL_CMD_STATUS_UPDATE 0x8
+#define UDL_CMD_IMAGE_SEND_RESP 0x9
+#define UDL_CMD_EFS_CLEAR_RESP 0xB
+#define UDL_CMD_ALARM_BOOT_OK 0xC
+#define UDL_CMD_ALARM_BOOT_FAIL 0xD
+
+#define CMD_IMG_START_REQ 0x9200
+#define CMD_IMG_SEND_REQ 0x9400
+#define CMD_DL_SEND_DONE_REQ 0x9600
+#define CMD_UL_RECV_RESP 0x9601
+#define CMD_UL_RECV_DONE_RESP 0x9801
+
+/* special interrupt cmd indicating modem boot failure. */
+#define INT_POWERSAFE_FAIL 0xDEAD
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+#define INT_MASK_RES_ACK_SET \
+ (INT_MASK_RES_ACK_F | INT_MASK_RES_ACK_R | INT_MASK_RES_ACK_RFS)
+
+#define INT_MASK_SEND_SET \
+ (INT_MASK_SEND_F | INT_MASK_SEND_R | INT_MASK_SEND_RFS)
+
+#define INT_CMD_MASK(x) ((x) & 0xF)
+#define INT_CMD_INIT_START 0x1
+#define INT_CMD_INIT_END 0x2
+#define INT_CMD_REQ_ACTIVE 0x3
+#define INT_CMD_RES_ACTIVE 0x4
+#define INT_CMD_REQ_TIME_SYNC 0x5
+#define INT_CMD_CRASH_RESET 0x7
+#define INT_CMD_PHONE_START 0x8
+#define INT_CMD_ERR_DISPLAY 0x9
+#define INT_CMD_CRASH_EXIT 0x9
+#define INT_CMD_CP_DEEP_SLEEP 0xA
+#define INT_CMD_NV_REBUILDING 0xB
+#define INT_CMD_EMER_DOWN 0xC
+#define INT_CMD_PIF_INIT_DONE 0xD
+#define INT_CMD_SILENT_NV_REBUILDING 0xE
+#define INT_CMD_NORMAL_PWR_OFF 0xF
+
+#define START_FLAG 0x7F
+#define END_FLAG 0x7E
+
+#define DP_MAGIC_DMDL 0x4445444C
+#define DP_MAGIC_UMDL 0x4445444D
+#define DP_DPRAM_SIZE 0x4000
+#define DP_DEFAULT_WRITE_LEN 8168
+#define DP_DEFAULT_DUMP_LEN 16128
+#define DP_DUMP_HEADER_SIZE 7
+
+#define UDL_TIMEOUT (50 * HZ)
+#define UDL_SEND_TIMEOUT (200 * HZ)
+#define FORCE_CRASH_ACK_TIMEOUT (5 * HZ)
+#define DUMP_TIMEOUT (30 * HZ)
+#define DUMP_START_TIMEOUT (100 * HZ)
+#define DUMP_WAIT_TIMEOUT (HZ >> 10) /* 1/1024 second */
+
+#define PLD_ADDR_MASK(x) (0x00003FFF & (unsigned long)(x))
+
+enum host_boot_mode {
+ HOST_BOOT_MODE_NORMAL,
+ HOST_BOOT_MODE_DUMP,
+};
+
+enum dpram_init_status {
+ DPRAM_INIT_STATE_NONE,
+ DPRAM_INIT_STATE_READY,
+};
+
+struct dpram_boot_img {
+ char *addr;
+ int size;
+ enum host_boot_mode mode;
+ unsigned req;
+ unsigned resp;
+};
+
+#define MAX_PAYLOAD_SIZE 0x2000
+struct dpram_boot_frame {
+ unsigned req; /* AP->CP request */
+ unsigned resp; /* response expected by AP */
+ ssize_t len; /* data size in the buffer */
+ unsigned offset; /* offset to write into DPRAM */
+ char data[MAX_PAYLOAD_SIZE];
+};
+
+/* buffer type for modem image */
+struct dpram_dump_arg {
+ char *buff; /* pointer to the buffer */
+ int buff_size; /* buffer size */
+ unsigned req; /* AP->CP request */
+ unsigned resp; /* CP->AP response */
+ bool cmd; /* AP->CP command */
+};
+
+struct dpram_firmware {
+ char *firmware;
+ int size;
+ int is_delta;
+};
+enum dpram_link_mode {
+ DPRAM_LINK_MODE_INVALID = 0,
+ DPRAM_LINK_MODE_IPC,
+ DPRAM_LINK_MODE_BOOT,
+ DPRAM_LINK_MODE_DLOAD,
+ DPRAM_LINK_MODE_ULOAD,
+};
+
+struct dpram_boot_map {
+ u32 __iomem *magic;
+ u8 __iomem *buff;
+ u32 __iomem *req;
+ u32 __iomem *resp;
+ u32 size;
+};
+
+struct qc_dpram_boot_map {
+ u8 __iomem *buff;
+ u16 __iomem *frame_size;
+ u16 __iomem *tag;
+ u16 __iomem *count;
+};
+
+struct dpram_dload_map {
+ u32 __iomem *magic;
+ u8 __iomem *buff;
+};
+
+struct dpram_uload_map {
+ u32 __iomem *magic;
+ u8 __iomem *buff;
+};
+
+struct dpram_ota_header {
+ u8 start_index;
+ u16 nframes;
+ u16 curframe;
+ u16 len;
+
+} __packed;
+
+struct ul_header {
+ u8 bop;
+ u16 total_frame;
+ u16 curr_frame;
+ u16 len;
+} __packed;
+
+struct dpram_udl_param {
+ unsigned char *addr;
+ unsigned int size;
+ unsigned int count;
+ unsigned int tag;
+};
+
+struct dpram_udl_check {
+ unsigned int total_size;
+ unsigned int rest_size;
+ unsigned int send_size;
+ unsigned int copy_start;
+ unsigned int copy_complete;
+ unsigned int boot_complete;
+};
+
+#define DP_BOOT_BUFF_OFFSET 4
+#define DP_DLOAD_BUFF_OFFSET 4
+#define DP_ULOAD_BUFF_OFFSET 4
+#define DP_BOOT_REQ_OFFSET 0
+#define DP_BOOT_RESP_OFFSET 8
+
+#define MAX_WQ_NAME_LENGTH 64
+
+#define DPRAM_MAX_RXBQ_SIZE 256
+
+struct dpram_rxb {
+ u8 *buff;
+ unsigned size;
+
+ u8 *data;
+ unsigned len;
+};
+
+struct dpram_rxb_queue {
+ int size;
+ int in;
+ int out;
+ struct dpram_rxb *rxb;
+};
+
+/*
+ mbx_ap2cp + 0x0
+ magic_code +
+ access_enable +
+ padding +
+ mbx_cp2ap + 0x1000
+ magic_code +
+ access_enable +
+ padding +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff + 0x2000
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff + 0x3000
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ = 2 +
+ 4094 +
+ 2 +
+ 4094 +
+ 2 +
+ 2 +
+ 2 + 2 + 1020 +
+ 2 + 2 + 3064 +
+ 2 + 2 + 1020 +
+ 2 + 2 + 3064
+ */
+
+#define DP_PLD_FMT_TX_BUFF_SZ 1024
+#define DP_PLD_RAW_TX_BUFF_SZ 3072
+#define DP_PLD_FMT_RX_BUFF_SZ 1024
+#define DP_PLD_RAW_RX_BUFF_SZ 3072
+
+#define MAX_MSM_EDPRAM_IPC_DEV 2 /* FMT, RAW */
+
+struct dpram_ipc_pld_map {
+ u16 mbx_ap2cp;
+ u16 magic_ap2cp;
+ u16 access_ap2cp;
+ u16 fmt_tx_head;
+ u16 raw_tx_head;
+ u16 fmt_rx_tail;
+ u16 raw_rx_tail;
+ u16 temp1;
+ u8 padding1[4080];
+
+ u16 mbx_cp2ap;
+ u16 magic_cp2ap;
+ u16 access_cp2ap;
+ u16 fmt_tx_tail;
+ u16 raw_tx_tail;
+ u16 fmt_rx_head;
+ u16 raw_rx_head;
+ u16 temp2;
+ u8 padding2[4080];
+
+ u8 fmt_tx_buff[DP_PLD_FMT_TX_BUFF_SZ];
+ u8 raw_tx_buff[DP_PLD_RAW_TX_BUFF_SZ];
+ u8 fmt_rx_buff[DP_PLD_RAW_TX_BUFF_SZ];
+ u8 raw_rx_buff[DP_PLD_RAW_RX_BUFF_SZ];
+
+ u8 padding3[16384];
+
+ u16 address_buffer;
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+#define DP_16K_FMT_TX_BUFF_SZ 1336
+#define DP_16K_RAW_TX_BUFF_SZ 4564
+#define DP_16K_FMT_RX_BUFF_SZ 1336
+#define DP_16K_RAW_RX_BUFF_SZ 9124
+
+struct dpram_ipc_16k_map {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[DP_16K_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[DP_16K_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[DP_16K_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[DP_16K_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+#define DP_MAX_NAME_LEN 32
+
+struct dpram_ext_op;
+
+struct dpram_link_device {
+ struct link_device ld;
+
+ /* The mode of this DPRAM link device */
+ enum dpram_link_mode mode;
+
+ /* DPRAM address and size */
+ u8 __iomem *dp_base; /* DPRAM base virtual address */
+ u32 dp_size; /* DPRAM size */
+ enum dpram_type dp_type; /* DPRAM type */
+
+ /* DPRAM IRQ GPIO# */
+ unsigned gpio_dpram_int;
+
+ /* DPRAM IRQ from CP */
+ int irq;
+ unsigned long irq_flags;
+ char irq_name[DP_MAX_NAME_LEN];
+
+ /* Link to DPRAM control functions dependent on each platform */
+ int max_ipc_dev;
+ struct modemlink_dpram_control *dpctl;
+
+ /* Physical configuration -> logical configuration */
+ union {
+ struct dpram_boot_map bt_map;
+ struct qc_dpram_boot_map qc_bt_map;
+ };
+
+ struct dpram_dload_map dl_map;
+ struct dpram_uload_map ul_map;
+
+ /* IPC device map */
+ struct dpram_ipc_map ipc_map;
+
+ /* Pointers (aliases) to IPC device map */
+ u16 __iomem *magic_ap2cp;
+ u16 __iomem *access_ap2cp;
+ u16 __iomem *magic_cp2ap;
+ u16 __iomem *access_cp2ap;
+ u16 __iomem *address_buffer;
+
+ struct dpram_ipc_device *dev[MAX_IPC_DEV];
+ u16 __iomem *mbx2ap;
+ u16 __iomem *mbx2cp;
+
+ /* Wakelock for DPRAM device */
+ struct wake_lock wlock;
+ char wlock_name[DP_MAX_NAME_LEN];
+
+ /* For booting */
+ unsigned boot_start_complete;
+ struct completion dpram_init_cmd;
+ struct completion modem_pif_init_done;
+
+ /* For UDL */
+ struct tasklet_struct ul_tsk;
+ struct tasklet_struct dl_tsk;
+ struct completion udl_start_complete;
+ struct completion udl_cmd_complete;
+ struct dpram_udl_check udl_check;
+ struct dpram_udl_param udl_param;
+
+ /* For CP RAM dump */
+ struct timer_list crash_ack_timer;
+ struct completion dump_start_complete;
+ struct completion dump_recv_done;
+ struct timer_list dump_timer;
+ int dump_rcvd; /* Count of dump packets received */
+
+ /* For locking TX process */
+ spinlock_t tx_rx_lock;
+ spinlock_t pld_lock;
+
+ /* For efficient RX process */
+ struct tasklet_struct rx_tsk;
+ struct dpram_rxb_queue rxbq[MAX_IPC_DEV];
+ struct io_device *iod[MAX_IPC_DEV];
+ bool use_skb;
+ struct sk_buff_head skb_rxq[MAX_IPC_DEV];
+
+ /* For retransmission after buffer full state */
+ atomic_t res_required[MAX_IPC_DEV];
+
+ /* For wake-up/sleep control */
+ atomic_t accessing;
+
+ /* Multi-purpose miscellaneous buffer */
+ u8 *buff;
+
+ /* DPRAM IPC initialization status */
+ int dpram_init_status;
+
+ /* Alias to device-specific IOCTL function */
+ int (*ext_ioctl)(struct dpram_link_device *dpld, struct io_device *iod,
+ unsigned int cmd, unsigned long arg);
+
+ /* For DPRAM dump */
+ void (*dpram_dump)(struct link_device *ld, char *buff);
+
+ /* Common operations for each DPRAM */
+ void (*clear_intr)(struct dpram_link_device *dpld);
+ u16 (*recv_intr)(struct dpram_link_device *dpld);
+ void (*send_intr)(struct dpram_link_device *dpld, u16 mask);
+ u16 (*get_magic)(struct dpram_link_device *dpld);
+ void (*set_magic)(struct dpram_link_device *dpld, u16 value);
+ u16 (*get_access)(struct dpram_link_device *dpld);
+ void (*set_access)(struct dpram_link_device *dpld, u16 value);
+ u32 (*get_tx_head)(struct dpram_link_device *dpld, int id);
+ u32 (*get_tx_tail)(struct dpram_link_device *dpld, int id);
+ void (*set_tx_head)(struct dpram_link_device *dpld, int id, u32 head);
+ void (*set_tx_tail)(struct dpram_link_device *dpld, int id, u32 tail);
+ u8 *(*get_tx_buff)(struct dpram_link_device *dpld, int id);
+ u32 (*get_tx_buff_size)(struct dpram_link_device *dpld, int id);
+ u32 (*get_rx_head)(struct dpram_link_device *dpld, int id);
+ u32 (*get_rx_tail)(struct dpram_link_device *dpld, int id);
+ void (*set_rx_head)(struct dpram_link_device *dpld, int id, u32 head);
+ void (*set_rx_tail)(struct dpram_link_device *dpld, int id, u32 tail);
+ u8 *(*get_rx_buff)(struct dpram_link_device *dpld, int id);
+ u32 (*get_rx_buff_size)(struct dpram_link_device *dpld, int id);
+ u16 (*get_mask_req_ack)(struct dpram_link_device *dpld, int id);
+ u16 (*get_mask_res_ack)(struct dpram_link_device *dpld, int id);
+ u16 (*get_mask_send)(struct dpram_link_device *dpld, int id);
+
+ /* Extended operations for various modems */
+ struct dpram_ext_op *ext_op;
+};
+
+/* converts from struct link_device* to struct xxx_link_device* */
+#define to_dpram_link_device(linkdev) \
+ container_of(linkdev, struct dpram_link_device, ld)
+
+struct dpram_ext_op {
+ int exist;
+
+ void (*init_boot_map)(struct dpram_link_device *dpld);
+ void (*init_dl_map)(struct dpram_link_device *dpld);
+ void (*init_ul_map)(struct dpram_link_device *dpld);
+
+ int (*dload_bin)(struct dpram_link_device *dpld, struct sk_buff *skb);
+ void (*dload_cmd_handler)(struct dpram_link_device *dpld, u16 cmd);
+
+ void (*cp_start_handler)(struct dpram_link_device *dpld);
+
+ void (*crash_log)(struct dpram_link_device *dpld);
+ int (*dump_start)(struct dpram_link_device *dpld);
+ int (*dump_update)(struct dpram_link_device *dpld, void *arg);
+
+ int (*ioctl)(struct dpram_link_device *dpld, struct io_device *iod,
+ unsigned int cmd, unsigned long arg);
+};
+
+struct dpram_ext_op *dpram_get_ext_op(enum modem_t modem);
+#endif