Commit 94b756f3 authored by Masahiro Yamada's avatar Masahiro Yamada
Browse files

ARM: uniphier: refactor UMC init code for ProXstream2

Currently, a dummy value is defined for the UMC_SPCCTLA register
when the DRAM size is zero.  This seems weird because the controller
does not need setting in the first place if the size is zero.

Also, redefine enum dram_size to represent the DRAM size per 16-bit
unit.  This makes things simpler because the channel 0 and 1 are
connected with 32-bit width DRAM, while the channel 2 is connected
with 16-bit width one.

I am renaming SIZE_* into DRAM_SZ_* (and also FREQ_* to DRAM_FREQ_*
for consistency) while I am here because SIZE_* might be easily
mixed-up with the macros in include/linux/sizes.h.
Signed-off-by: default avatarMasahiro Yamada <>
parent a54c879a
......@@ -18,46 +18,45 @@
#include "ddrmphy-regs.h"
#include "umc-regs.h"
#define CH_NR 3
#define DRAM_CH_NR 3
enum dram_freq {
enum dram_size {
static u32 ddrphy_pgcr2[FREQ_NR] = {0x00FC7E5D, 0x00FC90AB};
static u32 ddrphy_ptr0[FREQ_NR] = {0x0EA09205, 0x10C0A6C6};
static u32 ddrphy_ptr1[FREQ_NR] = {0x0DAC041B, 0x0FA104B1};
static u32 ddrphy_ptr3[FREQ_NR] = {0x15171e45, 0x18182357};
static u32 ddrphy_ptr4[FREQ_NR] = {0x0e9ad8e9, 0x10b34157};
static u32 ddrphy_dtpr0[FREQ_NR] = {0x35a00d88, 0x39e40e88};
static u32 ddrphy_dtpr1[FREQ_NR] = {0x2288cc2c, 0x228a04d0};
static u32 ddrphy_dtpr2[FREQ_NR] = {0x50005e00, 0x50006a00};
static u32 ddrphy_dtpr3[FREQ_NR] = {0x0010cb49, 0x0010ec89};
static u32 ddrphy_mr0[FREQ_NR] = {0x00000115, 0x00000125};
static u32 ddrphy_mr2[FREQ_NR] = {0x000002a0, 0x000002a8};
static u32 ddrphy_pgcr2[DRAM_FREQ_NR] = {0x00FC7E5D, 0x00FC90AB};
static u32 ddrphy_ptr0[DRAM_FREQ_NR] = {0x0EA09205, 0x10C0A6C6};
static u32 ddrphy_ptr1[DRAM_FREQ_NR] = {0x0DAC041B, 0x0FA104B1};
static u32 ddrphy_ptr3[DRAM_FREQ_NR] = {0x15171e45, 0x18182357};
static u32 ddrphy_ptr4[DRAM_FREQ_NR] = {0x0e9ad8e9, 0x10b34157};
static u32 ddrphy_dtpr0[DRAM_FREQ_NR] = {0x35a00d88, 0x39e40e88};
static u32 ddrphy_dtpr1[DRAM_FREQ_NR] = {0x2288cc2c, 0x228a04d0};
static u32 ddrphy_dtpr2[DRAM_FREQ_NR] = {0x50005e00, 0x50006a00};
static u32 ddrphy_dtpr3[DRAM_FREQ_NR] = {0x0010cb49, 0x0010ec89};
static u32 ddrphy_mr0[DRAM_FREQ_NR] = {0x00000115, 0x00000125};
static u32 ddrphy_mr2[DRAM_FREQ_NR] = {0x000002a0, 0x000002a8};
/* dependent on package and board design */
static u32 ddrphy_acbdlr0[CH_NR] = {0x0000000c, 0x0000000c, 0x00000009};
static u32 ddrphy_acbdlr0[DRAM_CH_NR] = {0x0000000c, 0x0000000c, 0x00000009};
static u32 umc_cmdctla[FREQ_NR] = {0x66DD131D, 0x77EE1722};
static u32 umc_cmdctla[DRAM_FREQ_NR] = {0x66DD131D, 0x77EE1722};
* The ch2 is a different generation UMC core.
* The register spec is different, unfortunately.
static u32 umc_cmdctlb_ch01[FREQ_NR] = {0x13E87C44, 0x18F88C44};
static u32 umc_cmdctlb_ch2[FREQ_NR] = {0x19E8DC44, 0x1EF8EC44};
static u32 umc_spcctla[FREQ_NR][SIZE_NR] = {
{0x00000000, 0x004A071D, 0x0078071D},
{0x00000000, 0x0055081E, 0x0089081E},
static u32 umc_cmdctlb_ch01[DRAM_FREQ_NR] = {0x13E87C44, 0x18F88C44};
static u32 umc_cmdctlb_ch2[DRAM_FREQ_NR] = {0x19E8DC44, 0x1EF8EC44};
static u32 umc_spcctla[DRAM_FREQ_NR][DRAM_SZ_NR] = {
{0x004A071D, 0x0078071D},
{0x0055081E, 0x0089081E},
static u32 umc_spcctlb[] = {0x00FF000A, 0x00FF000B};
......@@ -459,18 +458,34 @@ static void umc_ud_init(void __iomem *umc_base, int ch)
writel(0x00000033, umc_base + UMC_PAIR1DOFF_D0);
static void umc_dc_init(void __iomem *umc_dc_base, enum dram_freq freq,
enum dram_size size, int ch, int width)
static int umc_dc_init(void __iomem *umc_dc_base, enum dram_freq freq,
unsigned long size, int width, int ch)
enum dram_size size_e;
int latency;
u32 val;
switch (size) {
case 0:
return 0;
case SZ_256M:
size_e = DRAM_SZ_256M;
case SZ_512M:
size_e = DRAM_SZ_512M;
pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
size, ch);
return -EINVAL;
writel(umc_cmdctla[freq], umc_dc_base + UMC_CMDCTLA);
writel(ch == 2 ? umc_cmdctlb_ch2[freq] : umc_cmdctlb_ch01[freq],
umc_dc_base + UMC_CMDCTLB);
writel(umc_spcctla[freq][size / (width / 16)],
umc_dc_base + UMC_SPCCTLA);
writel(umc_spcctlb[freq], umc_dc_base + UMC_SPCCTLB);
......@@ -519,13 +534,15 @@ static void umc_dc_init(void __iomem *umc_dc_base, enum dram_freq freq,
writel(0x00000000, umc_dc_base + UMC_ERRMASKA);
writel(0x00000000, umc_dc_base + UMC_ERRMASKB);
return 0;
static int umc_init(void __iomem *umc_base, enum dram_freq freq, int ch,
enum dram_size size, int width)
static int umc_ch_init(void __iomem *umc_ch_base, enum dram_freq freq,
unsigned long size, unsigned int width, int ch)
void __iomem *umc_dc_base = umc_base + 0x00011000;
void __iomem *phy_base = umc_base + 0x00030000;
void __iomem *umc_dc_base = umc_ch_base + 0x00011000;
void __iomem *phy_base = umc_ch_base + 0x00030000;
int ret;
writel(0x00000002, umc_dc_base + UMC_INITSET);
......@@ -546,15 +563,15 @@ static int umc_init(void __iomem *umc_base, enum dram_freq freq, int ch,
if (ret)
return ret;
umc_dc_init(umc_dc_base, freq, size, ch, width);
ret = umc_dc_init(umc_dc_base, freq, size, width, ch);
if (ret)
return ret;
umc_ud_init(umc_base, ch);
umc_ud_init(umc_ch_base, ch);
if (size) {
ret = ddrphy_training(phy_base);
if (ret)
return ret;
ret = ddrphy_training(phy_base);
if (ret)
return ret;
......@@ -591,10 +608,10 @@ int proxstream2_umc_init(const struct uniphier_board_data *bd)
switch (bd->dram_freq) {
case 1866:
freq = FREQ_1866M;
freq = DRAM_FREQ_1866M;
case 2133:
freq = FREQ_2133M;
freq = DRAM_FREQ_2133M;
pr_err("unsupported DRAM frequency %d MHz\n", bd->dram_freq);
......@@ -602,9 +619,11 @@ int proxstream2_umc_init(const struct uniphier_board_data *bd)
for (ch = 0; ch < bd->dram_nr_ch; ch++) {
ret = umc_init(umc_ch_base, freq, ch,
bd->dram_ch[ch].size / SZ_256M,
unsigned long size = bd->dram_ch[ch].size;
unsigned int width = bd->dram_ch[ch].width;
ret = umc_ch_init(umc_ch_base, freq, size / (width / 16),
width, ch);
if (ret) {
pr_err("failed to initialize UMC ch%d\n", ch);
return ret;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment