]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-uniphier/dram/umc-ph1-ld4.c
2 * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/sizes.h>
11 #include <asm/processor.h>
14 #include "ddrphy-regs.h"
31 static u32 umc_cmdctla_plus
[DRAM_FREQ_NR
] = {0x45990b11, 0x36bb0f17};
32 static u32 umc_cmdctlb_plus
[DRAM_FREQ_NR
] = {0x16958924, 0x18c6aa24};
33 static u32 umc_spcctla
[DRAM_FREQ_NR
][DRAM_SZ_NR
] = {
34 {0x00240512, 0x00350512},
35 {0x002b0617, 0x003f0617},
37 static u32 umc_spcctlb
[DRAM_FREQ_NR
] = {0x00ff0006, 0x00ff0008};
38 static u32 umc_rdatactl
[DRAM_FREQ_NR
] = {0x000a00ac, 0x000c00ae};
40 static int umc_get_rank(int ch
)
42 return ch
; /* ch0: rank0, ch1: rank1 for this SoC */
45 static void umc_start_ssif(void __iomem
*ssif_base
)
47 writel(0x00000000, ssif_base
+ 0x0000b004);
48 writel(0xffffffff, ssif_base
+ 0x0000c004);
49 writel(0x000fffcf, ssif_base
+ 0x0000c008);
50 writel(0x00000001, ssif_base
+ 0x0000b000);
51 writel(0x00000001, ssif_base
+ 0x0000c000);
52 writel(0x03010101, ssif_base
+ UMC_MDMCHSEL
);
53 writel(0x03010100, ssif_base
+ UMC_DMDCHSEL
);
55 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_FETCH
);
56 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE0
);
57 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC0
);
58 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC0
);
59 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE1
);
60 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC1
);
61 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC1
);
62 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_WC
);
63 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_RC
);
64 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_DST
);
66 writel(0x00000001, ssif_base
+ UMC_CPURST
);
67 writel(0x00000001, ssif_base
+ UMC_IDSRST
);
68 writel(0x00000001, ssif_base
+ UMC_IXMRST
);
69 writel(0x00000001, ssif_base
+ UMC_MDMRST
);
70 writel(0x00000001, ssif_base
+ UMC_MDDRST
);
71 writel(0x00000001, ssif_base
+ UMC_SIORST
);
72 writel(0x00000001, ssif_base
+ UMC_VIORST
);
73 writel(0x00000001, ssif_base
+ UMC_FRCRST
);
74 writel(0x00000001, ssif_base
+ UMC_RGLRST
);
75 writel(0x00000001, ssif_base
+ UMC_AIORST
);
76 writel(0x00000001, ssif_base
+ UMC_DMDRST
);
79 static int umc_dramcont_init(void __iomem
*dc_base
, void __iomem
*ca_base
,
80 int freq
, unsigned long size
, bool ddr3plus
)
82 enum dram_freq freq_e
;
83 enum dram_size size_e
;
86 pr_err("DDR3 standard is not supported\n");
92 freq_e
= DRAM_FREQ_1333M
;
95 freq_e
= DRAM_FREQ_1600M
;
98 pr_err("unsupported DRAM frequency %d MHz\n", freq
);
106 size_e
= DRAM_SZ_128M
;
109 size_e
= DRAM_SZ_256M
;
112 pr_err("unsupported DRAM size 0x%08lx\n", size
);
116 writel(umc_cmdctla_plus
[freq_e
], dc_base
+ UMC_CMDCTLA
);
117 writel(umc_cmdctlb_plus
[freq_e
], dc_base
+ UMC_CMDCTLB
);
118 writel(umc_spcctla
[freq_e
][size_e
], dc_base
+ UMC_SPCCTLA
);
119 writel(umc_spcctlb
[freq_e
], dc_base
+ UMC_SPCCTLB
);
120 writel(umc_rdatactl
[freq_e
], dc_base
+ UMC_RDATACTL_D0
);
121 writel(0x04060806, dc_base
+ UMC_WDATACTL_D0
);
122 writel(0x04a02000, dc_base
+ UMC_DATASET
);
123 writel(0x00000000, ca_base
+ 0x2300);
124 writel(0x00400020, dc_base
+ UMC_DCCGCTL
);
125 writel(0x00000003, dc_base
+ 0x7000);
126 writel(0x0000000f, dc_base
+ 0x8000);
127 writel(0x000000c3, dc_base
+ 0x8004);
128 writel(0x00000071, dc_base
+ 0x8008);
129 writel(0x0000003b, dc_base
+ UMC_DICGCTLA
);
130 writel(0x020a0808, dc_base
+ UMC_DICGCTLB
);
131 writel(0x00000004, dc_base
+ UMC_FLOWCTLG
);
132 writel(0x80000201, ca_base
+ 0xc20);
133 writel(0x0801e01e, dc_base
+ UMC_FLOWCTLA
);
134 writel(0x00200000, dc_base
+ UMC_FLOWCTLB
);
135 writel(0x00004444, dc_base
+ UMC_FLOWCTLC
);
136 writel(0x200a0a00, dc_base
+ UMC_SPCSETB
);
137 writel(0x00000000, dc_base
+ UMC_SPCSETD
);
138 writel(0x00000520, dc_base
+ UMC_DFICUPDCTLA
);
143 static int umc_ch_init(void __iomem
*dc_base
, void __iomem
*ca_base
,
144 int freq
, unsigned long size
, bool ddr3plus
, int ch
)
146 void __iomem
*phy_base
= dc_base
+ 0x00001000;
149 writel(UMC_INITSET_INIT1EN
, dc_base
+ UMC_INITSET
);
150 while (readl(dc_base
+ UMC_INITSET
) & UMC_INITSTAT_INIT1ST
)
153 writel(0x00000101, dc_base
+ UMC_DIOCTLA
);
155 ret
= ph1_ld4_ddrphy_init(phy_base
, freq
, ddr3plus
);
159 ddrphy_prepare_training(phy_base
, umc_get_rank(ch
));
160 ret
= ddrphy_training(phy_base
);
164 return umc_dramcont_init(dc_base
, ca_base
, freq
, size
, ddr3plus
);
167 int ph1_ld4_umc_init(const struct uniphier_board_data
*bd
)
169 void __iomem
*umc_base
= (void __iomem
*)0x5b800000;
170 void __iomem
*ca_base
= umc_base
+ 0x00001000;
171 void __iomem
*dc_base
= umc_base
+ 0x00400000;
172 void __iomem
*ssif_base
= umc_base
;
175 for (ch
= 0; ch
< DRAM_CH_NR
; ch
++) {
176 ret
= umc_ch_init(dc_base
, ca_base
, bd
->dram_freq
,
177 bd
->dram_ch
[ch
].size
,
178 bd
->dram_ddr3plus
, ch
);
180 pr_err("failed to initialize UMC ch%d\n", ch
);
184 ca_base
+= 0x00001000;
185 dc_base
+= 0x00200000;
188 umc_start_ssif(ssif_base
);