irqchip/ls-scfg-msi: Add LS1043a v1.1 MSI support

A MSI controller of LS1043a v1.0 only includes one MSIR and
is assigned one GIC interrupt. In order to support affinity,
LS1043a v1.1 MSI is assigned 4 MSIRs and 4 GIC interrupts.
But the MSIR has the different offset and only supports 8 MSIs.
The bits between variable bit_start and bit_end in structure
ls_scfg_msir are used to show 8 MSI interrupts. msir_irqs and
msir_base are added to describe the difference of MSI between
LS1043a v1.1 and other SoCs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

authored by

Minghuan Lian and committed by
Marc Zyngier
fd100dab 4dd5da65

+40 -6
+1
Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
··· 7 "fsl,ls1021a-msi" 8 "fsl,ls1043a-msi" 9 "fsl,ls1046a-msi" 10 - msi-controller: indicates that this is a PCIe MSI controller node 11 - reg: physical base address of the controller and length of memory mapped. 12 - interrupts: an interrupt to the parent interrupt controller.
··· 7 "fsl,ls1021a-msi" 8 "fsl,ls1043a-msi" 9 "fsl,ls1046a-msi" 10 + "fsl,ls1043a-v1.1-msi" 11 - msi-controller: indicates that this is a PCIe MSI controller node 12 - reg: physical base address of the controller and length of memory mapped. 13 - interrupts: an interrupt to the parent interrupt controller.
+39 -6
drivers/irqchip/irq-ls-scfg-msi.c
··· 25 #define MSI_IRQS_PER_MSIR 32 26 #define MSI_MSIR_OFFSET 4 27 28 struct ls_scfg_msi_cfg { 29 u32 ibs_shift; /* Shift of interrupt bit select */ 30 }; 31 32 struct ls_scfg_msir { 33 struct ls_scfg_msi *msi_data; 34 unsigned int index; 35 unsigned int gic_irq; 36 void __iomem *reg; 37 }; 38 ··· 147 struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); 148 struct ls_scfg_msi *msi_data = msir->msi_data; 149 unsigned long val; 150 - int pos, virq, hwirq; 151 152 chained_irq_enter(irq_desc_get_chip(desc), desc); 153 154 val = ioread32be(msir->reg); 155 - for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) { 156 - hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index; 157 virq = irq_find_mapping(msi_data->parent, hwirq); 158 if (virq) 159 generic_handle_irq(virq); ··· 205 msir->index = index; 206 msir->msi_data = msi_data; 207 msir->gic_irq = virq; 208 - msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index; 209 210 irq_set_chained_handler_and_data(msir->gic_irq, 211 ls_scfg_msi_irq_handler, 212 msir); 213 214 /* Release the hwirqs corresponding to this MSIR */ 215 - for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { 216 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 217 bitmap_clear(msi_data->used, hwirq, 1); 218 } ··· 238 if (msir->gic_irq > 0) 239 irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL); 240 241 - for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { 242 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 243 bitmap_set(msi_data->used, hwirq, 1); 244 } ··· 248 249 static struct ls_scfg_msi_cfg ls1021_msi_cfg = { 250 .ibs_shift = 3, 251 }; 252 253 static struct ls_scfg_msi_cfg ls1046_msi_cfg = { 254 .ibs_shift = 2, 255 }; 256 257 static const struct of_device_id ls_scfg_msi_id[] = { ··· 271 272 { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, 273 { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, 274 { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg }, 275 {}, 276 };
··· 25 #define MSI_IRQS_PER_MSIR 32 26 #define MSI_MSIR_OFFSET 4 27 28 + #define MSI_LS1043V1_1_IRQS_PER_MSIR 8 29 + #define MSI_LS1043V1_1_MSIR_OFFSET 0x10 30 + 31 struct ls_scfg_msi_cfg { 32 u32 ibs_shift; /* Shift of interrupt bit select */ 33 + u32 msir_irqs; /* The irq number per MSIR */ 34 + u32 msir_base; /* The base address of MSIR */ 35 }; 36 37 struct ls_scfg_msir { 38 struct ls_scfg_msi *msi_data; 39 unsigned int index; 40 unsigned int gic_irq; 41 + unsigned int bit_start; 42 + unsigned int bit_end; 43 void __iomem *reg; 44 }; 45 ··· 140 struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); 141 struct ls_scfg_msi *msi_data = msir->msi_data; 142 unsigned long val; 143 + int pos, size, virq, hwirq; 144 145 chained_irq_enter(irq_desc_get_chip(desc), desc); 146 147 val = ioread32be(msir->reg); 148 + 149 + pos = msir->bit_start; 150 + size = msir->bit_end + 1; 151 + 152 + for_each_set_bit_from(pos, &val, size) { 153 + hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) | 154 + msir->index; 155 virq = irq_find_mapping(msi_data->parent, hwirq); 156 if (virq) 157 generic_handle_irq(virq); ··· 193 msir->index = index; 194 msir->msi_data = msi_data; 195 msir->gic_irq = virq; 196 + msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index; 197 + 198 + if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) { 199 + msir->bit_start = 32 - ((msir->index + 1) * 200 + MSI_LS1043V1_1_IRQS_PER_MSIR); 201 + msir->bit_end = msir->bit_start + 202 + MSI_LS1043V1_1_IRQS_PER_MSIR - 1; 203 + } else { 204 + msir->bit_start = 0; 205 + msir->bit_end = msi_data->cfg->msir_irqs - 1; 206 + } 207 208 irq_set_chained_handler_and_data(msir->gic_irq, 209 ls_scfg_msi_irq_handler, 210 msir); 211 212 /* Release the hwirqs corresponding to this MSIR */ 213 + for (i = 0; i < msi_data->cfg->msir_irqs; i++) { 214 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 215 bitmap_clear(msi_data->used, hwirq, 1); 216 } ··· 216 if (msir->gic_irq > 0) 217 irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL); 218 219 + for (i = 0; i < msi_data->cfg->msir_irqs; i++) { 220 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 221 bitmap_set(msi_data->used, hwirq, 1); 222 } ··· 226 227 static struct ls_scfg_msi_cfg ls1021_msi_cfg = { 228 .ibs_shift = 3, 229 + .msir_irqs = MSI_IRQS_PER_MSIR, 230 + .msir_base = MSI_MSIR_OFFSET, 231 }; 232 233 static struct ls_scfg_msi_cfg ls1046_msi_cfg = { 234 .ibs_shift = 2, 235 + .msir_irqs = MSI_IRQS_PER_MSIR, 236 + .msir_base = MSI_MSIR_OFFSET, 237 + }; 238 + 239 + static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = { 240 + .ibs_shift = 2, 241 + .msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR, 242 + .msir_base = MSI_LS1043V1_1_MSIR_OFFSET, 243 }; 244 245 static const struct of_device_id ls_scfg_msi_id[] = { ··· 239 240 { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, 241 { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, 242 + { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg }, 243 { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg }, 244 {}, 245 };