40
40
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
41
41
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
42
42
#define FLAGS_WORKAROUND_MTK_GICR_SAVE (1ULL << 2)
43
+ #define FLAGS_WORKAROUND_ASR_ERRATUM_8601001 (1ULL << 3)
43
44
44
45
#define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1)
45
46
@@ -656,10 +657,16 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
656
657
return 0 ;
657
658
}
658
659
659
- static u64 gic_mpidr_to_affinity ( unsigned long mpidr )
660
+ static u64 gic_cpu_to_affinity ( int cpu )
660
661
{
662
+ u64 mpidr = cpu_logical_map (cpu );
661
663
u64 aff ;
662
664
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
+
663
670
aff = ((u64 )MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 32 |
664
671
MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
665
672
MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
@@ -914,7 +921,7 @@ static void __init gic_dist_init(void)
914
921
* Set all global interrupts to the boot CPU only. ARE must be
915
922
* enabled.
916
923
*/
917
- affinity = gic_mpidr_to_affinity ( cpu_logical_map ( smp_processor_id () ));
924
+ affinity = gic_cpu_to_affinity ( smp_processor_id ());
918
925
for (i = 32 ; i < GIC_LINE_NR ; i ++ )
919
926
gic_write_irouter (affinity , base + GICD_IROUTER + i * 8 );
920
927
@@ -963,14 +970,16 @@ static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
963
970
964
971
static int __gic_populate_rdist (struct redist_region * region , void __iomem * ptr )
965
972
{
966
- unsigned long mpidr = cpu_logical_map ( smp_processor_id ()) ;
973
+ unsigned long mpidr ;
967
974
u64 typer ;
968
975
u32 aff ;
969
976
970
977
/*
971
978
* Convert affinity to a 32bit value that can be matched to
972
979
* GICR_TYPER bits [63:32].
973
980
*/
981
+ mpidr = gic_cpu_to_affinity (smp_processor_id ());
982
+
974
983
aff = (MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 24 |
975
984
MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
976
985
MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
@@ -1084,7 +1093,7 @@ static inline bool gic_dist_security_disabled(void)
1084
1093
static void gic_cpu_sys_reg_init (void )
1085
1094
{
1086
1095
int i , cpu = smp_processor_id ();
1087
- u64 mpidr = cpu_logical_map (cpu );
1096
+ u64 mpidr = gic_cpu_to_affinity (cpu );
1088
1097
u64 need_rss = MPIDR_RS (mpidr );
1089
1098
bool group0 ;
1090
1099
u32 pribits ;
@@ -1183,11 +1192,11 @@ static void gic_cpu_sys_reg_init(void)
1183
1192
for_each_online_cpu (i ) {
1184
1193
bool have_rss = per_cpu (has_rss , i ) && per_cpu (has_rss , cpu );
1185
1194
1186
- need_rss |= MPIDR_RS (cpu_logical_map (i ));
1195
+ need_rss |= MPIDR_RS (gic_cpu_to_affinity (i ));
1187
1196
if (need_rss && (!have_rss ))
1188
1197
pr_crit ("CPU%d (%lx) can't SGI CPU%d (%lx), no RSS\n" ,
1189
1198
cpu , (unsigned long )mpidr ,
1190
- i , (unsigned long )cpu_logical_map (i ));
1199
+ i , (unsigned long )gic_cpu_to_affinity (i ));
1191
1200
}
1192
1201
1193
1202
/**
@@ -1263,9 +1272,11 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
1263
1272
unsigned long cluster_id )
1264
1273
{
1265
1274
int next_cpu , cpu = * base_cpu ;
1266
- unsigned long mpidr = cpu_logical_map ( cpu ) ;
1275
+ unsigned long mpidr ;
1267
1276
u16 tlist = 0 ;
1268
1277
1278
+ mpidr = gic_cpu_to_affinity (cpu );
1279
+
1269
1280
while (cpu < nr_cpu_ids ) {
1270
1281
tlist |= 1 << (mpidr & 0xf );
1271
1282
@@ -1274,7 +1285,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
1274
1285
goto out ;
1275
1286
cpu = next_cpu ;
1276
1287
1277
- mpidr = cpu_logical_map (cpu );
1288
+ mpidr = gic_cpu_to_affinity (cpu );
1278
1289
1279
1290
if (cluster_id != MPIDR_TO_SGI_CLUSTER_ID (mpidr )) {
1280
1291
cpu -- ;
@@ -1319,7 +1330,7 @@ static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
1319
1330
dsb (ishst );
1320
1331
1321
1332
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 ));
1323
1334
u16 tlist ;
1324
1335
1325
1336
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,
1377
1388
1378
1389
offset = convert_offset_index (d , GICD_IROUTER , & index );
1379
1390
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 );
1381
1392
1382
1393
gic_write_irouter (val , reg );
1383
1394
@@ -1796,12 +1807,26 @@ static bool gic_enable_quirk_nvidia_t241(void *data)
1796
1807
return true;
1797
1808
}
1798
1809
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
+
1799
1819
static const struct gic_quirk gic_quirks [] = {
1800
1820
{
1801
1821
.desc = "GICv3: Qualcomm MSM8996 broken firmware" ,
1802
1822
.compatible = "qcom,msm8996-gic-v3" ,
1803
1823
.init = gic_enable_quirk_msm8996 ,
1804
1824
},
1825
+ {
1826
+ .desc = "GICv3: ASR erratum 8601001" ,
1827
+ .compatible = "asr,asr8601-gic-v3" ,
1828
+ .init = gic_enable_quirk_asr8601 ,
1829
+ },
1805
1830
{
1806
1831
.desc = "GICv3: Mediatek Chromebook GICR save problem" ,
1807
1832
.property = "mediatek,broken-save-restore-fw" ,
0 commit comments