| 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | |
| 3 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 4 | * Copyright (C) 2018-2023 Linaro Ltd. |
| 5 | */ |
| 6 | #ifndef _GSI_REG_H_ |
| 7 | #define _GSI_REG_H_ |
| 8 | |
| 9 | /* === Only "gsi.c" and "gsi_reg.c" should include this file === */ |
| 10 | |
| 11 | #include <linux/bits.h> |
| 12 | |
| 13 | struct platform_device; |
| 14 | |
| 15 | struct gsi; |
| 16 | |
| 17 | /** |
| 18 | * DOC: GSI Registers |
| 19 | * |
| 20 | * GSI registers are located within the "gsi" address space defined by Device |
| 21 | * Tree. The offset of each register within that space is specified by |
| 22 | * symbols defined below. The GSI address space is mapped to virtual memory |
| 23 | * space in gsi_init(). All GSI registers are 32 bits wide. |
| 24 | * |
| 25 | * Each register type is duplicated for a number of instances of something. |
| 26 | * For example, each GSI channel has its own set of registers defining its |
| 27 | * configuration. The offset to a channel's set of registers is computed |
| 28 | * based on a "base" offset plus an additional "stride" amount computed |
| 29 | * from the channel's ID. For such registers, the offset is computed by a |
| 30 | * function-like macro that takes a parameter used in the computation. |
| 31 | * |
| 32 | * The offset of a register dependent on execution environment is computed |
| 33 | * by a macro that is supplied a parameter "ee". The "ee" value is a member |
| 34 | * of the gsi_ee_id enumerated type. |
| 35 | * |
| 36 | * The offset of a channel register is computed by a macro that is supplied a |
| 37 | * parameter "ch". The "ch" value is a channel id whose maximum value is 30 |
| 38 | * (though the actual limit is hardware-dependent). |
| 39 | * |
| 40 | * The offset of an event register is computed by a macro that is supplied a |
| 41 | * parameter "ev". The "ev" value is an event id whose maximum value is 15 |
| 42 | * (though the actual limit is hardware-dependent). |
| 43 | */ |
| 44 | |
| 45 | /* enum gsi_reg_id - GSI register IDs */ |
| 46 | enum gsi_reg_id { |
| 47 | INTER_EE_SRC_CH_IRQ_MSK, /* IPA v3.5+ */ |
| 48 | INTER_EE_SRC_EV_CH_IRQ_MSK, /* IPA v3.5+ */ |
| 49 | CH_C_CNTXT_0, |
| 50 | CH_C_CNTXT_1, |
| 51 | CH_C_CNTXT_2, |
| 52 | CH_C_CNTXT_3, |
| 53 | CH_C_QOS, |
| 54 | CH_C_SCRATCH_0, |
| 55 | CH_C_SCRATCH_1, |
| 56 | CH_C_SCRATCH_2, |
| 57 | CH_C_SCRATCH_3, |
| 58 | EV_CH_E_CNTXT_0, |
| 59 | EV_CH_E_CNTXT_1, |
| 60 | EV_CH_E_CNTXT_2, |
| 61 | EV_CH_E_CNTXT_3, |
| 62 | EV_CH_E_CNTXT_4, |
| 63 | EV_CH_E_CNTXT_8, |
| 64 | EV_CH_E_CNTXT_9, |
| 65 | EV_CH_E_CNTXT_10, |
| 66 | EV_CH_E_CNTXT_11, |
| 67 | EV_CH_E_CNTXT_12, |
| 68 | EV_CH_E_CNTXT_13, |
| 69 | EV_CH_E_SCRATCH_0, |
| 70 | EV_CH_E_SCRATCH_1, |
| 71 | CH_C_DOORBELL_0, |
| 72 | EV_CH_E_DOORBELL_0, |
| 73 | GSI_STATUS, |
| 74 | CH_CMD, |
| 75 | EV_CH_CMD, |
| 76 | GENERIC_CMD, |
| 77 | HW_PARAM_2, /* IPA v3.5.1+ */ |
| 78 | HW_PARAM_4, /* IPA v5.0+ */ |
| 79 | CNTXT_TYPE_IRQ, |
| 80 | CNTXT_TYPE_IRQ_MSK, |
| 81 | CNTXT_SRC_CH_IRQ, |
| 82 | CNTXT_SRC_CH_IRQ_MSK, |
| 83 | CNTXT_SRC_CH_IRQ_CLR, |
| 84 | CNTXT_SRC_EV_CH_IRQ, |
| 85 | CNTXT_SRC_EV_CH_IRQ_MSK, |
| 86 | CNTXT_SRC_EV_CH_IRQ_CLR, |
| 87 | CNTXT_SRC_IEOB_IRQ, |
| 88 | CNTXT_SRC_IEOB_IRQ_MSK, |
| 89 | CNTXT_SRC_IEOB_IRQ_CLR, |
| 90 | CNTXT_GLOB_IRQ_STTS, |
| 91 | CNTXT_GLOB_IRQ_EN, |
| 92 | CNTXT_GLOB_IRQ_CLR, |
| 93 | CNTXT_GSI_IRQ_STTS, |
| 94 | CNTXT_GSI_IRQ_EN, |
| 95 | CNTXT_GSI_IRQ_CLR, |
| 96 | CNTXT_INTSET, |
| 97 | ERROR_LOG, |
| 98 | ERROR_LOG_CLR, |
| 99 | CNTXT_SCRATCH_0, |
| 100 | GSI_REG_ID_COUNT, /* Last; not an ID */ |
| 101 | }; |
| 102 | |
| 103 | /* CH_C_CNTXT_0 register */ |
| 104 | enum gsi_reg_ch_c_cntxt_0_field_id { |
| 105 | CHTYPE_PROTOCOL, |
| 106 | CHTYPE_DIR, |
| 107 | CH_EE, |
| 108 | CHID, |
| 109 | CHTYPE_PROTOCOL_MSB, /* IPA v4.5-4.11 */ |
| 110 | ERINDEX, /* Not IPA v5.0+ */ |
| 111 | CHSTATE, |
| 112 | ELEMENT_SIZE, |
| 113 | }; |
| 114 | |
| 115 | /** enum gsi_channel_type - CHTYPE_PROTOCOL field values in CH_C_CNTXT_0 */ |
| 116 | enum gsi_channel_type { |
| 117 | GSI_CHANNEL_TYPE_MHI = 0x0, |
| 118 | GSI_CHANNEL_TYPE_XHCI = 0x1, |
| 119 | GSI_CHANNEL_TYPE_GPI = 0x2, |
| 120 | GSI_CHANNEL_TYPE_XDCI = 0x3, |
| 121 | GSI_CHANNEL_TYPE_WDI2 = 0x4, |
| 122 | GSI_CHANNEL_TYPE_GCI = 0x5, |
| 123 | GSI_CHANNEL_TYPE_WDI3 = 0x6, |
| 124 | GSI_CHANNEL_TYPE_MHIP = 0x7, |
| 125 | GSI_CHANNEL_TYPE_AQC = 0x8, |
| 126 | GSI_CHANNEL_TYPE_11AD = 0x9, |
| 127 | }; |
| 128 | |
| 129 | /* CH_C_CNTXT_1 register */ |
| 130 | enum gsi_reg_ch_c_cntxt_1_field_id { |
| 131 | CH_R_LENGTH, |
| 132 | CH_ERINDEX, /* IPA v5.0+ */ |
| 133 | }; |
| 134 | |
| 135 | /* CH_C_QOS register */ |
| 136 | enum gsi_reg_ch_c_qos_field_id { |
| 137 | WRR_WEIGHT, |
| 138 | MAX_PREFETCH, |
| 139 | USE_DB_ENG, |
| 140 | USE_ESCAPE_BUF_ONLY, /* IPA v4.0-4.2 */ |
| 141 | PREFETCH_MODE, /* IPA v4.5+ */ |
| 142 | EMPTY_LVL_THRSHOLD, /* IPA v4.5+ */ |
| 143 | DB_IN_BYTES, /* IPA v4.9+ */ |
| 144 | LOW_LATENCY_EN, /* IPA v5.0+ */ |
| 145 | }; |
| 146 | |
| 147 | /** enum gsi_prefetch_mode - PREFETCH_MODE field in CH_C_QOS */ |
| 148 | enum gsi_prefetch_mode { |
| 149 | USE_PREFETCH_BUFS = 0, |
| 150 | ESCAPE_BUF_ONLY = 1, |
| 151 | SMART_PREFETCH = 2, |
| 152 | FREE_PREFETCH = 3, |
| 153 | }; |
| 154 | |
| 155 | /* EV_CH_E_CNTXT_0 register */ |
| 156 | enum gsi_reg_ch_c_ev_ch_e_cntxt_0_field_id { |
| 157 | EV_CHTYPE, /* enum gsi_channel_type */ |
| 158 | EV_EE, /* enum gsi_ee_id; always GSI_EE_AP for us */ |
| 159 | EV_EVCHID, |
| 160 | EV_INTYPE, |
| 161 | EV_CHSTATE, |
| 162 | EV_ELEMENT_SIZE, |
| 163 | }; |
| 164 | |
| 165 | /* EV_CH_E_CNTXT_1 register */ |
| 166 | enum gsi_reg_ev_ch_c_cntxt_1_field_id { |
| 167 | R_LENGTH, |
| 168 | }; |
| 169 | |
| 170 | /* EV_CH_E_CNTXT_8 register */ |
| 171 | enum gsi_reg_ch_c_ev_ch_e_cntxt_8_field_id { |
| 172 | EV_MODT, |
| 173 | EV_MODC, |
| 174 | EV_MOD_CNT, |
| 175 | }; |
| 176 | |
| 177 | /* GSI_STATUS register */ |
| 178 | enum gsi_reg_gsi_status_field_id { |
| 179 | ENABLED, |
| 180 | }; |
| 181 | |
| 182 | /* CH_CMD register */ |
| 183 | enum gsi_reg_gsi_ch_cmd_field_id { |
| 184 | CH_CHID, |
| 185 | CH_OPCODE, |
| 186 | }; |
| 187 | |
| 188 | /** enum gsi_ch_cmd_opcode - CH_OPCODE field values in CH_CMD */ |
| 189 | enum gsi_ch_cmd_opcode { |
| 190 | GSI_CH_ALLOCATE = 0x0, |
| 191 | GSI_CH_START = 0x1, |
| 192 | GSI_CH_STOP = 0x2, |
| 193 | GSI_CH_RESET = 0x9, |
| 194 | GSI_CH_DE_ALLOC = 0xa, |
| 195 | GSI_CH_DB_STOP = 0xb, |
| 196 | }; |
| 197 | |
| 198 | /* EV_CH_CMD register */ |
| 199 | enum gsi_ev_ch_cmd_field_id { |
| 200 | EV_CHID, |
| 201 | EV_OPCODE, |
| 202 | }; |
| 203 | |
| 204 | /** enum gsi_evt_cmd_opcode - EV_OPCODE field values in EV_CH_CMD */ |
| 205 | enum gsi_evt_cmd_opcode { |
| 206 | GSI_EVT_ALLOCATE = 0x0, |
| 207 | GSI_EVT_RESET = 0x9, |
| 208 | GSI_EVT_DE_ALLOC = 0xa, |
| 209 | }; |
| 210 | |
| 211 | /* GENERIC_CMD register */ |
| 212 | enum gsi_generic_cmd_field_id { |
| 213 | GENERIC_OPCODE, |
| 214 | GENERIC_CHID, |
| 215 | GENERIC_EE, |
| 216 | GENERIC_PARAMS, /* IPA v4.11+ */ |
| 217 | }; |
| 218 | |
| 219 | /** enum gsi_generic_cmd_opcode - GENERIC_OPCODE field values in GENERIC_CMD */ |
| 220 | enum gsi_generic_cmd_opcode { |
| 221 | GSI_GENERIC_HALT_CHANNEL = 0x1, |
| 222 | GSI_GENERIC_ALLOCATE_CHANNEL = 0x2, |
| 223 | GSI_GENERIC_ENABLE_FLOW_CONTROL = 0x3, /* IPA v4.2+ */ |
| 224 | GSI_GENERIC_DISABLE_FLOW_CONTROL = 0x4, /* IPA v4.2+ */ |
| 225 | GSI_GENERIC_QUERY_FLOW_CONTROL = 0x5, /* IPA v4.11+ */ |
| 226 | }; |
| 227 | |
| 228 | /* HW_PARAM_2 register */ /* IPA v3.5.1+ */ |
| 229 | enum gsi_hw_param_2_field_id { |
| 230 | IRAM_SIZE, |
| 231 | NUM_CH_PER_EE, |
| 232 | NUM_EV_PER_EE, /* Not IPA v5.0+ */ |
| 233 | GSI_CH_PEND_TRANSLATE, |
| 234 | GSI_CH_FULL_LOGIC, |
| 235 | GSI_USE_SDMA, /* IPA v4.0+ */ |
| 236 | GSI_SDMA_N_INT, /* IPA v4.0+ */ |
| 237 | GSI_SDMA_MAX_BURST, /* IPA v4.0+ */ |
| 238 | GSI_SDMA_N_IOVEC, /* IPA v4.0+ */ |
| 239 | GSI_USE_RD_WR_ENG, /* IPA v4.2+ */ |
| 240 | GSI_USE_INTER_EE, /* IPA v4.2+ */ |
| 241 | }; |
| 242 | |
| 243 | /** enum gsi_iram_size - IRAM_SIZE field values in HW_PARAM_2 */ |
| 244 | enum gsi_iram_size { |
| 245 | IRAM_SIZE_ONE_KB = 0x0, |
| 246 | IRAM_SIZE_TWO_KB = 0x1, |
| 247 | /* The next two values are available for IPA v4.0 and above */ |
| 248 | IRAM_SIZE_TWO_N_HALF_KB = 0x2, |
| 249 | IRAM_SIZE_THREE_KB = 0x3, |
| 250 | /* The next two values are available for IPA v4.5 and above */ |
| 251 | IRAM_SIZE_THREE_N_HALF_KB = 0x4, |
| 252 | IRAM_SIZE_FOUR_KB = 0x5, |
| 253 | }; |
| 254 | |
| 255 | /* HW_PARAM_4 register */ /* IPA v5.0+ */ |
| 256 | enum gsi_hw_param_4_field_id { |
| 257 | EV_PER_EE, |
| 258 | IRAM_PROTOCOL_COUNT, |
| 259 | }; |
| 260 | |
| 261 | /** |
| 262 | * enum gsi_irq_type_id: GSI IRQ types |
| 263 | * @GSI_CH_CTRL: Channel allocation, deallocation, etc. |
| 264 | * @GSI_EV_CTRL: Event ring allocation, deallocation, etc. |
| 265 | * @GSI_GLOB_EE: Global/general event |
| 266 | * @GSI_IEOB: Transfer (TRE) completion |
| 267 | * @GSI_INTER_EE_CH_CTRL: Remote-issued stop/reset (unused) |
| 268 | * @GSI_INTER_EE_EV_CTRL: Remote-issued event reset (unused) |
| 269 | * @GSI_GENERAL: General hardware event (bus error, etc.) |
| 270 | */ |
| 271 | enum gsi_irq_type_id { |
| 272 | GSI_CH_CTRL = BIT(0), |
| 273 | GSI_EV_CTRL = BIT(1), |
| 274 | GSI_GLOB_EE = BIT(2), |
| 275 | GSI_IEOB = BIT(3), |
| 276 | GSI_INTER_EE_CH_CTRL = BIT(4), |
| 277 | GSI_INTER_EE_EV_CTRL = BIT(5), |
| 278 | GSI_GENERAL = BIT(6), |
| 279 | /* IRQ types 7-31 (and their bit values) are reserved */ |
| 280 | }; |
| 281 | |
| 282 | /** enum gsi_global_irq_id: Global GSI interrupt events */ |
| 283 | enum gsi_global_irq_id { |
| 284 | ERROR_INT = BIT(0), |
| 285 | GP_INT1 = BIT(1), |
| 286 | GP_INT2 = BIT(2), |
| 287 | GP_INT3 = BIT(3), |
| 288 | /* Global IRQ types 4-31 (and their bit values) are reserved */ |
| 289 | }; |
| 290 | |
| 291 | /** enum gsi_general_irq_id: GSI general IRQ conditions */ |
| 292 | enum gsi_general_irq_id { |
| 293 | BREAK_POINT = BIT(0), |
| 294 | BUS_ERROR = BIT(1), |
| 295 | CMD_FIFO_OVRFLOW = BIT(2), |
| 296 | MCS_STACK_OVRFLOW = BIT(3), |
| 297 | /* General IRQ types 4-31 (and their bit values) are reserved */ |
| 298 | }; |
| 299 | |
| 300 | /* CNTXT_INTSET register */ |
| 301 | enum gsi_cntxt_intset_field_id { |
| 302 | INTYPE, |
| 303 | }; |
| 304 | |
| 305 | /* ERROR_LOG register */ |
| 306 | enum gsi_error_log_field_id { |
| 307 | ERR_ARG3, |
| 308 | ERR_ARG2, |
| 309 | ERR_ARG1, |
| 310 | ERR_CODE, |
| 311 | ERR_VIRT_IDX, |
| 312 | ERR_TYPE, |
| 313 | ERR_EE, |
| 314 | }; |
| 315 | |
| 316 | /** enum gsi_err_code - ERR_CODE field values in EE_ERR_LOG */ |
| 317 | enum gsi_err_code { |
| 318 | GSI_INVALID_TRE = 0x1, |
| 319 | GSI_OUT_OF_BUFFERS = 0x2, |
| 320 | GSI_OUT_OF_RESOURCES = 0x3, |
| 321 | GSI_UNSUPPORTED_INTER_EE_OP = 0x4, |
| 322 | GSI_EVT_RING_EMPTY = 0x5, |
| 323 | GSI_NON_ALLOCATED_EVT_ACCESS = 0x6, |
| 324 | /* 7 is not assigned */ |
| 325 | GSI_HWO_1 = 0x8, |
| 326 | }; |
| 327 | |
| 328 | /** enum gsi_err_type - ERR_TYPE field values in EE_ERR_LOG */ |
| 329 | enum gsi_err_type { |
| 330 | GSI_ERR_TYPE_GLOB = 0x1, |
| 331 | GSI_ERR_TYPE_CHAN = 0x2, |
| 332 | GSI_ERR_TYPE_EVT = 0x3, |
| 333 | }; |
| 334 | |
| 335 | /* CNTXT_SCRATCH_0 register */ |
| 336 | enum gsi_cntxt_scratch_0_field_id { |
| 337 | INTER_EE_RESULT, |
| 338 | GENERIC_EE_RESULT, |
| 339 | }; |
| 340 | |
| 341 | /** enum gsi_generic_ee_result - GENERIC_EE_RESULT field values in SCRATCH_0 */ |
| 342 | enum gsi_generic_ee_result { |
| 343 | GENERIC_EE_SUCCESS = 0x1, |
| 344 | GENERIC_EE_INCORRECT_CHANNEL_STATE = 0x2, |
| 345 | GENERIC_EE_INCORRECT_DIRECTION = 0x3, |
| 346 | GENERIC_EE_INCORRECT_CHANNEL_TYPE = 0x4, |
| 347 | GENERIC_EE_INCORRECT_CHANNEL = 0x5, |
| 348 | GENERIC_EE_RETRY = 0x6, |
| 349 | GENERIC_EE_NO_RESOURCES = 0x7, |
| 350 | }; |
| 351 | |
| 352 | extern const struct regs gsi_regs_v3_1; |
| 353 | extern const struct regs gsi_regs_v3_5_1; |
| 354 | extern const struct regs gsi_regs_v4_0; |
| 355 | extern const struct regs gsi_regs_v4_5; |
| 356 | extern const struct regs gsi_regs_v4_9; |
| 357 | extern const struct regs gsi_regs_v4_11; |
| 358 | extern const struct regs gsi_regs_v5_0; |
| 359 | |
| 360 | /** |
| 361 | * gsi_reg() - Return the structure describing a GSI register |
| 362 | * @gsi: GSI pointer |
| 363 | * @reg_id: GSI register ID |
| 364 | */ |
| 365 | const struct reg *gsi_reg(struct gsi *gsi, enum gsi_reg_id reg_id); |
| 366 | |
| 367 | /** |
| 368 | * gsi_reg_init() - Perform GSI register initialization |
| 369 | * @gsi: GSI pointer |
| 370 | * @pdev: GSI (IPA) platform device |
| 371 | * |
| 372 | * Initialize GSI registers, including looking up and I/O mapping |
| 373 | * the "gsi" memory space. |
| 374 | */ |
| 375 | int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev); |
| 376 | |
| 377 | /** |
| 378 | * gsi_reg_exit() - Inverse of gsi_reg_init() |
| 379 | * @gsi: GSI pointer |
| 380 | */ |
| 381 | void gsi_reg_exit(struct gsi *gsi); |
| 382 | |
| 383 | #endif /* _GSI_REG_H_ */ |
| 384 | |