123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- #ifndef _SPI_Q2SPI_MSM_H_
- #define _SPI_Q2SPI_MSM_H_
- #include <linux/cdev.h>
- #include <linux/idr.h>
- #include <linux/ipc_logging.h>
- #include <linux/kthread.h>
- #include <linux/msm_gpi.h>
- #include <linux/poll.h>
- #include <linux/soc/qcom/geni-se.h>
- #include <linux/qcom-geni-se-common.h>
- #include <linux/types.h>
- #include <uapi/linux/q2spi/q2spi.h>
- #include "q2spi-gsi.h"
- #define DATA_WORD_LEN 4
- #define SMA_BUF_SIZE (4096)
- #define MAX_CR_SIZE 24
- #define MAX_RX_CRS 4
- #define RX_DMA_CR_BUF_SIZE (MAX_CR_SIZE * MAX_RX_CRS)
- #define Q2SPI_MAX_BUF 2
- #define Q2SPI_MAX_RESP_BUF 40
- #define Q2SPI_RESP_BUF_SIZE SMA_BUF_SIZE
- #define XFER_TIMEOUT_OFFSET (250)
- #define Q2SPI_RESPONSE_WAIT_TIMEOUT (1000)
- #define EXT_CR_TIMEOUT_MSECS (50)
- #define TIMEOUT_MSECONDS 10
- #define RETRIES 1
- #define Q2SPI_MAX_DATA_LEN 4096
- #define Q2SPI_MAX_TX_RETRIES 5
- #define HC_DB_REPORT_LEN_READ 1
- #define HC_DB_REPORT_BODY_READ 2
- #define HC_ABORT 3
- #define HC_DATA_READ 5
- #define HC_DATA_WRITE 6
- #define HC_SMA_READ 5
- #define HC_SMA_WRITE 6
- #define HC_SOFT_RESET 0xF
- #define CM_FLOW 1
- #define MC_FLOW 0
- #define CLIENT_INTERRUPT 1
- #define SEGMENT_LST 1
- #define LOCAL_REG_ACCESS 0
- #define SYSTEM_MEMORY_ACCESS 1
- #define CLIENT_ADDRESS 1
- #define NO_CLIENT_ADDRESS 0
- #define HC_SOFT_RESET_FLAGS 0xF
- #define HC_SOFT_RESET_CODE 0x2
- #define ADDR_LESS_WR_ACCESS 0x3
- #define ADDR_LESS_RD_ACCESS 0x4
- #define BULK_ACCESS_STATUS 0x8
- #define CR_EXTENSION 0xF
- #define CR_ADDR_LESS_WR 0xE3
- #define CR_ADDR_LESS_RD 0xF4
- #define CR_BULK_ACCESS_STATUS 0x98
- #define Q2SPI_HEADER_LEN 7
- #define DMA_Q2SPI_SIZE 2048
- #define MAX_DW_LEN_1 4
- #define MAX_DW_LEN_2 1024
- #define CS_LESS_MODE 0
- #define INTR_HIGH_POLARITY 1
- #define MAX_TX_SG (3)
- #define NUM_Q2SPI_XFER (10)
- #define Q2SPI_START_TID_ID (0)
- #define Q2SPI_END_TID_ID (8)
- #define IO_MACRO_IO3_DATA_IN_SEL_MASK GENMASK(15, 14)
- #define IO_MACRO_IO3_DATA_IN_SEL_SHIFT 14
- #define IO_MACRO_IO3_DATA_IN_SEL 1
- #define SE_SPI_TRANS_CFG 0x25c
- #define CS_TOGGLE BIT(1)
- #define SPI_NOT_USED_CFG1 BIT(2)
- #define SE_SPI_PRE_POST_CMD_DLY 0x274
- #define SPI_DELAYS_COUNTERS 0x278
- #define M_GP_CNT4_TAN 0
- #define M_GP_CNT4_TAN_MASK GENMASK(9, 0)
- #define M_GP_CNT5_TE2D GENMASK(19, 10)
- #define M_GP_CNT5_TE2D_SHIFT 10
- #define M_GP_CNT6_CN GENMASK(29, 20)
- #define M_GP_CNT6_CN_SHIFT 20
- #define SE_GENI_CFG_REG95 0x27C
- #define M_GP_CNT7 GENMASK(9, 0)
- #define M_GP_CNT7_TSN 0
- #define SPI_INTER_WORDS_DLY 0
- #define SPI_CS_CLK_DLY 0x80
- #define SPI_PIPE_DLY_TPM 0x320
- #define SE_GENI_CFG_REG103 0x29C
- #define S_GP_CNT5 GENMASK(19, 10)
- #define S_GP_CNT5_SHIFT 10
- #define S_GP_CNT5_TDN 0
- #define SE_GENI_CFG_REG104 0x2A0
- #define S_GP_CNT7 GENMASK(9, 0)
- #define S_GP_CNT7_SSN 0x80
- #define M_GP_CNT6_CN_DELAY 0x50
- #define SE_SPI_WORD_LEN 0x268
- #define WORD_LEN_MSK GENMASK(9, 0)
- #define MIN_WORD_LEN 4
- #define NUMBER_OF_DATA_LINES GENMASK(1, 0)
- #define PARAM_14 BIT(14)
- #define SE_GENI_CGC_CTRL 0x28
- #define SE_GENI_CFG_SEQ_START 0x84
- #define SE_GENI_CFG_STATUS 0x88
- #define SE_UART_TX_TRANS_CFG 0x25C
- #define CFG_SEQ_DONE BIT(1)
- #define SPI_CS_CLK_DL 0
- #define SPI_PRE_POST_CMD_DLY 0
- #define SE_SPI_CPHA 0x224
- #define CPHA BIT(0)
- #define SE_SPI_CPOL 0x230
- #define CPOL BIT(2)
- #define SPI_LSB_TO_MSB 0
- #define SPI_MSB_TO_LSB 1
- #define SE_SPI_TX_TRANS_LEN 0x26c
- #define SE_SPI_RX_TRANS_LEN 0x270
- #define TRANS_LEN_MSK GENMASK(23, 0)
- #define HRF_ENTRY_OPCODE 3
- #define HRF_ENTRY_TYPE 3
- #define HRF_ENTRY_FLOW 0
- #define HRF_ENTRY_PARITY 0
- #define HRF_ENTRY_DATA_LEN 16
- #define Q2SPI_CLIENT_SLEEP_BYTE 0xFE
- #define Q2SPI_SLEEP_OPCODE 0xF
- #define LRA_SINGLE_REG_LENGTH 4
- #define Q2SPI_TX_ONLY (1)
- #define Q2SPI_RX_ONLY (2)
- #define Q2SPI_TX_RX (7)
- #define PRE_CMD_DELAY BIT(0)
- #define TIMESTAMP_BEFORE BIT(1)
- #define TIMESTAMP_AFTER BIT(3)
- #define POST_CMD_DELAY BIT(4)
- #define Q2SPI_MODE GENMASK(11, 8)
- #define Q2SPI_MODE_SHIFT 8
- #define SINGLE_SDR_MODE 0
- #define Q2SPI_CMD BIT(14)
- #define CS_MODE CS_LESS_MODE
- #define Q2SPI_INTR_POL INTR_HIGH_POLARITY
- #define CR_BULK_DATA_SIZE 1
- #define CR_DMA_DATA_SIZE 7
- #define CR_EXTENSION_DATA_BYTES 5
- #define Q2SPI_HRF_SLEEP_CMD 0x100
- #define Q2SPI_AUTOSUSPEND_DELAY (XFER_TIMEOUT_OFFSET + 3000)
- #define PINCTRL_DEFAULT "default"
- #define PINCTRL_ACTIVE "active"
- #define PINCTRL_SLEEP "sleep"
- #define PINCTRL_SHUTDOWN "shutdown"
- #define MAX_DEV 2
- #define DEVICE_NAME_MAX_LEN 64
- #define QSPI_NUM_CS 2
- #define QSPI_BYTES_PER_WORD 4
- #define Q2SPI_RESP_BUF_RETRIES (100)
- #define Q2SPI_INFO(q2spi_ptr, x...) do { \
- if (q2spi_ptr) { \
- ipc_log_string(q2spi_ptr->ipc, x); \
- if (q2spi_ptr->dev) \
- q2spi_trace_log(q2spi_ptr->dev, x); \
- pr_info(x); \
- } \
- } while (0)
- #define Q2SPI_DEBUG(q2spi_ptr, x...) do { \
- if (q2spi_ptr) { \
- GENI_SE_DBG(q2spi_ptr->ipc, false, q2spi_ptr->dev, x); \
- if (q2spi_ptr->dev) \
- q2spi_trace_log(q2spi_ptr->dev, x); \
- } \
- } while (0)
- #define Q2SPI_ERROR(q2spi_ptr, x...) do { \
- if (q2spi_ptr) { \
- GENI_SE_ERR(q2spi_ptr->ipc, true, q2spi_ptr->dev, x); \
- if (q2spi_ptr->dev) \
- q2spi_trace_log(q2spi_ptr->dev, x); \
- } \
- } while (0)
- #define DATA_BYTES_PER_LINE (64)
- #define Q2SPI_DATA_DUMP_SIZE (16)
- static unsigned int q2spi_max_speed;
- static int q2spi_cdev_major;
- static bool q2spi_sys_restart;
- enum abort_code {
- TERMINATE_CMD = 0,
- ERR_DUPLICATE_ID = 1,
- ERR_NOT_VALID = 2,
- ERR_ACCESS_BLOCKED = 3,
- ERR_DWLEN = 4,
- OTHERS = 5,
- };
- enum q2spi_pkt_state {
- NOT_IN_USE = 0,
- IN_USE = 1,
- DATA_AVAIL = 2,
- IN_DELETION = 3,
- DELETED = 4,
- };
- enum q2spi_cr_hdr_type {
- CR_HDR_BULK = 1,
- CR_HDR_VAR3 = 2,
- CR_HDR_EXT = 3,
- };
- struct q2spi_mc_hrf_entry {
- u8 cmd:4;
- u8 flow:1;
- u8 type:2;
- u8 parity:1;
- u8 resrv_0:4;
- u8 flow_id:4;
- u8 resrv_1:4;
- u8 dwlen_part1:4;
- u8 dwlen_part2:8;
- u8 dwlen_part3:8;
- u8 arg1:8;
- u8 arg2:8;
- u8 arg3:8;
- u8 reserved[8];
- };
- struct q2spi_cr_header {
- u8 cmd:4;
- u8 flow:1;
- u8 type:2;
- u8 parity:1;
- };
- struct q2spi_ext_cr_header {
- u8 cmd:4;
- u8 dw_len:2;
- u8 rsvd:1;
- u8 parity:1;
- };
- struct q2spi_client_bulk_access_pkt {
- u8 cmd:4;
- u8 flow:1;
- u8 rsvd:2;
- u8 parity:1;
- u8 status:4;
- u8 flow_id:4;
- u8 reserved[2];
- };
- struct q2spi_client_dma_pkt {
- u8 seg_len:4;
- u8 flow_id:4;
- u8 interrupt:1;
- u8 seg_last:1;
- u8 channel:2;
- u8 dw_len_part1:4;
- u8 dw_len_part2:8;
- u8 dw_len_part3:8;
- u8 arg1:8;
- u8 arg2:8;
- u8 arg3:8;
- };
- struct q2spi_host_variant1_pkt {
- u8 cmd:4;
- u8 flow:1;
- u8 interrupt:1;
- u8 seg_last:1;
- u8 rsvd:1;
- u8 dw_len:2;
- u8 access_type:1;
- u8 address_mode:1;
- u8 flow_id:4;
- u8 reg_offset;
- u8 reserved[4];
- u8 data_buf[16];
- u8 status;
- };
- struct q2spi_host_variant4_5_pkt {
- u8 cmd:4;
- u8 flow:1;
- u8 interrupt:1;
- u8 seg_last:1;
- u8 rsvd:1;
- u8 dw_len_part1:2;
- u8 access_type:1;
- u8 address_mode:1;
- u8 flow_id:4;
- u8 dw_len_part2;
- u8 rsvd_1[4];
- u8 data_buf[4096];
- u8 status;
- };
- struct q2spi_host_abort_pkt {
- u8 cmd:4;
- u8 rsvd:4;
- u8 code:4;
- u8 flow_id:4;
- u8 reserved[5];
- };
- struct q2spi_host_soft_reset_pkt {
- u8 cmd:4;
- u8 flags:4;
- u8 code:4;
- u8 rsvd:4;
- u8 rsvd_1[5];
- };
- enum cr_var_type {
- VARIANT_T_3 = 1,
- VARIANT_T_4 = 2,
- VARIANT_T_5 = 3,
- };
- enum var_type {
- VARIANT_1_LRA = 1,
- VARIANT_1_HRF = 2,
- VARIANT_2 = 3,
- VARIANT_3 = 4,
- VARIANT_4 = 5,
- VARIANT_5 = 6,
- VARIANT_5_HRF = 7,
- VAR_ABORT = 8,
- VAR_SOFT_RESET = 9,
- };
- struct q2spi_chrdev {
- dev_t q2spi_dev;
- struct cdev cdev[MAX_DEV];
- int major;
- int minor;
- struct device *dev;
- char dev_name[DEVICE_NAME_MAX_LEN];
- struct device *class_dev;
- struct class *q2spi_class;
- };
- struct q2spi_dma_transfer {
- void *tx_buf;
- void *rx_buf;
- unsigned int tx_len;
- unsigned int rx_len;
- unsigned int tx_data_len;
- unsigned int rx_data_len;
- dma_addr_t tx_dma;
- dma_addr_t rx_dma;
- enum cmd_type cmd;
- int tid;
- struct list_head queue;
- struct q2spi_packet *q2spi_pkt;
- };
- struct q2spi_geni {
- struct device *wrapper_dev;
- struct device *dev;
- void __iomem *base;
- struct clk *m_ahb_clk;
- struct clk *s_ahb_clk;
- struct clk *se_clk;
- struct pinctrl *geni_pinctrl;
- struct pinctrl_state *geni_gpio_default;
- struct pinctrl_state *geni_gpio_active;
- struct pinctrl_state *geni_gpio_sleep;
- struct pinctrl_state *geni_gpio_shutdown;
- struct q2spi_chrdev chrdev;
- struct geni_se se;
- struct q2spi_gsi *gsi;
- bool qup_gsi_err;
- struct q2spi_dma_transfer *db_xfer;
- struct q2spi_request *req;
- struct q2spi_client_request *c_req;
- bool setup_config0;
- int irq;
- struct list_head tx_queue_list;
- struct kthread_worker *kworker;
- struct kthread_work send_messages;
-
- struct mutex gsi_lock;
-
- spinlock_t txn_lock;
-
- struct mutex queue_lock;
-
- struct mutex send_msgs_lock;
-
- spinlock_t cr_queue_lock;
-
- struct mutex geni_resource_lock;
- u32 max_speed_hz;
- u32 cur_speed_hz;
- int oversampling;
- int xfer_mode;
- int cur_xfer_mode;
- bool gsi_mode;
- struct completion tx_cb;
- struct completion rx_cb;
- struct completion db_rx_cb;
- struct completion wait_for_ext_cr;
- atomic_t rx_avail;
- struct idr tid_idr;
- wait_queue_head_t readq;
- void *rx_buf;
- dma_addr_t rx_dma;
- bool hrf_flow;
- struct q2spi_packet *db_q2spi_pkt;
- struct completion db_setup_wait;
- void *var1_buf[Q2SPI_MAX_BUF];
- dma_addr_t var1_dma_buf[Q2SPI_MAX_BUF];
- void *var1_buf_used[Q2SPI_MAX_BUF];
- void *var5_buf[Q2SPI_MAX_BUF];
- dma_addr_t var5_dma_buf[Q2SPI_MAX_BUF];
- void *var5_buf_used[Q2SPI_MAX_BUF];
- void *cr_buf[Q2SPI_MAX_BUF];
- dma_addr_t cr_dma_buf[Q2SPI_MAX_BUF];
- void *cr_buf_used[Q2SPI_MAX_BUF];
- void *bulk_buf[Q2SPI_MAX_BUF];
- dma_addr_t bulk_dma_buf[Q2SPI_MAX_BUF];
- void *bulk_buf_used[Q2SPI_MAX_BUF];
- void *resp_buf[Q2SPI_MAX_RESP_BUF];
- dma_addr_t resp_dma_buf[Q2SPI_MAX_RESP_BUF];
- void *resp_buf_used[Q2SPI_MAX_RESP_BUF];
- dma_addr_t dma_buf;
- struct completion sma_wait;
- void *ipc;
- struct work_struct q2spi_doorbell_work;
- struct workqueue_struct *doorbell_wq;
- struct work_struct q2spi_wakeup_work;
- struct workqueue_struct *wakeup_wq;
- bool doorbell_setup;
- struct qup_q2spi_cr_header_event q2spi_cr_hdr_event;
- wait_queue_head_t read_wq;
- bool hw_state_is_bad;
- int max_data_dump_size;
- atomic_t doorbell_pending;
- atomic_t retry;
- atomic_t alloc_count;
- atomic_t sma_wr_pending;
- atomic_t sma_rd_pending;
- struct completion sma_wr_comp;
- struct completion sma_rd_comp;
- bool resources_on;
- bool port_release;
- atomic_t is_suspend;
- u32 m_clk_cfg;
- int doorbell_irq;
- int wake_clk_gpio;
- int wake_mosi_gpio;
- };
- struct q2spi_client_extension_pkt {
- u8 cmd:4;
- u8 dw_len:1;
- u8 reserved:1;
- u8 parity:1;
- u8 extid:8;
- u8 byte[16];
- };
- struct q2spi_cr_packet {
- struct q2spi_cr_header cr_hdr[4];
- struct q2spi_ext_cr_header ext_cr_hdr;
- struct q2spi_client_dma_pkt var3_pkt[4];
- struct q2spi_client_bulk_access_pkt bulk_pkt[4];
- struct q2spi_client_extension_pkt extension_pkt;
- u8 cr_hdr_type[4];
- int num_valid_crs;
- };
- struct q2spi_packet {
- unsigned int m_cmd_param;
- struct q2spi_host_variant1_pkt *var1_pkt;
- struct q2spi_host_variant4_5_pkt *var4_pkt;
- struct q2spi_host_variant4_5_pkt *var5_pkt;
- struct q2spi_host_abort_pkt *abort_pkt;
- struct q2spi_host_soft_reset_pkt *soft_reset_pkt;
- struct q2spi_dma_transfer *xfer;
- enum var_type vtype;
- bool valid;
- u8 flow_id;
- enum xfer_status status;
- dma_addr_t var1_tx_dma;
- dma_addr_t var5_tx_dma;
- dma_addr_t var1_rx_dma;
- dma_addr_t var5_rx_dma;
- dma_addr_t soft_reset_tx_dma;
- bool sync;
- struct q2spi_geni *q2spi;
- struct list_head list;
- u8 state;
- unsigned int data_length;
- struct completion bulk_wait;
- struct completion wait_for_db;
-
- struct q2spi_cr_header cr_hdr;
- struct q2spi_client_dma_pkt cr_var3;
- struct q2spi_client_bulk_access_pkt cr_bulk;
- int cr_hdr_type;
- int var3_data_len;
- bool is_client_sleep_pkt;
- };
- void q2spi_doorbell(struct q2spi_geni *q2spi, const struct qup_q2spi_cr_header_event *event);
- void q2spi_gsi_ch_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb, void *ptr);
- void q2spi_geni_se_dump_regs(struct q2spi_geni *q2spi);
- void q2spi_dump_ipc(struct q2spi_geni *q2spi, void *ipc_ctx, char *prefix, char *str, int size);
- void q2spi_trace_log(struct device *dev, const char *fmt, ...);
- void dump_ipc(struct q2spi_geni *q2spi, void *ctx, char *prefix, char *str, int size);
- void *q2spi_kzalloc(struct q2spi_geni *q2spi, int size, int line);
- void q2spi_kfree(struct q2spi_geni *q2spi, void *ptr, int line);
- int q2spi_setup_gsi_xfer(struct q2spi_packet *q2spi_pkt);
- int q2spi_alloc_xfer_tid(struct q2spi_geni *q2spi);
- int q2spi_geni_gsi_setup(struct q2spi_geni *q2spi);
- void q2spi_geni_gsi_release(struct q2spi_geni *q2spi);
- int check_gsi_transfer_completion(struct q2spi_geni *q2spi);
- int check_gsi_transfer_completion_db_rx(struct q2spi_geni *q2spi);
- int q2spi_read_reg(struct q2spi_geni *q2spi, int reg_offset);
- void q2spi_dump_client_error_regs(struct q2spi_geni *q2spi);
- int q2spi_geni_resources_on(struct q2spi_geni *q2spi);
- void q2spi_geni_resources_off(struct q2spi_geni *q2spi);
- int __q2spi_send_messages(struct q2spi_geni *q2spi, void *ptr);
- int q2spi_wakeup_hw_through_gpio(struct q2spi_geni *q2spi);
- int q2spi_process_hrf_flow_after_lra(struct q2spi_geni *q2spi, struct q2spi_packet *q2spi_pkt);
- void q2spi_transfer_soft_reset(struct q2spi_geni *q2spi);
- #endif
|