Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/bus/mhi/ep/internal.h
26285 views
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
224