Lines Matching +full:coresight +full:- +full:catu
1 // SPDX-License-Identifier: GPL-2.0
5 * Coresight Address Translation Unit support
13 #include <linux/dma-mapping.h>
19 #include "coresight-catu.h"
20 #include "coresight-priv.h"
21 #include "coresight-tmc.h"
24 dev_get_drvdata(csdev->dev.parent)
26 /* Verbose output for CATU table contents */
33 DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu");
41 * CATU uses a page size of 4KB for page tables as well as data pages.
45 * ------------------------------------
46 * | Address [63-12] | SBZ | V|
47 * ------------------------------------
57 * SLADDR ===> x------------------x x--> x-----------------x
58 * INADDR ->| Page 0 | V | | | Page 256 | V | <- INADDR+1M
59 * |------------------| | |-----------------|
60 * INADDR+4K ->| Page 1 | V | | | |
61 * |------------------| | |-----------------|
63 * |------------------| | |-----------------|
65 * |------------------| | |-----------------|
67 * SLADDR+2K==>|------------------| | |-----------------|
69 * |------------------| | | |
71 * |------------------| | | |
73 * |------------------| | |-----------------|
75 * |------------------| | |-----------------|
76 * | Table Page 1| 1 |--x | IGNORED | 0 |
77 * x------------------x x-----------------x
82 * The CATU maps INADDR{LO:HI} to the first page in the table pointed
95 #define CATU_LINK_PREV ((CATU_PAGE_SIZE / sizeof(cate_t)) - 2)
96 #define CATU_LINK_NEXT ((CATU_PAGE_SIZE / sizeof(cate_t)) - 1)
99 #define CATU_ADDR_MASK ~(((cate_t)1 << CATU_ADDR_SHIFT) - 1)
105 /* CATU expects the INADDR to be aligned to 1M. */
122 struct tmc_pages *table_pages = &catu_table->table_pages; in catu_get_table()
130 * contain "CATU_PAGES_PER_SYSPAGE" CATU tables. in catu_get_table()
137 *daddrp = table_pages->daddrs[pg_idx] + pg_offset; in catu_get_table()
138 ptr = page_address(table_pages->pages[pg_idx]); in catu_get_table()
150 dev_dbg(catu_table->dev, in catu_dump_table()
152 catu_table, catu_table->table_daddr); in catu_dump_table()
159 dev_dbg(catu_table->dev, "%d: %llx\n", i, table[i]); in catu_dump_table()
160 dev_dbg(catu_table->dev, "Prev : %llx, Next: %llx\n", in catu_dump_table()
162 dev_dbg(catu_table->dev, "== End of sub-table ==="); in catu_dump_table()
164 dev_dbg(catu_table->dev, "== End of Table ==="); in catu_dump_table()
179 * catu_populate_table : Populate the given CATU table.
191 int catu_pidx; /* Index of CATU page within the system data page */ in catu_populate_table()
216 data_daddr = catu_table->data_pages.daddrs[sys_pidx] + in catu_populate_table()
218 catu_dbg(catu_table->dev, in catu_populate_table()
235 sizeof(cate_t) * (CATU_PTRS_PER_PAGE - i)); in catu_populate_table()
245 catu_dbg(catu_table->dev, in catu_populate_table()
247 (offset >> 20) - 1, cur_taddr, prev_taddr, next_taddr); in catu_populate_table()
290 if (!etr_buf || etr_buf->mode != ETR_MODE_CATU || !etr_buf->private) in catu_free_etr_buf()
293 catu_buf = etr_buf->private; in catu_free_etr_buf()
294 tmc_free_sg_table(catu_buf->catu_table); in catu_free_etr_buf()
301 struct catu_etr_buf *catu_buf = etr_buf->private; in catu_get_data_etr_buf()
303 return tmc_sg_table_get_data(catu_buf->catu_table, offset, len, bufpp); in catu_get_data_etr_buf()
308 struct catu_etr_buf *catu_buf = etr_buf->private; in catu_sync_etr_buf()
309 struct tmc_sg_table *catu_table = catu_buf->catu_table; in catu_sync_etr_buf()
313 * ETR started off at etr_buf->hwaddr. Convert the RRP/RWP to in catu_sync_etr_buf()
316 r_offset = rrp - etr_buf->hwaddr; in catu_sync_etr_buf()
317 w_offset = rwp - etr_buf->hwaddr; in catu_sync_etr_buf()
319 if (!etr_buf->full) { in catu_sync_etr_buf()
320 etr_buf->len = w_offset - r_offset; in catu_sync_etr_buf()
322 etr_buf->len += etr_buf->size; in catu_sync_etr_buf()
324 etr_buf->len = etr_buf->size; in catu_sync_etr_buf()
327 etr_buf->offset = r_offset; in catu_sync_etr_buf()
328 tmc_sg_table_sync_data_range(catu_table, r_offset, etr_buf->len); in catu_sync_etr_buf()
340 return -ENODEV; in catu_alloc_etr_buf()
343 return -ENOMEM; in catu_alloc_etr_buf()
345 catu_table = catu_init_sg_table(&csdev->dev, node, in catu_alloc_etr_buf()
346 etr_buf->size, pages); in catu_alloc_etr_buf()
352 etr_buf->mode = ETR_MODE_CATU; in catu_alloc_etr_buf()
353 etr_buf->private = catu_buf; in catu_alloc_etr_buf()
354 etr_buf->hwaddr = CATU_DEFAULT_INADDR; in catu_alloc_etr_buf()
356 catu_buf->catu_table = catu_table; in catu_alloc_etr_buf()
358 catu_buf->sladdr = catu_table->table_daddr; in catu_alloc_etr_buf()
395 struct csdev_access *csa = &drvdata->csdev->access; in catu_wait_for_ready()
406 struct device *dev = &drvdata->csdev->dev; in catu_enable_hw()
407 struct coresight_device *csdev = drvdata->csdev; in catu_enable_hw()
418 dev_warn(dev, "CATU is already enabled\n"); in catu_enable_hw()
419 return -EBUSY; in catu_enable_hw()
427 csdev->pdata, CORESIGHT_DEV_TYPE_SINK, etr_subtype); in catu_enable_hw()
435 if (etr_buf && etr_buf->mode == ETR_MODE_CATU) { in catu_enable_hw()
436 struct catu_etr_buf *catu_buf = etr_buf->private; in catu_enable_hw()
440 catu_write_sladdr(drvdata, catu_buf->sladdr); in catu_enable_hw()
464 CS_UNLOCK(catu_drvdata->base); in catu_enable()
466 CS_LOCK(catu_drvdata->base); in catu_enable()
473 struct device *dev = &drvdata->csdev->dev; in catu_disable_hw()
474 struct coresight_device *csdev = drvdata->csdev; in catu_disable_hw()
480 rc = -EAGAIN; in catu_disable_hw()
492 CS_UNLOCK(catu_drvdata->base); in catu_disable()
494 CS_LOCK(catu_drvdata->base); in catu_disable()
518 return -ENOMEM; in __catu_probe()
538 /* Default to the 40bits as supported by TMC-ETR */ in __catu_probe()
550 dev->platform_data = pdata; in __catu_probe()
552 drvdata->base = base; in __catu_probe()
561 drvdata->csdev = coresight_register(&catu_desc); in __catu_probe()
562 if (IS_ERR(drvdata->csdev)) in __catu_probe()
563 ret = PTR_ERR(drvdata->csdev); in __catu_probe()
573 drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); in catu_probe()
575 return -ENOMEM; in catu_probe()
578 ret = __catu_probe(&adev->dev, &adev->res); in catu_probe()
580 pm_runtime_put(&adev->dev); in catu_probe()
589 coresight_unregister(drvdata->csdev); in __catu_remove()
594 __catu_remove(&adev->dev); in catu_remove()
606 .name = "coresight-catu",
620 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); in catu_platform_probe()
622 return -ENOMEM; in catu_platform_probe()
624 drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); in catu_platform_probe()
625 if (IS_ERR(drvdata->pclk)) in catu_platform_probe()
626 return -ENODEV; in catu_platform_probe()
628 pm_runtime_get_noresume(&pdev->dev); in catu_platform_probe()
629 pm_runtime_set_active(&pdev->dev); in catu_platform_probe()
630 pm_runtime_enable(&pdev->dev); in catu_platform_probe()
632 dev_set_drvdata(&pdev->dev, drvdata); in catu_platform_probe()
633 ret = __catu_probe(&pdev->dev, res); in catu_platform_probe()
634 pm_runtime_put(&pdev->dev); in catu_platform_probe()
636 pm_runtime_disable(&pdev->dev); in catu_platform_probe()
637 if (!IS_ERR_OR_NULL(drvdata->pclk)) in catu_platform_probe()
638 clk_put(drvdata->pclk); in catu_platform_probe()
646 struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); in catu_platform_remove()
651 __catu_remove(&pdev->dev); in catu_platform_remove()
652 pm_runtime_disable(&pdev->dev); in catu_platform_remove()
653 if (!IS_ERR_OR_NULL(drvdata->pclk)) in catu_platform_remove()
654 clk_put(drvdata->pclk); in catu_platform_remove()
662 if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) in catu_runtime_suspend()
663 clk_disable_unprepare(drvdata->pclk); in catu_runtime_suspend()
671 if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) in catu_runtime_resume()
672 clk_prepare_enable(drvdata->pclk); in catu_runtime_resume()
683 {"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */
694 .name = "coresight-catu-platform",
705 ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver); in catu_init()
720 MODULE_DESCRIPTION("Arm CoreSight Address Translation Unit (CATU) Driver");