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