19ca66164SMasahiro Yamada /* 24e3d8406SMasahiro Yamada * Copyright (C) 2014 Panasonic Corporation 34e3d8406SMasahiro Yamada * Copyright (C) 2015-2016 Socionext Inc. 44e3d8406SMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 59ca66164SMasahiro Yamada * 69ca66164SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 79ca66164SMasahiro Yamada */ 89ca66164SMasahiro Yamada 99ca66164SMasahiro Yamada #include <common.h> 109ca66164SMasahiro Yamada #include <linux/io.h> 111b1f2319SMasahiro Yamada #include <linux/sizes.h> 12107b3fb4SMasahiro Yamada 131b1f2319SMasahiro Yamada #include "../soc-info.h" 14107b3fb4SMasahiro Yamada #include "ddrphy-regs.h" 159ca66164SMasahiro Yamada 169ca66164SMasahiro Yamada /* Select either decimal or hexadecimal */ 179ca66164SMasahiro Yamada #if 1 189ca66164SMasahiro Yamada #define PRINTF_FORMAT "%2d" 199ca66164SMasahiro Yamada #else 209ca66164SMasahiro Yamada #define PRINTF_FORMAT "%02x" 219ca66164SMasahiro Yamada #endif 229ca66164SMasahiro Yamada /* field separator */ 239ca66164SMasahiro Yamada #define FS " " 249ca66164SMasahiro Yamada 25*adf55f63SMasahiro Yamada struct phy_param { 26*adf55f63SMasahiro Yamada resource_size_t base; 27*adf55f63SMasahiro Yamada unsigned int nr_dx; 281b1f2319SMasahiro Yamada }; 291b1f2319SMasahiro Yamada 30*adf55f63SMasahiro Yamada static const struct phy_param uniphier_ld4_phy_param[] = { 31*adf55f63SMasahiro Yamada { .base = 0x5bc01000, .nr_dx = 2, }, 32*adf55f63SMasahiro Yamada { .base = 0x5be01000, .nr_dx = 2, }, 33*adf55f63SMasahiro Yamada { /* sentinel */ } 341b1f2319SMasahiro Yamada }; 351b1f2319SMasahiro Yamada 36*adf55f63SMasahiro Yamada static const struct phy_param uniphier_pro4_phy_param[] = { 37*adf55f63SMasahiro Yamada { .base = 0x5bc01000, .nr_dx = 2, }, 38*adf55f63SMasahiro Yamada { .base = 0x5bc02000, .nr_dx = 2, }, 39*adf55f63SMasahiro Yamada { .base = 0x5be01000, .nr_dx = 2, }, 40*adf55f63SMasahiro Yamada { .base = 0x5be02000, .nr_dx = 2, }, 41*adf55f63SMasahiro Yamada { /* sentinel */ } 42*adf55f63SMasahiro Yamada }; 43*adf55f63SMasahiro Yamada 44*adf55f63SMasahiro Yamada static const struct phy_param uniphier_sld8_phy_param[] = { 45*adf55f63SMasahiro Yamada { .base = 0x5bc01000, .nr_dx = 2, }, 46*adf55f63SMasahiro Yamada { .base = 0x5be01000, .nr_dx = 2, }, 47*adf55f63SMasahiro Yamada { /* sentinel */ } 481b1f2319SMasahiro Yamada }; 491b1f2319SMasahiro Yamada 506dd34ae4SMasahiro Yamada static void print_bdl(void __iomem *reg, int n) 519ca66164SMasahiro Yamada { 526dd34ae4SMasahiro Yamada u32 val = readl(reg); 536dd34ae4SMasahiro Yamada int i; 546dd34ae4SMasahiro Yamada 556dd34ae4SMasahiro Yamada for (i = 0; i < n; i++) 566dd34ae4SMasahiro Yamada printf(FS PRINTF_FORMAT, (val >> i * 6) & 0x3f); 579ca66164SMasahiro Yamada } 589ca66164SMasahiro Yamada 59*adf55f63SMasahiro Yamada static void dump_loop(const struct phy_param *phy_param, 606dd34ae4SMasahiro Yamada void (*callback)(void __iomem *)) 619ca66164SMasahiro Yamada { 626dd34ae4SMasahiro Yamada void __iomem *phy_base, *dx_base; 631b1f2319SMasahiro Yamada int p, dx; 649ca66164SMasahiro Yamada 65*adf55f63SMasahiro Yamada for (p = 0; phy_param->base; phy_param++, p++) { 66*adf55f63SMasahiro Yamada phy_base = ioremap(phy_param->base, SZ_4K); 676dd34ae4SMasahiro Yamada dx_base = phy_base + PHY_DX_BASE; 689ca66164SMasahiro Yamada 69*adf55f63SMasahiro Yamada for (dx = 0; dx < phy_param->nr_dx; dx++) { 701b1f2319SMasahiro Yamada printf("PHY%dDX%d:", p, dx); 716dd34ae4SMasahiro Yamada (*callback)(dx_base); 726dd34ae4SMasahiro Yamada dx_base += PHY_DX_STRIDE; 739ca66164SMasahiro Yamada printf("\n"); 749ca66164SMasahiro Yamada } 751b1f2319SMasahiro Yamada 766dd34ae4SMasahiro Yamada iounmap(phy_base); 779ca66164SMasahiro Yamada } 789ca66164SMasahiro Yamada } 799ca66164SMasahiro Yamada 806dd34ae4SMasahiro Yamada static void __wbdl_dump(void __iomem *dx_base) 819ca66164SMasahiro Yamada { 826dd34ae4SMasahiro Yamada print_bdl(dx_base + PHY_DX_BDLR0, 5); 836dd34ae4SMasahiro Yamada print_bdl(dx_base + PHY_DX_BDLR1, 5); 849ca66164SMasahiro Yamada 856dd34ae4SMasahiro Yamada printf(FS "(+" PRINTF_FORMAT ")", 866dd34ae4SMasahiro Yamada readl(dx_base + PHY_DX_LCDLR1) & 0xff); 879ca66164SMasahiro Yamada } 889ca66164SMasahiro Yamada 89*adf55f63SMasahiro Yamada static void wbdl_dump(const struct phy_param *phy_param) 909ca66164SMasahiro Yamada { 919ca66164SMasahiro Yamada printf("\n--- Write Bit Delay Line ---\n"); 929ca66164SMasahiro Yamada printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n"); 939ca66164SMasahiro Yamada 94*adf55f63SMasahiro Yamada dump_loop(phy_param, &__wbdl_dump); 959ca66164SMasahiro Yamada } 969ca66164SMasahiro Yamada 976dd34ae4SMasahiro Yamada static void __rbdl_dump(void __iomem *dx_base) 989ca66164SMasahiro Yamada { 996dd34ae4SMasahiro Yamada print_bdl(dx_base + PHY_DX_BDLR3, 5); 1006dd34ae4SMasahiro Yamada print_bdl(dx_base + PHY_DX_BDLR4, 4); 1019ca66164SMasahiro Yamada 1026dd34ae4SMasahiro Yamada printf(FS "(+" PRINTF_FORMAT ")", 1036dd34ae4SMasahiro Yamada (readl(dx_base + PHY_DX_LCDLR1) >> 8) & 0xff); 1049ca66164SMasahiro Yamada } 1059ca66164SMasahiro Yamada 106*adf55f63SMasahiro Yamada static void rbdl_dump(const struct phy_param *phy_param) 1079ca66164SMasahiro Yamada { 1089ca66164SMasahiro Yamada printf("\n--- Read Bit Delay Line ---\n"); 1099ca66164SMasahiro Yamada printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD)\n"); 1109ca66164SMasahiro Yamada 111*adf55f63SMasahiro Yamada dump_loop(phy_param, &__rbdl_dump); 1129ca66164SMasahiro Yamada } 1139ca66164SMasahiro Yamada 1146dd34ae4SMasahiro Yamada static void __wld_dump(void __iomem *dx_base) 1159ca66164SMasahiro Yamada { 1169ca66164SMasahiro Yamada int rank; 1176dd34ae4SMasahiro Yamada u32 lcdlr0 = readl(dx_base + PHY_DX_LCDLR0); 1186dd34ae4SMasahiro Yamada u32 gtr = readl(dx_base + PHY_DX_GTR); 1199ca66164SMasahiro Yamada 1209ca66164SMasahiro Yamada for (rank = 0; rank < 4; rank++) { 1219ca66164SMasahiro Yamada u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */ 1229ca66164SMasahiro Yamada u32 wlsl = (gtr >> (12 + 2 * rank)) & 0x3; /* System Latency */ 1239ca66164SMasahiro Yamada 1249ca66164SMasahiro Yamada printf(FS PRINTF_FORMAT "%sT", wld, 1259ca66164SMasahiro Yamada wlsl == 0 ? "-1" : wlsl == 1 ? "+0" : "+1"); 1269ca66164SMasahiro Yamada } 1279ca66164SMasahiro Yamada } 1289ca66164SMasahiro Yamada 129*adf55f63SMasahiro Yamada static void wld_dump(const struct phy_param *phy_param) 1309ca66164SMasahiro Yamada { 1319ca66164SMasahiro Yamada printf("\n--- Write Leveling Delay ---\n"); 1329ca66164SMasahiro Yamada printf(" Rank0 Rank1 Rank2 Rank3\n"); 1339ca66164SMasahiro Yamada 134*adf55f63SMasahiro Yamada dump_loop(phy_param, &__wld_dump); 1359ca66164SMasahiro Yamada } 1369ca66164SMasahiro Yamada 1376dd34ae4SMasahiro Yamada static void __dqsgd_dump(void __iomem *dx_base) 1389ca66164SMasahiro Yamada { 1399ca66164SMasahiro Yamada int rank; 1406dd34ae4SMasahiro Yamada u32 lcdlr2 = readl(dx_base + PHY_DX_LCDLR2); 1416dd34ae4SMasahiro Yamada u32 gtr = readl(dx_base + PHY_DX_GTR); 1429ca66164SMasahiro Yamada 1439ca66164SMasahiro Yamada for (rank = 0; rank < 4; rank++) { 1449ca66164SMasahiro Yamada u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */ 1459ca66164SMasahiro Yamada u32 dgsl = (gtr >> (3 * rank)) & 0x7; /* System Latency */ 1469ca66164SMasahiro Yamada 1479ca66164SMasahiro Yamada printf(FS PRINTF_FORMAT "+%dT", dqsgd, dgsl); 1489ca66164SMasahiro Yamada } 1499ca66164SMasahiro Yamada } 1509ca66164SMasahiro Yamada 151*adf55f63SMasahiro Yamada static void dqsgd_dump(const struct phy_param *phy_param) 1529ca66164SMasahiro Yamada { 1539ca66164SMasahiro Yamada printf("\n--- DQS Gating Delay ---\n"); 1549ca66164SMasahiro Yamada printf(" Rank0 Rank1 Rank2 Rank3\n"); 1559ca66164SMasahiro Yamada 156*adf55f63SMasahiro Yamada dump_loop(phy_param, &__dqsgd_dump); 1579ca66164SMasahiro Yamada } 1589ca66164SMasahiro Yamada 1596dd34ae4SMasahiro Yamada static void __mdl_dump(void __iomem *dx_base) 1609ca66164SMasahiro Yamada { 1619ca66164SMasahiro Yamada int i; 1626dd34ae4SMasahiro Yamada u32 mdl = readl(dx_base + PHY_DX_MDLR); 1639ca66164SMasahiro Yamada for (i = 0; i < 3; i++) 1649ca66164SMasahiro Yamada printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff); 1659ca66164SMasahiro Yamada } 1669ca66164SMasahiro Yamada 167*adf55f63SMasahiro Yamada static void mdl_dump(const struct phy_param *phy_param) 1689ca66164SMasahiro Yamada { 1699ca66164SMasahiro Yamada printf("\n--- Master Delay Line ---\n"); 1709ca66164SMasahiro Yamada printf(" IPRD TPRD MDLD\n"); 1719ca66164SMasahiro Yamada 172*adf55f63SMasahiro Yamada dump_loop(phy_param, &__mdl_dump); 1739ca66164SMasahiro Yamada } 1749ca66164SMasahiro Yamada 1759ca66164SMasahiro Yamada #define REG_DUMP(x) \ 1766dd34ae4SMasahiro Yamada { int ofst = PHY_ ## x; void __iomem *reg = phy_base + ofst; \ 1776dd34ae4SMasahiro Yamada printf("%3d: %-10s: %p : %08x\n", \ 1786dd34ae4SMasahiro Yamada ofst >> PHY_REG_SHIFT, #x, reg, readl(reg)); } 1796dd34ae4SMasahiro Yamada 1806dd34ae4SMasahiro Yamada #define DX_REG_DUMP(dx, x) \ 1816dd34ae4SMasahiro Yamada { int ofst = PHY_DX_BASE + PHY_DX_STRIDE * (dx) + \ 1826dd34ae4SMasahiro Yamada PHY_DX_## x; \ 1836dd34ae4SMasahiro Yamada void __iomem *reg = phy_base + ofst; \ 1846dd34ae4SMasahiro Yamada printf("%3d: DX%d%-7s: %p : %08x\n", \ 1856dd34ae4SMasahiro Yamada ofst >> PHY_REG_SHIFT, (dx), #x, reg, readl(reg)); } 1869ca66164SMasahiro Yamada 187*adf55f63SMasahiro Yamada static void reg_dump(const struct phy_param *phy_param) 1889ca66164SMasahiro Yamada { 1896dd34ae4SMasahiro Yamada void __iomem *phy_base; 1906dd34ae4SMasahiro Yamada int p, dx; 1919ca66164SMasahiro Yamada 1929ca66164SMasahiro Yamada printf("\n--- DDR PHY registers ---\n"); 1939ca66164SMasahiro Yamada 194*adf55f63SMasahiro Yamada for (p = 0; phy_param->base; phy_param++, p++) { 195*adf55f63SMasahiro Yamada phy_base = ioremap(phy_param->base, SZ_4K); 1969ca66164SMasahiro Yamada 1976dd34ae4SMasahiro Yamada printf("== PHY%d (base: %p) ==\n", p, phy_base); 1981b1f2319SMasahiro Yamada printf(" No: Name : Address : Data\n"); 1999ca66164SMasahiro Yamada 2006dd34ae4SMasahiro Yamada REG_DUMP(RIDR); 2016dd34ae4SMasahiro Yamada REG_DUMP(PIR); 2026dd34ae4SMasahiro Yamada REG_DUMP(PGCR0); 2036dd34ae4SMasahiro Yamada REG_DUMP(PGCR1); 2046dd34ae4SMasahiro Yamada REG_DUMP(PGSR0); 2056dd34ae4SMasahiro Yamada REG_DUMP(PGSR1); 2066dd34ae4SMasahiro Yamada REG_DUMP(PLLCR); 2076dd34ae4SMasahiro Yamada REG_DUMP(PTR0); 2086dd34ae4SMasahiro Yamada REG_DUMP(PTR1); 2096dd34ae4SMasahiro Yamada REG_DUMP(PTR2); 2106dd34ae4SMasahiro Yamada REG_DUMP(PTR3); 2116dd34ae4SMasahiro Yamada REG_DUMP(PTR4); 2126dd34ae4SMasahiro Yamada REG_DUMP(ACMDLR); 2136dd34ae4SMasahiro Yamada REG_DUMP(ACBDLR); 2146dd34ae4SMasahiro Yamada REG_DUMP(DXCCR); 2156dd34ae4SMasahiro Yamada REG_DUMP(DSGCR); 2166dd34ae4SMasahiro Yamada REG_DUMP(DCR); 2176dd34ae4SMasahiro Yamada REG_DUMP(DTPR0); 2186dd34ae4SMasahiro Yamada REG_DUMP(DTPR1); 2196dd34ae4SMasahiro Yamada REG_DUMP(DTPR2); 2206dd34ae4SMasahiro Yamada REG_DUMP(MR0); 2216dd34ae4SMasahiro Yamada REG_DUMP(MR1); 2226dd34ae4SMasahiro Yamada REG_DUMP(MR2); 2236dd34ae4SMasahiro Yamada REG_DUMP(MR3); 2241b1f2319SMasahiro Yamada 225*adf55f63SMasahiro Yamada for (dx = 0; dx < phy_param->nr_dx; dx++) { 2266dd34ae4SMasahiro Yamada DX_REG_DUMP(dx, GCR); 2276dd34ae4SMasahiro Yamada DX_REG_DUMP(dx, GTR); 2286dd34ae4SMasahiro Yamada } 2296dd34ae4SMasahiro Yamada 2306dd34ae4SMasahiro Yamada iounmap(phy_base); 2319ca66164SMasahiro Yamada } 2329ca66164SMasahiro Yamada } 2339ca66164SMasahiro Yamada 2349ca66164SMasahiro Yamada static int do_ddr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 2359ca66164SMasahiro Yamada { 2369ca66164SMasahiro Yamada char *cmd = argv[1]; 237*adf55f63SMasahiro Yamada const struct phy_param *phy_param; 2381b1f2319SMasahiro Yamada 2391b1f2319SMasahiro Yamada switch (uniphier_get_soc_type()) { 2401b1f2319SMasahiro Yamada case SOC_UNIPHIER_LD4: 241*adf55f63SMasahiro Yamada phy_param = uniphier_ld4_phy_param; 2421b1f2319SMasahiro Yamada break; 2431b1f2319SMasahiro Yamada case SOC_UNIPHIER_PRO4: 244*adf55f63SMasahiro Yamada phy_param = uniphier_pro4_phy_param; 2451b1f2319SMasahiro Yamada break; 2461b1f2319SMasahiro Yamada case SOC_UNIPHIER_SLD8: 247*adf55f63SMasahiro Yamada phy_param = uniphier_sld8_phy_param; 2481b1f2319SMasahiro Yamada break; 2491b1f2319SMasahiro Yamada default: 2501b1f2319SMasahiro Yamada printf("unsupported SoC\n"); 2511b1f2319SMasahiro Yamada return CMD_RET_FAILURE; 2521b1f2319SMasahiro Yamada } 2539ca66164SMasahiro Yamada 2549ca66164SMasahiro Yamada if (argc == 1) 2559ca66164SMasahiro Yamada cmd = "all"; 2569ca66164SMasahiro Yamada 2579ca66164SMasahiro Yamada if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all")) 258*adf55f63SMasahiro Yamada wbdl_dump(phy_param); 2599ca66164SMasahiro Yamada 2609ca66164SMasahiro Yamada if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all")) 261*adf55f63SMasahiro Yamada rbdl_dump(phy_param); 2629ca66164SMasahiro Yamada 2639ca66164SMasahiro Yamada if (!strcmp(cmd, "wld") || !strcmp(cmd, "all")) 264*adf55f63SMasahiro Yamada wld_dump(phy_param); 2659ca66164SMasahiro Yamada 2669ca66164SMasahiro Yamada if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all")) 267*adf55f63SMasahiro Yamada dqsgd_dump(phy_param); 2689ca66164SMasahiro Yamada 2699ca66164SMasahiro Yamada if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all")) 270*adf55f63SMasahiro Yamada mdl_dump(phy_param); 2719ca66164SMasahiro Yamada 2729ca66164SMasahiro Yamada if (!strcmp(cmd, "reg") || !strcmp(cmd, "all")) 273*adf55f63SMasahiro Yamada reg_dump(phy_param); 2749ca66164SMasahiro Yamada 2751b1f2319SMasahiro Yamada return CMD_RET_SUCCESS; 2769ca66164SMasahiro Yamada } 2779ca66164SMasahiro Yamada 2789ca66164SMasahiro Yamada U_BOOT_CMD( 2799ca66164SMasahiro Yamada ddr, 2, 1, do_ddr, 2809ca66164SMasahiro Yamada "UniPhier DDR PHY parameters dumper", 281c21fc7e2SMasahiro Yamada "- dump all of the following\n" 2829ca66164SMasahiro Yamada "ddr wbdl - dump Write Bit Delay\n" 2839ca66164SMasahiro Yamada "ddr rbdl - dump Read Bit Delay\n" 2849ca66164SMasahiro Yamada "ddr wld - dump Write Leveling\n" 2859ca66164SMasahiro Yamada "ddr dqsgd - dump DQS Gating Delay\n" 2869ca66164SMasahiro Yamada "ddr mdl - dump Master Delay Line\n" 2879ca66164SMasahiro Yamada "ddr reg - dump registers\n" 2889ca66164SMasahiro Yamada ); 289