@@ -356,7 +356,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
356
356
if (map -> flags & ACPI_IORT_ID_SINGLE_MAPPING ) {
357
357
if (node -> type == ACPI_IORT_NODE_NAMED_COMPONENT ||
358
358
node -> type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
359
- node -> type == ACPI_IORT_NODE_SMMU_V3 ) {
359
+ node -> type == ACPI_IORT_NODE_SMMU_V3 ||
360
+ node -> type == ACPI_IORT_NODE_PMCG ) {
360
361
* id_out = map -> output_base ;
361
362
return parent ;
362
363
}
@@ -394,6 +395,8 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node)
394
395
}
395
396
396
397
return smmu -> id_mapping_index ;
398
+ case ACPI_IORT_NODE_PMCG :
399
+ return 0 ;
397
400
default :
398
401
return - EINVAL ;
399
402
}
@@ -1218,14 +1221,23 @@ static void __init arm_smmu_v3_init_resources(struct resource *res,
1218
1221
}
1219
1222
}
1220
1223
1221
- static bool __init arm_smmu_v3_is_coherent (struct acpi_iort_node * node )
1224
+ static void __init arm_smmu_v3_dma_configure (struct device * dev ,
1225
+ struct acpi_iort_node * node )
1222
1226
{
1223
1227
struct acpi_iort_smmu_v3 * smmu ;
1228
+ enum dev_dma_attr attr ;
1224
1229
1225
1230
/* Retrieve SMMUv3 specific data */
1226
1231
smmu = (struct acpi_iort_smmu_v3 * )node -> node_data ;
1227
1232
1228
- return smmu -> flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE ;
1233
+ attr = (smmu -> flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE ) ?
1234
+ DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT ;
1235
+
1236
+ /* We expect the dma masks to be equivalent for all SMMUv3 set-ups */
1237
+ dev -> dma_mask = & dev -> coherent_dma_mask ;
1238
+
1239
+ /* Configure DMA for the page table walker */
1240
+ acpi_dma_configure (dev , attr );
1229
1241
}
1230
1242
1231
1243
#if defined(CONFIG_ACPI_NUMA )
@@ -1307,40 +1319,113 @@ static void __init arm_smmu_init_resources(struct resource *res,
1307
1319
}
1308
1320
}
1309
1321
1310
- static bool __init arm_smmu_is_coherent (struct acpi_iort_node * node )
1322
+ static void __init arm_smmu_dma_configure (struct device * dev ,
1323
+ struct acpi_iort_node * node )
1311
1324
{
1312
1325
struct acpi_iort_smmu * smmu ;
1326
+ enum dev_dma_attr attr ;
1313
1327
1314
1328
/* Retrieve SMMU specific data */
1315
1329
smmu = (struct acpi_iort_smmu * )node -> node_data ;
1316
1330
1317
- return smmu -> flags & ACPI_IORT_SMMU_COHERENT_WALK ;
1331
+ attr = (smmu -> flags & ACPI_IORT_SMMU_COHERENT_WALK ) ?
1332
+ DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT ;
1333
+
1334
+ /* We expect the dma masks to be equivalent for SMMU set-ups */
1335
+ dev -> dma_mask = & dev -> coherent_dma_mask ;
1336
+
1337
+ /* Configure DMA for the page table walker */
1338
+ acpi_dma_configure (dev , attr );
1339
+ }
1340
+
1341
+ static int __init arm_smmu_v3_pmcg_count_resources (struct acpi_iort_node * node )
1342
+ {
1343
+ struct acpi_iort_pmcg * pmcg ;
1344
+
1345
+ /* Retrieve PMCG specific data */
1346
+ pmcg = (struct acpi_iort_pmcg * )node -> node_data ;
1347
+
1348
+ /*
1349
+ * There are always 2 memory resources.
1350
+ * If the overflow_gsiv is present then add that for a total of 3.
1351
+ */
1352
+ return pmcg -> overflow_gsiv ? 3 : 2 ;
1353
+ }
1354
+
1355
+ static void __init arm_smmu_v3_pmcg_init_resources (struct resource * res ,
1356
+ struct acpi_iort_node * node )
1357
+ {
1358
+ struct acpi_iort_pmcg * pmcg ;
1359
+
1360
+ /* Retrieve PMCG specific data */
1361
+ pmcg = (struct acpi_iort_pmcg * )node -> node_data ;
1362
+
1363
+ res [0 ].start = pmcg -> page0_base_address ;
1364
+ res [0 ].end = pmcg -> page0_base_address + SZ_4K - 1 ;
1365
+ res [0 ].flags = IORESOURCE_MEM ;
1366
+ res [1 ].start = pmcg -> page1_base_address ;
1367
+ res [1 ].end = pmcg -> page1_base_address + SZ_4K - 1 ;
1368
+ res [1 ].flags = IORESOURCE_MEM ;
1369
+
1370
+ if (pmcg -> overflow_gsiv )
1371
+ acpi_iort_register_irq (pmcg -> overflow_gsiv , "overflow" ,
1372
+ ACPI_EDGE_SENSITIVE , & res [2 ]);
1373
+ }
1374
+
1375
+ static struct acpi_platform_list pmcg_plat_info [] __initdata = {
1376
+ /* HiSilicon Hip08 Platform */
1377
+ {"HISI " , "HIP08 " , 0 , ACPI_SIG_IORT , greater_than_or_equal ,
1378
+ "Erratum #162001800" , IORT_SMMU_V3_PMCG_HISI_HIP08 },
1379
+ { }
1380
+ };
1381
+
1382
+ static int __init arm_smmu_v3_pmcg_add_platdata (struct platform_device * pdev )
1383
+ {
1384
+ u32 model ;
1385
+ int idx ;
1386
+
1387
+ idx = acpi_match_platform_list (pmcg_plat_info );
1388
+ if (idx >= 0 )
1389
+ model = pmcg_plat_info [idx ].data ;
1390
+ else
1391
+ model = IORT_SMMU_V3_PMCG_GENERIC ;
1392
+
1393
+ return platform_device_add_data (pdev , & model , sizeof (model ));
1318
1394
}
1319
1395
1320
1396
struct iort_dev_config {
1321
1397
const char * name ;
1322
1398
int (* dev_init )(struct acpi_iort_node * node );
1323
- bool (* dev_is_coherent )(struct acpi_iort_node * node );
1399
+ void (* dev_dma_configure )(struct device * dev ,
1400
+ struct acpi_iort_node * node );
1324
1401
int (* dev_count_resources )(struct acpi_iort_node * node );
1325
1402
void (* dev_init_resources )(struct resource * res ,
1326
1403
struct acpi_iort_node * node );
1327
1404
int (* dev_set_proximity )(struct device * dev ,
1328
1405
struct acpi_iort_node * node );
1406
+ int (* dev_add_platdata )(struct platform_device * pdev );
1329
1407
};
1330
1408
1331
1409
static const struct iort_dev_config iort_arm_smmu_v3_cfg __initconst = {
1332
1410
.name = "arm-smmu-v3" ,
1333
- .dev_is_coherent = arm_smmu_v3_is_coherent ,
1411
+ .dev_dma_configure = arm_smmu_v3_dma_configure ,
1334
1412
.dev_count_resources = arm_smmu_v3_count_resources ,
1335
1413
.dev_init_resources = arm_smmu_v3_init_resources ,
1336
1414
.dev_set_proximity = arm_smmu_v3_set_proximity ,
1337
1415
};
1338
1416
1339
1417
static const struct iort_dev_config iort_arm_smmu_cfg __initconst = {
1340
1418
.name = "arm-smmu" ,
1341
- .dev_is_coherent = arm_smmu_is_coherent ,
1419
+ .dev_dma_configure = arm_smmu_dma_configure ,
1342
1420
.dev_count_resources = arm_smmu_count_resources ,
1343
- .dev_init_resources = arm_smmu_init_resources
1421
+ .dev_init_resources = arm_smmu_init_resources ,
1422
+ };
1423
+
1424
+ static const struct iort_dev_config iort_arm_smmu_v3_pmcg_cfg __initconst = {
1425
+ .name = "arm-smmu-v3-pmcg" ,
1426
+ .dev_count_resources = arm_smmu_v3_pmcg_count_resources ,
1427
+ .dev_init_resources = arm_smmu_v3_pmcg_init_resources ,
1428
+ .dev_add_platdata = arm_smmu_v3_pmcg_add_platdata ,
1344
1429
};
1345
1430
1346
1431
static __init const struct iort_dev_config * iort_get_dev_cfg (
@@ -1351,6 +1436,8 @@ static __init const struct iort_dev_config *iort_get_dev_cfg(
1351
1436
return & iort_arm_smmu_v3_cfg ;
1352
1437
case ACPI_IORT_NODE_SMMU :
1353
1438
return & iort_arm_smmu_cfg ;
1439
+ case ACPI_IORT_NODE_PMCG :
1440
+ return & iort_arm_smmu_v3_pmcg_cfg ;
1354
1441
default :
1355
1442
return NULL ;
1356
1443
}
@@ -1368,7 +1455,6 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
1368
1455
struct fwnode_handle * fwnode ;
1369
1456
struct platform_device * pdev ;
1370
1457
struct resource * r ;
1371
- enum dev_dma_attr attr ;
1372
1458
int ret , count ;
1373
1459
1374
1460
pdev = platform_device_alloc (ops -> name , PLATFORM_DEVID_AUTO );
@@ -1402,19 +1488,19 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
1402
1488
goto dev_put ;
1403
1489
1404
1490
/*
1405
- * Add a copy of IORT node pointer to platform_data to
1406
- * be used to retrieve IORT data information.
1491
+ * Platform devices based on PMCG nodes uses platform_data to
1492
+ * pass the hardware model info to the driver. For others, add
1493
+ * a copy of IORT node pointer to platform_data to be used to
1494
+ * retrieve IORT data information.
1407
1495
*/
1408
- ret = platform_device_add_data (pdev , & node , sizeof (node ));
1496
+ if (ops -> dev_add_platdata )
1497
+ ret = ops -> dev_add_platdata (pdev );
1498
+ else
1499
+ ret = platform_device_add_data (pdev , & node , sizeof (node ));
1500
+
1409
1501
if (ret )
1410
1502
goto dev_put ;
1411
1503
1412
- /*
1413
- * We expect the dma masks to be equivalent for
1414
- * all SMMUs set-ups
1415
- */
1416
- pdev -> dev .dma_mask = & pdev -> dev .coherent_dma_mask ;
1417
-
1418
1504
fwnode = iort_get_fwnode (node );
1419
1505
1420
1506
if (!fwnode ) {
@@ -1424,11 +1510,8 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
1424
1510
1425
1511
pdev -> dev .fwnode = fwnode ;
1426
1512
1427
- attr = ops -> dev_is_coherent && ops -> dev_is_coherent (node ) ?
1428
- DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT ;
1429
-
1430
- /* Configure DMA for the page table walker */
1431
- acpi_dma_configure (& pdev -> dev , attr );
1513
+ if (ops -> dev_dma_configure )
1514
+ ops -> dev_dma_configure (& pdev -> dev , node );
1432
1515
1433
1516
iort_set_device_domain (& pdev -> dev , node );
1434
1517
0 commit comments