1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 Arm Limited. All rights reserved.
4 *
5 * Coresight Address Translation Unit support
6 *
7 * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
8 */
9
10#include <linux/amba/bus.h>
11#include <linux/device.h>
12#include <linux/dma-mapping.h>
13#include <linux/io.h>
14#include <linux/kernel.h>
15#include <linux/slab.h>
16
17#include "coresight-catu.h"
18#include "coresight-priv.h"
19#include "coresight-tmc.h"
20
21#define csdev_to_catu_drvdata(csdev) \
22 dev_get_drvdata(csdev->dev.parent)
23
24/* Verbose output for CATU table contents */
25#ifdef CATU_DEBUG
26#define catu_dbg(x, ...) dev_dbg(x, __VA_ARGS__)
27#else
28#define catu_dbg(x, ...) do {} while (0)
29#endif
30
31DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu");
32
33struct catu_etr_buf {
34 struct tmc_sg_table *catu_table;
35 dma_addr_t sladdr;
36};
37
38/*
39 * CATU uses a page size of 4KB for page tables as well as data pages.
40 * Each 64bit entry in the table has the following format.
41 *
42 * 63 12 1 0
43 * ------------------------------------
44 * | Address [63-12] | SBZ | V|
45 * ------------------------------------
46 *
47 * Where bit[0] V indicates if the address is valid or not.
48 * Each 4K table pages have upto 256 data page pointers, taking upto 2K
49 * size. There are two Link pointers, pointing to the previous and next
50 * table pages respectively at the end of the 4K page. (i.e, entry 510
51 * and 511).
52 * E.g, a table of two pages could look like :
53 *
54 * Table Page 0 Table Page 1
55 * SLADDR ===> x------------------x x--> x-----------------x
56 * INADDR ->| Page 0 | V | | | Page 256 | V | <- INADDR+1M
57 * |------------------| | |-----------------|
58 * INADDR+4K ->| Page 1 | V | | | |
59 * |------------------| | |-----------------|
60 * | Page 2 | V | | | |
61 * |------------------| | |-----------------|
62 * | ... | V | | | ... |
63 * |------------------| | |-----------------|
64 * INADDR+1020K| Page 255 | V | | | Page 511 | V |
65 * SLADDR+2K==>|------------------| | |-----------------|
66 * | UNUSED | | | | |
67 * |------------------| | | |
68 * | UNUSED | | | | |
69 * |------------------| | | |
70 * | ... | | | | |
71 * |------------------| | |-----------------|
72 * | IGNORED | 0 | | | Table Page 0| 1 |
73 * |------------------| | |-----------------|
74 * | Table Page 1| 1 |--x | IGNORED | 0 |
75 * x------------------x x-----------------x
76 * SLADDR+4K==>
77 *
78 * The base input address (used by the ETR, programmed in INADDR_{LO,HI})
79 * must be aligned to 1MB (the size addressable by a single page table).
80 * The CATU maps INADDR{LO:HI} to the first page in the table pointed
81 * to by SLADDR{LO:HI} and so on.
82 *
83 */
84typedef u64 cate_t;
85
86#define CATU_PAGE_SHIFT 12
87#define CATU_PAGE_SIZE (1UL << CATU_PAGE_SHIFT)
88#define CATU_PAGES_PER_SYSPAGE (PAGE_SIZE / CATU_PAGE_SIZE)
89
90/* Page pointers are only allocated in the first 2K half */
91#define CATU_PTRS_PER_PAGE ((CATU_PAGE_SIZE >> 1) / sizeof(cate_t))
92#define CATU_PTRS_PER_SYSPAGE (CATU_PAGES_PER_SYSPAGE * CATU_PTRS_PER_PAGE)
93#define CATU_LINK_PREV ((CATU_PAGE_SIZE / sizeof(cate_t)) - 2)
94#define CATU_LINK_NEXT ((CATU_PAGE_SIZE / sizeof(cate_t)) - 1)
95
96#define CATU_ADDR_SHIFT 12
97#define CATU_ADDR_MASK ~(((cate_t)1 << CATU_ADDR_SHIFT) - 1)
98#define CATU_ENTRY_VALID ((cate_t)0x1)
99#define CATU_VALID_ENTRY(addr) \
100 (((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID)
101#define CATU_ENTRY_ADDR(entry) ((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID))
102
103/* CATU expects the INADDR to be aligned to 1M. */
104#define CATU_DEFAULT_INADDR (1ULL << 20)
105
106/*
107 * catu_get_table : Retrieve the table pointers for the given @offset
108 * within the buffer. The buffer is wrapped around to a valid offset.
109 *
110 * Returns : The CPU virtual address for the beginning of the table
111 * containing the data page pointer for @offset. If @daddrp is not NULL,
112 * @daddrp points the DMA address of the beginning of the table.
113 */
114static inline cate_t *catu_get_table(struct tmc_sg_table *catu_table,
115 unsigned long offset,
116 dma_addr_t *daddrp)
117{
118 unsigned long buf_size = tmc_sg_table_buf_size(sg_table: catu_table);
119 unsigned int table_nr, pg_idx, pg_offset;
120 struct tmc_pages *table_pages = &catu_table->table_pages;
121 void *ptr;
122
123 /* Make sure offset is within the range */
124 offset %= buf_size;
125
126 /*
127 * Each table can address 1MB and a single kernel page can
128 * contain "CATU_PAGES_PER_SYSPAGE" CATU tables.
129 */
130 table_nr = offset >> 20;
131 /* Find the table page where the table_nr lies in */
132 pg_idx = table_nr / CATU_PAGES_PER_SYSPAGE;
133 pg_offset = (table_nr % CATU_PAGES_PER_SYSPAGE) * CATU_PAGE_SIZE;
134 if (daddrp)
135 *daddrp = table_pages->daddrs[pg_idx] + pg_offset;
136 ptr = page_address(table_pages->pages[pg_idx]);
137 return (cate_t *)((unsigned long)ptr + pg_offset);
138}
139
140#ifdef CATU_DEBUG
141static void catu_dump_table(struct tmc_sg_table *catu_table)
142{
143 int i;
144 cate_t *table;
145 unsigned long table_end, buf_size, offset = 0;
146
147 buf_size = tmc_sg_table_buf_size(catu_table);
148 dev_dbg(catu_table->dev,
149 "Dump table %p, tdaddr: %llx\n",
150 catu_table, catu_table->table_daddr);
151
152 while (offset < buf_size) {
153 table_end = offset + SZ_1M < buf_size ?
154 offset + SZ_1M : buf_size;
155 table = catu_get_table(catu_table, offset, NULL);
156 for (i = 0; offset < table_end; i++, offset += CATU_PAGE_SIZE)
157 dev_dbg(catu_table->dev, "%d: %llx\n", i, table[i]);
158 dev_dbg(catu_table->dev, "Prev : %llx, Next: %llx\n",
159 table[CATU_LINK_PREV], table[CATU_LINK_NEXT]);
160 dev_dbg(catu_table->dev, "== End of sub-table ===");
161 }
162 dev_dbg(catu_table->dev, "== End of Table ===");
163}
164
165#else
166static inline void catu_dump_table(struct tmc_sg_table *catu_table)
167{
168}
169#endif
170
171static inline cate_t catu_make_entry(dma_addr_t addr)
172{
173 return addr ? CATU_VALID_ENTRY(addr) : 0;
174}
175
176/*
177 * catu_populate_table : Populate the given CATU table.
178 * The table is always populated as a circular table.
179 * i.e, the "prev" link of the "first" table points to the "last"
180 * table and the "next" link of the "last" table points to the
181 * "first" table. The buffer should be made linear by calling
182 * catu_set_table().
183 */
184static void
185catu_populate_table(struct tmc_sg_table *catu_table)
186{
187 int i;
188 int sys_pidx; /* Index to current system data page */
189 int catu_pidx; /* Index of CATU page within the system data page */
190 unsigned long offset, buf_size, table_end;
191 dma_addr_t data_daddr;
192 dma_addr_t prev_taddr, next_taddr, cur_taddr;
193 cate_t *table_ptr, *next_table;
194
195 buf_size = tmc_sg_table_buf_size(sg_table: catu_table);
196 sys_pidx = catu_pidx = 0;
197 offset = 0;
198
199 table_ptr = catu_get_table(catu_table, offset: 0, daddrp: &cur_taddr);
200 prev_taddr = 0; /* Prev link for the first table */
201
202 while (offset < buf_size) {
203 /*
204 * The @offset is always 1M aligned here and we have an
205 * empty table @table_ptr to fill. Each table can address
206 * upto 1MB data buffer. The last table may have fewer
207 * entries if the buffer size is not aligned.
208 */
209 table_end = (offset + SZ_1M) < buf_size ?
210 (offset + SZ_1M) : buf_size;
211 for (i = 0; offset < table_end;
212 i++, offset += CATU_PAGE_SIZE) {
213
214 data_daddr = catu_table->data_pages.daddrs[sys_pidx] +
215 catu_pidx * CATU_PAGE_SIZE;
216 catu_dbg(catu_table->dev,
217 "[table %5ld:%03d] 0x%llx\n",
218 (offset >> 20), i, data_daddr);
219 table_ptr[i] = catu_make_entry(addr: data_daddr);
220 /* Move the pointers for data pages */
221 catu_pidx = (catu_pidx + 1) % CATU_PAGES_PER_SYSPAGE;
222 if (catu_pidx == 0)
223 sys_pidx++;
224 }
225
226 /*
227 * If we have finished all the valid entries, fill the rest of
228 * the table (i.e, last table page) with invalid entries,
229 * to fail the lookups.
230 */
231 if (offset == buf_size) {
232 memset(&table_ptr[i], 0,
233 sizeof(cate_t) * (CATU_PTRS_PER_PAGE - i));
234 next_taddr = 0;
235 } else {
236 next_table = catu_get_table(catu_table,
237 offset, daddrp: &next_taddr);
238 }
239
240 table_ptr[CATU_LINK_PREV] = catu_make_entry(addr: prev_taddr);
241 table_ptr[CATU_LINK_NEXT] = catu_make_entry(addr: next_taddr);
242
243 catu_dbg(catu_table->dev,
244 "[table%5ld]: Cur: 0x%llx Prev: 0x%llx, Next: 0x%llx\n",
245 (offset >> 20) - 1, cur_taddr, prev_taddr, next_taddr);
246
247 /* Update the prev/next addresses */
248 if (next_taddr) {
249 prev_taddr = cur_taddr;
250 cur_taddr = next_taddr;
251 table_ptr = next_table;
252 }
253 }
254
255 /* Sync the table for device */
256 tmc_sg_table_sync_table(sg_table: catu_table);
257}
258
259static struct tmc_sg_table *
260catu_init_sg_table(struct device *catu_dev, int node,
261 ssize_t size, void **pages)
262{
263 int nr_tpages;
264 struct tmc_sg_table *catu_table;
265
266 /*
267 * Each table can address upto 1MB and we can have
268 * CATU_PAGES_PER_SYSPAGE tables in a system page.
269 */
270 nr_tpages = DIV_ROUND_UP(size, SZ_1M) / CATU_PAGES_PER_SYSPAGE;
271 catu_table = tmc_alloc_sg_table(dev: catu_dev, node, nr_tpages,
272 nr_dpages: size >> PAGE_SHIFT, pages);
273 if (IS_ERR(ptr: catu_table))
274 return catu_table;
275
276 catu_populate_table(catu_table);
277 dev_dbg(catu_dev,
278 "Setup table %p, size %ldKB, %d table pages\n",
279 catu_table, (unsigned long)size >> 10, nr_tpages);
280 catu_dump_table(catu_table);
281 return catu_table;
282}
283
284static void catu_free_etr_buf(struct etr_buf *etr_buf)
285{
286 struct catu_etr_buf *catu_buf;
287
288 if (!etr_buf || etr_buf->mode != ETR_MODE_CATU || !etr_buf->private)
289 return;
290
291 catu_buf = etr_buf->private;
292 tmc_free_sg_table(sg_table: catu_buf->catu_table);
293 kfree(objp: catu_buf);
294}
295
296static ssize_t catu_get_data_etr_buf(struct etr_buf *etr_buf, u64 offset,
297 size_t len, char **bufpp)
298{
299 struct catu_etr_buf *catu_buf = etr_buf->private;
300
301 return tmc_sg_table_get_data(sg_table: catu_buf->catu_table, offset, len, bufpp);
302}
303
304static void catu_sync_etr_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
305{
306 struct catu_etr_buf *catu_buf = etr_buf->private;
307 struct tmc_sg_table *catu_table = catu_buf->catu_table;
308 u64 r_offset, w_offset;
309
310 /*
311 * ETR started off at etr_buf->hwaddr. Convert the RRP/RWP to
312 * offsets within the trace buffer.
313 */
314 r_offset = rrp - etr_buf->hwaddr;
315 w_offset = rwp - etr_buf->hwaddr;
316
317 if (!etr_buf->full) {
318 etr_buf->len = w_offset - r_offset;
319 if (w_offset < r_offset)
320 etr_buf->len += etr_buf->size;
321 } else {
322 etr_buf->len = etr_buf->size;
323 }
324
325 etr_buf->offset = r_offset;
326 tmc_sg_table_sync_data_range(table: catu_table, offset: r_offset, size: etr_buf->len);
327}
328
329static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata,
330 struct etr_buf *etr_buf, int node, void **pages)
331{
332 struct coresight_device *csdev;
333 struct tmc_sg_table *catu_table;
334 struct catu_etr_buf *catu_buf;
335
336 csdev = tmc_etr_get_catu_device(drvdata: tmc_drvdata);
337 if (!csdev)
338 return -ENODEV;
339 catu_buf = kzalloc(size: sizeof(*catu_buf), GFP_KERNEL);
340 if (!catu_buf)
341 return -ENOMEM;
342
343 catu_table = catu_init_sg_table(catu_dev: &csdev->dev, node,
344 size: etr_buf->size, pages);
345 if (IS_ERR(ptr: catu_table)) {
346 kfree(objp: catu_buf);
347 return PTR_ERR(ptr: catu_table);
348 }
349
350 etr_buf->mode = ETR_MODE_CATU;
351 etr_buf->private = catu_buf;
352 etr_buf->hwaddr = CATU_DEFAULT_INADDR;
353
354 catu_buf->catu_table = catu_table;
355 /* Get the table base address */
356 catu_buf->sladdr = catu_table->table_daddr;
357
358 return 0;
359}
360
361static const struct etr_buf_operations etr_catu_buf_ops = {
362 .alloc = catu_alloc_etr_buf,
363 .free = catu_free_etr_buf,
364 .sync = catu_sync_etr_buf,
365 .get_data = catu_get_data_etr_buf,
366};
367
368static struct attribute *catu_mgmt_attrs[] = {
369 coresight_simple_reg32(devid, CORESIGHT_DEVID),
370 coresight_simple_reg32(control, CATU_CONTROL),
371 coresight_simple_reg32(status, CATU_STATUS),
372 coresight_simple_reg32(mode, CATU_MODE),
373 coresight_simple_reg32(axictrl, CATU_AXICTRL),
374 coresight_simple_reg32(irqen, CATU_IRQEN),
375 coresight_simple_reg64(sladdr, CATU_SLADDRLO, CATU_SLADDRHI),
376 coresight_simple_reg64(inaddr, CATU_INADDRLO, CATU_INADDRHI),
377 NULL,
378};
379
380static const struct attribute_group catu_mgmt_group = {
381 .attrs = catu_mgmt_attrs,
382 .name = "mgmt",
383};
384
385static const struct attribute_group *catu_groups[] = {
386 &catu_mgmt_group,
387 NULL,
388};
389
390
391static inline int catu_wait_for_ready(struct catu_drvdata *drvdata)
392{
393 struct csdev_access *csa = &drvdata->csdev->access;
394
395 return coresight_timeout(csa, CATU_STATUS, CATU_STATUS_READY, value: 1);
396}
397
398static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode,
399 void *data)
400{
401 int rc;
402 u32 control, mode;
403 struct etr_buf *etr_buf = NULL;
404 struct device *dev = &drvdata->csdev->dev;
405 struct coresight_device *csdev = drvdata->csdev;
406 struct coresight_device *etrdev;
407 union coresight_dev_subtype etr_subtype = {
408 .sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM
409 };
410
411 if (catu_wait_for_ready(drvdata))
412 dev_warn(dev, "Timeout while waiting for READY\n");
413
414 control = catu_read_control(drvdata);
415 if (control & BIT(CATU_CONTROL_ENABLE)) {
416 dev_warn(dev, "CATU is already enabled\n");
417 return -EBUSY;
418 }
419
420 rc = coresight_claim_device_unlocked(csdev);
421 if (rc)
422 return rc;
423
424 etrdev = coresight_find_input_type(
425 pdata: csdev->pdata, type: CORESIGHT_DEV_TYPE_SINK, subtype: etr_subtype);
426 if (etrdev) {
427 etr_buf = tmc_etr_get_buffer(csdev: etrdev, mode: cs_mode, data);
428 if (IS_ERR(ptr: etr_buf))
429 return PTR_ERR(ptr: etr_buf);
430 }
431 control |= BIT(CATU_CONTROL_ENABLE);
432
433 if (etr_buf && etr_buf->mode == ETR_MODE_CATU) {
434 struct catu_etr_buf *catu_buf = etr_buf->private;
435
436 mode = CATU_MODE_TRANSLATE;
437 catu_write_axictrl(drvdata, CATU_OS_AXICTRL);
438 catu_write_sladdr(drvdata, val: catu_buf->sladdr);
439 catu_write_inaddr(drvdata, CATU_DEFAULT_INADDR);
440 } else {
441 mode = CATU_MODE_PASS_THROUGH;
442 catu_write_sladdr(drvdata, val: 0);
443 catu_write_inaddr(drvdata, val: 0);
444 }
445
446 catu_write_irqen(drvdata, val: 0);
447 catu_write_mode(drvdata, val: mode);
448 catu_write_control(drvdata, val: control);
449 dev_dbg(dev, "Enabled in %s mode\n",
450 (mode == CATU_MODE_PASS_THROUGH) ?
451 "Pass through" :
452 "Translate");
453 return 0;
454}
455
456static int catu_enable(struct coresight_device *csdev, enum cs_mode mode,
457 void *data)
458{
459 int rc;
460 struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
461
462 CS_UNLOCK(addr: catu_drvdata->base);
463 rc = catu_enable_hw(drvdata: catu_drvdata, cs_mode: mode, data);
464 CS_LOCK(addr: catu_drvdata->base);
465 return rc;
466}
467
468static int catu_disable_hw(struct catu_drvdata *drvdata)
469{
470 int rc = 0;
471 struct device *dev = &drvdata->csdev->dev;
472 struct coresight_device *csdev = drvdata->csdev;
473
474 catu_write_control(drvdata, val: 0);
475 coresight_disclaim_device_unlocked(csdev);
476 if (catu_wait_for_ready(drvdata)) {
477 dev_info(dev, "Timeout while waiting for READY\n");
478 rc = -EAGAIN;
479 }
480
481 dev_dbg(dev, "Disabled\n");
482 return rc;
483}
484
485static int catu_disable(struct coresight_device *csdev, void *__unused)
486{
487 int rc;
488 struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
489
490 CS_UNLOCK(addr: catu_drvdata->base);
491 rc = catu_disable_hw(drvdata: catu_drvdata);
492 CS_LOCK(addr: catu_drvdata->base);
493 return rc;
494}
495
496static const struct coresight_ops_helper catu_helper_ops = {
497 .enable = catu_enable,
498 .disable = catu_disable,
499};
500
501static const struct coresight_ops catu_ops = {
502 .helper_ops = &catu_helper_ops,
503};
504
505static int catu_probe(struct amba_device *adev, const struct amba_id *id)
506{
507 int ret = 0;
508 u32 dma_mask;
509 struct catu_drvdata *drvdata;
510 struct coresight_desc catu_desc;
511 struct coresight_platform_data *pdata = NULL;
512 struct device *dev = &adev->dev;
513 void __iomem *base;
514
515 catu_desc.name = coresight_alloc_device_name(devs: &catu_devs, dev);
516 if (!catu_desc.name)
517 return -ENOMEM;
518
519 drvdata = devm_kzalloc(dev, size: sizeof(*drvdata), GFP_KERNEL);
520 if (!drvdata) {
521 ret = -ENOMEM;
522 goto out;
523 }
524
525 dev_set_drvdata(dev, data: drvdata);
526 base = devm_ioremap_resource(dev, res: &adev->res);
527 if (IS_ERR(ptr: base)) {
528 ret = PTR_ERR(ptr: base);
529 goto out;
530 }
531
532 /* Setup dma mask for the device */
533 dma_mask = readl_relaxed(base + CORESIGHT_DEVID) & 0x3f;
534 switch (dma_mask) {
535 case 32:
536 case 40:
537 case 44:
538 case 48:
539 case 52:
540 case 56:
541 case 64:
542 break;
543 default:
544 /* Default to the 40bits as supported by TMC-ETR */
545 dma_mask = 40;
546 }
547 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_mask));
548 if (ret)
549 goto out;
550
551 pdata = coresight_get_platform_data(dev);
552 if (IS_ERR(ptr: pdata)) {
553 ret = PTR_ERR(ptr: pdata);
554 goto out;
555 }
556 dev->platform_data = pdata;
557
558 drvdata->base = base;
559 catu_desc.access = CSDEV_ACCESS_IOMEM(base);
560 catu_desc.pdata = pdata;
561 catu_desc.dev = dev;
562 catu_desc.groups = catu_groups;
563 catu_desc.type = CORESIGHT_DEV_TYPE_HELPER;
564 catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
565 catu_desc.ops = &catu_ops;
566
567 drvdata->csdev = coresight_register(desc: &catu_desc);
568 if (IS_ERR(ptr: drvdata->csdev))
569 ret = PTR_ERR(ptr: drvdata->csdev);
570 else
571 pm_runtime_put(dev: &adev->dev);
572out:
573 return ret;
574}
575
576static void catu_remove(struct amba_device *adev)
577{
578 struct catu_drvdata *drvdata = dev_get_drvdata(dev: &adev->dev);
579
580 coresight_unregister(csdev: drvdata->csdev);
581}
582
583static struct amba_id catu_ids[] = {
584 CS_AMBA_ID(0x000bb9ee),
585 {},
586};
587
588MODULE_DEVICE_TABLE(amba, catu_ids);
589
590static struct amba_driver catu_driver = {
591 .drv = {
592 .name = "coresight-catu",
593 .owner = THIS_MODULE,
594 .suppress_bind_attrs = true,
595 },
596 .probe = catu_probe,
597 .remove = catu_remove,
598 .id_table = catu_ids,
599};
600
601static int __init catu_init(void)
602{
603 int ret;
604
605 ret = amba_driver_register(drv: &catu_driver);
606 if (ret)
607 pr_info("Error registering catu driver\n");
608 tmc_etr_set_catu_ops(catu: &etr_catu_buf_ops);
609 return ret;
610}
611
612static void __exit catu_exit(void)
613{
614 tmc_etr_remove_catu_ops();
615 amba_driver_unregister(drv: &catu_driver);
616}
617
618module_init(catu_init);
619module_exit(catu_exit);
620
621MODULE_AUTHOR("Suzuki K Poulose <suzuki.poulose@arm.com>");
622MODULE_DESCRIPTION("Arm CoreSight Address Translation Unit (CATU) Driver");
623MODULE_LICENSE("GPL v2");
624

source code of linux/drivers/hwtracing/coresight/coresight-catu.c