diff options
author | Aneesh V <aneesh@ti.com> | 2012-04-27 08:24:09 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-02 14:00:08 -0400 |
commit | aac10aaa8cc65a6fef6f5bc7d0b96035b0225a61 (patch) | |
tree | 3c61053e233eacdc80f4cb02bf598246c9547cce /drivers/memory/emif.c | |
parent | 98231c4fc3b95a0e9d37ba3711ad993bb27605c8 (diff) |
memory: emif: add debugfs entries for emif
Add debug entries for:
1. calculated registers per frequency
2. last polled value of MR4(temperature level
of LPDDR2 memory)
Signed-off-by: Aneesh V <aneesh@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Benoit Cousson <b-cousson@ti.com>
[santosh.shilimkar@ti.com: Moved to drivers/memory from drivers/misc]
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Tested-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/memory/emif.c')
-rw-r--r-- | drivers/memory/emif.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index 3dfffbb8ab40..33a4396b24cb 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/debugfs.h> | ||
21 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/list.h> | 24 | #include <linux/list.h> |
@@ -47,6 +48,7 @@ | |||
47 | * frequency change (i.e. corresponding to the | 48 | * frequency change (i.e. corresponding to the |
48 | * frequency in effect at the moment) | 49 | * frequency in effect at the moment) |
49 | * @plat_data: Pointer to saved platform data. | 50 | * @plat_data: Pointer to saved platform data. |
51 | * @debugfs_root: dentry to the root folder for EMIF in debugfs | ||
50 | */ | 52 | */ |
51 | struct emif_data { | 53 | struct emif_data { |
52 | u8 duplicate; | 54 | u8 duplicate; |
@@ -60,6 +62,7 @@ struct emif_data { | |||
60 | struct emif_regs *regs_cache[EMIF_MAX_NUM_FREQUENCIES]; | 62 | struct emif_regs *regs_cache[EMIF_MAX_NUM_FREQUENCIES]; |
61 | struct emif_regs *curr_regs; | 63 | struct emif_regs *curr_regs; |
62 | struct emif_platform_data *plat_data; | 64 | struct emif_platform_data *plat_data; |
65 | struct dentry *debugfs_root; | ||
63 | }; | 66 | }; |
64 | 67 | ||
65 | static struct emif_data *emif1; | 68 | static struct emif_data *emif1; |
@@ -68,6 +71,130 @@ static unsigned long irq_state; | |||
68 | static u32 t_ck; /* DDR clock period in ps */ | 71 | static u32 t_ck; /* DDR clock period in ps */ |
69 | static LIST_HEAD(device_list); | 72 | static LIST_HEAD(device_list); |
70 | 73 | ||
74 | static void do_emif_regdump_show(struct seq_file *s, struct emif_data *emif, | ||
75 | struct emif_regs *regs) | ||
76 | { | ||
77 | u32 type = emif->plat_data->device_info->type; | ||
78 | u32 ip_rev = emif->plat_data->ip_rev; | ||
79 | |||
80 | seq_printf(s, "EMIF register cache dump for %dMHz\n", | ||
81 | regs->freq/1000000); | ||
82 | |||
83 | seq_printf(s, "ref_ctrl_shdw\t: 0x%08x\n", regs->ref_ctrl_shdw); | ||
84 | seq_printf(s, "sdram_tim1_shdw\t: 0x%08x\n", regs->sdram_tim1_shdw); | ||
85 | seq_printf(s, "sdram_tim2_shdw\t: 0x%08x\n", regs->sdram_tim2_shdw); | ||
86 | seq_printf(s, "sdram_tim3_shdw\t: 0x%08x\n", regs->sdram_tim3_shdw); | ||
87 | |||
88 | if (ip_rev == EMIF_4D) { | ||
89 | seq_printf(s, "read_idle_ctrl_shdw_normal\t: 0x%08x\n", | ||
90 | regs->read_idle_ctrl_shdw_normal); | ||
91 | seq_printf(s, "read_idle_ctrl_shdw_volt_ramp\t: 0x%08x\n", | ||
92 | regs->read_idle_ctrl_shdw_volt_ramp); | ||
93 | } else if (ip_rev == EMIF_4D5) { | ||
94 | seq_printf(s, "dll_calib_ctrl_shdw_normal\t: 0x%08x\n", | ||
95 | regs->dll_calib_ctrl_shdw_normal); | ||
96 | seq_printf(s, "dll_calib_ctrl_shdw_volt_ramp\t: 0x%08x\n", | ||
97 | regs->dll_calib_ctrl_shdw_volt_ramp); | ||
98 | } | ||
99 | |||
100 | if (type == DDR_TYPE_LPDDR2_S2 || type == DDR_TYPE_LPDDR2_S4) { | ||
101 | seq_printf(s, "ref_ctrl_shdw_derated\t: 0x%08x\n", | ||
102 | regs->ref_ctrl_shdw_derated); | ||
103 | seq_printf(s, "sdram_tim1_shdw_derated\t: 0x%08x\n", | ||
104 | regs->sdram_tim1_shdw_derated); | ||
105 | seq_printf(s, "sdram_tim3_shdw_derated\t: 0x%08x\n", | ||
106 | regs->sdram_tim3_shdw_derated); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static int emif_regdump_show(struct seq_file *s, void *unused) | ||
111 | { | ||
112 | struct emif_data *emif = s->private; | ||
113 | struct emif_regs **regs_cache; | ||
114 | int i; | ||
115 | |||
116 | if (emif->duplicate) | ||
117 | regs_cache = emif1->regs_cache; | ||
118 | else | ||
119 | regs_cache = emif->regs_cache; | ||
120 | |||
121 | for (i = 0; i < EMIF_MAX_NUM_FREQUENCIES && regs_cache[i]; i++) { | ||
122 | do_emif_regdump_show(s, emif, regs_cache[i]); | ||
123 | seq_printf(s, "\n"); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int emif_regdump_open(struct inode *inode, struct file *file) | ||
130 | { | ||
131 | return single_open(file, emif_regdump_show, inode->i_private); | ||
132 | } | ||
133 | |||
134 | static const struct file_operations emif_regdump_fops = { | ||
135 | .open = emif_regdump_open, | ||
136 | .read = seq_read, | ||
137 | .release = single_release, | ||
138 | }; | ||
139 | |||
140 | static int emif_mr4_show(struct seq_file *s, void *unused) | ||
141 | { | ||
142 | struct emif_data *emif = s->private; | ||
143 | |||
144 | seq_printf(s, "MR4=%d\n", emif->temperature_level); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int emif_mr4_open(struct inode *inode, struct file *file) | ||
149 | { | ||
150 | return single_open(file, emif_mr4_show, inode->i_private); | ||
151 | } | ||
152 | |||
153 | static const struct file_operations emif_mr4_fops = { | ||
154 | .open = emif_mr4_open, | ||
155 | .read = seq_read, | ||
156 | .release = single_release, | ||
157 | }; | ||
158 | |||
159 | static int __init_or_module emif_debugfs_init(struct emif_data *emif) | ||
160 | { | ||
161 | struct dentry *dentry; | ||
162 | int ret; | ||
163 | |||
164 | dentry = debugfs_create_dir(dev_name(emif->dev), NULL); | ||
165 | if (IS_ERR(dentry)) { | ||
166 | ret = PTR_ERR(dentry); | ||
167 | goto err0; | ||
168 | } | ||
169 | emif->debugfs_root = dentry; | ||
170 | |||
171 | dentry = debugfs_create_file("regcache_dump", S_IRUGO, | ||
172 | emif->debugfs_root, emif, &emif_regdump_fops); | ||
173 | if (IS_ERR(dentry)) { | ||
174 | ret = PTR_ERR(dentry); | ||
175 | goto err1; | ||
176 | } | ||
177 | |||
178 | dentry = debugfs_create_file("mr4", S_IRUGO, | ||
179 | emif->debugfs_root, emif, &emif_mr4_fops); | ||
180 | if (IS_ERR(dentry)) { | ||
181 | ret = PTR_ERR(dentry); | ||
182 | goto err1; | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | err1: | ||
187 | debugfs_remove_recursive(emif->debugfs_root); | ||
188 | err0: | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static void __exit emif_debugfs_exit(struct emif_data *emif) | ||
193 | { | ||
194 | debugfs_remove_recursive(emif->debugfs_root); | ||
195 | emif->debugfs_root = NULL; | ||
196 | } | ||
197 | |||
71 | /* | 198 | /* |
72 | * Calculate the period of DDR clock from frequency value | 199 | * Calculate the period of DDR clock from frequency value |
73 | */ | 200 | */ |
@@ -1175,6 +1302,7 @@ static int __init_or_module emif_probe(struct platform_device *pdev) | |||
1175 | } | 1302 | } |
1176 | 1303 | ||
1177 | emif_onetime_settings(emif); | 1304 | emif_onetime_settings(emif); |
1305 | emif_debugfs_init(emif); | ||
1178 | disable_and_clear_all_interrupts(emif); | 1306 | disable_and_clear_all_interrupts(emif); |
1179 | setup_interrupts(emif, irq); | 1307 | setup_interrupts(emif, irq); |
1180 | 1308 | ||
@@ -1198,6 +1326,15 @@ error: | |||
1198 | return -ENODEV; | 1326 | return -ENODEV; |
1199 | } | 1327 | } |
1200 | 1328 | ||
1329 | static int __exit emif_remove(struct platform_device *pdev) | ||
1330 | { | ||
1331 | struct emif_data *emif = platform_get_drvdata(pdev); | ||
1332 | |||
1333 | emif_debugfs_exit(emif); | ||
1334 | |||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1201 | static void emif_shutdown(struct platform_device *pdev) | 1338 | static void emif_shutdown(struct platform_device *pdev) |
1202 | { | 1339 | { |
1203 | struct emif_data *emif = platform_get_drvdata(pdev); | 1340 | struct emif_data *emif = platform_get_drvdata(pdev); |
@@ -1508,6 +1645,7 @@ static void __attribute__((unused)) freq_post_notify_handling(void) | |||
1508 | } | 1645 | } |
1509 | 1646 | ||
1510 | static struct platform_driver emif_driver = { | 1647 | static struct platform_driver emif_driver = { |
1648 | .remove = __exit_p(emif_remove), | ||
1511 | .shutdown = emif_shutdown, | 1649 | .shutdown = emif_shutdown, |
1512 | .driver = { | 1650 | .driver = { |
1513 | .name = "emif", | 1651 | .name = "emif", |