1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2022, Linaro Ltd. 4 * 5 */ 6 7 #ifndef _MHI_EP_INTERNAL_ 8 #define _MHI_EP_INTERNAL_ 9 10 #include <linux/bitfield.h> 11 12 #include "../common.h" 13 14 extern struct bus_type mhi_ep_bus_type; 15 16 #define MHI_REG_OFFSET 0x100 17 #define BHI_REG_OFFSET 0x200 18 19 /* MHI registers */ 20 #define EP_MHIREGLEN (MHI_REG_OFFSET + MHIREGLEN) 21 #define EP_MHIVER (MHI_REG_OFFSET + MHIVER) 22 #define EP_MHICFG (MHI_REG_OFFSET + MHICFG) 23 #define EP_CHDBOFF (MHI_REG_OFFSET + CHDBOFF) 24 #define EP_ERDBOFF (MHI_REG_OFFSET + ERDBOFF) 25 #define EP_BHIOFF (MHI_REG_OFFSET + BHIOFF) 26 #define EP_BHIEOFF (MHI_REG_OFFSET + BHIEOFF) 27 #define EP_DEBUGOFF (MHI_REG_OFFSET + DEBUGOFF) 28 #define EP_MHICTRL (MHI_REG_OFFSET + MHICTRL) 29 #define EP_MHISTATUS (MHI_REG_OFFSET + MHISTATUS) 30 #define EP_CCABAP_LOWER (MHI_REG_OFFSET + CCABAP_LOWER) 31 #define EP_CCABAP_HIGHER (MHI_REG_OFFSET + CCABAP_HIGHER) 32 #define EP_ECABAP_LOWER (MHI_REG_OFFSET + ECABAP_LOWER) 33 #define EP_ECABAP_HIGHER (MHI_REG_OFFSET + ECABAP_HIGHER) 34 #define EP_CRCBAP_LOWER (MHI_REG_OFFSET + CRCBAP_LOWER) 35 #define EP_CRCBAP_HIGHER (MHI_REG_OFFSET + CRCBAP_HIGHER) 36 #define EP_CRDB_LOWER (MHI_REG_OFFSET + CRDB_LOWER) 37 #define EP_CRDB_HIGHER (MHI_REG_OFFSET + CRDB_HIGHER) 38 #define EP_MHICTRLBASE_LOWER (MHI_REG_OFFSET + MHICTRLBASE_LOWER) 39 #define EP_MHICTRLBASE_HIGHER (MHI_REG_OFFSET + MHICTRLBASE_HIGHER) 40 #define EP_MHICTRLLIMIT_LOWER (MHI_REG_OFFSET + MHICTRLLIMIT_LOWER) 41 #define EP_MHICTRLLIMIT_HIGHER (MHI_REG_OFFSET + MHICTRLLIMIT_HIGHER) 42 #define EP_MHIDATABASE_LOWER (MHI_REG_OFFSET + MHIDATABASE_LOWER) 43 #define EP_MHIDATABASE_HIGHER (MHI_REG_OFFSET + MHIDATABASE_HIGHER) 44 #define EP_MHIDATALIMIT_LOWER (MHI_REG_OFFSET + MHIDATALIMIT_LOWER) 45 #define EP_MHIDATALIMIT_HIGHER (MHI_REG_OFFSET + MHIDATALIMIT_HIGHER) 46 47 /* MHI BHI registers */ 48 #define EP_BHI_INTVEC (BHI_REG_OFFSET + BHI_INTVEC) 49 #define EP_BHI_EXECENV (BHI_REG_OFFSET + BHI_EXECENV) 50 51 /* MHI Doorbell registers */ 52 #define CHDB_LOWER_n(n) (0x400 + 0x8 * (n)) 53 #define CHDB_HIGHER_n(n) (0x404 + 0x8 * (n)) 54 #define ERDB_LOWER_n(n) (0x800 + 0x8 * (n)) 55 #define ERDB_HIGHER_n(n) (0x804 + 0x8 * (n)) 56 57 #define MHI_CTRL_INT_STATUS 0x4 58 #define MHI_CTRL_INT_STATUS_MSK BIT(0) 59 #define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1) 60 #define MHI_CHDB_INT_STATUS_n(n) (0x28 + 0x4 * (n)) 61 #define MHI_ERDB_INT_STATUS_n(n) (0x38 + 0x4 * (n)) 62 63 #define MHI_CTRL_INT_CLEAR 0x4c 64 #define MHI_CTRL_INT_MMIO_WR_CLEAR BIT(2) 65 #define MHI_CTRL_INT_CRDB_CLEAR BIT(1) 66 #define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR BIT(0) 67 68 #define MHI_CHDB_INT_CLEAR_n(n) (0x70 + 0x4 * (n)) 69 #define MHI_CHDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0) 70 #define MHI_ERDB_INT_CLEAR_n(n) (0x80 + 0x4 * (n)) 71 #define MHI_ERDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0) 72 73 /* 74 * Unlike the usual "masking" convention, writing "1" to a bit in this register 75 * enables the interrupt and writing "0" will disable it.. 76 */ 77 #define MHI_CTRL_INT_MASK 0x94 78 #define MHI_CTRL_INT_MASK_MASK GENMASK(1, 0) 79 #define MHI_CTRL_MHICTRL_MASK BIT(0) 80 #define MHI_CTRL_CRDB_MASK BIT(1) 81 82 #define MHI_CHDB_INT_MASK_n(n) (0xb8 + 0x4 * (n)) 83 #define MHI_CHDB_INT_MASK_n_EN_ALL GENMASK(31, 0) 84 #define MHI_ERDB_INT_MASK_n(n) (0xc8 + 0x4 * (n)) 85 #define MHI_ERDB_INT_MASK_n_EN_ALL GENMASK(31, 0) 86 87 #define NR_OF_CMD_RINGS 1 88 #define MHI_MASK_ROWS_CH_DB 4 89 #define MHI_MASK_ROWS_EV_DB 4 90 #define MHI_MASK_CH_LEN 32 91 #define MHI_MASK_EV_LEN 32 92 93 /* Generic context */ 94 struct mhi_generic_ctx { 95 __le32 reserved0; 96 __le32 reserved1; 97 __le32 reserved2; 98 99 __le64 rbase __packed __aligned(4); 100 __le64 rlen __packed __aligned(4); 101 __le64 rp __packed __aligned(4); 102 __le64 wp __packed __aligned(4); 103 }; 104 105 enum mhi_ep_ring_type { 106 RING_TYPE_CMD, 107 RING_TYPE_ER, 108 RING_TYPE_CH, 109 }; 110 111 /* Ring element */ 112 union mhi_ep_ring_ctx { 113 struct mhi_cmd_ctxt cmd; 114 struct mhi_event_ctxt ev; 115 struct mhi_chan_ctxt ch; 116 struct mhi_generic_ctx generic; 117 }; 118 119 struct mhi_ep_ring_item { 120 struct list_head node; 121 struct mhi_ep_ring *ring; 122 }; 123 124 struct mhi_ep_ring { 125 struct mhi_ep_cntrl *mhi_cntrl; 126 union mhi_ep_ring_ctx *ring_ctx; 127 struct mhi_ring_element *ring_cache; 128 enum mhi_ep_ring_type type; 129 u64 rbase; 130 size_t rd_offset; 131 size_t wr_offset; 132 size_t ring_size; 133 u32 db_offset_h; 134 u32 db_offset_l; 135 u32 ch_id; 136 u32 er_index; 137 u32 irq_vector; 138 bool started; 139 }; 140 141 struct mhi_ep_cmd { 142 struct mhi_ep_ring ring; 143 }; 144 145 struct mhi_ep_event { 146 struct mhi_ep_ring ring; 147 }; 148 149 struct mhi_ep_state_transition { 150 struct list_head node; 151 enum mhi_state state; 152 }; 153 154 struct mhi_ep_chan { 155 char *name; 156 struct mhi_ep_device *mhi_dev; 157 struct mhi_ep_ring ring; 158 struct mutex lock; 159 void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result); 160 enum mhi_ch_state state; 161 enum dma_data_direction dir; 162 u64 tre_loc; 163 u32 tre_size; 164 u32 tre_bytes_left; 165 u32 chan; 166 bool skip_td; 167 }; 168 169 /* MHI Ring related functions */ 170 void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id); 171 void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring); 172 int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, 173 union mhi_ep_ring_ctx *ctx); 174 size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr); 175 int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *element); 176 void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring); 177 int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring); 178 179 /* MMIO related functions */ 180 u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset); 181 void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val); 182 void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val); 183 u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask); 184 void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); 185 void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); 186 void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); 187 void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); 188 void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); 189 void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); 190 void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl); 191 bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl); 192 void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl); 193 void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl); 194 void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl); 195 void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl); 196 u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring); 197 void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value); 198 void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl); 199 void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl); 200 void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state, 201 bool *mhi_reset); 202 void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl); 203 void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); 204 205 /* MHI EP core functions */ 206 int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state); 207 int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env); 208 bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state, 209 enum mhi_state mhi_state); 210 int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state); 211 int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); 212 int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); 213 int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); 214 void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl); 215 void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl); 216 void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl); 217 218 #endif 219