1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Renesas RZ/V2H(P) ICU Driver 4 * 5 * Based on irq-renesas-rzg2l.c 6 * 7 * Copyright (C) 2024 Renesas Electronics Corporation. 8 * 9 * Author: Fabrizio Castro <fabrizio.castro.jz@renesas.com> 10 */ 11 12 #include <linux/bitfield.h> 13 #include <linux/cleanup.h> 14 #include <linux/err.h> 15 #include <linux/interrupt.h> 16 #include <linux/io.h> 17 #include <linux/irqchip.h> 18 #include <linux/irqchip/irq-renesas-rzv2h.h> 19 #include <linux/irqdomain.h> 20 #include <linux/of_platform.h> 21 #include <linux/pm_runtime.h> 22 #include <linux/reset.h> 23 #include <linux/spinlock.h> 24 #include <linux/syscore_ops.h> 25 26 /* DT "interrupts" indexes */ 27 #define ICU_IRQ_START 1 28 #define ICU_IRQ_COUNT 16 29 #define ICU_IRQ_LAST (ICU_IRQ_START + ICU_IRQ_COUNT - 1) 30 #define ICU_TINT_START (ICU_IRQ_LAST + 1) 31 #define ICU_TINT_COUNT 32 32 #define ICU_TINT_LAST (ICU_TINT_START + ICU_TINT_COUNT - 1) 33 #define ICU_CA55_INT_START (ICU_TINT_LAST + 1) 34 #define ICU_CA55_INT_COUNT 4 35 #define ICU_CA55_INT_LAST (ICU_CA55_INT_START + ICU_CA55_INT_COUNT - 1) 36 #define ICU_ERR_INT_START (ICU_CA55_INT_LAST + 1) 37 #define ICU_ERR_INT_COUNT 1 38 #define ICU_ERR_INT_LAST (ICU_ERR_INT_START + ICU_ERR_INT_COUNT - 1) 39 #define ICU_NUM_IRQ (ICU_ERR_INT_LAST + 1) 40 41 /* Registers */ 42 #define ICU_NSCNT 0x00 43 #define ICU_NSCLR 0x04 44 #define ICU_NITSR 0x08 45 #define ICU_ISCTR 0x10 46 #define ICU_ISCLR 0x14 47 #define ICU_IITSR 0x18 48 #define ICU_TSCTR 0x20 49 #define ICU_TSCLR 0x24 50 #define ICU_TITSR(k) (0x28 + (k) * 4) 51 #define ICU_TSSR(k) (0x30 + (k) * 4) 52 #define ICU_BEISR(k) (0x70 + (k) * 4) 53 #define ICU_BECLR(k) (0x80 + (k) * 4) 54 #define ICU_EREISR(k) (0x90 + (k) * 4) 55 #define ICU_ERCLR(k) (0xE0 + (k) * 4) 56 #define ICU_SWINT 0x130 57 #define ICU_ERINTA55CTL(k) (0x338 + (k) * 4) 58 #define ICU_ERINTA55CRL(k) (0x348 + (k) * 4) 59 #define ICU_ERINTA55MSK(k) (0x358 + (k) * 4) 60 #define ICU_SWPE 0x370 61 #define ICU_DMkSELy(k, y) (0x420 + (k) * 0x20 + (y) * 4) 62 #define ICU_DMACKSELk(k) (0x500 + (k) * 4) 63 64 /* NMI */ 65 #define ICU_NMI_EDGE_FALLING 0 66 #define ICU_NMI_EDGE_RISING 1 67 68 #define ICU_NSCLR_NCLR BIT(0) 69 70 /* IRQ */ 71 #define ICU_IRQ_LEVEL_LOW 0 72 #define ICU_IRQ_EDGE_FALLING 1 73 #define ICU_IRQ_EDGE_RISING 2 74 #define ICU_IRQ_EDGE_BOTH 3 75 76 #define ICU_IITSR_IITSEL_PREP(iitsel, n) ((iitsel) << ((n) * 2)) 77 #define ICU_IITSR_IITSEL_GET(iitsr, n) (((iitsr) >> ((n) * 2)) & 0x03) 78 #define ICU_IITSR_IITSEL_MASK(n) ICU_IITSR_IITSEL_PREP(0x03, n) 79 80 /* TINT */ 81 #define ICU_TINT_EDGE_RISING 0 82 #define ICU_TINT_EDGE_FALLING 1 83 #define ICU_TINT_LEVEL_HIGH 2 84 #define ICU_TINT_LEVEL_LOW 3 85 86 #define ICU_TSSR_TSSEL_PREP(tssel, n, field_width) ((tssel) << ((n) * (field_width))) 87 #define ICU_TSSR_TSSEL_MASK(n, field_width) \ 88 ({\ 89 typeof(field_width) (_field_width) = (field_width); \ 90 ICU_TSSR_TSSEL_PREP((GENMASK(((_field_width) - 2), 0)), (n), _field_width); \ 91 }) 92 93 #define ICU_TSSR_TIEN(n, field_width) \ 94 ({\ 95 typeof(field_width) (_field_width) = (field_width); \ 96 BIT((_field_width) - 1) << ((n) * (_field_width)); \ 97 }) 98 99 #define ICU_TITSR_K(tint_nr) ((tint_nr) / 16) 100 #define ICU_TITSR_TITSEL_N(tint_nr) ((tint_nr) % 16) 101 #define ICU_TITSR_TITSEL_PREP(titsel, n) ICU_IITSR_IITSEL_PREP(titsel, n) 102 #define ICU_TITSR_TITSEL_MASK(n) ICU_IITSR_IITSEL_MASK(n) 103 #define ICU_TITSR_TITSEL_GET(titsr, n) ICU_IITSR_IITSEL_GET(titsr, n) 104 105 #define ICU_TINT_EXTRACT_HWIRQ(x) FIELD_GET(GENMASK(15, 0), (x)) 106 #define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x)) 107 #define ICU_RZG3E_TINT_OFFSET 0x800 108 #define ICU_RZG3E_TSSEL_MAX_VAL 0x8c 109 #define ICU_RZV2H_TSSEL_MAX_VAL 0x55 110 111 #define ICU_SWPE_NUM 16 112 #define ICU_NUM_BE 4 113 #define ICU_NUM_A55ERR 4 114 115 /** 116 * struct rzv2h_irqc_reg_cache - registers cache (necessary for suspend/resume) 117 * @nitsr: ICU_NITSR register 118 * @iitsr: ICU_IITSR register 119 * @titsr: ICU_TITSR registers 120 */ 121 struct rzv2h_irqc_reg_cache { 122 u32 nitsr; 123 u32 iitsr; 124 u32 titsr[2]; 125 }; 126 127 /** 128 * struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure. 129 * @tssel_lut: TINT lookup table 130 * @t_offs: TINT offset 131 * @max_tssel: TSSEL max value 132 * @field_width: TSSR field width 133 * @ecc_start: Start index of ECC RAM interrupts 134 * @ecc_end: End index of ECC RAM interrupts 135 */ 136 struct rzv2h_hw_info { 137 const u8 *tssel_lut; 138 u16 t_offs; 139 u8 max_tssel; 140 u8 field_width; 141 u8 ecc_start; 142 u8 ecc_end; 143 }; 144 145 /* DMAC */ 146 #define ICU_DMAC_DkRQ_SEL_MASK GENMASK(9, 0) 147 148 #define ICU_DMAC_DMAREQ_SHIFT(up) ((up) * 16) 149 #define ICU_DMAC_DMAREQ_MASK(up) (ICU_DMAC_DkRQ_SEL_MASK \ 150 << ICU_DMAC_DMAREQ_SHIFT(up)) 151 #define ICU_DMAC_PREP_DMAREQ(sel, up) (FIELD_PREP(ICU_DMAC_DkRQ_SEL_MASK, (sel)) \ 152 << ICU_DMAC_DMAREQ_SHIFT(up)) 153 154 /* DMAC ACK routing - 4 x 7-bit fields per 32-bit register, 8-bit spacing */ 155 #define ICU_DMAC_DACK_SEL_MASK GENMASK(6, 0) 156 #define ICU_DMAC_DACK_SHIFT(n) ((n) * 8) 157 #define ICU_DMAC_DACK_FIELD_MASK(n) (ICU_DMAC_DACK_SEL_MASK << ICU_DMAC_DACK_SHIFT(n)) 158 #define ICU_DMAC_PREP_DACK(val, n) (((val) & ICU_DMAC_DACK_SEL_MASK) << ICU_DMAC_DACK_SHIFT(n)) 159 160 /** 161 * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure. 162 * @base: Controller's base address 163 * @fwspec: IRQ firmware specific data 164 * @lock: Lock to serialize access to hardware registers 165 * @info: Pointer to struct rzv2h_hw_info 166 * @cache: Registers cache for suspend/resume 167 */ 168 static struct rzv2h_icu_priv { 169 void __iomem *base; 170 struct irq_fwspec fwspec[ICU_NUM_IRQ]; 171 raw_spinlock_t lock; 172 const struct rzv2h_hw_info *info; 173 struct rzv2h_irqc_reg_cache cache; 174 } *rzv2h_icu_data; 175 176 void rzv2h_icu_register_dma_req(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel, 177 u16 req_no) 178 { 179 struct rzv2h_icu_priv *priv = platform_get_drvdata(icu_dev); 180 u32 icu_dmksely, dmareq, dmareq_mask; 181 u8 y, upper; 182 183 y = dmac_channel / 2; 184 upper = dmac_channel % 2; 185 186 dmareq = ICU_DMAC_PREP_DMAREQ(req_no, upper); 187 dmareq_mask = ICU_DMAC_DMAREQ_MASK(upper); 188 189 guard(raw_spinlock_irqsave)(&priv->lock); 190 191 icu_dmksely = readl(priv->base + ICU_DMkSELy(dmac_index, y)); 192 icu_dmksely = (icu_dmksely & ~dmareq_mask) | dmareq; 193 writel(icu_dmksely, priv->base + ICU_DMkSELy(dmac_index, y)); 194 } 195 EXPORT_SYMBOL_GPL(rzv2h_icu_register_dma_req); 196 197 /** 198 * rzv2h_icu_register_dma_ack - Configure DMA ACK signal routing 199 * @icu_dev: ICU platform device 200 * @dmac_index: DMAC instance index (0-4) 201 * @dmac_channel: DMAC channel number (0-15), or RZV2H_ICU_DMAC_ACK_NO_DEFAULT 202 * to disconnect routing for a given ack_no 203 * @ack_no: Peripheral ACK number (0-88) per RZ/G3E manual Table 4.6-28, 204 * used as index into ICU_DMACKSELk 205 * 206 * Routes the ACK signal of the peripheral identified by @ack_no to DMAC 207 * channel @dmac_channel of instance @dmac_index. When @dmac_channel is 208 * RZV2H_ICU_DMAC_ACK_NO_DEFAULT the field is reset, disconnecting any 209 * previously configured routing for that peripheral. 210 */ 211 void rzv2h_icu_register_dma_ack(struct platform_device *icu_dev, u8 dmac_index, 212 u8 dmac_channel, u16 ack_no) 213 { 214 struct rzv2h_icu_priv *priv = platform_get_drvdata(icu_dev); 215 u8 reg_idx = ack_no / 4; 216 u8 field_idx = ack_no & 0x3; 217 u8 dmac_ack_src = (dmac_channel == RZV2H_ICU_DMAC_ACK_NO_DEFAULT) ? 218 RZV2H_ICU_DMAC_ACK_NO_DEFAULT : 219 (dmac_index * 16 + dmac_channel); 220 u32 val; 221 222 guard(raw_spinlock_irqsave)(&priv->lock); 223 224 val = readl(priv->base + ICU_DMACKSELk(reg_idx)); 225 val &= ~ICU_DMAC_DACK_FIELD_MASK(field_idx); 226 val |= ICU_DMAC_PREP_DACK(dmac_ack_src, field_idx); 227 writel(val, priv->base + ICU_DMACKSELk(reg_idx)); 228 } 229 EXPORT_SYMBOL_GPL(rzv2h_icu_register_dma_ack); 230 231 static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data) 232 { 233 return data->domain->host_data; 234 } 235 236 static void rzv2h_icu_tint_eoi(struct irq_data *d) 237 { 238 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 239 unsigned int hw_irq = irqd_to_hwirq(d); 240 unsigned int tintirq_nr; 241 u32 bit; 242 243 if (!irqd_is_level_type(d)) { 244 tintirq_nr = hw_irq - ICU_TINT_START; 245 bit = BIT(tintirq_nr); 246 writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); 247 } 248 249 irq_chip_eoi_parent(d); 250 } 251 252 static void rzv2h_icu_irq_eoi(struct irq_data *d) 253 { 254 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 255 unsigned int hw_irq = irqd_to_hwirq(d); 256 unsigned int tintirq_nr; 257 u32 bit; 258 259 if (!irqd_is_level_type(d)) { 260 tintirq_nr = hw_irq - ICU_IRQ_START; 261 bit = BIT(tintirq_nr); 262 writel_relaxed(bit, priv->base + ICU_ISCLR); 263 } 264 265 irq_chip_eoi_parent(d); 266 } 267 268 static void rzv2h_icu_nmi_eoi(struct irq_data *d) 269 { 270 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 271 272 writel_relaxed(ICU_NSCLR_NCLR, priv->base + ICU_NSCLR); 273 274 irq_chip_eoi_parent(d); 275 } 276 277 static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable) 278 { 279 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 280 unsigned int hw_irq = irqd_to_hwirq(d); 281 u32 tint_nr, tssel_n, k, tssr; 282 u8 nr_tint; 283 284 tint_nr = hw_irq - ICU_TINT_START; 285 nr_tint = 32 / priv->info->field_width; 286 k = tint_nr / nr_tint; 287 tssel_n = tint_nr % nr_tint; 288 289 guard(raw_spinlock)(&priv->lock); 290 tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k)); 291 if (enable) 292 tssr |= ICU_TSSR_TIEN(tssel_n, priv->info->field_width); 293 else 294 tssr &= ~ICU_TSSR_TIEN(tssel_n, priv->info->field_width); 295 writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k)); 296 297 /* 298 * A glitch in the edge detection circuit can cause a spurious 299 * interrupt. Clear the status flag after setting the ICU_TSSRk 300 * registers, which is recommended by the hardware manual as a 301 * countermeasure. 302 */ 303 writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR); 304 } 305 306 static void rzv2h_icu_tint_disable(struct irq_data *d) 307 { 308 irq_chip_disable_parent(d); 309 rzv2h_tint_irq_endisable(d, false); 310 } 311 312 static void rzv2h_icu_tint_enable(struct irq_data *d) 313 { 314 rzv2h_tint_irq_endisable(d, true); 315 irq_chip_enable_parent(d); 316 } 317 318 static int rzv2h_nmi_set_type(struct irq_data *d, unsigned int type) 319 { 320 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 321 u32 sense; 322 323 switch (type & IRQ_TYPE_SENSE_MASK) { 324 case IRQ_TYPE_EDGE_FALLING: 325 sense = ICU_NMI_EDGE_FALLING; 326 break; 327 328 case IRQ_TYPE_EDGE_RISING: 329 sense = ICU_NMI_EDGE_RISING; 330 break; 331 332 default: 333 return -EINVAL; 334 } 335 336 writel_relaxed(sense, priv->base + ICU_NITSR); 337 338 return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); 339 } 340 341 static void rzv2h_clear_irq_int(struct rzv2h_icu_priv *priv, unsigned int hwirq) 342 { 343 unsigned int irq_nr = hwirq - ICU_IRQ_START; 344 u32 isctr, iitsr, iitsel; 345 u32 bit = BIT(irq_nr); 346 347 isctr = readl_relaxed(priv->base + ICU_ISCTR); 348 iitsr = readl_relaxed(priv->base + ICU_IITSR); 349 iitsel = ICU_IITSR_IITSEL_GET(iitsr, irq_nr); 350 351 /* 352 * When level sensing is used, the interrupt flag gets automatically cleared when the 353 * interrupt signal is de-asserted by the source of the interrupt request, therefore clear 354 * the interrupt only for edge triggered interrupts. 355 */ 356 if ((isctr & bit) && (iitsel != ICU_IRQ_LEVEL_LOW)) 357 writel_relaxed(bit, priv->base + ICU_ISCLR); 358 } 359 360 static int rzv2h_irq_set_type(struct irq_data *d, unsigned int type) 361 { 362 struct rzv2h_icu_priv *priv = irq_data_to_priv(d); 363 unsigned int hwirq = irqd_to_hwirq(d); 364 u32 irq_nr = hwirq - ICU_IRQ_START; 365 u32 iitsr, sense; 366 367 switch (type & IRQ_TYPE_SENSE_MASK) { 368 case IRQ_TYPE_LEVEL_LOW: 369 sense = ICU_IRQ_LEVEL_LOW; 370 break; 371 372 case IRQ_TYPE_EDGE_FALLING: 373 sense = ICU_IRQ_EDGE_FALLING; 374 break; 375 376 case IRQ_TYPE_EDGE_RISING: 377 sense = ICU_IRQ_EDGE_RISING; 378 break; 379 380 case IRQ_TYPE_EDGE_BOTH: 381 sense = ICU_IRQ_EDGE_BOTH; 382 break; 383 384 default: 385 return -EINVAL; 386 } 387 388 scoped_guard(raw_spinlock, &priv->lock) { 389 iitsr = readl_relaxed(priv->base + ICU_IITSR); 390 iitsr &= ~ICU_IITSR_IITSEL_MASK(irq_nr); 391 iitsr |= ICU_IITSR_IITSEL_PREP(sense, irq_nr); 392 rzv2h_clear_irq_int(priv, hwirq); 393 writel_relaxed(iitsr, priv->base + ICU_IITSR); 394 } 395 396 return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); 397 } 398 399 static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq) 400 { 401 unsigned int tint_nr = hwirq - ICU_TINT_START; 402 int titsel_n = ICU_TITSR_TITSEL_N(tint_nr); 403 u32 tsctr, titsr, titsel; 404 u32 bit = BIT(tint_nr); 405 int k = tint_nr / 16; 406 407 tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR); 408 titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k)); 409 titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n); 410 411 /* 412 * Writing 1 to the corresponding flag from register ICU_TSCTR only has effect if 413 * TSTATn = 1b and if it's a rising edge or a falling edge interrupt. 414 */ 415 if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) || 416 (titsel == ICU_TINT_EDGE_FALLING))) 417 writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); 418 } 419 420 static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type) 421 { 422 u32 titsr, titsr_k, titsel_n, tien; 423 struct rzv2h_icu_priv *priv; 424 u32 tssr, tssr_k, tssel_n; 425 u32 titsr_cur, tssr_cur; 426 unsigned int hwirq; 427 u32 tint, sense; 428 int tint_nr; 429 u8 nr_tint; 430 431 switch (type & IRQ_TYPE_SENSE_MASK) { 432 case IRQ_TYPE_LEVEL_LOW: 433 sense = ICU_TINT_LEVEL_LOW; 434 break; 435 436 case IRQ_TYPE_LEVEL_HIGH: 437 sense = ICU_TINT_LEVEL_HIGH; 438 break; 439 440 case IRQ_TYPE_EDGE_RISING: 441 sense = ICU_TINT_EDGE_RISING; 442 break; 443 444 case IRQ_TYPE_EDGE_FALLING: 445 sense = ICU_TINT_EDGE_FALLING; 446 break; 447 448 default: 449 return -EINVAL; 450 } 451 452 priv = irq_data_to_priv(d); 453 tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d); 454 if (tint > priv->info->max_tssel) 455 return -EINVAL; 456 457 if (priv->info->tssel_lut) 458 tint = priv->info->tssel_lut[tint]; 459 460 hwirq = irqd_to_hwirq(d); 461 tint_nr = hwirq - ICU_TINT_START; 462 463 nr_tint = 32 / priv->info->field_width; 464 tssr_k = tint_nr / nr_tint; 465 tssel_n = tint_nr % nr_tint; 466 tien = ICU_TSSR_TIEN(tssel_n, priv->info->field_width); 467 468 titsr_k = ICU_TITSR_K(tint_nr); 469 titsel_n = ICU_TITSR_TITSEL_N(tint_nr); 470 471 scoped_guard(raw_spinlock, &priv->lock) { 472 tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); 473 titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); 474 475 tssr_cur = field_get(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width), tssr); 476 titsr_cur = field_get(ICU_TITSR_TITSEL_MASK(titsel_n), titsr); 477 if (tssr_cur == tint && titsr_cur == sense) 478 goto set_parent_type; 479 480 tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien); 481 tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width); 482 483 writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); 484 485 titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n); 486 titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n); 487 488 writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); 489 490 rzv2h_clear_tint_int(priv, hwirq); 491 492 writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); 493 } 494 set_parent_type: 495 return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); 496 } 497 498 static int rzv2h_icu_swint_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, 499 bool state) 500 { 501 unsigned int hwirq = irqd_to_hwirq(d); 502 struct rzv2h_icu_priv *priv; 503 unsigned int bit; 504 505 if (which != IRQCHIP_STATE_PENDING) 506 return irq_chip_set_parent_state(d, which, state); 507 508 if (!state) 509 return 0; 510 511 priv = irq_data_to_priv(d); 512 bit = BIT(hwirq - ICU_CA55_INT_START); 513 514 /* Trigger the software interrupt */ 515 writel_relaxed(bit, priv->base + ICU_SWINT); 516 517 return 0; 518 } 519 520 static int rzv2h_icu_swpe_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, 521 bool state) 522 { 523 struct rzv2h_icu_priv *priv; 524 unsigned int bit; 525 static u8 swpe; 526 527 if (which != IRQCHIP_STATE_PENDING) 528 return irq_chip_set_parent_state(d, which, state); 529 530 if (!state) 531 return 0; 532 533 priv = irq_data_to_priv(d); 534 535 bit = BIT(swpe); 536 /* 537 * SWPE has 16 bits; the bit position is rotated on each trigger 538 * and wraps around once all bits have been used. 539 */ 540 if (++swpe >= ICU_SWPE_NUM) 541 swpe = 0; 542 543 /* Trigger the pseudo error interrupt */ 544 writel_relaxed(bit, priv->base + ICU_SWPE); 545 546 return 0; 547 } 548 549 static int rzv2h_irqc_irq_suspend(void *data) 550 { 551 struct rzv2h_irqc_reg_cache *cache = &rzv2h_icu_data->cache; 552 void __iomem *base = rzv2h_icu_data->base; 553 554 cache->nitsr = readl_relaxed(base + ICU_NITSR); 555 cache->iitsr = readl_relaxed(base + ICU_IITSR); 556 for (unsigned int i = 0; i < 2; i++) 557 cache->titsr[i] = readl_relaxed(base + rzv2h_icu_data->info->t_offs + ICU_TITSR(i)); 558 559 return 0; 560 } 561 562 static void rzv2h_irqc_irq_resume(void *data) 563 { 564 struct rzv2h_irqc_reg_cache *cache = &rzv2h_icu_data->cache; 565 void __iomem *base = rzv2h_icu_data->base; 566 567 /* 568 * Restore only interrupt type. TSSRx will be restored at the 569 * request of pin controller to avoid spurious interrupts due 570 * to invalid PIN states. 571 */ 572 for (unsigned int i = 0; i < 2; i++) 573 writel_relaxed(cache->titsr[i], base + rzv2h_icu_data->info->t_offs + ICU_TITSR(i)); 574 writel_relaxed(cache->iitsr, base + ICU_IITSR); 575 writel_relaxed(cache->nitsr, base + ICU_NITSR); 576 } 577 578 static const struct syscore_ops rzv2h_irqc_syscore_ops = { 579 .suspend = rzv2h_irqc_irq_suspend, 580 .resume = rzv2h_irqc_irq_resume, 581 }; 582 583 static struct syscore rzv2h_irqc_syscore = { 584 .ops = &rzv2h_irqc_syscore_ops, 585 }; 586 587 static const struct irq_chip rzv2h_icu_tint_chip = { 588 .name = "rzv2h-icu", 589 .irq_eoi = rzv2h_icu_tint_eoi, 590 .irq_mask = irq_chip_mask_parent, 591 .irq_unmask = irq_chip_unmask_parent, 592 .irq_disable = rzv2h_icu_tint_disable, 593 .irq_enable = rzv2h_icu_tint_enable, 594 .irq_get_irqchip_state = irq_chip_get_parent_state, 595 .irq_set_irqchip_state = irq_chip_set_parent_state, 596 .irq_retrigger = irq_chip_retrigger_hierarchy, 597 .irq_set_type = rzv2h_tint_set_type, 598 .irq_set_affinity = irq_chip_set_affinity_parent, 599 .flags = IRQCHIP_MASK_ON_SUSPEND | 600 IRQCHIP_SET_TYPE_MASKED | 601 IRQCHIP_SKIP_SET_WAKE, 602 }; 603 604 static const struct irq_chip rzv2h_icu_irq_chip = { 605 .name = "rzv2h-icu", 606 .irq_eoi = rzv2h_icu_irq_eoi, 607 .irq_mask = irq_chip_mask_parent, 608 .irq_unmask = irq_chip_unmask_parent, 609 .irq_disable = irq_chip_disable_parent, 610 .irq_enable = irq_chip_enable_parent, 611 .irq_get_irqchip_state = irq_chip_get_parent_state, 612 .irq_set_irqchip_state = irq_chip_set_parent_state, 613 .irq_retrigger = irq_chip_retrigger_hierarchy, 614 .irq_set_type = rzv2h_irq_set_type, 615 .irq_set_affinity = irq_chip_set_affinity_parent, 616 .flags = IRQCHIP_MASK_ON_SUSPEND | 617 IRQCHIP_SET_TYPE_MASKED | 618 IRQCHIP_SKIP_SET_WAKE, 619 }; 620 621 static const struct irq_chip rzv2h_icu_nmi_chip = { 622 .name = "rzv2h-icu", 623 .irq_eoi = rzv2h_icu_nmi_eoi, 624 .irq_mask = irq_chip_mask_parent, 625 .irq_unmask = irq_chip_unmask_parent, 626 .irq_disable = irq_chip_disable_parent, 627 .irq_enable = irq_chip_enable_parent, 628 .irq_get_irqchip_state = irq_chip_get_parent_state, 629 .irq_set_irqchip_state = irq_chip_set_parent_state, 630 .irq_retrigger = irq_chip_retrigger_hierarchy, 631 .irq_set_type = rzv2h_nmi_set_type, 632 .irq_set_affinity = irq_chip_set_affinity_parent, 633 .flags = IRQCHIP_MASK_ON_SUSPEND | 634 IRQCHIP_SET_TYPE_MASKED | 635 IRQCHIP_SKIP_SET_WAKE, 636 }; 637 638 static const struct irq_chip rzv2h_icu_swint_chip = { 639 .name = "rzv2h-icu", 640 .irq_eoi = irq_chip_eoi_parent, 641 .irq_mask = irq_chip_mask_parent, 642 .irq_unmask = irq_chip_unmask_parent, 643 .irq_disable = irq_chip_disable_parent, 644 .irq_enable = irq_chip_enable_parent, 645 .irq_get_irqchip_state = irq_chip_get_parent_state, 646 .irq_set_irqchip_state = rzv2h_icu_swint_set_irqchip_state, 647 .irq_retrigger = irq_chip_retrigger_hierarchy, 648 .irq_set_type = irq_chip_set_type_parent, 649 .irq_set_affinity = irq_chip_set_affinity_parent, 650 .flags = IRQCHIP_MASK_ON_SUSPEND | 651 IRQCHIP_SET_TYPE_MASKED | 652 IRQCHIP_SKIP_SET_WAKE, 653 }; 654 655 static const struct irq_chip rzv2h_icu_swpe_err_chip = { 656 .name = "rzv2h-icu", 657 .irq_eoi = irq_chip_eoi_parent, 658 .irq_mask = irq_chip_mask_parent, 659 .irq_unmask = irq_chip_unmask_parent, 660 .irq_disable = irq_chip_disable_parent, 661 .irq_enable = irq_chip_enable_parent, 662 .irq_get_irqchip_state = irq_chip_get_parent_state, 663 .irq_set_irqchip_state = rzv2h_icu_swpe_set_irqchip_state, 664 .irq_retrigger = irq_chip_retrigger_hierarchy, 665 .irq_set_type = irq_chip_set_type_parent, 666 .irq_set_affinity = irq_chip_set_affinity_parent, 667 .flags = IRQCHIP_MASK_ON_SUSPEND | 668 IRQCHIP_SET_TYPE_MASKED | 669 IRQCHIP_SKIP_SET_WAKE, 670 }; 671 672 #define hwirq_within(hwirq, which) ((hwirq) >= which##_START && (hwirq) <= which##_LAST) 673 674 static int rzv2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, 675 void *arg) 676 { 677 struct rzv2h_icu_priv *priv = domain->host_data; 678 const struct irq_chip *chip; 679 unsigned long tint = 0; 680 irq_hw_number_t hwirq; 681 unsigned int type; 682 int ret; 683 684 ret = irq_domain_translate_twocell(domain, arg, &hwirq, &type); 685 if (ret) 686 return ret; 687 688 /* 689 * For TINT interrupts the hwirq and TINT are encoded in 690 * fwspec->param[0]. 691 * hwirq is embedded in bits 0-15. 692 * TINT is embedded in bits 16-31. 693 */ 694 tint = ICU_TINT_EXTRACT_GPIOINT(hwirq); 695 if (tint || hwirq_within(hwirq, ICU_TINT)) { 696 hwirq = ICU_TINT_EXTRACT_HWIRQ(hwirq); 697 698 if (!hwirq_within(hwirq, ICU_TINT)) 699 return -EINVAL; 700 chip = &rzv2h_icu_tint_chip; 701 } else if (hwirq_within(hwirq, ICU_IRQ)) { 702 chip = &rzv2h_icu_irq_chip; 703 } else if (hwirq_within(hwirq, ICU_CA55_INT)) { 704 chip = &rzv2h_icu_swint_chip; 705 } else if (hwirq_within(hwirq, ICU_ERR_INT)) { 706 chip = &rzv2h_icu_swpe_err_chip; 707 } else { 708 chip = &rzv2h_icu_nmi_chip; 709 } 710 711 if (hwirq > (ICU_NUM_IRQ - 1)) 712 return -EINVAL; 713 714 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, (void *)(uintptr_t)tint); 715 if (ret) 716 return ret; 717 718 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &priv->fwspec[hwirq]); 719 } 720 721 static const struct irq_domain_ops rzv2h_icu_domain_ops = { 722 .alloc = rzv2h_icu_alloc, 723 .free = irq_domain_free_irqs_common, 724 .translate = irq_domain_translate_twocell, 725 }; 726 727 static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device_node *np) 728 { 729 struct of_phandle_args map; 730 unsigned int i; 731 int ret; 732 733 for (i = 0; i < ICU_NUM_IRQ; i++) { 734 ret = of_irq_parse_one(np, i, &map); 735 if (ret) 736 return ret; 737 738 of_phandle_args_to_fwspec(np, map.args, map.args_count, &priv->fwspec[i]); 739 } 740 741 return 0; 742 } 743 744 static irqreturn_t rzv2h_icu_error_irq(int irq, void *data) 745 { 746 struct rzv2h_icu_priv *priv = data; 747 const struct rzv2h_hw_info *hw_info = priv->info; 748 void __iomem *base = priv->base; 749 unsigned int k; 750 u32 st; 751 752 /* 1) Bus errors (BEISR0..3) */ 753 for (k = 0; k < ICU_NUM_BE; k++) { 754 st = readl(base + ICU_BEISR(k)); 755 if (!st) 756 continue; 757 758 writel_relaxed(st, base + ICU_BECLR(k)); 759 pr_warn("rzv2h-icu: BUS error k=%u status=0x%08x\n", k, st); 760 } 761 762 /* 2) ECC RAM errors (EREISR0..X) */ 763 for (k = hw_info->ecc_start; k <= hw_info->ecc_end; k++) { 764 st = readl(base + ICU_EREISR(k)); 765 if (!st) 766 continue; 767 768 writel_relaxed(st, base + ICU_ERCLR(k)); 769 pr_warn("rzv2h-icu: ECC error k=%u status=0x%08x\n", k, st); 770 } 771 772 /* 3) IP/CA55 error interrupt status (ERINTA55CTL0..3) */ 773 for (k = 0; k < ICU_NUM_A55ERR; k++) { 774 st = readl(base + ICU_ERINTA55CTL(k)); 775 if (!st) 776 continue; 777 778 /* there is no relation with status bits so clear all the interrupts */ 779 writel_relaxed(0xffffffff, base + ICU_ERINTA55CRL(k)); 780 pr_warn("rzv2h-icu: IP/CA55 error k=%u status=0x%08x\n", k, st); 781 } 782 783 return IRQ_HANDLED; 784 } 785 786 static irqreturn_t rzv2h_icu_swint_irq(int irq, void *data) 787 { 788 unsigned int cpu = (uintptr_t)data; 789 790 pr_info("SWINT interrupt for CA55 core %u\n", cpu); 791 return IRQ_HANDLED; 792 } 793 794 static int rzv2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain *irq_domain) 795 { 796 const struct rzv2h_hw_info *hw_info = rzv2h_icu_data->info; 797 bool irq_inject = IS_ENABLED(CONFIG_GENERIC_IRQ_INJECTION); 798 void __iomem *base = rzv2h_icu_data->base; 799 struct device *dev = &pdev->dev; 800 struct irq_fwspec fwspec; 801 unsigned int i, virq; 802 int ret; 803 804 for (i = 0; i < ICU_CA55_INT_COUNT && irq_inject; i++) { 805 fwspec.fwnode = irq_domain->fwnode; 806 fwspec.param_count = 2; 807 fwspec.param[0] = ICU_CA55_INT_START + i; 808 fwspec.param[1] = IRQ_TYPE_EDGE_RISING; 809 810 virq = irq_create_fwspec_mapping(&fwspec); 811 if (!virq) { 812 return dev_err_probe(dev, -EINVAL, 813 "failed to create int-ca55-%u IRQ mapping\n", i); 814 } 815 816 ret = devm_request_irq(dev, virq, rzv2h_icu_swint_irq, 0, dev_name(dev), 817 (void *)(uintptr_t)i); 818 if (ret) 819 return dev_err_probe(dev, ret, "Failed to request int-ca55-%u IRQ\n", i); 820 } 821 822 /* Unmask and clear all IP/CA55 error interrupts */ 823 for (i = 0; i < ICU_NUM_A55ERR; i++) { 824 writel_relaxed(0xffffff, base + ICU_ERINTA55CRL(i)); 825 writel_relaxed(0x0, base + ICU_ERINTA55MSK(i)); 826 } 827 828 /* Clear all Bus errors */ 829 for (i = 0; i < ICU_NUM_BE; i++) 830 writel_relaxed(0xffffffff, base + ICU_BECLR(i)); 831 832 /* Clear all ECCRAM errors */ 833 for (i = hw_info->ecc_start; i <= hw_info->ecc_end; i++) 834 writel_relaxed(0xffffffff, base + ICU_ERCLR(i)); 835 836 fwspec.fwnode = irq_domain->fwnode; 837 fwspec.param_count = 2; 838 fwspec.param[0] = ICU_ERR_INT_START; 839 fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; 840 841 virq = irq_create_fwspec_mapping(&fwspec); 842 if (!virq) 843 return dev_err_probe(dev, -EINVAL, "failed to create icu-error-ca55 IRQ mapping\n"); 844 845 ret = devm_request_irq(dev, virq, rzv2h_icu_error_irq, 0, dev_name(dev), rzv2h_icu_data); 846 if (ret) 847 return dev_err_probe(dev, ret, "Failed to request icu-error-ca55 IRQ\n"); 848 849 return 0; 850 } 851 852 static int rzv2h_icu_probe_common(struct platform_device *pdev, struct device_node *parent, 853 const struct rzv2h_hw_info *hw_info) 854 { 855 struct irq_domain *irq_domain, *parent_domain; 856 struct device_node *node = pdev->dev.of_node; 857 struct device *dev = &pdev->dev; 858 struct reset_control *resetn; 859 int ret; 860 861 parent_domain = irq_find_host(parent); 862 if (!parent_domain) 863 return dev_err_probe(dev, -ENODEV, "cannot find parent domain\n"); 864 865 rzv2h_icu_data = devm_kzalloc(dev, sizeof(*rzv2h_icu_data), GFP_KERNEL); 866 if (!rzv2h_icu_data) 867 return -ENOMEM; 868 869 platform_set_drvdata(pdev, rzv2h_icu_data); 870 871 rzv2h_icu_data->base = devm_of_iomap(dev, node, 0, NULL); 872 if (IS_ERR(rzv2h_icu_data->base)) 873 return PTR_ERR(rzv2h_icu_data->base); 874 875 ret = rzv2h_icu_parse_interrupts(rzv2h_icu_data, node); 876 if (ret) 877 return dev_err_probe(dev, ret, "cannot parse interrupts\n"); 878 879 resetn = devm_reset_control_get_exclusive_deasserted(dev, NULL); 880 if (IS_ERR(resetn)) 881 return dev_err_probe(dev, PTR_ERR(resetn), "failed to acquire deasserted reset\n"); 882 883 ret = devm_pm_runtime_enable(dev); 884 if (ret < 0) 885 return dev_err_probe(dev, ret, "devm_pm_runtime_enable failed\n"); 886 887 ret = pm_runtime_resume_and_get(dev); 888 if (ret < 0) 889 return dev_err_probe(dev, ret, "pm_runtime_resume_and_get failed\n"); 890 891 raw_spin_lock_init(&rzv2h_icu_data->lock); 892 893 irq_domain = irq_domain_create_hierarchy(parent_domain, 0, ICU_NUM_IRQ, 894 dev_fwnode(dev), &rzv2h_icu_domain_ops, 895 rzv2h_icu_data); 896 if (!irq_domain) { 897 dev_err(dev, "failed to add irq domain\n"); 898 ret = -ENOMEM; 899 goto pm_put; 900 } 901 902 rzv2h_icu_data->info = hw_info; 903 904 register_syscore(&rzv2h_irqc_syscore); 905 906 ret = rzv2h_icu_setup_irqs(pdev, irq_domain); 907 if (ret) 908 goto pm_put; 909 910 /* 911 * coccicheck complains about a missing put_device call before returning, but it's a false 912 * positive. We still need dev after successfully returning from this function. 913 */ 914 return 0; 915 916 pm_put: 917 pm_runtime_put_sync(dev); 918 return ret; 919 } 920 921 /* Mapping based on port index on Table 4.2-6 and TSSEL bits on Table 4.6-4 */ 922 static const u8 rzg3e_tssel_lut[] = { 923 81, 82, 83, 84, 85, 86, 87, 88, /* P00-P07 */ 924 89, 90, 91, 92, 93, 94, 95, 96, /* P10-P17 */ 925 111, 112, /* P20-P21 */ 926 97, 98, 99, 100, 101, 102, 103, 104, /* P30-P37 */ 927 105, 106, 107, 108, 109, 110, /* P40-P45 */ 928 113, 114, 115, 116, 117, 118, 119, /* P50-P56 */ 929 120, 121, 122, 123, 124, 125, 126, /* P60-P66 */ 930 127, 128, 129, 130, 131, 132, 133, 134, /* P70-P77 */ 931 135, 136, 137, 138, 139, 140, /* P80-P85 */ 932 43, 44, 45, 46, 47, 48, 49, 50, /* PA0-PA7 */ 933 51, 52, 53, 54, 55, 56, 57, 58, /* PB0-PB7 */ 934 59, 60, 61, /* PC0-PC2 */ 935 62, 63, 64, 65, 66, 67, 68, 69, /* PD0-PD7 */ 936 70, 71, 72, 73, 74, 75, 76, 77, /* PE0-PE7 */ 937 78, 79, 80, /* PF0-PF2 */ 938 25, 26, 27, 28, 29, 30, 31, 32, /* PG0-PG7 */ 939 33, 34, 35, 36, 37, 38, /* PH0-PH5 */ 940 4, 5, 6, 7, 8, /* PJ0-PJ4 */ 941 39, 40, 41, 42, /* PK0-PK3 */ 942 9, 10, 11, 12, 21, 22, 23, 24, /* PL0-PL7 */ 943 13, 14, 15, 16, 17, 18, 19, 20, /* PM0-PM7 */ 944 0, 1, 2, 3 /* PS0-PS3 */ 945 }; 946 947 static const struct rzv2h_hw_info rzg3e_hw_params = { 948 .tssel_lut = rzg3e_tssel_lut, 949 .t_offs = ICU_RZG3E_TINT_OFFSET, 950 .max_tssel = ICU_RZG3E_TSSEL_MAX_VAL, 951 .field_width = 16, 952 .ecc_start = 1, 953 .ecc_end = 4, 954 }; 955 956 static const struct rzv2h_hw_info rzv2n_hw_params = { 957 .t_offs = 0, 958 .max_tssel = ICU_RZV2H_TSSEL_MAX_VAL, 959 .field_width = 8, 960 .ecc_start = 0, 961 .ecc_end = 2, 962 }; 963 964 static const struct rzv2h_hw_info rzv2h_hw_params = { 965 .t_offs = 0, 966 .max_tssel = ICU_RZV2H_TSSEL_MAX_VAL, 967 .field_width = 8, 968 .ecc_start = 0, 969 .ecc_end = 11, 970 }; 971 972 static int rzg3e_icu_probe(struct platform_device *pdev, struct device_node *parent) 973 { 974 return rzv2h_icu_probe_common(pdev, parent, &rzg3e_hw_params); 975 } 976 977 static int rzv2n_icu_probe(struct platform_device *pdev, struct device_node *parent) 978 { 979 return rzv2h_icu_probe_common(pdev, parent, &rzv2n_hw_params); 980 } 981 982 static int rzv2h_icu_probe(struct platform_device *pdev, struct device_node *parent) 983 { 984 return rzv2h_icu_probe_common(pdev, parent, &rzv2h_hw_params); 985 } 986 987 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu) 988 IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_probe) 989 IRQCHIP_MATCH("renesas,r9a09g056-icu", rzv2n_icu_probe) 990 IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_probe) 991 IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu) 992 MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>"); 993 MODULE_DESCRIPTION("Renesas RZ/V2H(P) ICU Driver"); 994