]>
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>
13 #include "ddrphy-regs.h"
30 static u32 umc_cmdctla_plus
[DRAM_FREQ_NR
] = {0x45990b11, 0x36bb0f17};
31 static u32 umc_cmdctlb_plus
[DRAM_FREQ_NR
] = {0x16958924, 0x18c6aa24};
32 static u32 umc_spcctla
[DRAM_FREQ_NR
][DRAM_SZ_NR
] = {
33 {0x00240512, 0x00350512},
34 {0x002b0617, 0x003f0617},
36 static u32 umc_spcctlb
[DRAM_FREQ_NR
] = {0x00ff0006, 0x00ff0008};
37 static u32 umc_rdatactl
[DRAM_FREQ_NR
] = {0x000a00ac, 0x000c00ae};
39 static int umc_get_rank(int ch
)
41 return ch
; /* ch0: rank0, ch1: rank1 for this SoC */
44 static void umc_start_ssif(void __iomem
*ssif_base
)
46 writel(0x00000000, ssif_base
+ 0x0000b004);
47 writel(0xffffffff, ssif_base
+ 0x0000c004);
48 writel(0x000fffcf, ssif_base
+ 0x0000c008);
49 writel(0x00000001, ssif_base
+ 0x0000b000);
50 writel(0x00000001, ssif_base
+ 0x0000c000);
51 writel(0x03010101, ssif_base
+ UMC_MDMCHSEL
);
52 writel(0x03010100, ssif_base
+ UMC_DMDCHSEL
);
54 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_FETCH
);
55 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE0
);
56 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC0
);
57 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC0
);
58 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE1
);
59 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC1
);
60 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC1
);
61 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_WC
);
62 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_RC
);
63 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_DST
);
65 writel(0x00000001, ssif_base
+ UMC_CPURST
);
66 writel(0x00000001, ssif_base
+ UMC_IDSRST
);
67 writel(0x00000001, ssif_base
+ UMC_IXMRST
);
68 writel(0x00000001, ssif_base
+ UMC_MDMRST
);
69 writel(0x00000001, ssif_base
+ UMC_MDDRST
);
70 writel(0x00000001, ssif_base
+ UMC_SIORST
);
71 writel(0x00000001, ssif_base
+ UMC_VIORST
);
72 writel(0x00000001, ssif_base
+ UMC_FRCRST
);
73 writel(0x00000001, ssif_base
+ UMC_RGLRST
);
74 writel(0x00000001, ssif_base
+ UMC_AIORST
);
75 writel(0x00000001, ssif_base
+ UMC_DMDRST
);
78 static int umc_dramcont_init(void __iomem
*dramcont
, void __iomem
*ca_base
,
79 int freq
, unsigned long size
, bool ddr3plus
)
81 enum dram_freq freq_e
;
82 enum dram_size size_e
;
85 pr_err("DDR3 standard is not supported\n");
91 freq_e
= DRAM_FREQ_1333M
;
94 freq_e
= DRAM_FREQ_1600M
;
97 pr_err("unsupported DRAM frequency %d MHz\n", freq
);
105 size_e
= DRAM_SZ_128M
;
108 size_e
= DRAM_SZ_256M
;
111 pr_err("unsupported DRAM size 0x%08lx\n", size
);
115 writel(umc_cmdctla_plus
[freq_e
], dramcont
+ UMC_CMDCTLA
);
116 writel(umc_cmdctlb_plus
[freq_e
], dramcont
+ UMC_CMDCTLB
);
117 writel(umc_spcctla
[freq_e
][size_e
], dramcont
+ UMC_SPCCTLA
);
118 writel(umc_spcctlb
[freq_e
], dramcont
+ UMC_SPCCTLB
);
119 writel(umc_rdatactl
[freq_e
], dramcont
+ UMC_RDATACTL_D0
);
120 writel(0x04060806, dramcont
+ UMC_WDATACTL_D0
);
121 writel(0x04a02000, dramcont
+ UMC_DATASET
);
122 writel(0x00000000, ca_base
+ 0x2300);
123 writel(0x00400020, dramcont
+ UMC_DCCGCTL
);
124 writel(0x00000003, dramcont
+ 0x7000);
125 writel(0x0000000f, dramcont
+ 0x8000);
126 writel(0x000000c3, dramcont
+ 0x8004);
127 writel(0x00000071, dramcont
+ 0x8008);
128 writel(0x0000003b, dramcont
+ UMC_DICGCTLA
);
129 writel(0x020a0808, dramcont
+ UMC_DICGCTLB
);
130 writel(0x00000004, dramcont
+ UMC_FLOWCTLG
);
131 writel(0x80000201, ca_base
+ 0xc20);
132 writel(0x0801e01e, dramcont
+ UMC_FLOWCTLA
);
133 writel(0x00200000, dramcont
+ UMC_FLOWCTLB
);
134 writel(0x00004444, dramcont
+ UMC_FLOWCTLC
);
135 writel(0x200a0a00, dramcont
+ UMC_SPCSETB
);
136 writel(0x00000000, dramcont
+ UMC_SPCSETD
);
137 writel(0x00000520, dramcont
+ UMC_DFICUPDCTLA
);
142 static int umc_ch_init(void __iomem
*dc_base
, void __iomem
*ca_base
,
143 int freq
, unsigned long size
, bool ddr3plus
, int ch
)
145 void __iomem
*phy_base
= dc_base
+ 0x00001000;
148 umc_dram_init_start(dc_base
);
149 umc_dram_init_poll(dc_base
);
151 writel(0x00000101, dc_base
+ UMC_DIOCTLA
);
153 ret
= ph1_ld4_ddrphy_init(phy_base
, freq
, ddr3plus
);
157 ddrphy_prepare_training(phy_base
, umc_get_rank(ch
));
158 ret
= ddrphy_training(phy_base
);
162 return umc_dramcont_init(dc_base
, ca_base
, freq
, size
, ddr3plus
);
165 int ph1_ld4_umc_init(const struct uniphier_board_data
*bd
)
167 void __iomem
*umc_base
= (void __iomem
*)0x5b800000;
168 void __iomem
*ca_base
= umc_base
+ 0x00001000;
169 void __iomem
*dc_base
= umc_base
+ 0x00400000;
170 void __iomem
*ssif_base
= umc_base
;
173 for (ch
= 0; ch
< DRAM_CH_NR
; ch
++) {
174 ret
= umc_ch_init(dc_base
, ca_base
, bd
->dram_freq
,
175 bd
->dram_ch
[ch
].size
,
176 bd
->dram_ddr3plus
, ch
);
178 pr_err("failed to initialize UMC ch%d\n", ch
);
182 ca_base
+= 0x00001000;
183 dc_base
+= 0x00200000;
186 umc_start_ssif(ssif_base
);