4040#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
4141#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
4242#define FLAGS_WORKAROUND_MTK_GICR_SAVE (1ULL << 2)
43+ #define FLAGS_WORKAROUND_ASR_ERRATUM_8601001 (1ULL << 3)
4344
4445#define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1)
4546
@@ -656,10 +657,16 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
656657 return 0 ;
657658}
658659
659- static u64 gic_mpidr_to_affinity ( unsigned long mpidr )
660+ static u64 gic_cpu_to_affinity ( int cpu )
660661{
662+ u64 mpidr = cpu_logical_map (cpu );
661663 u64 aff ;
662664
665+ /* ASR8601 needs to have its affinities shifted down... */
666+ if (unlikely (gic_data .flags & FLAGS_WORKAROUND_ASR_ERRATUM_8601001 ))
667+ mpidr = (MPIDR_AFFINITY_LEVEL (mpidr , 1 ) |
668+ (MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 8 ));
669+
663670 aff = ((u64 )MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 32 |
664671 MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
665672 MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
@@ -914,7 +921,7 @@ static void __init gic_dist_init(void)
914921 * Set all global interrupts to the boot CPU only. ARE must be
915922 * enabled.
916923 */
917- affinity = gic_mpidr_to_affinity ( cpu_logical_map ( smp_processor_id () ));
924+ affinity = gic_cpu_to_affinity ( smp_processor_id ());
918925 for (i = 32 ; i < GIC_LINE_NR ; i ++ )
919926 gic_write_irouter (affinity , base + GICD_IROUTER + i * 8 );
920927
@@ -963,14 +970,16 @@ static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
963970
964971static int __gic_populate_rdist (struct redist_region * region , void __iomem * ptr )
965972{
966- unsigned long mpidr = cpu_logical_map ( smp_processor_id ()) ;
973+ unsigned long mpidr ;
967974 u64 typer ;
968975 u32 aff ;
969976
970977 /*
971978 * Convert affinity to a 32bit value that can be matched to
972979 * GICR_TYPER bits [63:32].
973980 */
981+ mpidr = gic_cpu_to_affinity (smp_processor_id ());
982+
974983 aff = (MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 24 |
975984 MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
976985 MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
@@ -1084,7 +1093,7 @@ static inline bool gic_dist_security_disabled(void)
10841093static void gic_cpu_sys_reg_init (void )
10851094{
10861095 int i , cpu = smp_processor_id ();
1087- u64 mpidr = cpu_logical_map (cpu );
1096+ u64 mpidr = gic_cpu_to_affinity (cpu );
10881097 u64 need_rss = MPIDR_RS (mpidr );
10891098 bool group0 ;
10901099 u32 pribits ;
@@ -1183,11 +1192,11 @@ static void gic_cpu_sys_reg_init(void)
11831192 for_each_online_cpu (i ) {
11841193 bool have_rss = per_cpu (has_rss , i ) && per_cpu (has_rss , cpu );
11851194
1186- need_rss |= MPIDR_RS (cpu_logical_map (i ));
1195+ need_rss |= MPIDR_RS (gic_cpu_to_affinity (i ));
11871196 if (need_rss && (!have_rss ))
11881197 pr_crit ("CPU%d (%lx) can't SGI CPU%d (%lx), no RSS\n" ,
11891198 cpu , (unsigned long )mpidr ,
1190- i , (unsigned long )cpu_logical_map (i ));
1199+ i , (unsigned long )gic_cpu_to_affinity (i ));
11911200 }
11921201
11931202 /**
@@ -1263,9 +1272,11 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
12631272 unsigned long cluster_id )
12641273{
12651274 int next_cpu , cpu = * base_cpu ;
1266- unsigned long mpidr = cpu_logical_map ( cpu ) ;
1275+ unsigned long mpidr ;
12671276 u16 tlist = 0 ;
12681277
1278+ mpidr = gic_cpu_to_affinity (cpu );
1279+
12691280 while (cpu < nr_cpu_ids ) {
12701281 tlist |= 1 << (mpidr & 0xf );
12711282
@@ -1274,7 +1285,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
12741285 goto out ;
12751286 cpu = next_cpu ;
12761287
1277- mpidr = cpu_logical_map (cpu );
1288+ mpidr = gic_cpu_to_affinity (cpu );
12781289
12791290 if (cluster_id != MPIDR_TO_SGI_CLUSTER_ID (mpidr )) {
12801291 cpu -- ;
@@ -1319,7 +1330,7 @@ static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
13191330 dsb (ishst );
13201331
13211332 for_each_cpu (cpu , mask ) {
1322- u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID (cpu_logical_map (cpu ));
1333+ u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID (gic_cpu_to_affinity (cpu ));
13231334 u16 tlist ;
13241335
13251336 tlist = gic_compute_target_list (& cpu , mask , cluster_id );
@@ -1377,7 +1388,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
13771388
13781389 offset = convert_offset_index (d , GICD_IROUTER , & index );
13791390 reg = gic_dist_base (d ) + offset + (index * 8 );
1380- val = gic_mpidr_to_affinity ( cpu_logical_map ( cpu ) );
1391+ val = gic_cpu_to_affinity ( cpu );
13811392
13821393 gic_write_irouter (val , reg );
13831394
@@ -1796,12 +1807,26 @@ static bool gic_enable_quirk_nvidia_t241(void *data)
17961807 return true;
17971808}
17981809
1810+ static bool gic_enable_quirk_asr8601 (void * data )
1811+ {
1812+ struct gic_chip_data * d = data ;
1813+
1814+ d -> flags |= FLAGS_WORKAROUND_ASR_ERRATUM_8601001 ;
1815+
1816+ return true;
1817+ }
1818+
17991819static const struct gic_quirk gic_quirks [] = {
18001820 {
18011821 .desc = "GICv3: Qualcomm MSM8996 broken firmware" ,
18021822 .compatible = "qcom,msm8996-gic-v3" ,
18031823 .init = gic_enable_quirk_msm8996 ,
18041824 },
1825+ {
1826+ .desc = "GICv3: ASR erratum 8601001" ,
1827+ .compatible = "asr,asr8601-gic-v3" ,
1828+ .init = gic_enable_quirk_asr8601 ,
1829+ },
18051830 {
18061831 .desc = "GICv3: Mediatek Chromebook GICR save problem" ,
18071832 .property = "mediatek,broken-save-restore-fw" ,
0 commit comments