aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/memory/emif.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 3dfffbb8ab4..33a4396b24c 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 */
51struct emif_data { 53struct 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
65static struct emif_data *emif1; 68static struct emif_data *emif1;
@@ -68,6 +71,130 @@ static unsigned long irq_state;
68static u32 t_ck; /* DDR clock period in ps */ 71static u32 t_ck; /* DDR clock period in ps */
69static LIST_HEAD(device_list); 72static LIST_HEAD(device_list);
70 73
74static 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
110static 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
129static int emif_regdump_open(struct inode *inode, struct file *file)
130{
131 return single_open(file, emif_regdump_show, inode->i_private);
132}
133
134static const struct file_operations emif_regdump_fops = {
135 .open = emif_regdump_open,
136 .read = seq_read,
137 .release = single_release,
138};
139
140static 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
148static int emif_mr4_open(struct inode *inode, struct file *file)
149{
150 return single_open(file, emif_mr4_show, inode->i_private);
151}
152
153static const struct file_operations emif_mr4_fops = {
154 .open = emif_mr4_open,
155 .read = seq_read,
156 .release = single_release,
157};
158
159static 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;
186err1:
187 debugfs_remove_recursive(emif->debugfs_root);
188err0:
189 return ret;
190}
191
192static 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
1329static 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
1201static void emif_shutdown(struct platform_device *pdev) 1338static 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
1510static struct platform_driver emif_driver = { 1647static 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",