1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (C) 2012-2019 ARM Limited or its affiliates. */ |
3 | |
4 | #include <linux/kernel.h> |
5 | #include <linux/debugfs.h> |
6 | #include <linux/stringify.h> |
7 | #include "cc_driver.h" |
8 | #include "cc_crypto_ctx.h" |
9 | #include "cc_debugfs.h" |
10 | |
11 | #define CC_DEBUG_REG(_X) { \ |
12 | .name = __stringify(_X),\ |
13 | .offset = CC_REG(_X) \ |
14 | } |
15 | |
16 | /* |
17 | * This is a global var for the dentry of the |
18 | * debugfs ccree/ dir. It is not tied down to |
19 | * a specific instance of ccree, hence it is |
20 | * global. |
21 | */ |
22 | static struct dentry *cc_debugfs_dir; |
23 | |
24 | static struct debugfs_reg32 ver_sig_regs[] = { |
25 | { .name = "SIGNATURE" }, /* Must be 0th */ |
26 | { .name = "VERSION" }, /* Must be 1st */ |
27 | }; |
28 | |
29 | static const struct debugfs_reg32 pid_cid_regs[] = { |
30 | CC_DEBUG_REG(PERIPHERAL_ID_0), |
31 | CC_DEBUG_REG(PERIPHERAL_ID_1), |
32 | CC_DEBUG_REG(PERIPHERAL_ID_2), |
33 | CC_DEBUG_REG(PERIPHERAL_ID_3), |
34 | CC_DEBUG_REG(PERIPHERAL_ID_4), |
35 | CC_DEBUG_REG(COMPONENT_ID_0), |
36 | CC_DEBUG_REG(COMPONENT_ID_1), |
37 | CC_DEBUG_REG(COMPONENT_ID_2), |
38 | CC_DEBUG_REG(COMPONENT_ID_3), |
39 | }; |
40 | |
41 | static const struct debugfs_reg32 debug_regs[] = { |
42 | CC_DEBUG_REG(HOST_IRR), |
43 | CC_DEBUG_REG(HOST_POWER_DOWN_EN), |
44 | CC_DEBUG_REG(AXIM_MON_ERR), |
45 | CC_DEBUG_REG(DSCRPTR_QUEUE_CONTENT), |
46 | CC_DEBUG_REG(HOST_IMR), |
47 | CC_DEBUG_REG(AXIM_CFG), |
48 | CC_DEBUG_REG(AXIM_CACHE_PARAMS), |
49 | CC_DEBUG_REG(GPR_HOST), |
50 | CC_DEBUG_REG(AXIM_MON_COMP), |
51 | }; |
52 | |
53 | void __init cc_debugfs_global_init(void) |
54 | { |
55 | cc_debugfs_dir = debugfs_create_dir(name: "ccree" , NULL); |
56 | } |
57 | |
58 | void cc_debugfs_global_fini(void) |
59 | { |
60 | debugfs_remove(dentry: cc_debugfs_dir); |
61 | } |
62 | |
63 | int cc_debugfs_init(struct cc_drvdata *drvdata) |
64 | { |
65 | struct device *dev = drvdata_to_dev(drvdata); |
66 | struct debugfs_regset32 *regset, *verset; |
67 | |
68 | regset = devm_kzalloc(dev, size: sizeof(*regset), GFP_KERNEL); |
69 | if (!regset) |
70 | return -ENOMEM; |
71 | |
72 | regset->regs = debug_regs; |
73 | regset->nregs = ARRAY_SIZE(debug_regs); |
74 | regset->base = drvdata->cc_base; |
75 | regset->dev = dev; |
76 | |
77 | drvdata->dir = debugfs_create_dir(name: drvdata->plat_dev->name, |
78 | parent: cc_debugfs_dir); |
79 | |
80 | debugfs_create_regset32(name: "regs" , mode: 0400, parent: drvdata->dir, regset); |
81 | debugfs_create_bool(name: "coherent" , mode: 0400, parent: drvdata->dir, value: &drvdata->coherent); |
82 | |
83 | verset = devm_kzalloc(dev, size: sizeof(*verset), GFP_KERNEL); |
84 | /* Failing here is not important enough to fail the module load */ |
85 | if (!verset) |
86 | return 0; |
87 | |
88 | if (drvdata->hw_rev <= CC_HW_REV_712) { |
89 | ver_sig_regs[0].offset = drvdata->sig_offset; |
90 | ver_sig_regs[1].offset = drvdata->ver_offset; |
91 | verset->regs = ver_sig_regs; |
92 | verset->nregs = ARRAY_SIZE(ver_sig_regs); |
93 | } else { |
94 | verset->regs = pid_cid_regs; |
95 | verset->nregs = ARRAY_SIZE(pid_cid_regs); |
96 | } |
97 | verset->base = drvdata->cc_base; |
98 | verset->dev = dev; |
99 | |
100 | debugfs_create_regset32(name: "version" , mode: 0400, parent: drvdata->dir, regset: verset); |
101 | return 0; |
102 | } |
103 | |
104 | void cc_debugfs_fini(struct cc_drvdata *drvdata) |
105 | { |
106 | debugfs_remove_recursive(dentry: drvdata->dir); |
107 | } |
108 | |