blob: dbbefd424b9abec52d5eb8b012b7d66affbfc5ae [file] [log] [blame]
Masahiro Yamadac67b2af2014-12-19 20:20:53 +09001/*
Masahiro Yamadaf6e7f072015-05-29 17:30:00 +09002 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
Masahiro Yamadac67b2af2014-12-19 20:20:53 +09003 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
Masahiro Yamadaf6e7f072015-05-29 17:30:00 +09008#include <linux/io.h>
Masahiro Yamadaa86ac952015-02-27 02:26:44 +09009#include <mach/ddrphy-regs.h>
Masahiro Yamadac67b2af2014-12-19 20:20:53 +090010
11/* Select either decimal or hexadecimal */
12#if 1
13#define PRINTF_FORMAT "%2d"
14#else
15#define PRINTF_FORMAT "%02x"
16#endif
17/* field separator */
18#define FS " "
19
20static u32 read_bdl(struct ddrphy_datx8 __iomem *dx, int index)
21{
22 return (readl(&dx->bdlr[index / 5]) >> (index % 5 * 6)) & 0x3f;
23}
24
25static void dump_loop(void (*callback)(struct ddrphy_datx8 __iomem *))
26{
27 int ch, p, dx;
28 struct ddrphy __iomem *phy;
29
30 for (ch = 0; ch < NR_DDRCH; ch++) {
31 for (p = 0; p < NR_DDRPHY_PER_CH; p++) {
32 phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p);
33
34 for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
35 printf("CH%dP%dDX%d:", ch, p, dx);
36 (*callback)(&phy->dx[dx]);
37 printf("\n");
38 }
39 }
40 }
41}
42
43static void __wbdl_dump(struct ddrphy_datx8 __iomem *dx)
44{
45 int i;
46
47 for (i = 0; i < 10; i++)
48 printf(FS PRINTF_FORMAT, read_bdl(dx, i));
49
50 printf(FS "(+" PRINTF_FORMAT ")", readl(&dx->lcdlr[1]) & 0xff);
51}
52
53void wbdl_dump(void)
54{
55 printf("\n--- Write Bit Delay Line ---\n");
56 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n");
57
58 dump_loop(&__wbdl_dump);
59}
60
61static void __rbdl_dump(struct ddrphy_datx8 __iomem *dx)
62{
63 int i;
64
65 for (i = 15; i < 24; i++)
66 printf(FS PRINTF_FORMAT, read_bdl(dx, i));
67
68 printf(FS "(+" PRINTF_FORMAT ")", (readl(&dx->lcdlr[1]) >> 8) & 0xff);
69}
70
71void rbdl_dump(void)
72{
73 printf("\n--- Read Bit Delay Line ---\n");
74 printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD)\n");
75
76 dump_loop(&__rbdl_dump);
77}
78
79static void __wld_dump(struct ddrphy_datx8 __iomem *dx)
80{
81 int rank;
82 u32 lcdlr0 = readl(&dx->lcdlr[0]);
83 u32 gtr = readl(&dx->gtr);
84
85 for (rank = 0; rank < 4; rank++) {
86 u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */
87 u32 wlsl = (gtr >> (12 + 2 * rank)) & 0x3; /* System Latency */
88
89 printf(FS PRINTF_FORMAT "%sT", wld,
90 wlsl == 0 ? "-1" : wlsl == 1 ? "+0" : "+1");
91 }
92}
93
94void wld_dump(void)
95{
96 printf("\n--- Write Leveling Delay ---\n");
97 printf(" Rank0 Rank1 Rank2 Rank3\n");
98
99 dump_loop(&__wld_dump);
100}
101
102static void __dqsgd_dump(struct ddrphy_datx8 __iomem *dx)
103{
104 int rank;
105 u32 lcdlr2 = readl(&dx->lcdlr[2]);
106 u32 gtr = readl(&dx->gtr);
107
108 for (rank = 0; rank < 4; rank++) {
109 u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */
110 u32 dgsl = (gtr >> (3 * rank)) & 0x7; /* System Latency */
111
112 printf(FS PRINTF_FORMAT "+%dT", dqsgd, dgsl);
113 }
114}
115
116void dqsgd_dump(void)
117{
118 printf("\n--- DQS Gating Delay ---\n");
119 printf(" Rank0 Rank1 Rank2 Rank3\n");
120
121 dump_loop(&__dqsgd_dump);
122}
123
124static void __mdl_dump(struct ddrphy_datx8 __iomem *dx)
125{
126 int i;
127 u32 mdl = readl(&dx->mdlr);
128 for (i = 0; i < 3; i++)
129 printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
130}
131
132void mdl_dump(void)
133{
134 printf("\n--- Master Delay Line ---\n");
135 printf(" IPRD TPRD MDLD\n");
136
137 dump_loop(&__mdl_dump);
138}
139
140#define REG_DUMP(x) \
141 { u32 __iomem *p = &phy->x; printf("%3d: %-10s: %p : %08x\n", \
142 p - (u32 *)phy, #x, p, readl(p)); }
143
144void reg_dump(void)
145{
146 int ch, p;
147 struct ddrphy __iomem *phy;
148
149 printf("\n--- DDR PHY registers ---\n");
150
151 for (ch = 0; ch < NR_DDRCH; ch++) {
152 for (p = 0; p < NR_DDRPHY_PER_CH; p++) {
153 printf("== Ch%d, PHY%d ==\n", ch, p);
154 printf(" No: Name : Address : Data\n");
155
156 phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p);
157
158 REG_DUMP(ridr);
159 REG_DUMP(pir);
160 REG_DUMP(pgcr[0]);
161 REG_DUMP(pgcr[1]);
162 REG_DUMP(pgsr[0]);
163 REG_DUMP(pgsr[1]);
164 REG_DUMP(pllcr);
165 REG_DUMP(ptr[0]);
166 REG_DUMP(ptr[1]);
167 REG_DUMP(ptr[2]);
168 REG_DUMP(ptr[3]);
169 REG_DUMP(ptr[4]);
170 REG_DUMP(acmdlr);
171 REG_DUMP(acbdlr);
172 REG_DUMP(dxccr);
173 REG_DUMP(dsgcr);
174 REG_DUMP(dcr);
175 REG_DUMP(dtpr[0]);
176 REG_DUMP(dtpr[1]);
177 REG_DUMP(dtpr[2]);
178 REG_DUMP(mr0);
179 REG_DUMP(mr1);
180 REG_DUMP(mr2);
181 REG_DUMP(mr3);
182 REG_DUMP(dx[0].gcr);
183 REG_DUMP(dx[0].gtr);
184 REG_DUMP(dx[1].gcr);
185 REG_DUMP(dx[1].gtr);
186 }
187 }
188}
189
190static int do_ddr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
191{
192 char *cmd = argv[1];
193
194 if (argc == 1)
195 cmd = "all";
196
197 if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all"))
198 wbdl_dump();
199
200 if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all"))
201 rbdl_dump();
202
203 if (!strcmp(cmd, "wld") || !strcmp(cmd, "all"))
204 wld_dump();
205
206 if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all"))
207 dqsgd_dump();
208
209 if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all"))
210 mdl_dump();
211
212 if (!strcmp(cmd, "reg") || !strcmp(cmd, "all"))
213 reg_dump();
214
215 return 0;
216}
217
218U_BOOT_CMD(
219 ddr, 2, 1, do_ddr,
220 "UniPhier DDR PHY parameters dumper",
221 "- dump all of the followings\n"
222 "ddr wbdl - dump Write Bit Delay\n"
223 "ddr rbdl - dump Read Bit Delay\n"
224 "ddr wld - dump Write Leveling\n"
225 "ddr dqsgd - dump DQS Gating Delay\n"
226 "ddr mdl - dump Master Delay Line\n"
227 "ddr reg - dump registers\n"
228);