ARM: uniphier: rework existing DDR PHY code to reuse for LD11 SoC
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Thu, 27 Oct 2016 14:47:07 +0000 (23:47 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Sat, 29 Oct 2016 08:24:30 +0000 (17:24 +0900)
The DDR PHY register view of LD11 is slightly different from that
of LD4/Pro4/sLD8, but it will be possible to share the register
macros (and I want to re-use as much code as possible).  Change
the code in the more flexible form.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
arch/arm/mach-uniphier/dram/cmd_ddrphy.c
arch/arm/mach-uniphier/dram/ddrphy-init.h [new file with mode: 0644]
arch/arm/mach-uniphier/dram/ddrphy-ld4.c
arch/arm/mach-uniphier/dram/ddrphy-regs.h
arch/arm/mach-uniphier/dram/ddrphy-training.c
arch/arm/mach-uniphier/dram/umc-ld4.c
arch/arm/mach-uniphier/dram/umc-pro4.c
arch/arm/mach-uniphier/dram/umc-sld8.c

index 6ac261d..3dae129 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sizes.h>
 
 #include "../soc-info.h"
+#include "ddrphy-init.h"
 #include "ddrphy-regs.h"
 
 /* Select either decimal or hexadecimal */
@@ -40,38 +41,43 @@ static unsigned long uniphier_sld8_base[] = {
        0 /* sentinel */
 };
 
-static u32 read_bdl(struct ddrphy_datx8 __iomem *dx, int index)
+static void print_bdl(void __iomem *reg, int n)
 {
-       return (readl(&dx->bdlr[index / 5]) >> (index % 5 * 6)) & 0x3f;
+       u32 val = readl(reg);
+       int i;
+
+       for (i = 0; i < n; i++)
+               printf(FS PRINTF_FORMAT, (val >> i * 6) & 0x3f);
 }
 
 static void dump_loop(unsigned long *base,
-                     void (*callback)(struct ddrphy_datx8 __iomem *))
+                     void (*callback)(void __iomem *))
 {
-       struct ddrphy __iomem *phy;
+       void __iomem *phy_base, *dx_base;
        int p, dx;
 
        for (p = 0; *base; base++, p++) {
-               phy = ioremap(*base, SZ_4K);
+               phy_base = ioremap(*base, SZ_4K);
+               dx_base = phy_base + PHY_DX_BASE;
 
                for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
                        printf("PHY%dDX%d:", p, dx);
-                       (*callback)(&phy->dx[dx]);
+                       (*callback)(dx_base);
+                       dx_base += PHY_DX_STRIDE;
                        printf("\n");
                }
 
-               iounmap(phy);
+               iounmap(phy_base);
        }
 }
 
-static void __wbdl_dump(struct ddrphy_datx8 __iomem *dx)
+static void __wbdl_dump(void __iomem *dx_base)
 {
-       int i;
+       print_bdl(dx_base + PHY_DX_BDLR0, 5);
+       print_bdl(dx_base + PHY_DX_BDLR1, 5);
 
-       for (i = 0; i < 10; i++)
-               printf(FS PRINTF_FORMAT, read_bdl(dx, i));
-
-       printf(FS "(+" PRINTF_FORMAT ")", readl(&dx->lcdlr[1]) & 0xff);
+       printf(FS "(+" PRINTF_FORMAT ")",
+              readl(dx_base + PHY_DX_LCDLR1) & 0xff);
 }
 
 static void wbdl_dump(unsigned long *base)
@@ -82,14 +88,13 @@ static void wbdl_dump(unsigned long *base)
        dump_loop(base, &__wbdl_dump);
 }
 
-static void __rbdl_dump(struct ddrphy_datx8 __iomem *dx)
+static void __rbdl_dump(void __iomem *dx_base)
 {
-       int i;
-
-       for (i = 15; i < 24; i++)
-               printf(FS PRINTF_FORMAT, read_bdl(dx, i));
+       print_bdl(dx_base + PHY_DX_BDLR3, 5);
+       print_bdl(dx_base + PHY_DX_BDLR4, 4);
 
-       printf(FS "(+" PRINTF_FORMAT ")", (readl(&dx->lcdlr[1]) >> 8) & 0xff);
+       printf(FS "(+" PRINTF_FORMAT ")",
+              (readl(dx_base + PHY_DX_LCDLR1) >> 8) & 0xff);
 }
 
 static void rbdl_dump(unsigned long *base)
@@ -100,11 +105,11 @@ static void rbdl_dump(unsigned long *base)
        dump_loop(base, &__rbdl_dump);
 }
 
