7474
7575#define AIC_WHOAMI 0x2000
7676#define AIC_EVENT 0x2004
77- #define AIC_EVENT_TYPE GENMASK(31, 16)
77+ #define AIC_EVENT_DIE GENMASK(31, 24)
78+ #define AIC_EVENT_TYPE GENMASK(23, 16)
7879#define AIC_EVENT_NUM GENMASK(15, 0)
7980
8081#define AIC_EVENT_TYPE_FIQ 0 /* Software use */
159160#define MPIDR_CPU (x ) MPIDR_AFFINITY_LEVEL(x, 0)
160161#define MPIDR_CLUSTER (x ) MPIDR_AFFINITY_LEVEL(x, 1)
161162
162- #define AIC_IRQ_HWIRQ (x ) (FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_IRQ) | \
163- FIELD_PREP(AIC_EVENT_NUM, x))
163+ #define AIC_IRQ_HWIRQ (die , irq ) (FIELD_PREP(AIC_EVENT_DIE, die) | \
164+ FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_IRQ) | \
165+ FIELD_PREP(AIC_EVENT_NUM, irq))
164166#define AIC_FIQ_HWIRQ (x ) (FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_FIQ) | \
165167 FIELD_PREP(AIC_EVENT_NUM, x))
166168#define AIC_HWIRQ_IRQ (x ) FIELD_GET(AIC_EVENT_NUM, x)
169+ #define AIC_HWIRQ_DIE (x ) FIELD_GET(AIC_EVENT_DIE, x)
167170#define AIC_NR_FIQ 4
168171#define AIC_NR_SWIPI 32
169172
@@ -195,6 +198,8 @@ struct aic_info {
195198 u32 mask_set ;
196199 u32 mask_clr ;
197200
201+ u32 die_stride ;
202+
198203 /* Features */
199204 bool fast_ipi ;
200205};
@@ -234,6 +239,8 @@ struct aic_irq_chip {
234239
235240 int nr_irq ;
236241 int max_irq ;
242+ int nr_die ;
243+ int max_die ;
237244
238245 struct aic_info info ;
239246};
@@ -266,19 +273,21 @@ static void aic_irq_mask(struct irq_data *d)
266273 irq_hw_number_t hwirq = irqd_to_hwirq (d );
267274 struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
268275
276+ u32 off = AIC_HWIRQ_DIE (hwirq ) * ic -> info .die_stride ;
269277 u32 irq = AIC_HWIRQ_IRQ (hwirq );
270278
271- aic_ic_write (ic , ic -> info .mask_set + MASK_REG (irq ), MASK_BIT (irq ));
279+ aic_ic_write (ic , ic -> info .mask_set + off + MASK_REG (irq ), MASK_BIT (irq ));
272280}
273281
274282static void aic_irq_unmask (struct irq_data * d )
275283{
276284 irq_hw_number_t hwirq = irqd_to_hwirq (d );
277285 struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
278286
287+ u32 off = AIC_HWIRQ_DIE (hwirq ) * ic -> info .die_stride ;
279288 u32 irq = AIC_HWIRQ_IRQ (hwirq );
280289
281- aic_ic_write (ic , ic -> info .mask_clr + MASK_REG (irq ), MASK_BIT (irq ));
290+ aic_ic_write (ic , ic -> info .mask_clr + off + MASK_REG (irq ), MASK_BIT (irq ));
282291}
283292
284293static void aic_irq_eoi (struct irq_data * d )
@@ -541,27 +550,41 @@ static int aic_irq_domain_translate(struct irq_domain *id,
541550 unsigned int * type )
542551{
543552 struct aic_irq_chip * ic = id -> host_data ;
553+ u32 * args ;
554+ u32 die = 0 ;
544555
545- if (fwspec -> param_count != 3 || !is_of_node (fwspec -> fwnode ))
556+ if (fwspec -> param_count < 3 || fwspec -> param_count > 4 ||
557+ !is_of_node (fwspec -> fwnode ))
546558 return - EINVAL ;
547559
560+ args = & fwspec -> param [1 ];
561+
562+ if (fwspec -> param_count == 4 ) {
563+ die = args [0 ];
564+ args ++ ;
565+ }
566+
548567 switch (fwspec -> param [0 ]) {
549568 case AIC_IRQ :
550- if (fwspec -> param [ 1 ] >= ic -> nr_irq )
569+ if (die >= ic -> nr_die )
551570 return - EINVAL ;
552- * hwirq = AIC_IRQ_HWIRQ (fwspec -> param [1 ]);
571+ if (args [0 ] >= ic -> nr_irq )
572+ return - EINVAL ;
573+ * hwirq = AIC_IRQ_HWIRQ (die , args [0 ]);
553574 break ;
554575 case AIC_FIQ :
555- if (fwspec -> param [1 ] >= AIC_NR_FIQ )
576+ if (die != 0 )
577+ return - EINVAL ;
578+ if (args [0 ] >= AIC_NR_FIQ )
556579 return - EINVAL ;
557- * hwirq = AIC_FIQ_HWIRQ (fwspec -> param [ 1 ]);
580+ * hwirq = AIC_FIQ_HWIRQ (args [ 0 ]);
558581
559582 /*
560583 * In EL1 the non-redirected registers are the guest's,
561584 * not EL2's, so remap the hwirqs to match.
562585 */
563586 if (!is_kernel_in_hyp_mode ()) {
564- switch (fwspec -> param [ 1 ]) {
587+ switch (args [ 0 ]) {
565588 case AIC_TMR_GUEST_PHYS :
566589 * hwirq = AIC_FIQ_HWIRQ (AIC_TMR_EL0_PHYS );
567590 break ;
@@ -580,7 +603,7 @@ static int aic_irq_domain_translate(struct irq_domain *id,
580603 return - EINVAL ;
581604 }
582605
583- * type = fwspec -> param [ 2 ] & IRQ_TYPE_SENSE_MASK ;
606+ * type = args [ 1 ] & IRQ_TYPE_SENSE_MASK ;
584607
585608 return 0 ;
586609}
@@ -899,8 +922,8 @@ static struct gic_kvm_info vgic_info __initdata = {
899922
900923static int __init aic_of_ic_init (struct device_node * node , struct device_node * parent )
901924{
902- int i ;
903- u32 off ;
925+ int i , die ;
926+ u32 off , start_off ;
904927 void __iomem * regs ;
905928 struct aic_irq_chip * irqc ;
906929 const struct of_device_id * match ;
@@ -930,8 +953,9 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
930953 info = aic_ic_read (irqc , AIC_INFO );
931954 irqc -> nr_irq = FIELD_GET (AIC_INFO_NR_IRQ , info );
932955 irqc -> max_irq = AIC_MAX_IRQ ;
956+ irqc -> nr_die = irqc -> max_die = 1 ;
933957
934- off = irqc -> info .target_cpu ;
958+ off = start_off = irqc -> info .target_cpu ;
935959 off += sizeof (u32 ) * irqc -> max_irq ; /* TARGET_CPU */
936960
937961 break ;
@@ -953,6 +977,8 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
953977 else
954978 static_branch_disable (& use_fast_ipi );
955979
980+ irqc -> info .die_stride = off - start_off ;
981+
956982 irqc -> hw_domain = irq_domain_create_tree (of_node_to_fwnode (node ),
957983 & aic_irq_domain_ops , irqc );
958984 if (WARN_ON (!irqc -> hw_domain )) {
@@ -973,12 +999,17 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
973999 set_handle_irq (aic_handle_irq );
9741000 set_handle_fiq (aic_handle_fiq );
9751001
976- for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
977- aic_ic_write (irqc , irqc -> info .mask_set + i * 4 , U32_MAX );
978- for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
979- aic_ic_write (irqc , irqc -> info .sw_clr + i * 4 , U32_MAX );
980- for (i = 0 ; i < irqc -> nr_irq ; i ++ )
981- aic_ic_write (irqc , irqc -> info .target_cpu + i * 4 , 1 );
1002+ off = 0 ;
1003+ for (die = 0 ; die < irqc -> nr_die ; die ++ ) {
1004+ for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
1005+ aic_ic_write (irqc , irqc -> info .mask_set + off + i * 4 , U32_MAX );
1006+ for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
1007+ aic_ic_write (irqc , irqc -> info .sw_clr + off + i * 4 , U32_MAX );
1008+ if (irqc -> info .target_cpu )
1009+ for (i = 0 ; i < irqc -> nr_irq ; i ++ )
1010+ aic_ic_write (irqc , irqc -> info .target_cpu + off + i * 4 , 1 );
1011+ off += irqc -> info .die_stride ;
1012+ }
9821013
9831014 if (!is_kernel_in_hyp_mode ())
9841015 pr_info ("Kernel running in EL1, mapping interrupts" );
@@ -992,8 +1023,8 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
9921023
9931024 vgic_set_kvm_info (& vgic_info );
9941025
995- pr_info ("Initialized with %d/%d IRQs, %d FIQs, %d vIPIs" ,
996- irqc -> nr_irq , irqc -> max_irq , AIC_NR_FIQ , AIC_NR_SWIPI );
1026+ pr_info ("Initialized with %d/%d IRQs * %d/%d die(s) , %d FIQs, %d vIPIs" ,
1027+ irqc -> nr_irq , irqc -> max_irq , irqc -> nr_die , irqc -> max_die , AIC_NR_FIQ , AIC_NR_SWIPI );
9971028
9981029 return 0 ;
9991030}
0 commit comments