Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

coresight: tpdm: add static tpdm support

The static TPDM function as a dummy source, however, it is essential
to enable the port connected to the TPDA and configure the element size.
Without this, the TPDA cannot correctly receive trace data from the
static TPDM. Since the static TPDM does not require MMIO mapping to
access its registers, a clock controller is not mandatory for its
operation.

Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20251028-add_static_tpdm_support-v4-2-84e21b98e727@oss.qualcomm.com
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

authored by

Jie Gan and committed by
Suzuki K Poulose
14ae052f 8d204b6f

+154 -39
-7
drivers/hwtracing/coresight/coresight-tpda.c
··· 22 22 23 23 DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda"); 24 24 25 - static bool coresight_device_is_tpdm(struct coresight_device *csdev) 26 - { 27 - return (coresight_is_device_source(csdev)) && 28 - (csdev->subtype.source_subtype == 29 - CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); 30 - } 31 - 32 25 static void tpda_clear_element_size(struct coresight_device *csdev) 33 26 { 34 27 struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+142 -32
drivers/hwtracing/coresight/coresight-tpdm.c
··· 470 470 */ 471 471 static void __tpdm_enable(struct tpdm_drvdata *drvdata) 472 472 { 473 + if (coresight_is_static_tpdm(drvdata->csdev)) 474 + return; 475 + 473 476 CS_UNLOCK(drvdata->base); 474 477 475 478 tpdm_enable_dsb(drvdata); ··· 535 532 /* TPDM disable operations */ 536 533 static void __tpdm_disable(struct tpdm_drvdata *drvdata) 537 534 { 535 + if (coresight_is_static_tpdm(drvdata->csdev)) 536 + return; 537 + 538 538 CS_UNLOCK(drvdata->base); 539 539 540 540 tpdm_disable_dsb(drvdata); ··· 597 591 } 598 592 599 593 tpdm_reset_datasets(drvdata); 594 + 595 + return 0; 596 + } 597 + 598 + static int static_tpdm_datasets_setup(struct tpdm_drvdata *drvdata, struct device *dev) 599 + { 600 + /* setup datasets for static TPDM */ 601 + if (fwnode_property_present(dev->fwnode, "qcom,dsb-element-bits") && 602 + (!drvdata->dsb)) { 603 + drvdata->dsb = devm_kzalloc(drvdata->dev, 604 + sizeof(*drvdata->dsb), GFP_KERNEL); 605 + 606 + if (!drvdata->dsb) 607 + return -ENOMEM; 608 + } 609 + 610 + if (fwnode_property_present(dev->fwnode, "qcom,cmb-element-bits") && 611 + (!drvdata->cmb)) { 612 + drvdata->cmb = devm_kzalloc(drvdata->dev, 613 + sizeof(*drvdata->cmb), GFP_KERNEL); 614 + 615 + if (!drvdata->cmb) 616 + return -ENOMEM; 617 + } 600 618 601 619 return 0; 602 620 } ··· 1372 1342 NULL, 1373 1343 }; 1374 1344 1375 - static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) 1345 + static int tpdm_probe(struct device *dev, struct resource *res) 1376 1346 { 1377 1347 void __iomem *base; 1378 - struct device *dev = &adev->dev; 1379 1348 struct coresight_platform_data *pdata; 1380 1349 struct tpdm_drvdata *drvdata; 1381 1350 struct coresight_desc desc = { 0 }; ··· 1383 1354 pdata = coresight_get_platform_data(dev); 1384 1355 if (IS_ERR(pdata)) 1385 1356 return PTR_ERR(pdata); 1386 - adev->dev.platform_data = pdata; 1357 + dev->platform_data = pdata; 1387 1358 1388 1359 /* driver data*/ 1389 1360 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 1390 1361 if (!drvdata) 1391 1362 return -ENOMEM; 1392 - drvdata->dev = &adev->dev; 1363 + drvdata->dev = dev; 1393 1364 dev_set_drvdata(dev, drvdata); 1394 1365 1395 - base = devm_ioremap_resource(dev, &adev->res); 1396 - if (IS_ERR(base)) 1397 - return PTR_ERR(base); 1366 + if (res) { 1367 + base = devm_ioremap_resource(dev, res); 1368 + if (IS_ERR(base)) 1369 + return PTR_ERR(base); 1398 1370 1399 - drvdata->base = base; 1371 + drvdata->base = base; 1372 + ret = tpdm_datasets_setup(drvdata); 1373 + if (ret) 1374 + return ret; 1400 1375 1401 - ret = tpdm_datasets_setup(drvdata); 1402 - if (ret) 1403 - return ret; 1376 + if (drvdata && tpdm_has_dsb_dataset(drvdata)) 1377 + of_property_read_u32(drvdata->dev->of_node, 1378 + "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); 1404 1379 1405 - if (drvdata && tpdm_has_dsb_dataset(drvdata)) 1406 - of_property_read_u32(drvdata->dev->of_node, 1407 - "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); 1408 - 1409 - if (drvdata && tpdm_has_cmb_dataset(drvdata)) 1410 - of_property_read_u32(drvdata->dev->of_node, 1411 - "qcom,cmb-msrs-num", &drvdata->cmb_msr_num); 1380 + if (drvdata && tpdm_has_cmb_dataset(drvdata)) 1381 + of_property_read_u32(drvdata->dev->of_node, 1382 + "qcom,cmb-msrs-num", &drvdata->cmb_msr_num); 1383 + } else { 1384 + ret = static_tpdm_datasets_setup(drvdata, dev); 1385 + if (ret) 1386 + return ret; 1387 + } 1412 1388 1413 1389 /* Set up coresight component description */ 1414 1390 desc.name = coresight_alloc_device_name(&tpdm_devs, dev); ··· 1422 1388 desc.type = CORESIGHT_DEV_TYPE_SOURCE; 1423 1389 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM; 1424 1390 desc.ops = &tpdm_cs_ops; 1425 - desc.pdata = adev->dev.platform_data; 1426 - desc.dev = &adev->dev; 1391 + desc.pdata = dev->platform_data; 1392 + desc.dev = dev; 1427 1393 desc.access = CSDEV_ACCESS_IOMEM(base); 1428 - desc.groups = tpdm_attr_grps; 1394 + if (res) 1395 + desc.groups = tpdm_attr_grps; 1429 1396 drvdata->csdev = coresight_register(&desc); 1430 1397 if (IS_ERR(drvdata->csdev)) 1431 1398 return PTR_ERR(drvdata->csdev); 1432 1399 1433 1400 spin_lock_init(&drvdata->spinlock); 1434 1401 1435 - /* Decrease pm refcount when probe is done.*/ 1436 - pm_runtime_put(&adev->dev); 1402 + return 0; 1403 + } 1404 + 1405 + static int tpdm_remove(struct device *dev) 1406 + { 1407 + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev); 1408 + 1409 + coresight_unregister(drvdata->csdev); 1437 1410 1438 1411 return 0; 1439 1412 } 1440 1413 1441 - static void tpdm_remove(struct amba_device *adev) 1414 + static int dynamic_tpdm_probe(struct amba_device *adev, 1415 + const struct amba_id *id) 1442 1416 { 1443 - struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev); 1417 + int ret; 1444 1418 1445 - coresight_unregister(drvdata->csdev); 1419 + ret = tpdm_probe(&adev->dev, &adev->res); 1420 + if (!ret) 1421 + pm_runtime_put(&adev->dev); 1422 + 1423 + return ret; 1424 + } 1425 + 1426 + static void dynamic_tpdm_remove(struct amba_device *adev) 1427 + { 1428 + tpdm_remove(&adev->dev); 1446 1429 } 1447 1430 1448 1431 /* 1449 1432 * Different TPDM has different periph id. 1450 1433 * The difference is 0-7 bits' value. So ignore 0-7 bits. 1451 1434 */ 1452 - static const struct amba_id tpdm_ids[] = { 1435 + static const struct amba_id dynamic_tpdm_ids[] = { 1453 1436 { 1454 1437 .id = 0x001f0e00, 1455 1438 .mask = 0x00ffff00, ··· 1474 1423 { 0, 0, NULL }, 1475 1424 }; 1476 1425 1477 - static struct amba_driver tpdm_driver = { 1426 + MODULE_DEVICE_TABLE(amba, dynamic_tpdm_ids); 1427 + 1428 + static struct amba_driver dynamic_tpdm_driver = { 1478 1429 .drv = { 1479 1430 .name = "coresight-tpdm", 1480 1431 .suppress_bind_attrs = true, 1481 1432 }, 1482 - .probe = tpdm_probe, 1483 - .id_table = tpdm_ids, 1484 - .remove = tpdm_remove, 1433 + .probe = dynamic_tpdm_probe, 1434 + .id_table = dynamic_tpdm_ids, 1435 + .remove = dynamic_tpdm_remove, 1485 1436 }; 1486 1437 1487 - module_amba_driver(tpdm_driver); 1438 + static int tpdm_platform_probe(struct platform_device *pdev) 1439 + { 1440 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1441 + int ret; 1442 + 1443 + pm_runtime_get_noresume(&pdev->dev); 1444 + pm_runtime_set_active(&pdev->dev); 1445 + pm_runtime_enable(&pdev->dev); 1446 + 1447 + ret = tpdm_probe(&pdev->dev, res); 1448 + pm_runtime_put(&pdev->dev); 1449 + if (ret) 1450 + pm_runtime_disable(&pdev->dev); 1451 + 1452 + return ret; 1453 + } 1454 + 1455 + static void tpdm_platform_remove(struct platform_device *pdev) 1456 + { 1457 + struct tpdm_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 1458 + 1459 + if (WARN_ON(!drvdata)) 1460 + return; 1461 + 1462 + tpdm_remove(&pdev->dev); 1463 + pm_runtime_disable(&pdev->dev); 1464 + } 1465 + 1466 + static const struct of_device_id static_tpdm_match[] = { 1467 + {.compatible = "qcom,coresight-static-tpdm"}, 1468 + {} 1469 + }; 1470 + 1471 + MODULE_DEVICE_TABLE(of, static_tpdm_match); 1472 + 1473 + static struct platform_driver static_tpdm_driver = { 1474 + .probe = tpdm_platform_probe, 1475 + .remove = tpdm_platform_remove, 1476 + .driver = { 1477 + .name = "coresight-static-tpdm", 1478 + .of_match_table = static_tpdm_match, 1479 + .suppress_bind_attrs = true, 1480 + }, 1481 + }; 1482 + 1483 + static int __init tpdm_init(void) 1484 + { 1485 + return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver, 1486 + THIS_MODULE); 1487 + } 1488 + 1489 + static void __exit tpdm_exit(void) 1490 + { 1491 + coresight_remove_driver(&dynamic_tpdm_driver, &static_tpdm_driver); 1492 + } 1493 + 1494 + module_init(tpdm_init); 1495 + module_exit(tpdm_exit); 1488 1496 1489 1497 MODULE_LICENSE("GPL"); 1490 1498 MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
+12
drivers/hwtracing/coresight/coresight-tpdm.h
··· 343 343 enum dataset_mem mem; 344 344 u32 idx; 345 345 }; 346 + 347 + static inline bool coresight_device_is_tpdm(struct coresight_device *csdev) 348 + { 349 + return (coresight_is_device_source(csdev)) && 350 + (csdev->subtype.source_subtype == 351 + CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); 352 + } 353 + 354 + static inline bool coresight_is_static_tpdm(struct coresight_device *csdev) 355 + { 356 + return (coresight_device_is_tpdm(csdev) && !csdev->access.base); 357 + } 346 358 #endif /* _CORESIGHT_CORESIGHT_TPDM_H */