-static void __wld_dump(struct ddrphy_datx8 __iomem *dx)
+static void __wld_dump(void __iomem *dx_base)
 {
        int rank;
-       u32 lcdlr0 = readl(&dx->lcdlr[0]);
-       u32 gtr = readl(&dx->gtr);
+       u32 lcdlr0 = readl(dx_base + PHY_DX_LCDLR0);
+       u32 gtr = readl(dx_base + PHY_DX_GTR);
 
        for (rank = 0; rank < 4; rank++) {
                u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */
@@ -123,11 +128,11 @@ static void wld_dump(unsigned long *base)
        dump_loop(base, &__wld_dump);
 }
 
-static void __dqsgd_dump(struct ddrphy_datx8 __iomem *dx)
+static void __dqsgd_dump(void __iomem *dx_base)
 {
        int rank;
-       u32 lcdlr2 = readl(&dx->lcdlr[2]);
-       u32 gtr = readl(&dx->gtr);
+       u32 lcdlr2 = readl(dx_base + PHY_DX_LCDLR2);
+       u32 gtr = readl(dx_base + PHY_DX_GTR);
 
        for (rank = 0; rank < 4; rank++) {
                u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */
@@ -145,10 +150,10 @@ static void dqsgd_dump(unsigned long *base)
        dump_loop(base, &__dqsgd_dump);
 }
 
-static void __mdl_dump(struct ddrphy_datx8 __iomem *dx)
+static void __mdl_dump(void __iomem *dx_base)
 {
        int i;
-       u32 mdl = readl(&dx->mdlr);
+       u32 mdl = readl(dx_base + PHY_DX_MDLR);
        for (i = 0; i < 3; i++)
                printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
 }
@@ -161,53 +166,62 @@ static void mdl_dump(unsigned long *base)
        dump_loop(base, &__mdl_dump);
 }
 
-#define REG_DUMP(x) \
-       { u32 __iomem *p = &phy->x; printf("%3d: %-10s: %p : %08x\n", \
-                                       p - (u32 *)phy, #x, p, readl(p)); }
+#define REG_DUMP(x)                                                    \
+       { int ofst = PHY_ ## x; void __iomem *reg = phy_base + ofst;    \
+               printf("%3d: %-10s: %p : %08x\n",                       \
+                      ofst >> PHY_REG_SHIFT, #x, reg, readl(reg)); }
+
+#define DX_REG_DUMP(dx, x)                                             \
+       { int ofst = PHY_DX_BASE + PHY_DX_STRIDE * (dx) +               \
+                       PHY_DX_## x;                                    \
+               void __iomem *reg = phy_base + ofst;                    \
+               printf("%3d: DX%d%-7s: %p : %08x\n",                    \
+                      ofst >> PHY_REG_SHIFT, (dx), #x, reg, readl(reg)); }
 
 static void reg_dump(unsigned long *base)
 {
-       struct ddrphy __iomem *phy;
-       int p;
+       void __iomem *phy_base;
+       int p, dx;
 
        printf("\n--- DDR PHY registers ---\n");
 
        for (p = 0; *base; base++, p++) {
-               phy = ioremap(*base, SZ_4K);
+               phy_base = ioremap(*base, SZ_4K);
 
-               printf("== PHY%d (base: %p) ==\n", p, phy);
+               printf("== PHY%d (base: %p) ==\n", p, phy_base);
                printf(" No: Name      : Address  : Data\n");
 
-               REG_DUMP(ridr);
-               REG_DUMP(pir);
-               REG_DUMP(pgcr[0]);
-               REG_DUMP(pgcr[1]);
-               REG_DUMP(pgsr[0]);
-               REG_DUMP(pgsr[1]);
-               REG_DUMP(pllcr);
-               REG_DUMP(ptr[0]);
-               REG_DUMP(ptr[1]);
-               REG_DUMP(ptr[2]);
-               REG_DUMP(ptr[3]);
-               REG_DUMP(ptr[4]);
-               REG_DUMP(acmdlr);
-               REG_DUMP(acbdlr);
-               REG_DUMP(dxccr);
-               REG_DUMP(dsgcr);
-               REG_DUMP(dcr);
-               REG_DUMP(dtpr[0]);
-               REG_DUMP(dtpr[1]);
-               REG_DUMP(dtpr[2]);
-               REG_DUMP(mr0);
-               REG_DUMP(mr1);
-               REG_DUMP(mr2);
-               REG_DUMP(mr3);
-               REG_DUMP(dx[0].gcr);
-               REG_DUMP(dx[0].gtr);
-               REG_DUMP(dx[1].gcr);
-               REG_DUMP(dx[1].gtr);
-
-               iounmap(phy);
+               REG_DUMP(RIDR);
+               REG_DUMP(PIR);
+               REG_DUMP(PGCR0);
+               REG_DUMP(PGCR1);
+               REG_DUMP(PGSR0);
+               REG_DUMP(PGSR1);
+               REG_DUMP(PLLCR);
+               REG_DUMP(PTR0);
+               REG_DUMP(PTR1);
+               REG_DUMP(PTR2);
+               REG_DUMP(PTR3);
+               REG_DUMP(PTR4);
+               REG_DUMP(ACMDLR);
+               REG_DUMP(ACBDLR);
+               REG_DUMP(DXCCR);
+               REG_DUMP(DSGCR);
+               REG_DUMP(DCR);
+               REG_DUMP(DTPR0);
+               REG_DUMP(DTPR1);
+               REG_DUMP(DTPR2);
+               REG_DUMP(MR0);
+               REG_DUMP(MR1);
+               REG_DUMP(MR2);
+               REG_DUMP(MR3);
+
+               for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
+                       DX_REG_DUMP(dx, GCR);
+                       DX_REG_DUMP(dx, GTR);
+               }
+
+               iounmap(phy_base);
        }
 }
 
diff --git a/arch/arm/mach-uniphier/dram/ddrphy-init.h b/arch/arm/mach-uniphier/dram/ddrphy-init.h
new file mode 100644 (file)
index 0000000..3fc610b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef ARCH_DDRPHY_INIT_H
+#define ARCH_DDRPHY_INTT_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/* for LD4, Pro4, sLD8 */
+#define NR_DATX8_PER_DDRPHY    2
+
+int uniphier_ld4_ddrphy_init(void __iomem *phy_base, int freq, bool ddr3plus);
+void ddrphy_prepare_training(void __iomem *phy_base, int rank);
+int ddrphy_training(void __iomem *phy_base);
+
+#endif /* ARCH_DDRPHY_INT_H */
index c9e164f..620668e 100644 (file)
@@ -1,14 +1,15 @@
 /*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014      Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <linux/err.h>
-#include <linux/types.h>
 #include <linux/io.h>
 
+#include "ddrphy-init.h"
 #include "ddrphy-regs.h"
 
 enum dram_freq {
@@ -27,8 +28,7 @@ static u32 ddrphy_dtpr2[DRAM_FREQ_NR] = {0x5002c200, 0xa00214f8};
 static u32 ddrphy_mr0[DRAM_FREQ_NR] = {0x00000b51, 0x00000d71};
 static u32 ddrphy_mr2[DRAM_FREQ_NR] = {0x00000290, 0x00000298};
 
-int uniphier_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq,
-                            bool ddr3plus)
+int uniphier_ld4_ddrphy_init(void __iomem *phy_base, int freq, bool ddr3plus)
 {
        enum dram_freq freq_e;
        u32 tmp;
@@ -45,34 +45,34 @@ int uniphier_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq,
                return -EINVAL;
        }
 
-       writel(0x0300c473, &phy->pgcr[1]);
-       writel(ddrphy_ptr0[freq_e], &phy->ptr[0]);
-       writel(ddrphy_ptr1[freq_e], &phy->ptr[1]);
-       writel(0x00083DEF, &phy->ptr[2]);
-       writel(ddrphy_ptr3[freq_e], &phy->ptr[3]);
-       writel(ddrphy_ptr4[freq_e], &phy->ptr[4]);
-       writel(0xF004001A, &phy->dsgcr);
+       writel(0x0300c473, phy_base + PHY_PGCR1);
+       writel(ddrphy_ptr0[freq_e], phy_base + PHY_PTR0);
+       writel(ddrphy_ptr1[freq_e], phy_base + PHY_PTR1);
+       writel(0x00083DEF, phy_base + PHY_PTR2);
+       writel(ddrphy_ptr3[freq_e], phy_base + PHY_PTR3);
+       writel(ddrphy_ptr4[freq_e], phy_base + PHY_PTR4);
+       writel(0xF004001A, phy_base + PHY_DSGCR);
 
        /* change the value of the on-die pull-up/pull-down registors */
-       tmp = readl(&phy->dxccr);
+       tmp = readl(phy_base + PHY_DXCCR);
        tmp &= ~0x0ee0;
-       tmp |= DXCCR_DQSNRES_688_OHM | DXCCR_DQSRES_688_OHM;
-       writel(tmp, &phy->dxccr);
+       tmp |= PHY_DXCCR_DQSNRES_688_OHM | PHY_DXCCR_DQSRES_688_OHM;
+       writel(tmp, phy_base + PHY_DXCCR);
 
-       writel(0x0000040B, &phy->dcr);
-       writel(ddrphy_dtpr0[freq_e], &phy->dtpr[0]);
-       writel(ddrphy_dtpr1[freq_e], &phy->dtpr[1]);
-       writel(ddrphy_dtpr2[freq_e], &phy->dtpr[2]);
-       writel(ddrphy_mr0[freq_e], &phy->mr0);
-       writel(0x00000006, &phy->mr1);
-       writel(ddrphy_mr2[freq_e], &phy->mr2);
-       writel(ddr3plus ? 0x00000800 : 0x00000000, &phy->mr3);
+       writel(0x0000040B, phy_base + PHY_DCR);
+       writel(ddrphy_dtpr0[freq_e], phy_base + PHY_DTPR0);
+       writel(ddrphy_dtpr1[freq_e], phy_base + PHY_DTPR1);
+       writel(ddrphy_dtpr2[freq_e], phy_base + PHY_DTPR2);
+       writel(ddrphy_mr0[freq_e], phy_base + PHY_MR0);
+       writel(0x00000006, phy_base + PHY_MR1);
+       writel(ddrphy_mr2[freq_e], phy_base + PHY_MR2);
+       writel(ddr3plus ? 0x00000800 : 0x00000000, phy_base + PHY_MR3);
 
-       while (!(readl(&phy->pgsr[0]) & PGSR0_IDONE))
+       while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE))
                ;
 
-       writel(0x0300C473, &phy->pgcr[1]);
-       writel(0x0000005D, &phy->zq[0].cr[1]);
+       writel(0x0300C473, phy_base + PHY_PGCR1);
+       writel(0x0000005D, phy_base + PHY_ZQ_BASE + PHY_ZQ_CR1);
 
        return 0;
 }
index a8fe6a0..965ea18 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * UniPhier DDR PHY registers
  *
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014      Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef ARCH_DDRPHY_REGS_H
 #define ARCH_DDRPHY_REGS_H
 
-#include <linux/bitops.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
+#define PHY_REG_SHIFT          2
 
-#ifndef __ASSEMBLY__
-
-struct ddrphy {
-       u32 ridr;               /* Revision Identification Register */
-       u32 pir;                /* PHY Initialixation Register */
-       u32 pgcr[2];            /* PHY General Configuration Register */
-       u32 pgsr[2];            /* PHY General Status Register */
-       u32 pllcr;              /* PLL Control Register */
-       u32 ptr[5];             /* PHY Timing Register */
-       u32 acmdlr;             /* AC Master Delay Line Register */
-       u32 acbdlr;             /* AC Bit Delay Line Register */
-       u32 aciocr;             /* AC I/O Configuration Register */
-       u32 dxccr;              /* DATX8 Common Configuration Register */
-       u32 dsgcr;              /* DDR System General Configuration Register */
-       u32 dcr;                /* DRAM Configuration Register */
-       u32 dtpr[3];            /* DRAM Timing Parameters Register */
-       u32 mr0;                /* Mode Register 0 */
-       u32 mr1;                /* Mode Register 1 */
-       u32 mr2;                /* Mode Register 2 */
-       u32 mr3;                /* Mode Register 3 */
-       u32 odtcr;              /* ODT Configuration Register */
-       u32 dtcr;               /* Data Training Configuration Register */
-       u32 dtar[4];            /* Data Training Address Register */
-       u32 dtdr[2];            /* Data Training Data Register */
-       u32 dtedr[2];           /* Data Training Eye Data Register */
-       u32 pgcr2;              /* PHY General Configuration Register 2 */
-       u32 rsv0[8];            /* Reserved */
-       u32 rdimmgcr[2];        /* RDIMM General Configuration Register */
-       u32 rdimmcr0[2];        /* RDIMM Control Register */
-       u32 dcuar;              /* DCU Address Register */
-       u32 dcudr;              /* DCU Data Register */
-       u32 dcurr;              /* DCU Run Register */
-       u32 dculr;              /* DCU Loop Register */
-       u32 dcugcr;             /* DCU General Configuration Register */
-       u32 dcutpr;             /* DCU Timing Parameters Register */
-       u32 dcusr[2];           /* DCU Status Register */
-       u32 rsv1[8];            /* Reserved */
-       u32 bistrr;             /* BIST Run Register */
-       u32 bistwcr;            /* BIST Word Count Register */
-       u32 bistmskr[3];        /* BIST Mask Register */
-       u32 bistlsr;            /* BIST LFSR Sed Register */
-       u32 bistar[3];          /* BIST Address Register */
-       u32 bistudpr;           /* BIST User Data Pattern Register */
-       u32 bistgsr;            /* BIST General Status Register */
-       u32 bistwer;            /* BIST Word Error Register */
-       u32 bistber[4];         /* BIST Bit Error Register */
-       u32 bistwcsr;           /* BIST Word Count Status Register */
-       u32 bistfwr[3];         /* BIST Fail Word Register */
-       u32 rsv2[10];           /* Reserved */
-       u32 gpr[2];             /* General Purpose Register */
-       struct ddrphy_zq {      /* ZQ */
-               u32 cr[2];      /* Impedance Control Register */
-               u32 sr[2];      /* Impedance Status Register */
-       } zq[4];
-       struct ddrphy_datx8 {   /* DATX8 */
-               u32 gcr;        /* General Configuration Register */
-               u32 gsr[2];     /* General Status Register */
-               u32 bdlr[5];    /* Bit Delay Line Register */
-               u32 lcdlr[3];   /* Local Calibrated Delay Line Register */
-               u32 mdlr;       /* Master Delay Line Register */
-               u32 gtr;        /* General Timing Register */
-               u32 gsr2;       /* General Status Register 2 */
-               u32 rsv[2];     /* Reserved */
-       } dx[9];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define PIR_INIT               BIT(0)          /* Initialization Trigger */
-#define PIR_ZCAL               BIT(1)          /* Impedance Calibration */
-#define PIR_PLLINIT            BIT(4)          /* PLL Initialization */
-#define PIR_DCAL               BIT(5)          /* DDL Calibration */
-#define PIR_PHYRST             BIT(6)          /* PHY Reset */
-#define PIR_DRAMRST            BIT(7)          /* DRAM Reset */
-#define PIR_DRAMINIT           BIT(8)          /* DRAM Initialization */
-#define PIR_WL                 BIT(9)          /* Write Leveling */
-#define PIR_QSGATE             BIT(10)         /* Read DQS Gate Training */
-#define PIR_WLADJ              BIT(11)         /* Write Leveling Adjust */
-#define PIR_RDDSKW             BIT(12)         /* Read Data Bit Deskew */
-#define PIR_WRDSKW             BIT(13)         /* Write Data Bit Deskew */
-#define PIR_RDEYE              BIT(14)         /* Read Data Eye Training */
-#define PIR_WREYE              BIT(15)         /* Write Data Eye Training */
-#define PIR_LOCKBYP            BIT(28)         /* PLL Lock Bypass */
-#define PIR_DCALBYP            BIT(29)         /* DDL Calibration Bypass */
-#define PIR_ZCALBYP            BIT(30)         /* Impedance Calib Bypass */
-#define PIR_INITBYP            BIT(31)         /* Initialization Bypass */
-
-#define PGSR0_IDONE            BIT(0)          /* Initialization Done */
-#define PGSR0_PLDONE           BIT(1)          /* PLL Lock Done */
-#define PGSR0_DCDONE           BIT(2)          /* DDL Calibration Done */
-#define PGSR0_ZCDONE           BIT(3)          /* Impedance Calibration Done */
-#define PGSR0_DIDONE           BIT(4)          /* DRAM Initialization Done */
-#define PGSR0_WLDONE           BIT(5)          /* Write Leveling Done */
-#define PGSR0_QSGDONE          BIT(6)          /* DQS Gate Training Done */
-#define PGSR0_WLADONE          BIT(7)          /* Write Leveling Adjust Done */
-#define PGSR0_RDDONE           BIT(8)          /* Read Bit Deskew Done */
-#define PGSR0_WDDONE           BIT(9)          /* Write Bit Deskew Done */
-#define PGSR0_REDONE           BIT(10)         /* Read Eye Training Done */
-#define PGSR0_WEDONE           BIT(11)         /* Write Eye Training Done */
-#define PGSR0_IERR             BIT(16)         /* Initialization Error */
-#define PGSR0_PLERR            BIT(17)         /* PLL Lock Error */
-#define PGSR0_DCERR            BIT(18)         /* DDL Calibration Error */
-#define PGSR0_ZCERR            BIT(19)         /* Impedance Calib Error */
-#define PGSR0_DIERR            BIT(20)         /* DRAM Initialization Error */
-#define PGSR0_WLERR            BIT(21)         /* Write Leveling Error */
-#define PGSR0_QSGERR           BIT(22)         /* DQS Gate Training Error */
-#define PGSR0_WLAERR           BIT(23)         /* Write Leveling Adj Error */
-#define PGSR0_RDERR            BIT(24)         /* Read Bit Deskew Error */
-#define PGSR0_WDERR            BIT(25)         /* Write Bit Deskew Error */
-#define PGSR0_REERR            BIT(26)         /* Read Eye Training Error */
-#define PGSR0_WEERR            BIT(27)         /* Write Eye Training Error */
-#define PGSR0_DTERR_SHIFT      28              /* Data Training Error Status*/
-#define PGSR0_DTERR            (7 << (PGSR0_DTERR_SHIFT))
-#define PGSR0_APLOCK           BIT(31)         /* AC PLL Lock */
-
-#define DXCCR_DQSRES_OPEN      (0 << 5)
-#define DXCCR_DQSRES_688_OHM   (1 << 5)
-#define DXCCR_DQSRES_611_OHM   (2 << 5)
-#define DXCCR_DQSRES_550_OHM   (3 << 5)
-#define DXCCR_DQSRES_500_OHM   (4 << 5)
-#define DXCCR_DQSRES_458_OHM   (5 << 5)
-#define DXCCR_DQSRES_393_OHM   (6 << 5)
-#define DXCCR_DQSRES_344_OHM   (7 << 5)
-
-#define DXCCR_DQSNRES_OPEN     (0 << 9)
-#define DXCCR_DQSNRES_688_OHM  (1 << 9)
-#define DXCCR_DQSNRES_611_OHM  (2 << 9)
-#define DXCCR_DQSNRES_550_OHM  (3 << 9)
-#define DXCCR_DQSNRES_500_OHM  (4 << 9)
-#define DXCCR_DQSNRES_458_OHM  (5 << 9)
-#define DXCCR_DQSNRES_393_OHM  (6 << 9)
-#define DXCCR_DQSNRES_344_OHM  (7 << 9)
-
-#define DTCR_DTRANK_SHIFT      4               /* Data Training Rank */
-#define DTCR_DTRANK_MASK       (0x3 << (DTCR_DTRANK_SHIFT))
-#define DTCR_DTMPR             BIT(6)          /* Data Training using MPR */
-#define DTCR_RANKEN_SHIFT      24              /* Rank Enable */
-#define DTCR_RANKEN_MASK       (0xf << (DTCR_RANKEN_SHIFT))
-
-#define DXGCR_WLRKEN_SHIFT     26              /* Write Level Rank Enable */
-#define DXGCR_WLRKEN_MASK      (0xf << (DXGCR_WLRKEN_SHIFT))
-
-/* SoC-specific parameters */
-#define NR_DATX8_PER_DDRPHY    2
-
-#ifndef __ASSEMBLY__
-int uniphier_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq,
-                            bool ddr3plus);
-void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank);
-int ddrphy_training(struct ddrphy __iomem *phy);
-#endif
+#define PHY_RIDR               (0x000 << PHY_REG_SHIFT)
+#define PHY_PIR                        (0x001 << PHY_REG_SHIFT)
+#define   PHY_PIR_INIT                 BIT(0)  /* Initialization Trigger */
+#define   PHY_PIR_ZCAL                 BIT(1)  /* Impedance Calibration */
+#define   PHY_PIR_PLLINIT              BIT(4)  /* PLL Initialization */
+#define   PHY_PIR_DCAL                 BIT(5)  /* DDL Calibration */
+#define   PHY_PIR_PHYRST               BIT(6)  /* PHY Reset */
+#define   PHY_PIR_DRAMRST              BIT(7)  /* DRAM Reset */
+#define   PHY_PIR_DRAMINIT             BIT(8)  /* DRAM Initialization */
+#define   PHY_PIR_WL                   BIT(9)  /* Write Leveling */
+#define   PHY_PIR_QSGATE               BIT(10) /* Read DQS Gate Training */
+#define   PHY_PIR_WLADJ                        BIT(11) /* Write Leveling Adjust */
+#define   PHY_PIR_RDDSKW               BIT(12) /* Read Data Bit Deskew */
+#define   PHY_PIR_WRDSKW               BIT(13) /* Write Data Bit Deskew */
+#define   PHY_PIR_RDEYE                        BIT(14) /* Read Data Eye Training */
+#define   PHY_PIR_WREYE                        BIT(15) /* Write Data Eye Training */
+#define   PHY_PIR_LOCKBYP              BIT(28) /* PLL Lock Bypass */
+#define   PHY_PIR_DCALBYP              BIT(29) /* DDL Calibration Bypass */
+#define   PHY_PIR_ZCALBYP              BIT(30) /* Impedance Calib Bypass */
+#define   PHY_PIR_INITBYP              BIT(31) /* Initialization Bypass */
+#define PHY_PGCR0              (0x002 << PHY_REG_SHIFT)
+#define PHY_PGCR1              (0x003 << PHY_REG_SHIFT)
+#define PHY_PGSR0              (0x004 << PHY_REG_SHIFT)
+#define   PHY_PGSR0_IDONE              BIT(0)  /* Initialization Done */
+#define   PHY_PGSR0_PLDONE             BIT(1)  /* PLL Lock Done */
+#define   PHY_PGSR0_DCDONE             BIT(2)  /* DDL Calibration Done */
+#define   PHY_PGSR0_ZCDONE             BIT(3)  /* Impedance Calibration Done */
+#define   PHY_PGSR0_DIDONE             BIT(4)  /* DRAM Initialization Done */
+#define   PHY_PGSR0_WLDONE             BIT(5)  /* Write Leveling Done */
+#define   PHY_PGSR0_QSGDONE            BIT(6)  /* DQS Gate Training Done */
+#define   PHY_PGSR0_WLADONE            BIT(7)  /* Write Leveling Adjust Done */
+#define   PHY_PGSR0_RDDONE             BIT(8)  /* Read Bit Deskew Done */
+#define   PHY_PGSR0_WDDONE             BIT(9)  /* Write Bit Deskew Done */
+#define   PHY_PGSR0_REDONE             BIT(10) /* Read Eye Training Done */
+#define   PHY_PGSR0_WEDONE             BIT(11) /* Write Eye Training Done */
+#define   PHY_PGSR0_DIERR              BIT(20) /* DRAM Initialization Error */
+#define   PHY_PGSR0_WLERR              BIT(21) /* Write Leveling Error */
+#define   PHY_PGSR0_QSGERR             BIT(22) /* DQS Gate Training Error */
+#define   PHY_PGSR0_WLAERR             BIT(23) /* Write Leveling Adj Error */
+#define   PHY_PGSR0_RDERR              BIT(24) /* Read Bit Deskew Error */
+#define   PHY_PGSR0_WDERR              BIT(25) /* Write Bit Deskew Error */
+#define   PHY_PGSR0_REERR              BIT(26) /* Read Eye Training Error */
+#define   PHY_PGSR0_WEERR              BIT(27) /* Write Eye Training Error */
+#define   PHY_PGSR0_DTERR_SHIFT                28      /* Data Training Error Status*/
+#define   PHY_PGSR0_DTERR              (7 << (PHY_PGSR0_DTERR_SHIFT))
+#define PHY_PGSR1              (0x005 << PHY_REG_SHIFT)
+#define PHY_PLLCR              (0x006 << PHY_REG_SHIFT)
+#define PHY_PTR0               (0x007 << PHY_REG_SHIFT)
+#define PHY_PTR1               (0x008 << PHY_REG_SHIFT)
+#define PHY_PTR2               (0x009 << PHY_REG_SHIFT)
+#define PHY_PTR3               (0x00A << PHY_REG_SHIFT)
+#define PHY_PTR4               (0x00B << PHY_REG_SHIFT)
+#define PHY_ACMDLR             (0x00C << PHY_REG_SHIFT)
+#define PHY_ACBDLR             (0x00D << PHY_REG_SHIFT)
+#define PHY_ACIOCR             (0x00E << PHY_REG_SHIFT)
+#define PHY_DXCCR              (0x00F << PHY_REG_SHIFT)
+#define   PHY_DXCCR_DQSRES_OPEN                (0 << 5)
+#define   PHY_DXCCR_DQSRES_688_OHM     (1 << 5)
+#define   PHY_DXCCR_DQSRES_611_OHM     (2 << 5)
+#define   PHY_DXCCR_DQSRES_550_OHM     (3 << 5)
+#define   PHY_DXCCR_DQSRES_500_OHM     (4 << 5)
+#define   PHY_DXCCR_DQSRES_458_OHM     (5 << 5)
+#define   PHY_DXCCR_DQSRES_393_OHM     (6 << 5)
+#define   PHY_DXCCR_DQSRES_344_OHM     (7 << 5)
+#define   PHY_DXCCR_DQSNRES_OPEN       (0 << 9)
+#define   PHY_DXCCR_DQSNRES_688_OHM    (1 << 9)
+#define   PHY_DXCCR_DQSNRES_611_OHM    (2 << 9)
+#define   PHY_DXCCR_DQSNRES_550_OHM    (3 << 9)
+#define   PHY_DXCCR_DQSNRES_500_OHM    (4 << 9)
+#define   PHY_DXCCR_DQSNRES_458_OHM    (5 << 9)
+#define   PHY_DXCCR_DQSNRES_393_OHM    (6 << 9)
+#define   PHY_DXCCR_DQSNRES_344_OHM    (7 << 9)
+#define PHY_DSGCR              (0x010 << PHY_REG_SHIFT)
+#define PHY_DCR                        (0x011 << PHY_REG_SHIFT)
+#define PHY_DTPR0              (0x012 << PHY_REG_SHIFT)
+#define PHY_DTPR1              (0x013 << PHY_REG_SHIFT)
+#define PHY_DTPR2              (0x014 << PHY_REG_SHIFT)
+#define PHY_MR0                        (0x015 << PHY_REG_SHIFT)
+#define PHY_MR1                        (0x016 << PHY_REG_SHIFT)
+#define PHY_MR2                        (0x017 << PHY_REG_SHIFT)
+#define PHY_MR3                        (0x018 << PHY_REG_SHIFT)
+#define PHY_ODTCR              (0x019 << PHY_REG_SHIFT)
+#define PHY_DTCR               (0x01A << PHY_REG_SHIFT)
+#define   PHY_DTCR_DTRANK_SHIFT                4       /* Data Training Rank */
+#define   PHY_DTCR_DTRANK_MASK         (0x3 << (PHY_DTCR_DTRANK_SHIFT))
+#define   PHY_DTCR_DTMPR               BIT(6)  /* Data Training using MPR */
+#define   PHY_DTCR_RANKEN_SHIFT                24      /* Rank Enable */
+#define   PHY_DTCR_RANKEN_MASK         (0xf << (PHY_DTCR_RANKEN_SHIFT))
+#define PHY_DTAR0              (0x01B << PHY_REG_SHIFT)
+#define PHY_DTAR1              (0x01C << PHY_REG_SHIFT)
+#define PHY_DTAR2              (0x01D << PHY_REG_SHIFT)
+#define PHY_DTAR3              (0x01E << PHY_REG_SHIFT)
+#define PHY_DTDR0              (0x01F << PHY_REG_SHIFT)
+#define PHY_DTDR1              (0x020 << PHY_REG_SHIFT)
+#define PHY_DTEDR0             (0x021 << PHY_REG_SHIFT)
+#define PHY_DTEDR1             (0x022 << PHY_REG_SHIFT)
+#define PHY_PGCR2              (0x023 << PHY_REG_SHIFT)
+#define PHY_GPR0               (0x05E << PHY_REG_SHIFT)
+#define PHY_GPR1               (0x05F << PHY_REG_SHIFT)
+/* ZQ */
+#define PHY_ZQ_BASE            (0x060 << PHY_REG_SHIFT)
+#define PHY_ZQ_STRIDE          (0x004 << PHY_REG_SHIFT)
+#define PHY_ZQ_CR0             (0x000 << PHY_REG_SHIFT)
+#define PHY_ZQ_CR1             (0x001 << PHY_REG_SHIFT)
+#define PHY_ZQ_SR0             (0x002 << PHY_REG_SHIFT)
+#define PHY_ZQ_SR1             (0x003 << PHY_REG_SHIFT)
+/* DATX8 */
+#define PHY_DX_BASE            (0x070 << PHY_REG_SHIFT)
+#define PHY_DX_STRIDE          (0x010 << PHY_REG_SHIFT)
+#define PHY_DX_GCR             (0x000 << PHY_REG_SHIFT)
+#define   PHY_DX_GCR_WLRKEN_SHIFT      26              /* Write Level Rank Enable */
+#define   PHY_DX_GCR_WLRKEN_MASK       (0xf << (PHY_DX_GCR_WLRKEN_SHIFT))
+#define PHY_DX_GSR0            (0x001 << PHY_REG_SHIFT)
+#define PHY_DX_GSR1            (0x002 << PHY_REG_SHIFT)
+#define PHY_DX_BDLR0           (0x003 << PHY_REG_SHIFT)
+#define PHY_DX_BDLR1           (0x004 << PHY_REG_SHIFT)
+#define PHY_DX_BDLR2           (0x005 << PHY_REG_SHIFT)
+#define PHY_DX_BDLR3           (0x006 << PHY_REG_SHIFT)
+#define PHY_DX_BDLR4           (0x007 << PHY_REG_SHIFT)
+#define PHY_DX_LCDLR0          (0x008 << PHY_REG_SHIFT)
+#define PHY_DX_LCDLR1          (0x009 << PHY_REG_SHIFT)
+#define PHY_DX_LCDLR2          (0x00A << PHY_REG_SHIFT)
+#define PHY_DX_MDLR            (0x00B << PHY_REG_SHIFT)
+#define PHY_DX_GTR             (0x00C << PHY_REG_SHIFT)
+#define PHY_DX_GSR2            (0x00D << PHY_REG_SHIFT)
 
 #endif /* ARCH_DDRPHY_REGS_H */
index a348136..a561fad 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -8,35 +9,35 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "ddrphy-init.h"
 #include "ddrphy-regs.h"
 
-void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank)
+void ddrphy_prepare_training(void __iomem *phy_base, int rank)
 {
+       void __iomem *dx_base = phy_base + PHY_DX_BASE;
        int dx;
-       u32 __iomem tmp, *p;
+       u32 tmp;
 
        for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
-               p = &phy->dx[dx].gcr;
-
-               tmp = readl(p);
+               tmp = readl(dx_base + PHY_DX_GCR);
                /* Specify the rank that should be write leveled */
-               tmp &= ~DXGCR_WLRKEN_MASK;
-               tmp |= (1 << (DXGCR_WLRKEN_SHIFT + rank)) & DXGCR_WLRKEN_MASK;
-               writel(tmp, p);
+               tmp &= ~PHY_DX_GCR_WLRKEN_MASK;
+               tmp |= (1 << (PHY_DX_GCR_WLRKEN_SHIFT + rank)) &
+                       PHY_DX_GCR_WLRKEN_MASK;
+               writel(tmp, dx_base + PHY_DX_GCR);
+               dx_base += PHY_DX_STRIDE;
        }
 
-       p = &phy->dtcr;
-
-       tmp = readl(p);
+       tmp = readl(phy_base + PHY_DTCR);
        /* Specify the rank used during data bit deskew and eye centering */
-       tmp &= ~DTCR_DTRANK_MASK;
-       tmp |= (rank << DTCR_DTRANK_SHIFT) & DTCR_DTRANK_MASK;
+       tmp &= ~PHY_DTCR_DTRANK_MASK;
+       tmp |= (rank << PHY_DTCR_DTRANK_SHIFT) & PHY_DTCR_DTRANK_MASK;
        /* Use Multi-Purpose Register for DQS gate training */
-       tmp |= DTCR_DTMPR;
+       tmp |= PHY_DTCR_DTMPR;
        /* Specify the rank enabled for data-training */
-       tmp &= ~DTCR_RANKEN_MASK;
-       tmp |= (1 << (DTCR_RANKEN_SHIFT + rank)) & DTCR_RANKEN_MASK;
-       writel(tmp, p);
+       tmp &= ~PHY_DTCR_RANKEN_MASK;
+       tmp |= (1 << (PHY_DTCR_RANKEN_SHIFT + rank)) & PHY_DTCR_RANKEN_MASK;
+       writel(tmp, phy_base + PHY_DTCR);
 }
 
 struct ddrphy_init_sequence {
@@ -49,60 +50,60 @@ struct ddrphy_init_sequence {
 static const struct ddrphy_init_sequence init_sequence[] = {
        {
                "DRAM Initialization",
-               PIR_DRAMRST | PIR_DRAMINIT,
-               PGSR0_DIDONE,
-               PGSR0_DIERR
+               PHY_PIR_DRAMRST | PHY_PIR_DRAMINIT,
+               PHY_PGSR0_DIDONE,
+               PHY_PGSR0_DIERR
        },
        {
                "Write Leveling",
-               PIR_WL,
-               PGSR0_WLDONE,
-               PGSR0_WLERR
+               PHY_PIR_WL,
+               PHY_PGSR0_WLDONE,
+               PHY_PGSR0_WLERR
        },
        {
                "Read DQS Gate Training",
-               PIR_QSGATE,
-               PGSR0_QSGDONE,
-               PGSR0_QSGERR
+               PHY_PIR_QSGATE,
+               PHY_PGSR0_QSGDONE,
+               PHY_PGSR0_QSGERR
        },
        {
                "Write Leveling Adjustment",
-               PIR_WLADJ,
-               PGSR0_WLADONE,
-               PGSR0_WLAERR
+               PHY_PIR_WLADJ,
+               PHY_PGSR0_WLADONE,
+               PHY_PGSR0_WLAERR
        },
        {
                "Read Bit Deskew",
-               PIR_RDDSKW,
-               PGSR0_RDDONE,
-               PGSR0_RDERR
+               PHY_PIR_RDDSKW,
+               PHY_PGSR0_RDDONE,
+               PHY_PGSR0_RDERR
        },
        {
                "Write Bit Deskew",
-               PIR_WRDSKW,
-               PGSR0_WDDONE,
-               PGSR0_WDERR
+               PHY_PIR_WRDSKW,
+               PHY_PGSR0_WDDONE,
+               PHY_PGSR0_WDERR
        },
        {
                "Read Eye Training",
-               PIR_RDEYE,
-               PGSR0_REDONE,
-               PGSR0_REERR
+               PHY_PIR_RDEYE,
+               PHY_PGSR0_REDONE,
+               PHY_PGSR0_REERR
        },
        {
                "Write Eye Training",
-               PIR_WREYE,
-               PGSR0_WEDONE,
-               PGSR0_WEERR
+               PHY_PIR_WREYE,
+               PHY_PGSR0_WEDONE,
+               PHY_PGSR0_WEERR
        }
 };
 
-int ddrphy_training(struct ddrphy __iomem *phy)
+int ddrphy_training(void __iomem *phy_base)
 {
        int i;
        u32 pgsr0;
-       u32 init_flag = PIR_INIT;
-       u32 done_flag = PGSR0_IDONE;
+       u32 init_flag = PHY_PIR_INIT;
+       u32 done_flag = PHY_PGSR0_IDONE;
        int timeout = 50000; /* 50 msec is long enough */
 #ifdef DISPLAY_ELAPSED_TIME
        ulong start = get_timer(0);
@@ -113,7 +114,7 @@ int ddrphy_training(struct ddrphy __iomem *phy)
                done_flag |= init_sequence[i].done_flag;
        }
 
-       writel(init_flag, &phy->pir);
+       writel(init_flag, phy_base + PHY_PIR);
 
        do {
                if (--timeout < 0) {
@@ -122,7 +123,7 @@ int ddrphy_training(struct ddrphy __iomem *phy)
                        return -ETIMEDOUT;
                }
                udelay(1);
-               pgsr0 = readl(&phy->pgsr[0]);
+               pgsr0 = readl(phy_base + PHY_PGSR0);
        } while ((pgsr0 & done_flag) != done_flag);
 
        for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
index 82ab63c..90e7f2d 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 
 #include "../init.h"
-#include "ddrphy-regs.h"
+#include "ddrphy-init.h"
 #include "umc-regs.h"
 
 #define DRAM_CH_NR     2
index 4a7aa78..5447fa9 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 
 #include "../init.h"
-#include "ddrphy-regs.h"
+#include "ddrphy-init.h"
 #include "umc-regs.h"
 
 #define DRAM_CH_NR     2
index 568a007..61369f1 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 
 #include "../init.h"
-#include "ddrphy-regs.h"
+#include "ddrphy-init.h"
 #include "umc-regs.h"
 
 #define DRAM_CH_NR     2