18
18
#include <linux/platform_device.h>
19
19
#include <linux/interrupt.h>
20
20
#include <linux/slab.h>
21
+ #include <linux/debugfs.h>
21
22
#include <linux/seq_file.h>
22
23
#include <linux/module.h>
23
24
#include <linux/list.h>
47
48
* frequency change (i.e. corresponding to the
48
49
* frequency in effect at the moment)
49
50
* @plat_data: Pointer to saved platform data.
51
+ * @debugfs_root: dentry to the root folder for EMIF in debugfs
50
52
*/
51
53
struct emif_data {
52
54
u8 duplicate ;
@@ -60,6 +62,7 @@ struct emif_data {
60
62
struct emif_regs * regs_cache [EMIF_MAX_NUM_FREQUENCIES ];
61
63
struct emif_regs * curr_regs ;
62
64
struct emif_platform_data * plat_data ;
65
+ struct dentry * debugfs_root ;
63
66
};
64
67
65
68
static struct emif_data * emif1 ;
@@ -68,6 +71,130 @@ static unsigned long irq_state;
68
71
static u32 t_ck ; /* DDR clock period in ps */
69
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
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
1304
emif_onetime_settings (emif );
1305
+ emif_debugfs_init (emif );
1178
1306
disable_and_clear_all_interrupts (emif );
1179
1307
setup_interrupts (emif , irq );
1180
1308
@@ -1198,6 +1326,15 @@ static int __init_or_module emif_probe(struct platform_device *pdev)
1198
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
1338
static void emif_shutdown (struct platform_device * pdev )
1202
1339
{
1203
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
1647
static struct platform_driver emif_driver = {
1648
+ .remove = __exit_p (emif_remove ),
1511
1649
.shutdown = emif_shutdown ,
1512
1650
.driver = {
1513
1651
.name = "emif" ,
0 commit comments