]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-uniphier/dram/umc-pro4.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"
26 static u32 umc_spcctla
[DRAM_SZ_NR
] = {0x002b0617, 0x003f0617, 0x00770617};
28 static void umc_start_ssif(void __iomem
*ssif_base
)
30 writel(0x00000000, ssif_base
+ 0x0000b004);
31 writel(0xffffffff, ssif_base
+ 0x0000c004);
32 writel(0x000fffcf, ssif_base
+ 0x0000c008);
33 writel(0x00000001, ssif_base
+ 0x0000b000);
34 writel(0x00000001, ssif_base
+ 0x0000c000);
36 writel(0x03010100, ssif_base
+ UMC_HDMCHSEL
);
37 writel(0x03010101, ssif_base
+ UMC_MDMCHSEL
);
38 writel(0x03010100, ssif_base
+ UMC_DVCCHSEL
);
39 writel(0x03010100, ssif_base
+ UMC_DMDCHSEL
);
41 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_FETCH
);
42 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE0
);
43 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC0
);
44 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC0
);
45 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMQUE1
);
46 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMWC1
);
47 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_COMRC1
);
48 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_WC
);
49 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_RC
);
50 writel(0x00000000, ssif_base
+ UMC_CLKEN_SSIF_DST
);
51 writel(0x00000000, ssif_base
+ 0x0000c044); /* DCGIV_SSIF_REG */
53 writel(0x00000001, ssif_base
+ UMC_CPURST
);
54 writel(0x00000001, ssif_base
+ UMC_IDSRST
);
55 writel(0x00000001, ssif_base
+ UMC_IXMRST
);
56 writel(0x00000001, ssif_base
+ UMC_HDMRST
);
57 writel(0x00000001, ssif_base
+ UMC_MDMRST
);
58 writel(0x00000001, ssif_base
+ UMC_HDDRST
);
59 writel(0x00000001, ssif_base
+ UMC_MDDRST
);
60 writel(0x00000001, ssif_base
+ UMC_SIORST
);
61 writel(0x00000001, ssif_base
+ UMC_GIORST
);
62 writel(0x00000001, ssif_base
+ UMC_HD2RST
);
63 writel(0x00000001, ssif_base
+ UMC_VIORST
);
64 writel(0x00000001, ssif_base
+ UMC_DVCRST
);
65 writel(0x00000001, ssif_base
+ UMC_RGLRST
);
66 writel(0x00000001, ssif_base
+ UMC_VPERST
);
67 writel(0x00000001, ssif_base
+ UMC_AIORST
);
68 writel(0x00000001, ssif_base
+ UMC_DMDRST
);
71 static int umc_dramcont_init(void __iomem
*dc_base
, void __iomem
*ca_base
,
72 int freq
, unsigned long size
, bool ddr3plus
)
74 enum dram_size size_e
;
77 pr_err("Unsupported DDR frequency %d MHz\n", freq
);
82 pr_err("DDR3+ is not supported\n");
88 size_e
= DRAM_SZ_128M
;
91 size_e
= DRAM_SZ_256M
;
94 size_e
= DRAM_SZ_512M
;
97 pr_err("unsupported DRAM size 0x%08lx (per 16bit)\n", size
);
101 writel(0x66bb0f17, dc_base
+ UMC_CMDCTLA
);
102 writel(0x18c6aa44, dc_base
+ UMC_CMDCTLB
);
103 writel(umc_spcctla
[size_e
], dc_base
+ UMC_SPCCTLA
);
104 writel(0x00ff0008, dc_base
+ UMC_SPCCTLB
);
105 writel(0x000c00ae, dc_base
+ UMC_RDATACTL_D0
);
106 writel(0x000c00ae, dc_base
+ UMC_RDATACTL_D1
);
107 writel(0x04060802, dc_base
+ UMC_WDATACTL_D0
);
108 writel(0x04060802, dc_base
+ UMC_WDATACTL_D1
);
109 writel(0x04a02000, dc_base
+ UMC_DATASET
);
110 writel(0x00000000, ca_base
+ 0x2300);
111 writel(0x00400020, dc_base
+ UMC_DCCGCTL
);
112 writel(0x0000000f, dc_base
+ 0x7000);
113 writel(0x0000000f, dc_base
+ 0x8000);
114 writel(0x000000c3, dc_base
+ 0x8004);
115 writel(0x00000071, dc_base
+ 0x8008);
116 writel(0x00000004, dc_base
+ UMC_FLOWCTLG
);
117 writel(0x00000000, dc_base
+ 0x0060);
118 writel(0x80000201, ca_base
+ 0xc20);
119 writel(0x0801e01e, dc_base
+ UMC_FLOWCTLA
);
120 writel(0x00200000, dc_base
+ UMC_FLOWCTLB
);
121 writel(0x00004444, dc_base
+ UMC_FLOWCTLC
);
122 writel(0x200a0a00, dc_base
+ UMC_SPCSETB
);
123 writel(0x00010000, dc_base
+ UMC_SPCSETD
);
124 writel(0x80000020, dc_base
+ UMC_DFICUPDCTLA
);
129 static int umc_ch_init(void __iomem
*dc_base
, void __iomem
*ca_base
,
130 int freq
, unsigned long size
, unsigned int width
,
133 void __iomem
*phy_base
= dc_base
+ 0x00001000;
134 int nr_phy
= width
/ 16;
137 writel(UMC_INITSET_INIT1EN
, dc_base
+ UMC_INITSET
);
138 while (readl(dc_base
+ UMC_INITSET
) & UMC_INITSTAT_INIT1ST
)
141 for (phy
= 0; phy
< nr_phy
; phy
++) {
142 writel(0x00000100 | ((1 << (phy
+ 1)) - 1),
143 dc_base
+ UMC_DIOCTLA
);
145 ret
= ph1_ld4_ddrphy_init(phy_base
, freq
, ddr3plus
);
149 ddrphy_prepare_training(phy_base
, phy
);
150 ret
= ddrphy_training(phy_base
);
154 phy_base
+= 0x00001000;
157 return umc_dramcont_init(dc_base
, ca_base
, freq
, size
/ (width
/ 16),
161 int ph1_pro4_umc_init(const struct uniphier_board_data
*bd
)
163 void __iomem
*umc_base
= (void __iomem
*)0x5b800000;
164 void __iomem
*ca_base
= umc_base
+ 0x00001000;
165 void __iomem
*dc_base
= umc_base
+ 0x00400000;
166 void __iomem
*ssif_base
= umc_base
;
169 for (ch
= 0; ch
< DRAM_CH_NR
; ch
++) {
170 ret
= umc_ch_init(dc_base
, ca_base
, bd
->dram_freq
,
171 bd
->dram_ch
[ch
].size
,
172 bd
->dram_ch
[ch
].width
,
175 pr_err("failed to initialize UMC ch%d\n", ch
);
179 ca_base
+= 0x00001000;
180 dc_base
+= 0x00200000;
183 umc_start_ssif(ssif_base
);