xref: /linux/drivers/bus/mhi/ep/internal.h (revision 20dfee95936413708701eb151f419597fdd9d948)
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 	struct delayed_work intmodt_work;
130 	u64 rbase;
131 	size_t rd_offset;
132 	size_t wr_offset;
133 	size_t ring_size;
134 	u32 db_offset_h;
135 	u32 db_offset_l;
136 	u32 ch_id;
137 	u32 er_index;
138 	u32 irq_vector;
139 	u32 intmodt;
140 	bool started;
141 	bool irq_pending;
142 };
143 
144 struct mhi_ep_cmd {
145 	struct mhi_ep_ring ring;
146 };
147 
148 struct mhi_ep_event {
149 	struct mhi_ep_ring ring;
150 };
151 
152 struct mhi_ep_state_transition {
153 	struct list_head node;
154 	enum mhi_state state;
155 };
156 
157 struct mhi_ep_chan {
158 	char *name;
159 	struct mhi_ep_device *mhi_dev;
160 	struct mhi_ep_ring ring;
161 	struct mutex lock;
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;
165 	size_t rd_offset;
166 	u64 tre_loc;
167 	u32 tre_size;
168 	u32 tre_bytes_left;
169 	u32 chan;
170 	bool skip_td;
171 };
172 
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);
182 
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,
205 			       bool *mhi_reset);
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);
208 
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);
221 
222 #endif
223