1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MSM_EP_PCIE_H
#define __MSM_EP_PCIE_H
#include <linux/types.h>
enum ep_pcie_link_status {
EP_PCIE_LINK_DISABLED,
EP_PCIE_LINK_UP,
EP_PCIE_LINK_ENABLED,
};
enum ep_pcie_event {
EP_PCIE_EVENT_INVALID = 0,
EP_PCIE_EVENT_PM_D0 = 0x1,
EP_PCIE_EVENT_PM_D3_HOT = 0x2,
EP_PCIE_EVENT_PM_D3_COLD = 0x4,
EP_PCIE_EVENT_PM_RST_DEAST = 0x8,
EP_PCIE_EVENT_LINKDOWN = 0x10,
EP_PCIE_EVENT_LINKUP = 0x20,
EP_PCIE_EVENT_MHI_A7 = 0x40,
EP_PCIE_EVENT_MMIO_WRITE = 0x80,
};
enum ep_pcie_irq_event {
EP_PCIE_INT_EVT_LINK_DOWN = 1,
EP_PCIE_INT_EVT_BME,
EP_PCIE_INT_EVT_PM_TURNOFF,
EP_PCIE_INT_EVT_DEBUG,
EP_PCIE_INT_EVT_LTR,
EP_PCIE_INT_EVT_MHI_Q6,
EP_PCIE_INT_EVT_MHI_A7,
EP_PCIE_INT_EVT_DSTATE_CHANGE,
EP_PCIE_INT_EVT_L1SUB_TIMEOUT,
EP_PCIE_INT_EVT_MMIO_WRITE,
EP_PCIE_INT_EVT_CFG_WRITE,
EP_PCIE_INT_EVT_BRIDGE_FLUSH_N,
EP_PCIE_INT_EVT_LINK_UP,
EP_PCIE_INT_EVT_MAX = 13,
};
enum ep_pcie_trigger {
EP_PCIE_TRIGGER_CALLBACK,
EP_PCIE_TRIGGER_COMPLETION,
};
enum ep_pcie_options {
EP_PCIE_OPT_NULL = 0,
EP_PCIE_OPT_AST_WAKE = 0x1,
EP_PCIE_OPT_POWER_ON = 0x2,
EP_PCIE_OPT_ENUM = 0x4,
EP_PCIE_OPT_ALL = 0xFFFFFFFF,
};
struct ep_pcie_notify {
enum ep_pcie_event event;
void *user;
void *data;
u32 options;
};
struct ep_pcie_register_event {
u32 events;
void *user;
enum ep_pcie_trigger mode;
void (*callback)(struct ep_pcie_notify *notify);
struct ep_pcie_notify notify;
struct completion *completion;
u32 options;
};
struct ep_pcie_iatu {
u32 start;
u32 end;
u32 tgt_lower;
u32 tgt_upper;
};
struct ep_pcie_msi_config {
u32 lower;
u32 upper;
u32 data;
u32 msg_num;
};
struct ep_pcie_db_config {
u8 base;
u8 end;
u32 tgt_addr;
};
struct ep_pcie_hw {
struct list_head node;
u32 device_id;
void **private_data;
int (*register_event)(struct ep_pcie_register_event *reg);
int (*deregister_event)(void);
enum ep_pcie_link_status (*get_linkstatus)(void);
int (*config_outbound_iatu)(struct ep_pcie_iatu entries[],
u32 num_entries);
int (*get_msi_config)(struct ep_pcie_msi_config *cfg);
int (*trigger_msi)(u32 idx);
int (*wakeup_host)(void);
int (*enable_endpoint)(enum ep_pcie_options opt);
int (*disable_endpoint)(void);
int (*config_db_routing)(struct ep_pcie_db_config chdb_cfg,
struct ep_pcie_db_config erdb_cfg);
int (*mask_irq_event)(enum ep_pcie_irq_event event,
bool enable);
};
/*
* ep_pcie_register_drv - register HW driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function registers PCIe HW driver to PCIe endpoint service
* layer.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_register_drv(struct ep_pcie_hw *phandle);
/*
* ep_pcie_deregister_drv - deregister HW driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function deregisters PCIe HW driver to PCIe endpoint service
* layer.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_deregister_drv(struct ep_pcie_hw *phandle);
/*
* ep_pcie_get_phandle - get PCIe endpoint HW driver handle.
* @id: PCIe endpoint device ID
*
* This function deregisters PCIe HW driver from PCIe endpoint service
* layer.
*
* Return: PCIe endpoint HW driver handle
*/
struct ep_pcie_hw *ep_pcie_get_phandle(u32 id);
/*
* ep_pcie_register_event - register event with PCIe driver.
* @phandle: PCIe endpoint HW driver handle
* @reg: event structure
*
* This function gives PCIe client driver an option to register
* event with PCIe driver.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_register_event(struct ep_pcie_hw *phandle,
struct ep_pcie_register_event *reg);
/*
* ep_pcie_deregister_event - deregister event with PCIe driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function gives PCIe client driver an option to deregister
* existing event with PCIe driver.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_deregister_event(struct ep_pcie_hw *phandle);
/*
* ep_pcie_get_linkstatus - indicate the status of PCIe link.
* @phandle: PCIe endpoint HW driver handle
*
* This function tells PCIe client about the status of PCIe link.
*
* Return: status of PCIe link
*/
enum ep_pcie_link_status ep_pcie_get_linkstatus(struct ep_pcie_hw *phandle);
/*
* ep_pcie_config_outbound_iatu - configure outbound iATU.
* @entries: iatu entries
* @num_entries: number of iatu entries
*
* This function configures the outbound iATU for PCIe
* client's access to the regions in the host memory which
* are specified by the SW on host side.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_config_outbound_iatu(struct ep_pcie_hw *phandle,
struct ep_pcie_iatu entries[],
u32 num_entries);
/*
* ep_pcie_get_msi_config - get MSI config info.
* @phandle: PCIe endpoint HW driver handle
* @cfg: pointer to MSI config
*
* This function returns MSI config info.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_get_msi_config(struct ep_pcie_hw *phandle,
struct ep_pcie_msi_config *cfg);
/*
* ep_pcie_trigger_msi - trigger an MSI.
* @phandle: PCIe endpoint HW driver handle
* @idx: MSI index number
*
* This function allows PCIe client to trigger an MSI
* on host side.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_trigger_msi(struct ep_pcie_hw *phandle, u32 idx);
/*
* ep_pcie_wakeup_host - wake up the host.
* @phandle: PCIe endpoint HW driver handle
*
* This function asserts WAKE GPIO to wake up the host.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_wakeup_host(struct ep_pcie_hw *phandle);
/*
* ep_pcie_enable_endpoint - enable PCIe endpoint.
* @phandle: PCIe endpoint HW driver handle
* @opt: endpoint enable options
*
* This function is to enable the PCIe endpoint device.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_enable_endpoint(struct ep_pcie_hw *phandle,
enum ep_pcie_options opt);
/*
* ep_pcie_disable_endpoint - disable PCIe endpoint.
* @phandle: PCIe endpoint HW driver handle
*
* This function is to disable the PCIe endpoint device.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_disable_endpoint(struct ep_pcie_hw *phandle);
/*
* ep_pcie_config_db_routing - Configure routing of doorbells to another block.
* @phandle: PCIe endpoint HW driver handle
* @chdb_cfg: channel doorbell config
* @erdb_cfg: event ring doorbell config
*
* This function allows PCIe core to route the doorbells intended
* for another entity via a target address.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_config_db_routing(struct ep_pcie_hw *phandle,
struct ep_pcie_db_config chdb_cfg,
struct ep_pcie_db_config erdb_cfg);
/*
* ep_pcie_mask_irq_event - enable and disable IRQ event.
* @phandle: PCIe endpoint HW driver handle
* @event: IRQ event
* @enable: true to enable that IRQ event and false to disable
*
* This function is to enable and disable IRQ event.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_mask_irq_event(struct ep_pcie_hw *phandle,
enum ep_pcie_irq_event event,
bool enable);
#endif
|