1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2010-2015, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #include "assert_support.h" 17 #include "irq.h" 18 19 #ifndef __INLINE_GP_DEVICE__ 20 #define __INLINE_GP_DEVICE__ 21 #endif 22 #include "gp_device.h" /* _REG_GP_IRQ_REQUEST_ADDR */ 23 24 static inline void irq_wait_for_write_complete( 25 const irq_ID_t ID); 26 27 static inline bool any_irq_channel_enabled( 28 const irq_ID_t ID); 29 30 static inline irq_ID_t virq_get_irq_id(const enum virq_id irq_ID, 31 unsigned int *channel_ID); 32 33 #ifndef __INLINE_IRQ__ 34 #include "irq_private.h" 35 #endif /* __INLINE_IRQ__ */ 36 37 static unsigned short IRQ_N_CHANNEL[N_IRQ_ID] = { 38 IRQ0_ID_N_CHANNEL, 39 IRQ1_ID_N_CHANNEL, 40 IRQ2_ID_N_CHANNEL, 41 IRQ3_ID_N_CHANNEL 42 }; 43 44 static unsigned short IRQ_N_ID_OFFSET[N_IRQ_ID + 1] = { 45 IRQ0_ID_OFFSET, 46 IRQ1_ID_OFFSET, 47 IRQ2_ID_OFFSET, 48 IRQ3_ID_OFFSET, 49 IRQ_END_OFFSET 50 }; 51 52 static enum virq_id IRQ_NESTING_ID[N_IRQ_ID] = { 53 N_virq_id, 54 virq_ifmt, 55 virq_isys, 56 virq_isel 57 }; 58 59 void irq_clear_all( 60 const irq_ID_t ID) 61 { 62 hrt_data mask = 0xFFFFFFFF; 63 64 assert(ID < N_IRQ_ID); 65 assert(IRQ_N_CHANNEL[ID] <= HRT_DATA_WIDTH); 66 67 if (IRQ_N_CHANNEL[ID] < HRT_DATA_WIDTH) { 68 mask = ~((~(hrt_data)0) >> IRQ_N_CHANNEL[ID]); 69 } 70 71 irq_reg_store(ID, 72 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, mask); 73 return; 74 } 75 76 /* 77 * Do we want the user to be able to set the signalling method ? 78 */ 79 void irq_enable_channel( 80 const irq_ID_t ID, 81 const unsigned int irq_id) 82 { 83 unsigned int mask = irq_reg_load(ID, 84 _HRT_IRQ_CONTROLLER_MASK_REG_IDX); 85 unsigned int enable = irq_reg_load(ID, 86 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); 87 unsigned int edge_in = irq_reg_load(ID, 88 _HRT_IRQ_CONTROLLER_EDGE_REG_IDX); 89 unsigned int me = 1U << irq_id; 90 91 assert(ID < N_IRQ_ID); 92 assert(irq_id < IRQ_N_CHANNEL[ID]); 93 94 mask |= me; 95 enable |= me; 96 edge_in |= me; /* rising edge */ 97 98 /* to avoid mishaps configuration must follow the following order */ 99 100 /* mask this interrupt */ 101 irq_reg_store(ID, 102 _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask & ~me); 103 /* rising edge at input */ 104 irq_reg_store(ID, 105 _HRT_IRQ_CONTROLLER_EDGE_REG_IDX, edge_in); 106 /* enable interrupt to output */ 107 irq_reg_store(ID, 108 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX, enable); 109 /* clear current irq only */ 110 irq_reg_store(ID, 111 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, me); 112 /* unmask interrupt from input */ 113 irq_reg_store(ID, 114 _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask); 115 116 irq_wait_for_write_complete(ID); 117 118 return; 119 } 120 121 void irq_enable_pulse( 122 const irq_ID_t ID, 123 bool pulse) 124 { 125 unsigned int edge_out = 0x0; 126 127 if (pulse) { 128 edge_out = 0xffffffff; 129 } 130 /* output is given as edge, not pulse */ 131 irq_reg_store(ID, 132 _HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX, edge_out); 133 return; 134 } 135 136 void irq_disable_channel( 137 const irq_ID_t ID, 138 const unsigned int irq_id) 139 { 140 unsigned int mask = irq_reg_load(ID, 141 _HRT_IRQ_CONTROLLER_MASK_REG_IDX); 142 unsigned int enable = irq_reg_load(ID, 143 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); 144 unsigned int me = 1U << irq_id; 145 146 assert(ID < N_IRQ_ID); 147 assert(irq_id < IRQ_N_CHANNEL[ID]); 148 149 mask &= ~me; 150 enable &= ~me; 151 152 /* enable interrupt to output */ 153 irq_reg_store(ID, 154 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX, enable); 155 /* unmask interrupt from input */ 156 irq_reg_store(ID, 157 _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask); 158 /* clear current irq only */ 159 irq_reg_store(ID, 160 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, me); 161 162 irq_wait_for_write_complete(ID); 163 164 return; 165 } 166 167 enum hrt_isp_css_irq_status irq_get_channel_id( 168 const irq_ID_t ID, 169 unsigned int *irq_id) 170 { 171 unsigned int irq_status = irq_reg_load(ID, 172 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 173 unsigned int idx; 174 enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_success; 175 176 assert(ID < N_IRQ_ID); 177 assert(irq_id); 178 179 /* find the first irq bit */ 180 for (idx = 0; idx < IRQ_N_CHANNEL[ID]; idx++) { 181 if (irq_status & (1U << idx)) 182 break; 183 } 184 if (idx == IRQ_N_CHANNEL[ID]) 185 return hrt_isp_css_irq_status_error; 186 187 /* now check whether there are more bits set */ 188 if (irq_status != (1U << idx)) 189 status = hrt_isp_css_irq_status_more_irqs; 190 191 irq_reg_store(ID, 192 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << idx); 193 194 irq_wait_for_write_complete(ID); 195 196 if (irq_id) 197 *irq_id = (unsigned int)idx; 198 199 return status; 200 } 201 202 static const hrt_address IRQ_REQUEST_ADDR[N_IRQ_SW_CHANNEL_ID] = { 203 _REG_GP_IRQ_REQUEST0_ADDR, 204 _REG_GP_IRQ_REQUEST1_ADDR 205 }; 206 207 void irq_raise( 208 const irq_ID_t ID, 209 const irq_sw_channel_id_t irq_id) 210 { 211 hrt_address addr; 212 213 OP___assert(ID == IRQ0_ID); 214 OP___assert(IRQ_BASE[ID] != (hrt_address)-1); 215 OP___assert(irq_id < N_IRQ_SW_CHANNEL_ID); 216 217 (void)ID; 218 219 addr = IRQ_REQUEST_ADDR[irq_id]; 220 /* The SW IRQ pins are remapped to offset zero */ 221 gp_device_reg_store(GP_DEVICE0_ID, 222 (unsigned int)addr, 1); 223 gp_device_reg_store(GP_DEVICE0_ID, 224 (unsigned int)addr, 0); 225 return; 226 } 227 228 void irq_controller_get_state(const irq_ID_t ID, 229 struct irq_controller_state *state) 230 { 231 assert(ID < N_IRQ_ID); 232 assert(state); 233 234 state->irq_edge = irq_reg_load(ID, 235 _HRT_IRQ_CONTROLLER_EDGE_REG_IDX); 236 state->irq_mask = irq_reg_load(ID, 237 _HRT_IRQ_CONTROLLER_MASK_REG_IDX); 238 state->irq_status = irq_reg_load(ID, 239 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 240 state->irq_enable = irq_reg_load(ID, 241 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); 242 state->irq_level_not_pulse = irq_reg_load(ID, 243 _HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX); 244 return; 245 } 246 247 bool any_virq_signal(void) 248 { 249 unsigned int irq_status = irq_reg_load(IRQ0_ID, 250 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 251 252 return (irq_status != 0); 253 } 254 255 void cnd_virq_enable_channel( 256 const enum virq_id irq_ID, 257 const bool en) 258 { 259 irq_ID_t i; 260 unsigned int channel_ID; 261 irq_ID_t ID = virq_get_irq_id(irq_ID, &channel_ID); 262 263 assert(ID < N_IRQ_ID); 264 265 for (i = IRQ1_ID; i < N_IRQ_ID; i++) { 266 /* It is not allowed to enable the pin of a nested IRQ directly */ 267 assert(irq_ID != IRQ_NESTING_ID[i]); 268 } 269 270 if (en) { 271 irq_enable_channel(ID, channel_ID); 272 if (IRQ_NESTING_ID[ID] != N_virq_id) { 273 /* Single level nesting, otherwise we'd need to recurse */ 274 irq_enable_channel(IRQ0_ID, IRQ_NESTING_ID[ID]); 275 } 276 } else { 277 irq_disable_channel(ID, channel_ID); 278 if ((IRQ_NESTING_ID[ID] != N_virq_id) && !any_irq_channel_enabled(ID)) { 279 /* Only disable the top if the nested ones are empty */ 280 irq_disable_channel(IRQ0_ID, IRQ_NESTING_ID[ID]); 281 } 282 } 283 return; 284 } 285 286 void virq_clear_all(void) 287 { 288 irq_ID_t irq_id; 289 290 for (irq_id = (irq_ID_t)0; irq_id < N_IRQ_ID; irq_id++) { 291 irq_clear_all(irq_id); 292 } 293 return; 294 } 295 296 enum hrt_isp_css_irq_status 297 virq_get_channel_signals(struct virq_info *irq_info) 298 { 299 enum hrt_isp_css_irq_status irq_status = hrt_isp_css_irq_status_error; 300 irq_ID_t ID; 301 302 assert(irq_info); 303 304 for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) { 305 if (any_irq_channel_enabled(ID)) { 306 hrt_data irq_data = irq_reg_load(ID, 307 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 308 309 if (irq_data != 0) { 310 /* The error condition is an IRQ pulse received with no IRQ status written */ 311 irq_status = hrt_isp_css_irq_status_success; 312 } 313 314 irq_info->irq_status_reg[ID] |= irq_data; 315 316 irq_reg_store(ID, 317 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, irq_data); 318 319 irq_wait_for_write_complete(ID); 320 } 321 } 322 323 return irq_status; 324 } 325 326 void virq_clear_info(struct virq_info *irq_info) 327 { 328 irq_ID_t ID; 329 330 assert(irq_info); 331 332 for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) { 333 irq_info->irq_status_reg[ID] = 0; 334 } 335 return; 336 } 337 338 enum hrt_isp_css_irq_status virq_get_channel_id( 339 enum virq_id *irq_id) 340 { 341 unsigned int irq_status = irq_reg_load(IRQ0_ID, 342 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 343 unsigned int idx; 344 enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_success; 345 irq_ID_t ID; 346 347 assert(irq_id); 348 349 /* find the first irq bit on device 0 */ 350 for (idx = 0; idx < IRQ_N_CHANNEL[IRQ0_ID]; idx++) { 351 if (irq_status & (1U << idx)) 352 break; 353 } 354 355 if (idx == IRQ_N_CHANNEL[IRQ0_ID]) { 356 return hrt_isp_css_irq_status_error; 357 } 358 359 /* Check whether there are more bits set on device 0 */ 360 if (irq_status != (1U << idx)) { 361 status = hrt_isp_css_irq_status_more_irqs; 362 } 363 364 /* Check whether we have an IRQ on one of the nested devices */ 365 for (ID = N_IRQ_ID - 1 ; ID > (irq_ID_t)0; ID--) { 366 if (IRQ_NESTING_ID[ID] == (enum virq_id)idx) { 367 break; 368 } 369 } 370 371 /* If we have a nested IRQ, load that state, discard the device 0 state */ 372 if (ID != IRQ0_ID) { 373 irq_status = irq_reg_load(ID, 374 _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); 375 /* find the first irq bit on device "id" */ 376 for (idx = 0; idx < IRQ_N_CHANNEL[ID]; idx++) { 377 if (irq_status & (1U << idx)) 378 break; 379 } 380 381 if (idx == IRQ_N_CHANNEL[ID]) { 382 return hrt_isp_css_irq_status_error; 383 } 384 385 /* Alternatively check whether there are more bits set on this device */ 386 if (irq_status != (1U << idx)) { 387 status = hrt_isp_css_irq_status_more_irqs; 388 } else { 389 /* If this device is empty, clear the state on device 0 */ 390 irq_reg_store(IRQ0_ID, 391 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << IRQ_NESTING_ID[ID]); 392 } 393 } /* if (ID != IRQ0_ID) */ 394 395 /* Here we proceed to clear the IRQ on detected device, if no nested IRQ, this is device 0 */ 396 irq_reg_store(ID, 397 _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << idx); 398 399 irq_wait_for_write_complete(ID); 400 401 idx += IRQ_N_ID_OFFSET[ID]; 402 if (irq_id) 403 *irq_id = (enum virq_id)idx; 404 405 return status; 406 } 407 408 static inline void irq_wait_for_write_complete( 409 const irq_ID_t ID) 410 { 411 assert(ID < N_IRQ_ID); 412 assert(IRQ_BASE[ID] != (hrt_address)-1); 413 (void)ia_css_device_load_uint32(IRQ_BASE[ID] + 414 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX * sizeof(hrt_data)); 415 } 416 417 static inline bool any_irq_channel_enabled( 418 const irq_ID_t ID) 419 { 420 hrt_data en_reg; 421 422 assert(ID < N_IRQ_ID); 423 424 en_reg = irq_reg_load(ID, 425 _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); 426 427 return (en_reg != 0); 428 } 429 430 static inline irq_ID_t virq_get_irq_id( 431 const enum virq_id irq_ID, 432 unsigned int *channel_ID) 433 { 434 irq_ID_t ID; 435 436 assert(channel_ID); 437 438 for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) { 439 if (irq_ID < IRQ_N_ID_OFFSET[ID + 1]) { 440 break; 441 } 442 } 443 444 *channel_ID = (unsigned int)irq_ID - IRQ_N_ID_OFFSET[ID]; 445 446 return ID; 447 } 448