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