blob: 69c83d42d5567a3bc0faee10349714b8eea1dac2 [file] [log] [blame]
Skylar Changa9516582017-05-09 11:36:47 -07001/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
Amir Levy9659e592016-10-27 18:08:27 +03002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/ipa_mhi.h>
14#include <linux/ipa_qmi_service_v01.h>
15
16#ifndef _IPA_COMMON_I_H_
17#define _IPA_COMMON_I_H_
18#include <linux/ipc_logging.h>
19#include <linux/ipa.h>
20#include <linux/ipa_uc_offload.h>
21
22#define __FILENAME__ \
23 (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
24
25#define IPA_ACTIVE_CLIENTS_PREP_EP(log_info, client) \
26 log_info.file = __FILENAME__; \
27 log_info.line = __LINE__; \
28 log_info.type = EP; \
Ghanim Fodia4bf8472017-07-12 14:44:15 +030029 log_info.id_string = (client < 0 || client >= IPA_CLIENT_MAX) \
30 ? "Invalid Client" : ipa_clients_strings[client]
Amir Levy9659e592016-10-27 18:08:27 +030031
32#define IPA_ACTIVE_CLIENTS_PREP_SIMPLE(log_info) \
33 log_info.file = __FILENAME__; \
34 log_info.line = __LINE__; \
35 log_info.type = SIMPLE; \
36 log_info.id_string = __func__
37
38#define IPA_ACTIVE_CLIENTS_PREP_RESOURCE(log_info, resource_name) \
39 log_info.file = __FILENAME__; \
40 log_info.line = __LINE__; \
41 log_info.type = RESOURCE; \
42 log_info.id_string = resource_name
43
44#define IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, id_str) \
45 log_info.file = __FILENAME__; \
46 log_info.line = __LINE__; \
47 log_info.type = SPECIAL; \
48 log_info.id_string = id_str
49
50#define IPA_ACTIVE_CLIENTS_INC_EP(client) \
51 do { \
52 struct ipa_active_client_logging_info log_info; \
53 IPA_ACTIVE_CLIENTS_PREP_EP(log_info, client); \
54 ipa_inc_client_enable_clks(&log_info); \
55 } while (0)
56
57#define IPA_ACTIVE_CLIENTS_DEC_EP(client) \
58 do { \
59 struct ipa_active_client_logging_info log_info; \
60 IPA_ACTIVE_CLIENTS_PREP_EP(log_info, client); \
61 ipa_dec_client_disable_clks(&log_info); \
62 } while (0)
63
64#define IPA_ACTIVE_CLIENTS_INC_SIMPLE() \
65 do { \
66 struct ipa_active_client_logging_info log_info; \
67 IPA_ACTIVE_CLIENTS_PREP_SIMPLE(log_info); \
68 ipa_inc_client_enable_clks(&log_info); \
69 } while (0)
70
71#define IPA_ACTIVE_CLIENTS_DEC_SIMPLE() \
72 do { \
73 struct ipa_active_client_logging_info log_info; \
74 IPA_ACTIVE_CLIENTS_PREP_SIMPLE(log_info); \
75 ipa_dec_client_disable_clks(&log_info); \
76 } while (0)
77
78#define IPA_ACTIVE_CLIENTS_INC_RESOURCE(resource_name) \
79 do { \
80 struct ipa_active_client_logging_info log_info; \
81 IPA_ACTIVE_CLIENTS_PREP_RESOURCE(log_info, resource_name); \
82 ipa_inc_client_enable_clks(&log_info); \
83 } while (0)
84
85#define IPA_ACTIVE_CLIENTS_DEC_RESOURCE(resource_name) \
86 do { \
87 struct ipa_active_client_logging_info log_info; \
88 IPA_ACTIVE_CLIENTS_PREP_RESOURCE(log_info, resource_name); \
89 ipa_dec_client_disable_clks(&log_info); \
90 } while (0)
91
92#define IPA_ACTIVE_CLIENTS_INC_SPECIAL(id_str) \
93 do { \
94 struct ipa_active_client_logging_info log_info; \
95 IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, id_str); \
96 ipa_inc_client_enable_clks(&log_info); \
97 } while (0)
98
99#define IPA_ACTIVE_CLIENTS_DEC_SPECIAL(id_str) \
100 do { \
101 struct ipa_active_client_logging_info log_info; \
102 IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, id_str); \
103 ipa_dec_client_disable_clks(&log_info); \
104 } while (0)
105
106#define ipa_assert_on(condition)\
107do {\
108 if (unlikely(condition))\
109 ipa_assert();\
110} while (0)
111
Skylar Changa9516582017-05-09 11:36:47 -0700112#define IPA_CLIENT_IS_PROD(x) \
113 (x < IPA_CLIENT_MAX && (x & 0x1) == 0)
114#define IPA_CLIENT_IS_CONS(x) \
115 (x < IPA_CLIENT_MAX && (x & 0x1) == 1)
Amir Levy9659e592016-10-27 18:08:27 +0300116
117#define IPA_GSI_CHANNEL_STOP_SLEEP_MIN_USEC (1000)
118#define IPA_GSI_CHANNEL_STOP_SLEEP_MAX_USEC (2000)
119
120enum ipa_active_client_log_type {
121 EP,
122 SIMPLE,
123 RESOURCE,
124 SPECIAL,
125 INVALID
126};
127
128struct ipa_active_client_logging_info {
129 const char *id_string;
130 char *file;
131 int line;
132 enum ipa_active_client_log_type type;
133};
134
135/**
136 * struct ipa_mem_buffer - IPA memory buffer
137 * @base: base
138 * @phys_base: physical base address
139 * @size: size of memory buffer
140 */
141struct ipa_mem_buffer {
142 void *base;
143 dma_addr_t phys_base;
144 u32 size;
145};
146
147#define IPA_MHI_GSI_ER_START 10
148#define IPA_MHI_GSI_ER_END 16
149
150/**
151 * enum ipa3_mhi_burst_mode - MHI channel burst mode state
152 *
153 * Values are according to MHI specification
154 * @IPA_MHI_BURST_MODE_DEFAULT: burst mode enabled for HW channels,
155 * disabled for SW channels
156 * @IPA_MHI_BURST_MODE_RESERVED:
157 * @IPA_MHI_BURST_MODE_DISABLE: Burst mode is disabled for this channel
158 * @IPA_MHI_BURST_MODE_ENABLE: Burst mode is enabled for this channel
159 *
160 */
161enum ipa3_mhi_burst_mode {
162 IPA_MHI_BURST_MODE_DEFAULT,
163 IPA_MHI_BURST_MODE_RESERVED,
164 IPA_MHI_BURST_MODE_DISABLE,
165 IPA_MHI_BURST_MODE_ENABLE,
166};
167
168/**
169 * enum ipa_hw_mhi_channel_states - MHI channel state machine
170 *
171 * Values are according to MHI specification
172 * @IPA_HW_MHI_CHANNEL_STATE_DISABLE: Channel is disabled and not processed by
173 * the host or device.
174 * @IPA_HW_MHI_CHANNEL_STATE_ENABLE: A channel is enabled after being
175 * initialized and configured by host, including its channel context and
176 * associated transfer ring. While this state, the channel is not active
177 * and the device does not process transfer.
178 * @IPA_HW_MHI_CHANNEL_STATE_RUN: The device processes transfers and doorbell
179 * for channels.
180 * @IPA_HW_MHI_CHANNEL_STATE_SUSPEND: Used to halt operations on the channel.
181 * The device does not process transfers for the channel in this state.
182 * This state is typically used to synchronize the transition to low power
183 * modes.
184 * @IPA_HW_MHI_CHANNEL_STATE_STOP: Used to halt operations on the channel.
185 * The device does not process transfers for the channel in this state.
186 * @IPA_HW_MHI_CHANNEL_STATE_ERROR: The device detected an error in an element
187 * from the transfer ring associated with the channel.
188 * @IPA_HW_MHI_CHANNEL_STATE_INVALID: Invalid state. Shall not be in use in
189 * operational scenario.
190 */
191enum ipa_hw_mhi_channel_states {
192 IPA_HW_MHI_CHANNEL_STATE_DISABLE = 0,
193 IPA_HW_MHI_CHANNEL_STATE_ENABLE = 1,
194 IPA_HW_MHI_CHANNEL_STATE_RUN = 2,
195 IPA_HW_MHI_CHANNEL_STATE_SUSPEND = 3,
196 IPA_HW_MHI_CHANNEL_STATE_STOP = 4,
197 IPA_HW_MHI_CHANNEL_STATE_ERROR = 5,
198 IPA_HW_MHI_CHANNEL_STATE_INVALID = 0xFF
199};
200
201/**
202 * Structure holding the parameters for IPA_CPU_2_HW_CMD_MHI_DL_UL_SYNC_INFO
203 * command. Parameters are sent as 32b immediate parameters.
204 * @isDlUlSyncEnabled: Flag to indicate if DL UL Syncronization is enabled
205 * @UlAccmVal: UL Timer Accumulation value (Period after which device will poll
206 * for UL data)
207 * @ulMsiEventThreshold: Threshold at which HW fires MSI to host for UL events
208 * @dlMsiEventThreshold: Threshold at which HW fires MSI to host for DL events
209 */
210union IpaHwMhiDlUlSyncCmdData_t {
211 struct IpaHwMhiDlUlSyncCmdParams_t {
212 u32 isDlUlSyncEnabled:8;
213 u32 UlAccmVal:8;
214 u32 ulMsiEventThreshold:8;
215 u32 dlMsiEventThreshold:8;
216 } params;
217 u32 raw32b;
218};
219
220struct ipa_mhi_ch_ctx {
221 u8 chstate;/*0-7*/
222 u8 brstmode:2;/*8-9*/
223 u8 pollcfg:6;/*10-15*/
224 u16 rsvd;/*16-31*/
225 u32 chtype;
226 u32 erindex;
227 u64 rbase;
228 u64 rlen;
229 u64 rp;
230 u64 wp;
231} __packed;
232
233struct ipa_mhi_ev_ctx {
234 u32 intmodc:16;
235 u32 intmodt:16;
236 u32 ertype;
237 u32 msivec;
238 u64 rbase;
239 u64 rlen;
240 u64 rp;
241 u64 wp;
242} __packed;
243
244struct ipa_mhi_init_uc_engine {
245 struct ipa_mhi_msi_info *msi;
246 u32 mmio_addr;
247 u32 host_ctrl_addr;
248 u32 host_data_addr;
249 u32 first_ch_idx;
250 u32 first_er_idx;
251 union IpaHwMhiDlUlSyncCmdData_t *ipa_cached_dl_ul_sync_info;
252};
253
254struct ipa_mhi_init_gsi_engine {
255 u32 first_ch_idx;
256};
257
258struct ipa_mhi_init_engine {
259 struct ipa_mhi_init_uc_engine uC;
260 struct ipa_mhi_init_gsi_engine gsi;
261};
262
263struct start_gsi_channel {
264 enum ipa_hw_mhi_channel_states state;
265 struct ipa_mhi_msi_info *msi;
266 struct ipa_mhi_ev_ctx *ev_ctx_host;
267 u64 event_context_addr;
268 struct ipa_mhi_ch_ctx *ch_ctx_host;
269 u64 channel_context_addr;
270 void (*ch_err_cb)(struct gsi_chan_err_notify *notify);
271 void (*ev_err_cb)(struct gsi_evt_err_notify *notify);
272 void *channel;
273 bool assert_bit40;
274 struct gsi_mhi_channel_scratch *mhi;
275 unsigned long *cached_gsi_evt_ring_hdl;
276 uint8_t evchid;
277};
278
279struct start_uc_channel {
280 enum ipa_hw_mhi_channel_states state;
281 u8 index;
282 u8 id;
283};
284
285struct start_mhi_channel {
286 struct start_uc_channel uC;
287 struct start_gsi_channel gsi;
288};
289
290struct ipa_mhi_connect_params_internal {
291 struct ipa_sys_connect_params *sys;
292 u8 channel_id;
293 struct start_mhi_channel start;
294};
295
296/**
297 * struct ipa_hdr_offset_entry - IPA header offset entry
298 * @link: entry's link in global header offset entries list
299 * @offset: the offset
300 * @bin: bin
301 */
302struct ipa_hdr_offset_entry {
303 struct list_head link;
304 u32 offset;
305 u32 bin;
306};
307
308extern const char *ipa_clients_strings[];
309
310#define IPA_IPC_LOGGING(buf, fmt, args...) \
311 do { \
312 if (buf) \
313 ipc_log_string((buf), fmt, __func__, __LINE__, \
314 ## args); \
315 } while (0)
316
317void ipa_inc_client_enable_clks(struct ipa_active_client_logging_info *id);
318void ipa_dec_client_disable_clks(struct ipa_active_client_logging_info *id);
319int ipa_inc_client_enable_clks_no_block(
320 struct ipa_active_client_logging_info *id);
321int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource);
322int ipa_resume_resource(enum ipa_rm_resource_name name);
323int ipa_suspend_resource_sync(enum ipa_rm_resource_name resource);
324int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
325 u32 bandwidth_mbps);
326void *ipa_get_ipc_logbuf(void);
327void *ipa_get_ipc_logbuf_low(void);
328void ipa_assert(void);
329
330/* MHI */
331int ipa_mhi_init_engine(struct ipa_mhi_init_engine *params);
332int ipa_connect_mhi_pipe(struct ipa_mhi_connect_params_internal *in,
333 u32 *clnt_hdl);
334int ipa_disconnect_mhi_pipe(u32 clnt_hdl);
335bool ipa_mhi_stop_gsi_channel(enum ipa_client_type client);
336int ipa_qmi_enable_force_clear_datapath_send(
337 struct ipa_enable_force_clear_datapath_req_msg_v01 *req);
338int ipa_qmi_disable_force_clear_datapath_send(
339 struct ipa_disable_force_clear_datapath_req_msg_v01 *req);
340int ipa_generate_tag_process(void);
341int ipa_disable_sps_pipe(enum ipa_client_type client);
342int ipa_mhi_reset_channel_internal(enum ipa_client_type client);
343int ipa_mhi_start_channel_internal(enum ipa_client_type client);
344bool ipa_mhi_sps_channel_empty(enum ipa_client_type client);
345int ipa_mhi_resume_channels_internal(enum ipa_client_type client,
346 bool LPTransitionRejected, bool brstmode_enabled,
347 union __packed gsi_channel_scratch ch_scratch, u8 index);
348int ipa_mhi_handle_ipa_config_req(struct ipa_config_req_msg_v01 *config_req);
349int ipa_mhi_query_ch_info(enum ipa_client_type client,
350 struct gsi_chan_info *ch_info);
351int ipa_mhi_destroy_channel(enum ipa_client_type client);
352int ipa_mhi_is_using_dma(bool *flag);
353const char *ipa_mhi_get_state_str(int state);
354
355/* MHI uC */
356int ipa_uc_mhi_send_dl_ul_sync_info(union IpaHwMhiDlUlSyncCmdData_t *cmd);
357int ipa_uc_mhi_init
358 (void (*ready_cb)(void), void (*wakeup_request_cb)(void));
359void ipa_uc_mhi_cleanup(void);
360int ipa_uc_mhi_reset_channel(int channelHandle);
361int ipa_uc_mhi_suspend_channel(int channelHandle);
362int ipa_uc_mhi_stop_event_update_channel(int channelHandle);
363int ipa_uc_mhi_print_stats(char *dbg_buff, int size);
364
365/* uC */
366int ipa_uc_state_check(void);
367
368/* general */
369void ipa_get_holb(int ep_idx, struct ipa_ep_cfg_holb *holb);
370void ipa_set_tag_process_before_gating(bool val);
371bool ipa_has_open_aggr_frame(enum ipa_client_type client);
372int ipa_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
373 ipa_notify_cb notify, void *priv, u8 hdr_len,
374 struct ipa_ntn_conn_out_params *outp);
375
376int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, int ipa_ep_idx_dl);
377
378u8 *ipa_write_64(u64 w, u8 *dest);
379u8 *ipa_write_32(u32 w, u8 *dest);
380u8 *ipa_write_16(u16 hw, u8 *dest);
381u8 *ipa_write_8(u8 b, u8 *dest);
382u8 *ipa_pad_to_64(u8 *dest);
383u8 *ipa_pad_to_32(u8 *dest);
384const char *ipa_get_version_string(enum ipa_hw_type ver);
385
386#endif /* _IPA_COMMON_I_H_ */