1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2022, Linaro Ltd.
7 #ifndef _MHI_EP_INTERNAL_
8 #define _MHI_EP_INTERNAL_
10 #include <linux/bitfield.h>
12 #include "../common.h"
14 extern struct bus_type mhi_ep_bus_type
;
16 #define MHI_REG_OFFSET 0x100
17 #define BHI_REG_OFFSET 0x200
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)
47 /* MHI BHI registers */
48 #define EP_BHI_INTVEC (BHI_REG_OFFSET + BHI_INTVEC)
49 #define EP_BHI_EXECENV (BHI_REG_OFFSET + BHI_EXECENV)
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))
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))
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)
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)
74 * Unlike the usual "masking" convention, writing "1" to a bit in this register
75 * enables the interrupt and writing "0" will disable it..
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)
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)
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
94 struct mhi_generic_ctx
{
99 __le64 rbase __packed
__aligned(4);
100 __le64 rlen __packed
__aligned(4);
101 __le64 rp __packed
__aligned(4);
102 __le64 wp __packed
__aligned(4);
105 enum mhi_ep_ring_type
{
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
;
119 struct mhi_ep_ring_item
{
120 struct list_head node
;
121 struct mhi_ep_ring
*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 struct delayed_work intmodt_work
;
145 struct mhi_ep_ring ring
;
148 struct mhi_ep_event
{
149 struct mhi_ep_ring ring
;
152 struct mhi_ep_state_transition
{
153 struct list_head node
;
154 enum mhi_state state
;
159 struct mhi_ep_device
*mhi_dev
;
160 struct mhi_ep_ring ring
;
162 void (*xfer_cb
)(struct mhi_ep_device
*mhi_dev
, struct mhi_result
*result
);
163 enum mhi_ch_state state
;
164 enum dma_data_direction dir
;
173 /* MHI Ring related functions */
174 void mhi_ep_ring_init(struct mhi_ep_ring
*ring
, enum mhi_ep_ring_type type
, u32 id
);
175 void mhi_ep_ring_reset(struct mhi_ep_cntrl
*mhi_cntrl
, struct mhi_ep_ring
*ring
);
176 int mhi_ep_ring_start(struct mhi_ep_cntrl
*mhi_cntrl
, struct mhi_ep_ring
*ring
,
177 union mhi_ep_ring_ctx
*ctx
);
178 size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring
*ring
, u64 ptr
);
179 int mhi_ep_ring_add_element(struct mhi_ep_ring
*ring
, struct mhi_ring_element
*element
);
180 void mhi_ep_ring_inc_index(struct mhi_ep_ring
*ring
);
181 int mhi_ep_update_wr_offset(struct mhi_ep_ring
*ring
);
183 /* MMIO related functions */
184 u32
mhi_ep_mmio_read(struct mhi_ep_cntrl
*mhi_cntrl
, u32 offset
);
185 void mhi_ep_mmio_write(struct mhi_ep_cntrl
*mhi_cntrl
, u32 offset
, u32 val
);
186 void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl
*mhi_cntrl
, u32 offset
, u32 mask
, u32 val
);
187 u32
mhi_ep_mmio_masked_read(struct mhi_ep_cntrl
*dev
, u32 offset
, u32 mask
);
188 void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl
*mhi_cntrl
);
189 void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl
*mhi_cntrl
);
190 void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl
*mhi_cntrl
);
191 void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl
*mhi_cntrl
);
192 void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl
*mhi_cntrl
, u32 ch_id
);
193 void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl
*mhi_cntrl
, u32 ch_id
);
194 void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl
*mhi_cntrl
);
195 bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl
*mhi_cntrl
);
196 void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl
*mhi_cntrl
);
197 void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl
*mhi_cntrl
);
198 void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl
*mhi_cntrl
);
199 void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl
*mhi_cntrl
);
200 u64
mhi_ep_mmio_get_db(struct mhi_ep_ring
*ring
);
201 void mhi_ep_mmio_set_env(struct mhi_ep_cntrl
*mhi_cntrl
, u32 value
);
202 void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl
*mhi_cntrl
);
203 void mhi_ep_mmio_reset(struct mhi_ep_cntrl
*mhi_cntrl
);
204 void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl
*mhi_cntrl
, enum mhi_state
*state
,
206 void mhi_ep_mmio_init(struct mhi_ep_cntrl
*mhi_cntrl
);
207 void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl
*mhi_cntrl
);
209 /* MHI EP core functions */
210 int mhi_ep_send_state_change_event(struct mhi_ep_cntrl
*mhi_cntrl
, enum mhi_state state
);
211 int mhi_ep_send_ee_event(struct mhi_ep_cntrl
*mhi_cntrl
, enum mhi_ee_type exec_env
);
212 bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl
*mhi_cntrl
, enum mhi_state cur_mhi_state
,
213 enum mhi_state mhi_state
);
214 int mhi_ep_set_mhi_state(struct mhi_ep_cntrl
*mhi_cntrl
, enum mhi_state mhi_state
);
215 int mhi_ep_set_m0_state(struct mhi_ep_cntrl
*mhi_cntrl
);
216 int mhi_ep_set_m3_state(struct mhi_ep_cntrl
*mhi_cntrl
);
217 int mhi_ep_set_ready_state(struct mhi_ep_cntrl
*mhi_cntrl
);
218 void mhi_ep_handle_syserr(struct mhi_ep_cntrl
*mhi_cntrl
);
219 void mhi_ep_resume_channels(struct mhi_ep_cntrl
*mhi_cntrl
);
220 void mhi_ep_suspend_channels(struct mhi_ep_cntrl
*mhi_cntrl
);