]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-uniphier/dram/cmd_ddrmphy.c
c18f099f2c008478396a5effe83b9002a9d9cc2c
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_ch2_width
? 3 : 2;
34 static int get_nr_datx8(int ch
)
38 const struct uniphier_board_data
*bd
= uniphier_get_board_param();
42 width
= bd
->dram_ch0_width
;
45 width
= bd
->dram_ch1_width
;
48 width
= bd
->dram_ch2_width
;
55 static void print_bdl(void __iomem
*reg
, int n
)
60 for (i
= 0; i
< n
; i
++)
61 printf(FS PRINTF_FORMAT
, (val
>> i
* 8) & 0x1f);
64 static void dump_loop(void (*callback
)(void __iomem
*))
66 int ch
, dx
, nr_ch
, nr_dx
;
67 void __iomem
*dx_base
;
71 for (ch
= 0; ch
< nr_ch
; ch
++) {
72 dx_base
= get_phy_base(ch
) + DMPHY_DX_BASE
;
73 nr_dx
= get_nr_datx8(ch
);
75 for (dx
= 0; dx
< nr_dx
; dx
++) {
76 printf("CH%dDX%d:", ch
, dx
);
78 dx_base
+= DMPHY_DX_STRIDE
;
84 static void zq_dump(void)
86 int ch
, zq
, nr_ch
, nr_zq
, i
;
87 void __iomem
*zq_base
;
90 printf("\n--- Impedance Data ---\n");
91 printf(" ZPD ZPU OPD OPU ZDV ODV\n");
95 for (ch
= 0; ch
< nr_ch
; ch
++) {
96 zq_base
= get_phy_base(ch
) + DMPHY_ZQ_BASE
;
99 for (zq
= 0; zq
< nr_zq
; zq
++) {
100 printf("CH%dZQ%d:", ch
, zq
);
102 dr
= readl(zq_base
+ DMPHY_ZQ_DR
);
103 for (i
= 0; i
< 4; i
++) {
104 printf(FS PRINTF_FORMAT
, dr
& 0x7f);
108 pr
= readl(zq_base
+ DMPHY_ZQ_PR
);
109 for (i
= 0; i
< 2; i
++) {
110 printf(FS PRINTF_FORMAT
, pr
& 0xf);
114 zq_base
+= DMPHY_ZQ_STRIDE
;
120 static void __wbdl_dump(void __iomem
*dx_base
)
122 print_bdl(dx_base
+ DMPHY_DX_BDLR0
, 4);
123 print_bdl(dx_base
+ DMPHY_DX_BDLR1
, 4);
124 print_bdl(dx_base
+ DMPHY_DX_BDLR2
, 2);
126 printf(FS
"(+" PRINTF_FORMAT
")",
127 readl(dx_base
+ DMPHY_DX_LCDLR1
) & 0xff);
130 static void wbdl_dump(void)
132 printf("\n--- Write Bit Delay Line ---\n");
133 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n");
135 dump_loop(&__wbdl_dump
);
138 static void __rbdl_dump(void __iomem
*dx_base
)
140 print_bdl(dx_base
+ DMPHY_DX_BDLR3
, 4);
141 print_bdl(dx_base
+ DMPHY_DX_BDLR4
, 4);
142 print_bdl(dx_base
+ DMPHY_DX_BDLR5
, 1);
144 printf(FS
"(+" PRINTF_FORMAT
")",
145 (readl(dx_base
+ DMPHY_DX_LCDLR1
) >> 8) & 0xff);
147 printf(FS
"(+" PRINTF_FORMAT
")",
148 (readl(dx_base
+ DMPHY_DX_LCDLR1
) >> 16) & 0xff);
151 static void rbdl_dump(void)
153 printf("\n--- Read Bit Delay Line ---\n");
154 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD) (RDQSND)\n");
156 dump_loop(&__rbdl_dump
);
159 static void __wld_dump(void __iomem
*dx_base
)
162 u32 lcdlr0
= readl(dx_base
+ DMPHY_DX_LCDLR0
);
163 u32 gtr
= readl(dx_base
+ DMPHY_DX_GTR
);
165 for (rank
= 0; rank
< 4; rank
++) {
166 u32 wld
= (lcdlr0
>> (8 * rank
)) & 0xff; /* Delay */
167 u32 wlsl
= (gtr
>> (12 + 2 * rank
)) & 0x3; /* System Latency */
169 printf(FS PRINTF_FORMAT
"%sT", wld
,
170 wlsl
== 0 ? "-1" : wlsl
== 1 ? "+0" : "+1");
174 static void wld_dump(void)
176 printf("\n--- Write Leveling Delay ---\n");
177 printf(" Rank0 Rank1 Rank2 Rank3\n");
179 dump_loop(&__wld_dump
);
182 static void __dqsgd_dump(void __iomem
*dx_base
)
185 u32 lcdlr2
= readl(dx_base
+ DMPHY_DX_LCDLR2
);
186 u32 gtr
= readl(dx_base
+ DMPHY_DX_GTR
);
188 for (rank
= 0; rank
< 4; rank
++) {
189 u32 dqsgd
= (lcdlr2
>> (8 * rank
)) & 0xff; /* Delay */
190 u32 dgsl
= (gtr
>> (3 * rank
)) & 0x7; /* System Latency */
192 printf(FS PRINTF_FORMAT
"+%dT", dqsgd
, dgsl
);
196 static void dqsgd_dump(void)
198 printf("\n--- DQS Gating Delay ---\n");
199 printf(" Rank0 Rank1 Rank2 Rank3\n");
201 dump_loop(&__dqsgd_dump
);
204 static void __mdl_dump(void __iomem
*dx_base
)
207 u32 mdl
= readl(dx_base
+ DMPHY_DX_MDLR
);
209 for (i
= 0; i
< 3; i
++)
210 printf(FS PRINTF_FORMAT
, (mdl
>> (8 * i
)) & 0xff);
213 static void mdl_dump(void)
215 printf("\n--- Master Delay Line ---\n");
216 printf(" IPRD TPRD MDLD\n");
218 dump_loop(&__mdl_dump
);
221 #define REG_DUMP(x) \
222 { int ofst = DMPHY_ ## x; void __iomem *reg = phy_base + ofst; \
223 printf("%3d: %-10s: %p : %08x\n", \
224 ofst >> DMPHY_SHIFT, #x, reg, readl(reg)); }
226 #define DX_REG_DUMP(dx, x) \
227 { int ofst = DMPHY_DX_BASE + DMPHY_DX_STRIDE * (dx) + \
229 void __iomem *reg = phy_base + ofst; \
230 printf("%3d: DX%d%-7s: %p : %08x\n", \
231 ofst >> DMPHY_SHIFT, (dx), #x, reg, readl(reg)); }
233 static void reg_dump(void)
235 int ch
, dx
, nr_ch
, nr_dx
;
236 void __iomem
*phy_base
;
238 printf("\n--- DDR PHY registers ---\n");
242 for (ch
= 0; ch
< nr_ch
; ch
++) {
243 phy_base
= get_phy_base(ch
);
244 nr_dx
= get_nr_datx8(ch
);
246 printf("== Ch%d ==\n", ch
);
247 printf(" No: Name : Address : Data\n");
277 for (dx
= 0; dx
< nr_dx
; dx
++) {
278 DX_REG_DUMP(dx
, GCR0
);
279 DX_REG_DUMP(dx
, GCR1
);
280 DX_REG_DUMP(dx
, GCR2
);
281 DX_REG_DUMP(dx
, GCR3
);
282 DX_REG_DUMP(dx
, GTR
);
287 static int do_ddrm(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
294 if (!strcmp(cmd
, "zq") || !strcmp(cmd
, "all"))
297 if (!strcmp(cmd
, "wbdl") || !strcmp(cmd
, "all"))
300 if (!strcmp(cmd
, "rbdl") || !strcmp(cmd
, "all"))
303 if (!strcmp(cmd
, "wld") || !strcmp(cmd
, "all"))
306 if (!strcmp(cmd
, "dqsgd") || !strcmp(cmd
, "all"))
309 if (!strcmp(cmd
, "mdl") || !strcmp(cmd
, "all"))
312 if (!strcmp(cmd
, "reg") || !strcmp(cmd
, "all"))
320 "UniPhier DDR PHY parameters dumper",
321 "- dump all of the followings\n"
322 "ddrm zq - dump Impedance Data\n"
323 "ddrm wbdl - dump Write Bit Delay\n"
324 "ddrm rbdl - dump Read Bit Delay\n"
325 "ddrm wld - dump Write Leveling\n"
326 "ddrm dqsgd - dump DQS Gating Delay\n"
327 "ddrm mdl - dump Master Delay Line\n"
328 "ddrm reg - dump registers\n"