1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. 3 */ 4 5 #include <linux/bitops.h> 6 #include <linux/debugfs.h> 7 #include <linux/slab.h> 8 9 #include <drm/drm_managed.h> 10 11 #include "dpu_core_irq.h" 12 #include "dpu_kms.h" 13 #include "dpu_hw_interrupts.h" 14 #include "dpu_hw_util.h" 15 #include "dpu_hw_mdss.h" 16 #include "dpu_trace.h" 17 18 /* 19 * Register offsets in MDSS register file for the interrupt registers 20 * w.r.t. the MDP base 21 */ 22 #define MDP_INTF_OFF(intf) (0x6A000 + 0x800 * (intf)) 23 #define MDP_INTF_INTR_EN(intf) (MDP_INTF_OFF(intf) + 0x1c0) 24 #define MDP_INTF_INTR_STATUS(intf) (MDP_INTF_OFF(intf) + 0x1c4) 25 #define MDP_INTF_INTR_CLEAR(intf) (MDP_INTF_OFF(intf) + 0x1c8) 26 #define MDP_INTF_TEAR_OFF(intf) (0x6D700 + 0x100 * (intf)) 27 #define MDP_INTF_INTR_TEAR_EN(intf) (MDP_INTF_TEAR_OFF(intf) + 0x000) 28 #define MDP_INTF_INTR_TEAR_STATUS(intf) (MDP_INTF_TEAR_OFF(intf) + 0x004) 29 #define MDP_INTF_INTR_TEAR_CLEAR(intf) (MDP_INTF_TEAR_OFF(intf) + 0x008) 30 #define MDP_AD4_OFF(ad4) (0x7C000 + 0x1000 * (ad4)) 31 #define MDP_AD4_INTR_EN_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x41c) 32 #define MDP_AD4_INTR_CLEAR_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x424) 33 #define MDP_AD4_INTR_STATUS_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x420) 34 #define MDP_INTF_REV_7xxx_OFF(intf) (0x34000 + 0x1000 * (intf)) 35 #define MDP_INTF_REV_7xxx_INTR_EN(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c0) 36 #define MDP_INTF_REV_7xxx_INTR_STATUS(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c4) 37 #define MDP_INTF_REV_7xxx_INTR_CLEAR(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c8) 38 #define MDP_INTF_REV_7xxx_TEAR_OFF(intf) (0x34800 + 0x1000 * (intf)) 39 #define MDP_INTF_REV_7xxx_INTR_TEAR_EN(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x000) 40 #define MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x004) 41 #define MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x008) 42 43 /** 44 * struct dpu_intr_reg - array of DPU register sets 45 * @clr_off: offset to CLEAR reg 46 * @en_off: offset to ENABLE reg 47 * @status_off: offset to STATUS reg 48 */ 49 struct dpu_intr_reg { 50 u32 clr_off; 51 u32 en_off; 52 u32 status_off; 53 }; 54 55 /* 56 * dpu_intr_set_legacy - List of DPU interrupt registers for DPU <= 6.x 57 */ 58 static const struct dpu_intr_reg dpu_intr_set_legacy[] = { 59 [MDP_SSPP_TOP0_INTR] = { 60 INTR_CLEAR, 61 INTR_EN, 62 INTR_STATUS 63 }, 64 [MDP_SSPP_TOP0_INTR2] = { 65 INTR2_CLEAR, 66 INTR2_EN, 67 INTR2_STATUS 68 }, 69 [MDP_SSPP_TOP0_HIST_INTR] = { 70 HIST_INTR_CLEAR, 71 HIST_INTR_EN, 72 HIST_INTR_STATUS 73 }, 74 [MDP_INTF0_INTR] = { 75 MDP_INTF_INTR_CLEAR(0), 76 MDP_INTF_INTR_EN(0), 77 MDP_INTF_INTR_STATUS(0) 78 }, 79 [MDP_INTF1_INTR] = { 80 MDP_INTF_INTR_CLEAR(1), 81 MDP_INTF_INTR_EN(1), 82 MDP_INTF_INTR_STATUS(1) 83 }, 84 [MDP_INTF2_INTR] = { 85 MDP_INTF_INTR_CLEAR(2), 86 MDP_INTF_INTR_EN(2), 87 MDP_INTF_INTR_STATUS(2) 88 }, 89 [MDP_INTF3_INTR] = { 90 MDP_INTF_INTR_CLEAR(3), 91 MDP_INTF_INTR_EN(3), 92 MDP_INTF_INTR_STATUS(3) 93 }, 94 [MDP_INTF4_INTR] = { 95 MDP_INTF_INTR_CLEAR(4), 96 MDP_INTF_INTR_EN(4), 97 MDP_INTF_INTR_STATUS(4) 98 }, 99 [MDP_INTF5_INTR] = { 100 MDP_INTF_INTR_CLEAR(5), 101 MDP_INTF_INTR_EN(5), 102 MDP_INTF_INTR_STATUS(5) 103 }, 104 [MDP_INTF1_TEAR_INTR] = { 105 MDP_INTF_INTR_TEAR_CLEAR(1), 106 MDP_INTF_INTR_TEAR_EN(1), 107 MDP_INTF_INTR_TEAR_STATUS(1) 108 }, 109 [MDP_INTF2_TEAR_INTR] = { 110 MDP_INTF_INTR_TEAR_CLEAR(2), 111 MDP_INTF_INTR_TEAR_EN(2), 112 MDP_INTF_INTR_TEAR_STATUS(2) 113 }, 114 [MDP_AD4_0_INTR] = { 115 MDP_AD4_INTR_CLEAR_OFF(0), 116 MDP_AD4_INTR_EN_OFF(0), 117 MDP_AD4_INTR_STATUS_OFF(0), 118 }, 119 [MDP_AD4_1_INTR] = { 120 MDP_AD4_INTR_CLEAR_OFF(1), 121 MDP_AD4_INTR_EN_OFF(1), 122 MDP_AD4_INTR_STATUS_OFF(1), 123 }, 124 }; 125 126 /* 127 * dpu_intr_set_7xxx - List of DPU interrupt registers for DPU >= 7.0 128 */ 129 static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { 130 [MDP_SSPP_TOP0_INTR] = { 131 INTR_CLEAR, 132 INTR_EN, 133 INTR_STATUS 134 }, 135 [MDP_SSPP_TOP0_INTR2] = { 136 INTR2_CLEAR, 137 INTR2_EN, 138 INTR2_STATUS 139 }, 140 [MDP_SSPP_TOP0_HIST_INTR] = { 141 HIST_INTR_CLEAR, 142 HIST_INTR_EN, 143 HIST_INTR_STATUS 144 }, 145 [MDP_INTF0_INTR] = { 146 MDP_INTF_REV_7xxx_INTR_CLEAR(0), 147 MDP_INTF_REV_7xxx_INTR_EN(0), 148 MDP_INTF_REV_7xxx_INTR_STATUS(0) 149 }, 150 [MDP_INTF1_INTR] = { 151 MDP_INTF_REV_7xxx_INTR_CLEAR(1), 152 MDP_INTF_REV_7xxx_INTR_EN(1), 153 MDP_INTF_REV_7xxx_INTR_STATUS(1) 154 }, 155 [MDP_INTF1_TEAR_INTR] = { 156 MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(1), 157 MDP_INTF_REV_7xxx_INTR_TEAR_EN(1), 158 MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(1) 159 }, 160 [MDP_INTF2_INTR] = { 161 MDP_INTF_REV_7xxx_INTR_CLEAR(2), 162 MDP_INTF_REV_7xxx_INTR_EN(2), 163 MDP_INTF_REV_7xxx_INTR_STATUS(2) 164 }, 165 [MDP_INTF2_TEAR_INTR] = { 166 MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(2), 167 MDP_INTF_REV_7xxx_INTR_TEAR_EN(2), 168 MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(2) 169 }, 170 [MDP_INTF3_INTR] = { 171 MDP_INTF_REV_7xxx_INTR_CLEAR(3), 172 MDP_INTF_REV_7xxx_INTR_EN(3), 173 MDP_INTF_REV_7xxx_INTR_STATUS(3) 174 }, 175 [MDP_INTF4_INTR] = { 176 MDP_INTF_REV_7xxx_INTR_CLEAR(4), 177 MDP_INTF_REV_7xxx_INTR_EN(4), 178 MDP_INTF_REV_7xxx_INTR_STATUS(4) 179 }, 180 [MDP_INTF5_INTR] = { 181 MDP_INTF_REV_7xxx_INTR_CLEAR(5), 182 MDP_INTF_REV_7xxx_INTR_EN(5), 183 MDP_INTF_REV_7xxx_INTR_STATUS(5) 184 }, 185 [MDP_INTF6_INTR] = { 186 MDP_INTF_REV_7xxx_INTR_CLEAR(6), 187 MDP_INTF_REV_7xxx_INTR_EN(6), 188 MDP_INTF_REV_7xxx_INTR_STATUS(6) 189 }, 190 [MDP_INTF7_INTR] = { 191 MDP_INTF_REV_7xxx_INTR_CLEAR(7), 192 MDP_INTF_REV_7xxx_INTR_EN(7), 193 MDP_INTF_REV_7xxx_INTR_STATUS(7) 194 }, 195 [MDP_INTF8_INTR] = { 196 MDP_INTF_REV_7xxx_INTR_CLEAR(8), 197 MDP_INTF_REV_7xxx_INTR_EN(8), 198 MDP_INTF_REV_7xxx_INTR_STATUS(8) 199 }, 200 }; 201 202 #define DPU_IRQ_MASK(irq_idx) (BIT(DPU_IRQ_BIT(irq_idx))) 203 204 static inline bool dpu_core_irq_is_valid(unsigned int irq_idx) 205 { 206 return irq_idx && irq_idx <= DPU_NUM_IRQS; 207 } 208 209 static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct dpu_hw_intr *intr, 210 unsigned int irq_idx) 211 { 212 return &intr->irq_tbl[irq_idx - 1]; 213 } 214 215 /** 216 * dpu_core_irq_callback_handler - dispatch core interrupts 217 * @dpu_kms: Pointer to DPU's KMS structure 218 * @irq_idx: interrupt index 219 */ 220 static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, unsigned int irq_idx) 221 { 222 struct dpu_hw_intr_entry *irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); 223 224 VERB("IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 225 226 if (!irq_entry->cb) { 227 DRM_ERROR("no registered cb, IRQ=[%d, %d]\n", 228 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 229 return; 230 } 231 232 atomic_inc(&irq_entry->count); 233 234 /* 235 * Perform registered function callback 236 */ 237 irq_entry->cb(irq_entry->arg); 238 } 239 240 irqreturn_t dpu_core_irq(struct msm_kms *kms) 241 { 242 struct dpu_kms *dpu_kms = to_dpu_kms(kms); 243 struct dpu_hw_intr *intr = dpu_kms->hw_intr; 244 int reg_idx; 245 unsigned int irq_idx; 246 u32 irq_status; 247 u32 enable_mask; 248 int bit; 249 unsigned long irq_flags; 250 251 if (!intr) 252 return IRQ_NONE; 253 254 spin_lock_irqsave(&intr->irq_lock, irq_flags); 255 for (reg_idx = 0; reg_idx < MDP_INTR_MAX; reg_idx++) { 256 if (!test_bit(reg_idx, &intr->irq_mask)) 257 continue; 258 259 /* Read interrupt status */ 260 irq_status = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].status_off); 261 262 /* Read enable mask */ 263 enable_mask = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].en_off); 264 265 /* and clear the interrupt */ 266 if (irq_status) 267 DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off, 268 irq_status); 269 270 /* Finally update IRQ status based on enable mask */ 271 irq_status &= enable_mask; 272 273 if (!irq_status) 274 continue; 275 276 /* 277 * Search through matching intr status. 278 */ 279 while ((bit = ffs(irq_status)) != 0) { 280 irq_idx = DPU_IRQ_IDX(reg_idx, bit - 1); 281 282 dpu_core_irq_callback_handler(dpu_kms, irq_idx); 283 284 /* 285 * When callback finish, clear the irq_status 286 * with the matching mask. Once irq_status 287 * is all cleared, the search can be stopped. 288 */ 289 irq_status &= ~BIT(bit - 1); 290 } 291 } 292 293 /* ensure register writes go through */ 294 wmb(); 295 296 spin_unlock_irqrestore(&intr->irq_lock, irq_flags); 297 298 return IRQ_HANDLED; 299 } 300 301 static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, 302 unsigned int irq_idx) 303 { 304 int reg_idx; 305 const struct dpu_intr_reg *reg; 306 const char *dbgstr = NULL; 307 uint32_t cache_irq_mask; 308 309 if (!intr) 310 return -EINVAL; 311 312 if (!dpu_core_irq_is_valid(irq_idx)) { 313 pr_err("invalid IRQ=[%d, %d]\n", 314 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 315 return -EINVAL; 316 } 317 318 /* 319 * The cache_irq_mask and hardware RMW operations needs to be done 320 * under irq_lock and it's the caller's responsibility to ensure that's 321 * held. 322 */ 323 assert_spin_locked(&intr->irq_lock); 324 325 reg_idx = DPU_IRQ_REG(irq_idx); 326 reg = &intr->intr_set[reg_idx]; 327 328 /* Is this interrupt register supported on the platform */ 329 if (WARN_ON(!reg->en_off)) 330 return -EINVAL; 331 332 cache_irq_mask = intr->cache_irq_mask[reg_idx]; 333 if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) { 334 dbgstr = "already "; 335 } else { 336 dbgstr = ""; 337 338 cache_irq_mask |= DPU_IRQ_MASK(irq_idx); 339 /* Cleaning any pending interrupt */ 340 DPU_REG_WRITE(&intr->hw, reg->clr_off, DPU_IRQ_MASK(irq_idx)); 341 /* Enabling interrupts with the new mask */ 342 DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask); 343 344 /* ensure register write goes through */ 345 wmb(); 346 347 intr->cache_irq_mask[reg_idx] = cache_irq_mask; 348 } 349 350 pr_debug("DPU IRQ=[%d, %d] %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", 351 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr, 352 DPU_IRQ_MASK(irq_idx), cache_irq_mask); 353 354 return 0; 355 } 356 357 static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, 358 unsigned int irq_idx) 359 { 360 int reg_idx; 361 const struct dpu_intr_reg *reg; 362 const char *dbgstr = NULL; 363 uint32_t cache_irq_mask; 364 365 if (!intr) 366 return -EINVAL; 367 368 if (!dpu_core_irq_is_valid(irq_idx)) { 369 pr_err("invalid IRQ=[%d, %d]\n", 370 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 371 return -EINVAL; 372 } 373 374 /* 375 * The cache_irq_mask and hardware RMW operations needs to be done 376 * under irq_lock and it's the caller's responsibility to ensure that's 377 * held. 378 */ 379 assert_spin_locked(&intr->irq_lock); 380 381 reg_idx = DPU_IRQ_REG(irq_idx); 382 reg = &intr->intr_set[reg_idx]; 383 384 cache_irq_mask = intr->cache_irq_mask[reg_idx]; 385 if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) { 386 dbgstr = "already "; 387 } else { 388 dbgstr = ""; 389 390 cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx); 391 /* Disable interrupts based on the new mask */ 392 DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask); 393 /* Cleaning any pending interrupt */ 394 DPU_REG_WRITE(&intr->hw, reg->clr_off, DPU_IRQ_MASK(irq_idx)); 395 396 /* ensure register write goes through */ 397 wmb(); 398 399 intr->cache_irq_mask[reg_idx] = cache_irq_mask; 400 } 401 402 pr_debug("DPU IRQ=[%d, %d] %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", 403 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr, 404 DPU_IRQ_MASK(irq_idx), cache_irq_mask); 405 406 return 0; 407 } 408 409 static void dpu_clear_irqs(struct dpu_kms *dpu_kms) 410 { 411 struct dpu_hw_intr *intr = dpu_kms->hw_intr; 412 int i; 413 414 if (!intr) 415 return; 416 417 for (i = 0; i < MDP_INTR_MAX; i++) { 418 if (test_bit(i, &intr->irq_mask)) 419 DPU_REG_WRITE(&intr->hw, 420 intr->intr_set[i].clr_off, 0xffffffff); 421 } 422 423 /* ensure register writes go through */ 424 wmb(); 425 } 426 427 static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms) 428 { 429 struct dpu_hw_intr *intr = dpu_kms->hw_intr; 430 int i; 431 432 if (!intr) 433 return; 434 435 for (i = 0; i < MDP_INTR_MAX; i++) { 436 if (test_bit(i, &intr->irq_mask)) 437 DPU_REG_WRITE(&intr->hw, 438 intr->intr_set[i].en_off, 0x00000000); 439 } 440 441 /* ensure register writes go through */ 442 wmb(); 443 } 444 445 u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, 446 unsigned int irq_idx) 447 { 448 struct dpu_hw_intr *intr = dpu_kms->hw_intr; 449 int reg_idx; 450 unsigned long irq_flags; 451 u32 intr_status; 452 453 if (!intr) 454 return 0; 455 456 if (!dpu_core_irq_is_valid(irq_idx)) { 457 pr_err("invalid IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 458 return 0; 459 } 460 461 spin_lock_irqsave(&intr->irq_lock, irq_flags); 462 463 reg_idx = DPU_IRQ_REG(irq_idx); 464 intr_status = DPU_REG_READ(&intr->hw, 465 intr->intr_set[reg_idx].status_off) & 466 DPU_IRQ_MASK(irq_idx); 467 if (intr_status) 468 DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off, 469 intr_status); 470 471 /* ensure register writes go through */ 472 wmb(); 473 474 spin_unlock_irqrestore(&intr->irq_lock, irq_flags); 475 476 return intr_status; 477 } 478 479 struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, 480 void __iomem *addr, 481 const struct dpu_mdss_cfg *m) 482 { 483 struct dpu_hw_intr *intr; 484 unsigned int i; 485 486 if (!addr || !m) 487 return ERR_PTR(-EINVAL); 488 489 intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL); 490 if (!intr) 491 return ERR_PTR(-ENOMEM); 492 493 if (m->mdss_ver->core_major_ver >= 7) 494 intr->intr_set = dpu_intr_set_7xxx; 495 else 496 intr->intr_set = dpu_intr_set_legacy; 497 498 intr->hw.blk_addr = addr + m->mdp[0].base; 499 500 intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | 501 BIT(MDP_SSPP_TOP0_INTR2) | 502 BIT(MDP_SSPP_TOP0_HIST_INTR); 503 for (i = 0; i < m->intf_count; i++) { 504 const struct dpu_intf_cfg *intf = &m->intf[i]; 505 506 if (intf->type == INTF_NONE) 507 continue; 508 509 intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id)); 510 511 if (intf->intr_tear_rd_ptr) 512 intr->irq_mask |= BIT(DPU_IRQ_REG(intf->intr_tear_rd_ptr)); 513 } 514 515 spin_lock_init(&intr->irq_lock); 516 517 return intr; 518 } 519 520 int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, 521 unsigned int irq_idx, 522 void (*irq_cb)(void *arg), 523 void *irq_arg) 524 { 525 struct dpu_hw_intr_entry *irq_entry; 526 unsigned long irq_flags; 527 int ret; 528 529 if (!irq_cb) { 530 DPU_ERROR("IRQ=[%d, %d] NULL callback\n", 531 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 532 return -EINVAL; 533 } 534 535 if (!dpu_core_irq_is_valid(irq_idx)) { 536 DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", 537 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); 538 return -EINVAL; 539 } 540 541 VERB("[%pS] IRQ=[%d, %d]\n", __builtin_return_address(0), 542 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 543 544 spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 545 546 irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); 547 if (unlikely(WARN_ON(irq_entry->cb))) { 548 spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 549 550 return -EBUSY; 551 } 552 553 trace_dpu_core_irq_register_callback(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); 554 irq_entry->arg = irq_arg; 555 irq_entry->cb = irq_cb; 556 557 ret = dpu_hw_intr_enable_irq_locked( 558 dpu_kms->hw_intr, 559 irq_idx); 560 if (ret) 561 DPU_ERROR("Failed/ to enable IRQ=[%d, %d]\n", 562 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 563 spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 564 565 trace_dpu_irq_register_success(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 566 567 return 0; 568 } 569 570 int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, 571 unsigned int irq_idx) 572 { 573 struct dpu_hw_intr_entry *irq_entry; 574 unsigned long irq_flags; 575 int ret; 576 577 if (!dpu_core_irq_is_valid(irq_idx)) { 578 DPU_ERROR("invalid IRQ=[%d, %d]\n", 579 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 580 return -EINVAL; 581 } 582 583 VERB("[%pS] IRQ=[%d, %d]\n", __builtin_return_address(0), 584 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 585 586 spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 587 trace_dpu_core_irq_unregister_callback(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 588 589 ret = dpu_hw_intr_disable_irq_locked(dpu_kms->hw_intr, irq_idx); 590 if (ret) 591 DPU_ERROR("Failed to disable IRQ=[%d, %d]: %d\n", 592 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), ret); 593 594 irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); 595 irq_entry->cb = NULL; 596 irq_entry->arg = NULL; 597 598 spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 599 600 trace_dpu_irq_unregister_success(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); 601 602 return 0; 603 } 604 605 #ifdef CONFIG_DEBUG_FS 606 static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) 607 { 608 struct dpu_kms *dpu_kms = s->private; 609 struct dpu_hw_intr_entry *irq_entry; 610 unsigned long irq_flags; 611 int i, irq_count; 612 void *cb; 613 614 for (i = 1; i <= DPU_NUM_IRQS; i++) { 615 spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 616 irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); 617 irq_count = atomic_read(&irq_entry->count); 618 cb = irq_entry->cb; 619 spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 620 621 if (irq_count || cb) 622 seq_printf(s, "IRQ=[%d, %d] count:%d cb:%ps\n", 623 DPU_IRQ_REG(i), DPU_IRQ_BIT(i), irq_count, cb); 624 } 625 626 return 0; 627 } 628 629 DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_core_irq); 630 631 void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, 632 struct dentry *parent) 633 { 634 debugfs_create_file("core_irq", 0600, parent, dpu_kms, 635 &dpu_debugfs_core_irq_fops); 636 } 637 #endif 638 639 void dpu_core_irq_preinstall(struct msm_kms *kms) 640 { 641 struct dpu_kms *dpu_kms = to_dpu_kms(kms); 642 struct dpu_hw_intr_entry *irq_entry; 643 int i; 644 645 pm_runtime_get_sync(&dpu_kms->pdev->dev); 646 dpu_clear_irqs(dpu_kms); 647 dpu_disable_all_irqs(dpu_kms); 648 pm_runtime_put_sync(&dpu_kms->pdev->dev); 649 650 for (i = 1; i <= DPU_NUM_IRQS; i++) { 651 irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); 652 atomic_set(&irq_entry->count, 0); 653 } 654 } 655 656 void dpu_core_irq_uninstall(struct msm_kms *kms) 657 { 658 struct dpu_kms *dpu_kms = to_dpu_kms(kms); 659 struct dpu_hw_intr_entry *irq_entry; 660 int i; 661 662 if (!dpu_kms->hw_intr) 663 return; 664 665 pm_runtime_get_sync(&dpu_kms->pdev->dev); 666 for (i = 1; i <= DPU_NUM_IRQS; i++) { 667 irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); 668 if (irq_entry->cb) 669 DPU_ERROR("IRQ=[%d, %d] still enabled/registered\n", 670 DPU_IRQ_REG(i), DPU_IRQ_BIT(i)); 671 } 672 673 dpu_clear_irqs(dpu_kms); 674 dpu_disable_all_irqs(dpu_kms); 675 pm_runtime_put_sync(&dpu_kms->pdev->dev); 676 } 677