Skylar Chang | a951658 | 2017-05-09 11:36:47 -0700 | [diff] [blame] | 1 | /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. |
Amir Levy | 9659e59 | 2016-10-27 18:08:27 +0300 | [diff] [blame] | 2 | * |
| 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 Fodi | a4bf847 | 2017-07-12 14:44:15 +0300 | [diff] [blame^] | 29 | log_info.id_string = (client < 0 || client >= IPA_CLIENT_MAX) \ |
| 30 | ? "Invalid Client" : ipa_clients_strings[client] |
Amir Levy | 9659e59 | 2016-10-27 18:08:27 +0300 | [diff] [blame] | 31 | |
| 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)\ |
| 107 | do {\ |
| 108 | if (unlikely(condition))\ |
| 109 | ipa_assert();\ |
| 110 | } while (0) |
| 111 | |
Skylar Chang | a951658 | 2017-05-09 11:36:47 -0700 | [diff] [blame] | 112 | #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 Levy | 9659e59 | 2016-10-27 18:08:27 +0300 | [diff] [blame] | 116 | |
| 117 | #define IPA_GSI_CHANNEL_STOP_SLEEP_MIN_USEC (1000) |
| 118 | #define IPA_GSI_CHANNEL_STOP_SLEEP_MAX_USEC (2000) |
| 119 | |
| 120 | enum ipa_active_client_log_type { |
| 121 | EP, |
| 122 | SIMPLE, |
| 123 | RESOURCE, |
| 124 | SPECIAL, |
| 125 | INVALID |
| 126 | }; |
| 127 | |
| 128 | struct 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 | */ |
| 141 | struct 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 | */ |
| 161 | enum 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 | */ |
| 191 | enum 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 | */ |
| 210 | union 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 | |
| 220 | struct 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 | |
| 233 | struct 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 | |
| 244 | struct 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 | |
| 254 | struct ipa_mhi_init_gsi_engine { |
| 255 | u32 first_ch_idx; |
| 256 | }; |
| 257 | |
| 258 | struct ipa_mhi_init_engine { |
| 259 | struct ipa_mhi_init_uc_engine uC; |
| 260 | struct ipa_mhi_init_gsi_engine gsi; |
| 261 | }; |
| 262 | |
| 263 | struct 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 | |
| 279 | struct start_uc_channel { |
| 280 | enum ipa_hw_mhi_channel_states state; |
| 281 | u8 index; |
| 282 | u8 id; |
| 283 | }; |
| 284 | |
| 285 | struct start_mhi_channel { |
| 286 | struct start_uc_channel uC; |
| 287 | struct start_gsi_channel gsi; |
| 288 | }; |
| 289 | |
| 290 | struct 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 | */ |
| 302 | struct ipa_hdr_offset_entry { |
| 303 | struct list_head link; |
| 304 | u32 offset; |
| 305 | u32 bin; |
| 306 | }; |
| 307 | |
| 308 | extern 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 | |
| 317 | void ipa_inc_client_enable_clks(struct ipa_active_client_logging_info *id); |
| 318 | void ipa_dec_client_disable_clks(struct ipa_active_client_logging_info *id); |
| 319 | int ipa_inc_client_enable_clks_no_block( |
| 320 | struct ipa_active_client_logging_info *id); |
| 321 | int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource); |
| 322 | int ipa_resume_resource(enum ipa_rm_resource_name name); |
| 323 | int ipa_suspend_resource_sync(enum ipa_rm_resource_name resource); |
| 324 | int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage, |
| 325 | u32 bandwidth_mbps); |
| 326 | void *ipa_get_ipc_logbuf(void); |
| 327 | void *ipa_get_ipc_logbuf_low(void); |
| 328 | void ipa_assert(void); |
| 329 | |
| 330 | /* MHI */ |
| 331 | int ipa_mhi_init_engine(struct ipa_mhi_init_engine *params); |
| 332 | int ipa_connect_mhi_pipe(struct ipa_mhi_connect_params_internal *in, |
| 333 | u32 *clnt_hdl); |
| 334 | int ipa_disconnect_mhi_pipe(u32 clnt_hdl); |
| 335 | bool ipa_mhi_stop_gsi_channel(enum ipa_client_type client); |
| 336 | int ipa_qmi_enable_force_clear_datapath_send( |
| 337 | struct ipa_enable_force_clear_datapath_req_msg_v01 *req); |
| 338 | int ipa_qmi_disable_force_clear_datapath_send( |
| 339 | struct ipa_disable_force_clear_datapath_req_msg_v01 *req); |
| 340 | int ipa_generate_tag_process(void); |
| 341 | int ipa_disable_sps_pipe(enum ipa_client_type client); |
| 342 | int ipa_mhi_reset_channel_internal(enum ipa_client_type client); |
| 343 | int ipa_mhi_start_channel_internal(enum ipa_client_type client); |
| 344 | bool ipa_mhi_sps_channel_empty(enum ipa_client_type client); |
| 345 | int 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); |
| 348 | int ipa_mhi_handle_ipa_config_req(struct ipa_config_req_msg_v01 *config_req); |
| 349 | int ipa_mhi_query_ch_info(enum ipa_client_type client, |
| 350 | struct gsi_chan_info *ch_info); |
| 351 | int ipa_mhi_destroy_channel(enum ipa_client_type client); |
| 352 | int ipa_mhi_is_using_dma(bool *flag); |
| 353 | const char *ipa_mhi_get_state_str(int state); |
| 354 | |
| 355 | /* MHI uC */ |
| 356 | int ipa_uc_mhi_send_dl_ul_sync_info(union IpaHwMhiDlUlSyncCmdData_t *cmd); |
| 357 | int ipa_uc_mhi_init |
| 358 | (void (*ready_cb)(void), void (*wakeup_request_cb)(void)); |
| 359 | void ipa_uc_mhi_cleanup(void); |
| 360 | int ipa_uc_mhi_reset_channel(int channelHandle); |
| 361 | int ipa_uc_mhi_suspend_channel(int channelHandle); |
| 362 | int ipa_uc_mhi_stop_event_update_channel(int channelHandle); |
| 363 | int ipa_uc_mhi_print_stats(char *dbg_buff, int size); |
| 364 | |
| 365 | /* uC */ |
| 366 | int ipa_uc_state_check(void); |
| 367 | |
| 368 | /* general */ |
| 369 | void ipa_get_holb(int ep_idx, struct ipa_ep_cfg_holb *holb); |
| 370 | void ipa_set_tag_process_before_gating(bool val); |
| 371 | bool ipa_has_open_aggr_frame(enum ipa_client_type client); |
| 372 | int 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 | |
| 376 | int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, int ipa_ep_idx_dl); |
| 377 | |
| 378 | u8 *ipa_write_64(u64 w, u8 *dest); |
| 379 | u8 *ipa_write_32(u32 w, u8 *dest); |
| 380 | u8 *ipa_write_16(u16 hw, u8 *dest); |
| 381 | u8 *ipa_write_8(u8 b, u8 *dest); |
| 382 | u8 *ipa_pad_to_64(u8 *dest); |
| 383 | u8 *ipa_pad_to_32(u8 *dest); |
| 384 | const char *ipa_get_version_string(enum ipa_hw_type ver); |
| 385 | |
| 386 | #endif /* _IPA_COMMON_I_H_ */ |