0001
0002
0003
0004
0005
0006
0007 #ifndef _MHI_EP_INTERNAL_
0008 #define _MHI_EP_INTERNAL_
0009
0010 #include <linux/bitfield.h>
0011
0012 #include "../common.h"
0013
0014 extern struct bus_type mhi_ep_bus_type;
0015
0016 #define MHI_REG_OFFSET 0x100
0017 #define BHI_REG_OFFSET 0x200
0018
0019
0020 #define EP_MHIREGLEN (MHI_REG_OFFSET + MHIREGLEN)
0021 #define EP_MHIVER (MHI_REG_OFFSET + MHIVER)
0022 #define EP_MHICFG (MHI_REG_OFFSET + MHICFG)
0023 #define EP_CHDBOFF (MHI_REG_OFFSET + CHDBOFF)
0024 #define EP_ERDBOFF (MHI_REG_OFFSET + ERDBOFF)
0025 #define EP_BHIOFF (MHI_REG_OFFSET + BHIOFF)
0026 #define EP_BHIEOFF (MHI_REG_OFFSET + BHIEOFF)
0027 #define EP_DEBUGOFF (MHI_REG_OFFSET + DEBUGOFF)
0028 #define EP_MHICTRL (MHI_REG_OFFSET + MHICTRL)
0029 #define EP_MHISTATUS (MHI_REG_OFFSET + MHISTATUS)
0030 #define EP_CCABAP_LOWER (MHI_REG_OFFSET + CCABAP_LOWER)
0031 #define EP_CCABAP_HIGHER (MHI_REG_OFFSET + CCABAP_HIGHER)
0032 #define EP_ECABAP_LOWER (MHI_REG_OFFSET + ECABAP_LOWER)
0033 #define EP_ECABAP_HIGHER (MHI_REG_OFFSET + ECABAP_HIGHER)
0034 #define EP_CRCBAP_LOWER (MHI_REG_OFFSET + CRCBAP_LOWER)
0035 #define EP_CRCBAP_HIGHER (MHI_REG_OFFSET + CRCBAP_HIGHER)
0036 #define EP_CRDB_LOWER (MHI_REG_OFFSET + CRDB_LOWER)
0037 #define EP_CRDB_HIGHER (MHI_REG_OFFSET + CRDB_HIGHER)
0038 #define EP_MHICTRLBASE_LOWER (MHI_REG_OFFSET + MHICTRLBASE_LOWER)
0039 #define EP_MHICTRLBASE_HIGHER (MHI_REG_OFFSET + MHICTRLBASE_HIGHER)
0040 #define EP_MHICTRLLIMIT_LOWER (MHI_REG_OFFSET + MHICTRLLIMIT_LOWER)
0041 #define EP_MHICTRLLIMIT_HIGHER (MHI_REG_OFFSET + MHICTRLLIMIT_HIGHER)
0042 #define EP_MHIDATABASE_LOWER (MHI_REG_OFFSET + MHIDATABASE_LOWER)
0043 #define EP_MHIDATABASE_HIGHER (MHI_REG_OFFSET + MHIDATABASE_HIGHER)
0044 #define EP_MHIDATALIMIT_LOWER (MHI_REG_OFFSET + MHIDATALIMIT_LOWER)
0045 #define EP_MHIDATALIMIT_HIGHER (MHI_REG_OFFSET + MHIDATALIMIT_HIGHER)
0046
0047
0048 #define EP_BHI_INTVEC (BHI_REG_OFFSET + BHI_INTVEC)
0049 #define EP_BHI_EXECENV (BHI_REG_OFFSET + BHI_EXECENV)
0050
0051
0052 #define CHDB_LOWER_n(n) (0x400 + 0x8 * (n))
0053 #define CHDB_HIGHER_n(n) (0x404 + 0x8 * (n))
0054 #define ERDB_LOWER_n(n) (0x800 + 0x8 * (n))
0055 #define ERDB_HIGHER_n(n) (0x804 + 0x8 * (n))
0056
0057 #define MHI_CTRL_INT_STATUS 0x4
0058 #define MHI_CTRL_INT_STATUS_MSK BIT(0)
0059 #define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1)
0060 #define MHI_CHDB_INT_STATUS_n(n) (0x28 + 0x4 * (n))
0061 #define MHI_ERDB_INT_STATUS_n(n) (0x38 + 0x4 * (n))
0062
0063 #define MHI_CTRL_INT_CLEAR 0x4c
0064 #define MHI_CTRL_INT_MMIO_WR_CLEAR BIT(2)
0065 #define MHI_CTRL_INT_CRDB_CLEAR BIT(1)
0066 #define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR BIT(0)
0067
0068 #define MHI_CHDB_INT_CLEAR_n(n) (0x70 + 0x4 * (n))
0069 #define MHI_CHDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0)
0070 #define MHI_ERDB_INT_CLEAR_n(n) (0x80 + 0x4 * (n))
0071 #define MHI_ERDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0)
0072
0073
0074
0075
0076
0077 #define MHI_CTRL_INT_MASK 0x94
0078 #define MHI_CTRL_INT_MASK_MASK GENMASK(1, 0)
0079 #define MHI_CTRL_MHICTRL_MASK BIT(0)
0080 #define MHI_CTRL_CRDB_MASK BIT(1)
0081
0082 #define MHI_CHDB_INT_MASK_n(n) (0xb8 + 0x4 * (n))
0083 #define MHI_CHDB_INT_MASK_n_EN_ALL GENMASK(31, 0)
0084 #define MHI_ERDB_INT_MASK_n(n) (0xc8 + 0x4 * (n))
0085 #define MHI_ERDB_INT_MASK_n_EN_ALL GENMASK(31, 0)
0086
0087 #define NR_OF_CMD_RINGS 1
0088 #define MHI_MASK_ROWS_CH_DB 4
0089 #define MHI_MASK_ROWS_EV_DB 4
0090 #define MHI_MASK_CH_LEN 32
0091 #define MHI_MASK_EV_LEN 32
0092
0093
0094 struct mhi_generic_ctx {
0095 __le32 reserved0;
0096 __le32 reserved1;
0097 __le32 reserved2;
0098
0099 __le64 rbase __packed __aligned(4);
0100 __le64 rlen __packed __aligned(4);
0101 __le64 rp __packed __aligned(4);
0102 __le64 wp __packed __aligned(4);
0103 };
0104
0105 enum mhi_ep_ring_type {
0106 RING_TYPE_CMD,
0107 RING_TYPE_ER,
0108 RING_TYPE_CH,
0109 };
0110
0111
0112 union mhi_ep_ring_ctx {
0113 struct mhi_cmd_ctxt cmd;
0114 struct mhi_event_ctxt ev;
0115 struct mhi_chan_ctxt ch;
0116 struct mhi_generic_ctx generic;
0117 };
0118
0119 struct mhi_ep_ring_item {
0120 struct list_head node;
0121 struct mhi_ep_ring *ring;
0122 };
0123
0124 struct mhi_ep_ring {
0125 struct mhi_ep_cntrl *mhi_cntrl;
0126 union mhi_ep_ring_ctx *ring_ctx;
0127 struct mhi_ring_element *ring_cache;
0128 enum mhi_ep_ring_type type;
0129 u64 rbase;
0130 size_t rd_offset;
0131 size_t wr_offset;
0132 size_t ring_size;
0133 u32 db_offset_h;
0134 u32 db_offset_l;
0135 u32 ch_id;
0136 u32 er_index;
0137 u32 irq_vector;
0138 bool started;
0139 };
0140
0141 struct mhi_ep_cmd {
0142 struct mhi_ep_ring ring;
0143 };
0144
0145 struct mhi_ep_event {
0146 struct mhi_ep_ring ring;
0147 };
0148
0149 struct mhi_ep_state_transition {
0150 struct list_head node;
0151 enum mhi_state state;
0152 };
0153
0154 struct mhi_ep_chan {
0155 char *name;
0156 struct mhi_ep_device *mhi_dev;
0157 struct mhi_ep_ring ring;
0158 struct mutex lock;
0159 void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result);
0160 enum mhi_ch_state state;
0161 enum dma_data_direction dir;
0162 u64 tre_loc;
0163 u32 tre_size;
0164 u32 tre_bytes_left;
0165 u32 chan;
0166 bool skip_td;
0167 };
0168
0169
0170 void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id);
0171 void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring);
0172 int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
0173 union mhi_ep_ring_ctx *ctx);
0174 size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr);
0175 int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *element);
0176 void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring);
0177 int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring);
0178
0179
0180 u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset);
0181 void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val);
0182 void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val);
0183 u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask);
0184 void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0185 void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0186 void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0187 void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0188 void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
0189 void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
0190 void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0191 bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0192 void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0193 void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl);
0194 void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl);
0195 void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl);
0196 u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring);
0197 void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value);
0198 void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl);
0199 void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl);
0200 void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state,
0201 bool *mhi_reset);
0202 void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl);
0203 void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl);
0204
0205
0206 int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state);
0207 int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env);
0208 bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state,
0209 enum mhi_state mhi_state);
0210 int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state);
0211 int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl);
0212 int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl);
0213 int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl);
0214 void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl);
0215 void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl);
0216 void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl);
0217
0218 #endif