]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - arch/arm/mach-uniphier/cmd_ddrphy.c
ARM: UniPhier: replace <asm/io.h> with <linux/io.h>
[karo-tx-uboot.git] / arch / arm / mach-uniphier / cmd_ddrphy.c
1 /*
2  * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <linux/io.h>
9 #include <mach/ddrphy-regs.h>
10
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
20 static u32 read_bdl(struct ddrphy_datx8 __iomem *dx, int index)
21 {
22         return (readl(&dx->bdlr[index / 5]) >> (index % 5 * 6)) & 0x3f;
23 }
24
25 static 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
43 static 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
53 void 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
61 static 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
71 void 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
79 static 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
94 void 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
102 static 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
116 void 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
124 static 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
132 void 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
144 void 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
190 static 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
218 U_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 );