]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-uniphier/dram/cmd_ddrmphy.c
2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * SPDX-License-Identifier: GPL-2.0+
11 #include "ddrmphy-regs.h"
13 /* Select either decimal or hexadecimal */
15 #define PRINTF_FORMAT "%2d"
17 #define PRINTF_FORMAT "%02x"
22 static void __iomem
*get_phy_base(int ch
)
24 return (void __iomem
*)(0x5b830000 + ch
* 0x00200000);
27 static int get_nr_ch(void)
29 const struct uniphier_board_data
*bd
= uniphier_get_board_param();
31 return bd
->dram_ch
[2].size
? 3 : 2;
34 static int get_nr_datx8(int ch
)
36 const struct uniphier_board_data
*bd
= uniphier_get_board_param();
38 return bd
->dram_ch
[ch
].width
/ 8;
41 static void print_bdl(void __iomem
*reg
, int n
)
46 for (i
= 0; i
< n
; i
++)
47 printf(FS PRINTF_FORMAT
, (val
>> i
* 8) & 0x1f);
50 static void dump_loop(void (*callback
)(void __iomem
*))
52 int ch
, dx
, nr_ch
, nr_dx
;
53 void __iomem
*dx_base
;
57 for (ch
= 0; ch
< nr_ch
; ch
++) {
58 dx_base
= get_phy_base(ch
) + DMPHY_DX_BASE
;
59 nr_dx
= get_nr_datx8(ch
);
61 for (dx
= 0; dx
< nr_dx
; dx
++) {
62 printf("CH%dDX%d:", ch
, dx
);
64 dx_base
+= DMPHY_DX_STRIDE
;
70 static void zq_dump(void)
72 int ch
, zq
, nr_ch
, nr_zq
, i
;
73 void __iomem
*zq_base
;
76 printf("\n--- Impedance Data ---\n");
77 printf(" ZPD ZPU OPD OPU ZDV ODV\n");
81 for (ch
= 0; ch
< nr_ch
; ch
++) {
82 zq_base
= get_phy_base(ch
) + DMPHY_ZQ_BASE
;
85 for (zq
= 0; zq
< nr_zq
; zq
++) {
86 printf("CH%dZQ%d:", ch
, zq
);
88 dr
= readl(zq_base
+ DMPHY_ZQ_DR
);
89 for (i
= 0; i
< 4; i
++) {
90 printf(FS PRINTF_FORMAT
, dr
& 0x7f);
94 pr
= readl(zq_base
+ DMPHY_ZQ_PR
);
95 for (i
= 0; i
< 2; i
++) {
96 printf(FS PRINTF_FORMAT
, pr
& 0xf);
100 zq_base
+= DMPHY_ZQ_STRIDE
;
106 static void __wbdl_dump(void __iomem
*dx_base
)
108 print_bdl(dx_base
+ DMPHY_DX_BDLR0
, 4);
109 print_bdl(dx_base
+ DMPHY_DX_BDLR1
, 4);
110 print_bdl(dx_base
+ DMPHY_DX_BDLR2
, 2);
112 printf(FS
"(+" PRINTF_FORMAT
")",
113 readl(dx_base
+ DMPHY_DX_LCDLR1
) & 0xff);
116 static void wbdl_dump(void)
118 printf("\n--- Write Bit Delay Line ---\n");
119 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n");
121 dump_loop(&__wbdl_dump
);
124 static void __rbdl_dump(void __iomem
*dx_base
)
126 print_bdl(dx_base
+ DMPHY_DX_BDLR3
, 4);
127 print_bdl(dx_base
+ DMPHY_DX_BDLR4
, 4);
128 print_bdl(dx_base
+ DMPHY_DX_BDLR5
, 1);
130 printf(FS
"(+" PRINTF_FORMAT
")",
131 (readl(dx_base
+ DMPHY_DX_LCDLR1
) >> 8) & 0xff);
133 printf(FS
"(+" PRINTF_FORMAT
")",
134 (readl(dx_base
+ DMPHY_DX_LCDLR1
) >> 16) & 0xff);
137 static void rbdl_dump(void)
139 printf("\n--- Read Bit Delay Line ---\n");
140 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD) (RDQSND)\n");
142 dump_loop(&__rbdl_dump
);
145 static void __wld_dump(void __iomem
*dx_base
)
148 u32 lcdlr0
= readl(dx_base
+ DMPHY_DX_LCDLR0
);
149 u32 gtr
= readl(dx_base
+ DMPHY_DX_GTR
);
151 for (rank
= 0; rank
< 4; rank
++) {
152 u32 wld
= (lcdlr0
>> (8 * rank
)) & 0xff; /* Delay */
153 u32 wlsl
= (gtr
>> (12 + 2 * rank
)) & 0x3; /* System Latency */
155 printf(FS PRINTF_FORMAT
"%sT", wld
,
156 wlsl
== 0 ? "-1" : wlsl
== 1 ? "+0" : "+1");
160 static void wld_dump(void)
162 printf("\n--- Write Leveling Delay ---\n");
163 printf(" Rank0 Rank1 Rank2 Rank3\n");
165 dump_loop(&__wld_dump
);
168 static void __dqsgd_dump(void __iomem
*dx_base
)
171 u32 lcdlr2
= readl(dx_base
+ DMPHY_DX_LCDLR2
);
172 u32 gtr
= readl(dx_base
+ DMPHY_DX_GTR
);
174 for (rank
= 0; rank
< 4; rank
++) {
175 u32 dqsgd
= (lcdlr2
>> (8 * rank
)) & 0xff; /* Delay */
176 u32 dgsl
= (gtr
>> (3 * rank
)) & 0x7; /* System Latency */
178 printf(FS PRINTF_FORMAT
"+%dT", dqsgd
, dgsl
);
182 static void dqsgd_dump(void)
184 printf("\n--- DQS Gating Delay ---\n");
185 printf(" Rank0 Rank1 Rank2 Rank3\n");
187 dump_loop(&__dqsgd_dump
);
190 static void __mdl_dump(void __iomem
*dx_base
)
193 u32 mdl
= readl(dx_base
+ DMPHY_DX_MDLR
);
195 for (i
= 0; i
< 3; i
++)
196 printf(FS PRINTF_FORMAT
, (mdl
>> (8 * i
)) & 0xff);
199 static void mdl_dump(void)
201 printf("\n--- Master Delay Line ---\n");
202 printf(" IPRD TPRD MDLD\n");
204 dump_loop(&__mdl_dump
);
207 #define REG_DUMP(x) \
208 { int ofst = DMPHY_ ## x; void __iomem *reg = phy_base + ofst; \
209 printf("%3d: %-10s: %p : %08x\n", \
210 ofst >> DMPHY_SHIFT, #x, reg, readl(reg)); }
212 #define DX_REG_DUMP(dx, x) \
213 { int ofst = DMPHY_DX_BASE + DMPHY_DX_STRIDE * (dx) + \
215 void __iomem *reg = phy_base + ofst; \
216 printf("%3d: DX%d%-7s: %p : %08x\n", \
217 ofst >> DMPHY_SHIFT, (dx), #x, reg, readl(reg)); }
219 static void reg_dump(void)
221 int ch
, dx
, nr_ch
, nr_dx
;
222 void __iomem
*phy_base
;
224 printf("\n--- DDR PHY registers ---\n");
228 for (ch
= 0; ch
< nr_ch
; ch
++) {
229 phy_base
= get_phy_base(ch
);
230 nr_dx
= get_nr_datx8(ch
);
232 printf("== Ch%d ==\n", ch
);
233 printf(" No: Name : Address : Data\n");
263 for (dx
= 0; dx
< nr_dx
; dx
++) {
264 DX_REG_DUMP(dx
, GCR0
);
265 DX_REG_DUMP(dx
, GCR1
);
266 DX_REG_DUMP(dx
, GCR2
);
267 DX_REG_DUMP(dx
, GCR3
);
268 DX_REG_DUMP(dx
, GTR
);
273 static int do_ddrm(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
280 if (!strcmp(cmd
, "zq") || !strcmp(cmd
, "all"))
283 if (!strcmp(cmd
, "wbdl") || !strcmp(cmd
, "all"))
286 if (!strcmp(cmd
, "rbdl") || !strcmp(cmd
, "all"))
289 if (!strcmp(cmd
, "wld") || !strcmp(cmd
, "all"))
292 if (!strcmp(cmd
, "dqsgd") || !strcmp(cmd
, "all"))
295 if (!strcmp(cmd
, "mdl") || !strcmp(cmd
, "all"))
298 if (!strcmp(cmd
, "reg") || !strcmp(cmd
, "all"))
306 "UniPhier DDR PHY parameters dumper",
307 "- dump all of the following\n"
308 "ddrm zq - dump Impedance Data\n"
309 "ddrm wbdl - dump Write Bit Delay\n"
310 "ddrm rbdl - dump Read Bit Delay\n"
311 "ddrm wld - dump Write Leveling\n"
312 "ddrm dqsgd - dump DQS Gating Delay\n"
313 "ddrm mdl - dump Master Delay Line\n"
314 "ddrm reg - dump registers\n"