diff options
Diffstat (limited to 'drivers/misc/modem_if/modem_link_device_pld.h')
-rw-r--r-- | drivers/misc/modem_if/modem_link_device_pld.h | 532 |
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 |