1a75d2fbeSKever Yang /*
2a75d2fbeSKever Yang * (C) Copyright 2015 Google, Inc
3a75d2fbeSKever Yang * Copyright 2014 Rockchip Inc.
4a75d2fbeSKever Yang *
5a75d2fbeSKever Yang * SPDX-License-Identifier: GPL-2.0
6a75d2fbeSKever Yang *
7a75d2fbeSKever Yang * Adapted from coreboot.
8a75d2fbeSKever Yang */
9a75d2fbeSKever Yang
10a75d2fbeSKever Yang #include <common.h>
11a75d2fbeSKever Yang #include <clk.h>
12a75d2fbeSKever Yang #include <dm.h>
13a75d2fbeSKever Yang #include <dt-structs.h>
14a75d2fbeSKever Yang #include <errno.h>
15a75d2fbeSKever Yang #include <ram.h>
16a75d2fbeSKever Yang #include <regmap.h>
17a75d2fbeSKever Yang #include <syscon.h>
18a75d2fbeSKever Yang #include <asm/io.h>
19a75d2fbeSKever Yang #include <asm/arch/clock.h>
20a75d2fbeSKever Yang #include <asm/arch/cru_rk3288.h>
21a75d2fbeSKever Yang #include <asm/arch/ddr_rk3288.h>
22a75d2fbeSKever Yang #include <asm/arch/grf_rk3288.h>
23a75d2fbeSKever Yang #include <asm/arch/pmu_rk3288.h>
24451da917SYouMin Chen #include <asm/arch/sdram_rk3288.h>
25e1f97ec3SYouMin Chen #include <asm/arch/sdram.h>
26a75d2fbeSKever Yang #include <linux/err.h>
27a75d2fbeSKever Yang #include <power/regulator.h>
28a75d2fbeSKever Yang #include <power/rk8xx_pmic.h>
29a75d2fbeSKever Yang
30a75d2fbeSKever Yang DECLARE_GLOBAL_DATA_PTR;
31a75d2fbeSKever Yang
32a75d2fbeSKever Yang struct chan_info {
33a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl;
34a75d2fbeSKever Yang struct rk3288_ddr_publ *publ;
35a75d2fbeSKever Yang struct rk3288_msch *msch;
36a75d2fbeSKever Yang };
37a75d2fbeSKever Yang
38a75d2fbeSKever Yang struct dram_info {
39a75d2fbeSKever Yang struct chan_info chan[2];
40a75d2fbeSKever Yang struct ram_info info;
41a75d2fbeSKever Yang struct clk ddr_clk;
42a75d2fbeSKever Yang struct rk3288_cru *cru;
43a75d2fbeSKever Yang struct rk3288_grf *grf;
44a75d2fbeSKever Yang struct rk3288_sgrf *sgrf;
45a75d2fbeSKever Yang struct rk3288_pmu *pmu;
46a75d2fbeSKever Yang bool is_veyron;
47a75d2fbeSKever Yang };
48a75d2fbeSKever Yang
49a75d2fbeSKever Yang struct rk3288_sdram_params {
50a75d2fbeSKever Yang #if CONFIG_IS_ENABLED(OF_PLATDATA)
51a75d2fbeSKever Yang struct dtd_rockchip_rk3288_dmc of_plat;
52a75d2fbeSKever Yang #endif
53a75d2fbeSKever Yang struct rk3288_sdram_channel ch[2];
54a75d2fbeSKever Yang struct rk3288_sdram_pctl_timing pctl_timing;
55a75d2fbeSKever Yang struct rk3288_sdram_phy_timing phy_timing;
56a75d2fbeSKever Yang struct rk3288_base_params base;
57a75d2fbeSKever Yang int num_channels;
58a75d2fbeSKever Yang struct regmap *map;
59a75d2fbeSKever Yang };
60a75d2fbeSKever Yang
61a75d2fbeSKever Yang const int ddrconf_table[] = {
62a75d2fbeSKever Yang /* row col,bw */
63a75d2fbeSKever Yang 0,
64a75d2fbeSKever Yang ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
65a75d2fbeSKever Yang ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
66a75d2fbeSKever Yang ((3 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
67a75d2fbeSKever Yang ((4 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
68a75d2fbeSKever Yang ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
69a75d2fbeSKever Yang ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
70a75d2fbeSKever Yang ((3 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
71a75d2fbeSKever Yang ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
72a75d2fbeSKever Yang ((2 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
73a75d2fbeSKever Yang ((3 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
74a75d2fbeSKever Yang 0,
75a75d2fbeSKever Yang 0,
76a75d2fbeSKever Yang 0,
77a75d2fbeSKever Yang 0,
78a75d2fbeSKever Yang ((4 << 4) | 2),
79a75d2fbeSKever Yang };
80a75d2fbeSKever Yang
81a75d2fbeSKever Yang #define TEST_PATTEN 0x5aa5f00f
82a75d2fbeSKever Yang #define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
83a75d2fbeSKever Yang #define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
84a75d2fbeSKever Yang
85a75d2fbeSKever Yang #ifdef CONFIG_SPL_BUILD
copy_to_reg(u32 * dest,const u32 * src,u32 n)86a75d2fbeSKever Yang static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
87a75d2fbeSKever Yang {
88a75d2fbeSKever Yang int i;
89a75d2fbeSKever Yang
90a75d2fbeSKever Yang for (i = 0; i < n / sizeof(u32); i++) {
91a75d2fbeSKever Yang writel(*src, dest);
92a75d2fbeSKever Yang src++;
93a75d2fbeSKever Yang dest++;
94a75d2fbeSKever Yang }
95a75d2fbeSKever Yang }
96a75d2fbeSKever Yang
ddr_reset(struct rk3288_cru * cru,u32 ch,u32 ctl,u32 phy)97a75d2fbeSKever Yang static void ddr_reset(struct rk3288_cru *cru, u32 ch, u32 ctl, u32 phy)
98a75d2fbeSKever Yang {
99a75d2fbeSKever Yang u32 phy_ctl_srstn_shift = 4 + 5 * ch;
100a75d2fbeSKever Yang u32 ctl_psrstn_shift = 3 + 5 * ch;
101a75d2fbeSKever Yang u32 ctl_srstn_shift = 2 + 5 * ch;
102a75d2fbeSKever Yang u32 phy_psrstn_shift = 1 + 5 * ch;
103a75d2fbeSKever Yang u32 phy_srstn_shift = 5 * ch;
104a75d2fbeSKever Yang
105a75d2fbeSKever Yang rk_clrsetreg(&cru->cru_softrst_con[10],
106a75d2fbeSKever Yang 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
107a75d2fbeSKever Yang 1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
108a75d2fbeSKever Yang 1 << phy_srstn_shift,
109a75d2fbeSKever Yang phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
110a75d2fbeSKever Yang ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
111a75d2fbeSKever Yang phy << phy_srstn_shift);
112a75d2fbeSKever Yang }
113a75d2fbeSKever Yang
ddr_phy_ctl_reset(struct rk3288_cru * cru,u32 ch,u32 n)114a75d2fbeSKever Yang static void ddr_phy_ctl_reset(struct rk3288_cru *cru, u32 ch, u32 n)
115a75d2fbeSKever Yang {
116a75d2fbeSKever Yang u32 phy_ctl_srstn_shift = 4 + 5 * ch;
117a75d2fbeSKever Yang
118a75d2fbeSKever Yang rk_clrsetreg(&cru->cru_softrst_con[10],
119a75d2fbeSKever Yang 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
120a75d2fbeSKever Yang }
121a75d2fbeSKever Yang
phy_pctrl_reset(struct rk3288_cru * cru,struct rk3288_ddr_publ * publ,int channel)122a75d2fbeSKever Yang static void phy_pctrl_reset(struct rk3288_cru *cru,
123a75d2fbeSKever Yang struct rk3288_ddr_publ *publ,
124a75d2fbeSKever Yang int channel)
125a75d2fbeSKever Yang {
126a75d2fbeSKever Yang int i;
127a75d2fbeSKever Yang
128a75d2fbeSKever Yang ddr_reset(cru, channel, 1, 1);
129a75d2fbeSKever Yang udelay(1);
130a75d2fbeSKever Yang clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
131a75d2fbeSKever Yang for (i = 0; i < 4; i++)
132a75d2fbeSKever Yang clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
133a75d2fbeSKever Yang
134a75d2fbeSKever Yang udelay(10);
135a75d2fbeSKever Yang setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
136a75d2fbeSKever Yang for (i = 0; i < 4; i++)
137a75d2fbeSKever Yang setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
138a75d2fbeSKever Yang
139a75d2fbeSKever Yang udelay(10);
140a75d2fbeSKever Yang ddr_reset(cru, channel, 1, 0);
141a75d2fbeSKever Yang udelay(10);
142a75d2fbeSKever Yang ddr_reset(cru, channel, 0, 0);
143a75d2fbeSKever Yang udelay(10);
144a75d2fbeSKever Yang }
145a75d2fbeSKever Yang
phy_dll_bypass_set(struct rk3288_ddr_publ * publ,u32 freq)146a75d2fbeSKever Yang static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
147a75d2fbeSKever Yang u32 freq)
148a75d2fbeSKever Yang {
149a75d2fbeSKever Yang int i;
150a75d2fbeSKever Yang
151a75d2fbeSKever Yang if (freq <= 250000000) {
152a75d2fbeSKever Yang if (freq <= 150000000)
153a75d2fbeSKever Yang clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
154a75d2fbeSKever Yang else
155a75d2fbeSKever Yang setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
156a75d2fbeSKever Yang setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
157a75d2fbeSKever Yang for (i = 0; i < 4; i++)
158a75d2fbeSKever Yang setbits_le32(&publ->datx8[i].dxdllcr,
159a75d2fbeSKever Yang DXDLLCR_DLLDIS);
160a75d2fbeSKever Yang
161a75d2fbeSKever Yang setbits_le32(&publ->pir, PIR_DLLBYP);
162a75d2fbeSKever Yang } else {
163a75d2fbeSKever Yang clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
164a75d2fbeSKever Yang clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
165a75d2fbeSKever Yang for (i = 0; i < 4; i++) {
166a75d2fbeSKever Yang clrbits_le32(&publ->datx8[i].dxdllcr,
167a75d2fbeSKever Yang DXDLLCR_DLLDIS);
168a75d2fbeSKever Yang }
169a75d2fbeSKever Yang
170a75d2fbeSKever Yang clrbits_le32(&publ->pir, PIR_DLLBYP);
171a75d2fbeSKever Yang }
172a75d2fbeSKever Yang }
173a75d2fbeSKever Yang
dfi_cfg(struct rk3288_ddr_pctl * pctl,u32 dramtype)174a75d2fbeSKever Yang static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
175a75d2fbeSKever Yang {
176a75d2fbeSKever Yang writel(DFI_INIT_START, &pctl->dfistcfg0);
177a75d2fbeSKever Yang writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
178a75d2fbeSKever Yang &pctl->dfistcfg1);
179a75d2fbeSKever Yang writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
180a75d2fbeSKever Yang writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
181a75d2fbeSKever Yang &pctl->dfilpcfg0);
182a75d2fbeSKever Yang
183a75d2fbeSKever Yang writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
184a75d2fbeSKever Yang writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
185a75d2fbeSKever Yang writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
186a75d2fbeSKever Yang writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
187a75d2fbeSKever Yang writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
188a75d2fbeSKever Yang writel(1, &pctl->dfitphyupdtype0);
189a75d2fbeSKever Yang
190a75d2fbeSKever Yang /* cs0 and cs1 write odt enable */
191a75d2fbeSKever Yang writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
192a75d2fbeSKever Yang &pctl->dfiodtcfg);
193a75d2fbeSKever Yang /* odt write length */
194a75d2fbeSKever Yang writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
195a75d2fbeSKever Yang /* phyupd and ctrlupd disabled */
196a75d2fbeSKever Yang writel(0, &pctl->dfiupdcfg);
197a75d2fbeSKever Yang }
198a75d2fbeSKever Yang
ddr_set_enable(struct rk3288_grf * grf,uint channel,bool enable)199a75d2fbeSKever Yang static void ddr_set_enable(struct rk3288_grf *grf, uint channel, bool enable)
200a75d2fbeSKever Yang {
201a75d2fbeSKever Yang uint val = 0;
202a75d2fbeSKever Yang
203a75d2fbeSKever Yang if (enable) {
204a75d2fbeSKever Yang val = 1 << (channel ? DDR1_16BIT_EN_SHIFT :
205a75d2fbeSKever Yang DDR0_16BIT_EN_SHIFT);
206a75d2fbeSKever Yang }
207a75d2fbeSKever Yang rk_clrsetreg(&grf->soc_con0,
208a75d2fbeSKever Yang 1 << (channel ? DDR1_16BIT_EN_SHIFT : DDR0_16BIT_EN_SHIFT),
209a75d2fbeSKever Yang val);
210a75d2fbeSKever Yang }
211a75d2fbeSKever Yang
ddr_set_ddr3_mode(struct rk3288_grf * grf,uint channel,bool ddr3_mode)212a75d2fbeSKever Yang static void ddr_set_ddr3_mode(struct rk3288_grf *grf, uint channel,
213a75d2fbeSKever Yang bool ddr3_mode)
214a75d2fbeSKever Yang {
215a75d2fbeSKever Yang uint mask, val;
216a75d2fbeSKever Yang
217a75d2fbeSKever Yang mask = 1 << (channel ? MSCH1_MAINDDR3_SHIFT : MSCH0_MAINDDR3_SHIFT);
218a75d2fbeSKever Yang val = ddr3_mode << (channel ? MSCH1_MAINDDR3_SHIFT :
219a75d2fbeSKever Yang MSCH0_MAINDDR3_SHIFT);
220a75d2fbeSKever Yang rk_clrsetreg(&grf->soc_con0, mask, val);
221a75d2fbeSKever Yang }
222a75d2fbeSKever Yang
ddr_set_en_bst_odt(struct rk3288_grf * grf,uint channel,bool enable,bool enable_bst,bool enable_odt)223a75d2fbeSKever Yang static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel,
224a75d2fbeSKever Yang bool enable, bool enable_bst, bool enable_odt)
225a75d2fbeSKever Yang {
226a75d2fbeSKever Yang uint mask;
227a75d2fbeSKever Yang bool disable_bst = !enable_bst;
228a75d2fbeSKever Yang
229a75d2fbeSKever Yang mask = channel ?
230a75d2fbeSKever Yang (1 << LPDDR3_EN1_SHIFT | 1 << UPCTL1_BST_DIABLE_SHIFT |
231a75d2fbeSKever Yang 1 << UPCTL1_LPDDR3_ODT_EN_SHIFT) :
232a75d2fbeSKever Yang (1 << LPDDR3_EN0_SHIFT | 1 << UPCTL0_BST_DIABLE_SHIFT |
233a75d2fbeSKever Yang 1 << UPCTL0_LPDDR3_ODT_EN_SHIFT);
234a75d2fbeSKever Yang rk_clrsetreg(&grf->soc_con2, mask,
235a75d2fbeSKever Yang enable << (channel ? LPDDR3_EN1_SHIFT : LPDDR3_EN0_SHIFT) |
236a75d2fbeSKever Yang disable_bst << (channel ? UPCTL1_BST_DIABLE_SHIFT :
237a75d2fbeSKever Yang UPCTL0_BST_DIABLE_SHIFT) |
238a75d2fbeSKever Yang enable_odt << (channel ? UPCTL1_LPDDR3_ODT_EN_SHIFT :
239a75d2fbeSKever Yang UPCTL0_LPDDR3_ODT_EN_SHIFT));
240a75d2fbeSKever Yang }
241a75d2fbeSKever Yang
pctl_cfg(int channel,struct rk3288_ddr_pctl * pctl,struct rk3288_sdram_params * sdram_params,struct rk3288_grf * grf)242a75d2fbeSKever Yang static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
243a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params,
244a75d2fbeSKever Yang struct rk3288_grf *grf)
245a75d2fbeSKever Yang {
246a75d2fbeSKever Yang unsigned int burstlen;
247a75d2fbeSKever Yang
248a75d2fbeSKever Yang burstlen = (sdram_params->base.noc_timing >> 18) & 0x7;
249a75d2fbeSKever Yang copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
250a75d2fbeSKever Yang sizeof(sdram_params->pctl_timing));
251a75d2fbeSKever Yang switch (sdram_params->base.dramtype) {
252a75d2fbeSKever Yang case LPDDR3:
253a75d2fbeSKever Yang writel(sdram_params->pctl_timing.tcl - 1,
254a75d2fbeSKever Yang &pctl->dfitrddataen);
255a75d2fbeSKever Yang writel(sdram_params->pctl_timing.tcwl,
256a75d2fbeSKever Yang &pctl->dfitphywrlat);
257a75d2fbeSKever Yang burstlen >>= 1;
258a75d2fbeSKever Yang writel(LPDDR2_S4 | 0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
259a75d2fbeSKever Yang LPDDR2_EN | burstlen << BURSTLENGTH_SHIFT |
260a75d2fbeSKever Yang (6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
261a75d2fbeSKever Yang 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
262a75d2fbeSKever Yang &pctl->mcfg);
263a75d2fbeSKever Yang ddr_set_ddr3_mode(grf, channel, false);
264a75d2fbeSKever Yang ddr_set_enable(grf, channel, true);
265a75d2fbeSKever Yang ddr_set_en_bst_odt(grf, channel, true, false,
266a75d2fbeSKever Yang sdram_params->base.odt);
267a75d2fbeSKever Yang break;
268a75d2fbeSKever Yang case DDR3:
269a75d2fbeSKever Yang if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
270a75d2fbeSKever Yang writel(sdram_params->pctl_timing.tcl - 3,
271a75d2fbeSKever Yang &pctl->dfitrddataen);
272a75d2fbeSKever Yang } else {
273a75d2fbeSKever Yang writel(sdram_params->pctl_timing.tcl - 2,
274a75d2fbeSKever Yang &pctl->dfitrddataen);
275a75d2fbeSKever Yang }
276a75d2fbeSKever Yang writel(sdram_params->pctl_timing.tcwl - 1,
277a75d2fbeSKever Yang &pctl->dfitphywrlat);
278a75d2fbeSKever Yang writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
279a75d2fbeSKever Yang DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
280a75d2fbeSKever Yang 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
281a75d2fbeSKever Yang &pctl->mcfg);
282a75d2fbeSKever Yang ddr_set_ddr3_mode(grf, channel, true);
283a75d2fbeSKever Yang ddr_set_enable(grf, channel, true);
284a75d2fbeSKever Yang
285a75d2fbeSKever Yang ddr_set_en_bst_odt(grf, channel, false, true, false);
286a75d2fbeSKever Yang break;
287a75d2fbeSKever Yang }
288a75d2fbeSKever Yang
289a75d2fbeSKever Yang setbits_le32(&pctl->scfg, 1);
290a75d2fbeSKever Yang }
291a75d2fbeSKever Yang
phy_cfg(const struct chan_info * chan,int channel,struct rk3288_sdram_params * sdram_params)292a75d2fbeSKever Yang static void phy_cfg(const struct chan_info *chan, int channel,
293a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
294a75d2fbeSKever Yang {
295a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
296a75d2fbeSKever Yang struct rk3288_msch *msch = chan->msch;
297a75d2fbeSKever Yang uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
298a75d2fbeSKever Yang u32 dinit2, tmp;
299a75d2fbeSKever Yang int i;
300a75d2fbeSKever Yang
301a75d2fbeSKever Yang dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
302a75d2fbeSKever Yang /* DDR PHY Timing */
303a75d2fbeSKever Yang copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
304a75d2fbeSKever Yang sizeof(sdram_params->phy_timing));
305a75d2fbeSKever Yang writel(sdram_params->base.noc_timing, &msch->ddrtiming);
306a75d2fbeSKever Yang writel(0x3f, &msch->readlatency);
307a75d2fbeSKever Yang writel(sdram_params->base.noc_activate, &msch->activate);
308a75d2fbeSKever Yang writel(2 << BUSWRTORD_SHIFT | 2 << BUSRDTOWR_SHIFT |
309a75d2fbeSKever Yang 1 << BUSRDTORD_SHIFT, &msch->devtodev);
310a75d2fbeSKever Yang writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
311a75d2fbeSKever Yang DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
312a75d2fbeSKever Yang 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
313a75d2fbeSKever Yang writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
314a75d2fbeSKever Yang DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
315a75d2fbeSKever Yang &publ->ptr[1]);
316a75d2fbeSKever Yang writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
317a75d2fbeSKever Yang DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
318a75d2fbeSKever Yang &publ->ptr[2]);
319a75d2fbeSKever Yang
320a75d2fbeSKever Yang switch (sdram_params->base.dramtype) {
321a75d2fbeSKever Yang case LPDDR3:
322a75d2fbeSKever Yang clrsetbits_le32(&publ->pgcr, 0x1F,
323a75d2fbeSKever Yang 0 << PGCR_DFTLMT_SHIFT |
324a75d2fbeSKever Yang 0 << PGCR_DFTCMP_SHIFT |
325a75d2fbeSKever Yang 1 << PGCR_DQSCFG_SHIFT |
326a75d2fbeSKever Yang 0 << PGCR_ITMDMD_SHIFT);
327a75d2fbeSKever Yang /* DDRMODE select LPDDR3 */
328a75d2fbeSKever Yang clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
329a75d2fbeSKever Yang DDRMD_LPDDR2_LPDDR3 << DDRMD_SHIFT);
330a75d2fbeSKever Yang clrsetbits_le32(&publ->dxccr,
331a75d2fbeSKever Yang DQSNRES_MASK << DQSNRES_SHIFT |
332a75d2fbeSKever Yang DQSRES_MASK << DQSRES_SHIFT,
333a75d2fbeSKever Yang 4 << DQSRES_SHIFT | 0xc << DQSNRES_SHIFT);
334a75d2fbeSKever Yang tmp = readl(&publ->dtpr[1]);
335a75d2fbeSKever Yang tmp = ((tmp >> TDQSCKMAX_SHIFT) & TDQSCKMAX_MASK) -
336a75d2fbeSKever Yang ((tmp >> TDQSCK_SHIFT) & TDQSCK_MASK);
337a75d2fbeSKever Yang clrsetbits_le32(&publ->dsgcr,
338a75d2fbeSKever Yang DQSGE_MASK << DQSGE_SHIFT |
339a75d2fbeSKever Yang DQSGX_MASK << DQSGX_SHIFT,
340a75d2fbeSKever Yang tmp << DQSGE_SHIFT | tmp << DQSGX_SHIFT);
341a75d2fbeSKever Yang break;
342a75d2fbeSKever Yang case DDR3:
343a75d2fbeSKever Yang clrbits_le32(&publ->pgcr, 0x1f);
344a75d2fbeSKever Yang clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
345a75d2fbeSKever Yang DDRMD_DDR3 << DDRMD_SHIFT);
346a75d2fbeSKever Yang break;
347a75d2fbeSKever Yang }
348a75d2fbeSKever Yang if (sdram_params->base.odt) {
349a75d2fbeSKever Yang /*dynamic RTT enable */
350a75d2fbeSKever Yang for (i = 0; i < 4; i++)
351a75d2fbeSKever Yang setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
352a75d2fbeSKever Yang } else {
353a75d2fbeSKever Yang /*dynamic RTT disable */
354a75d2fbeSKever Yang for (i = 0; i < 4; i++)
355a75d2fbeSKever Yang clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
356a75d2fbeSKever Yang }
357a75d2fbeSKever Yang }
358a75d2fbeSKever Yang
phy_init(struct rk3288_ddr_publ * publ)359a75d2fbeSKever Yang static void phy_init(struct rk3288_ddr_publ *publ)
360a75d2fbeSKever Yang {
361a75d2fbeSKever Yang setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
362a75d2fbeSKever Yang | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
363a75d2fbeSKever Yang udelay(1);
364a75d2fbeSKever Yang while ((readl(&publ->pgsr) &
365a75d2fbeSKever Yang (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
366a75d2fbeSKever Yang (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
367a75d2fbeSKever Yang ;
368a75d2fbeSKever Yang }
369a75d2fbeSKever Yang
send_command(struct rk3288_ddr_pctl * pctl,u32 rank,u32 cmd,u32 arg)370a75d2fbeSKever Yang static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
371a75d2fbeSKever Yang u32 cmd, u32 arg)
372a75d2fbeSKever Yang {
373a75d2fbeSKever Yang writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
374a75d2fbeSKever Yang udelay(1);
375a75d2fbeSKever Yang while (readl(&pctl->mcmd) & START_CMD)
376a75d2fbeSKever Yang ;
377a75d2fbeSKever Yang }
378a75d2fbeSKever Yang
send_command_op(struct rk3288_ddr_pctl * pctl,u32 rank,u32 cmd,u32 ma,u32 op)379a75d2fbeSKever Yang static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
380a75d2fbeSKever Yang u32 rank, u32 cmd, u32 ma, u32 op)
381a75d2fbeSKever Yang {
382a75d2fbeSKever Yang send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
383a75d2fbeSKever Yang (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
384a75d2fbeSKever Yang }
385a75d2fbeSKever Yang
memory_init(struct rk3288_ddr_publ * publ,u32 dramtype)386a75d2fbeSKever Yang static void memory_init(struct rk3288_ddr_publ *publ,
387a75d2fbeSKever Yang u32 dramtype)
388a75d2fbeSKever Yang {
389a75d2fbeSKever Yang setbits_le32(&publ->pir,
390a75d2fbeSKever Yang (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
391a75d2fbeSKever Yang | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
392a75d2fbeSKever Yang | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
393a75d2fbeSKever Yang udelay(1);
394a75d2fbeSKever Yang while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
395a75d2fbeSKever Yang != (PGSR_IDONE | PGSR_DLDONE))
396a75d2fbeSKever Yang ;
397a75d2fbeSKever Yang }
398a75d2fbeSKever Yang
move_to_config_state(struct rk3288_ddr_publ * publ,struct rk3288_ddr_pctl * pctl)399a75d2fbeSKever Yang static void move_to_config_state(struct rk3288_ddr_publ *publ,
400a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl)
401a75d2fbeSKever Yang {
402a75d2fbeSKever Yang unsigned int state;
403a75d2fbeSKever Yang
404a75d2fbeSKever Yang while (1) {
405a75d2fbeSKever Yang state = readl(&pctl->stat) & PCTL_STAT_MSK;
406a75d2fbeSKever Yang
407a75d2fbeSKever Yang switch (state) {
408a75d2fbeSKever Yang case LOW_POWER:
409a75d2fbeSKever Yang writel(WAKEUP_STATE, &pctl->sctl);
410a75d2fbeSKever Yang while ((readl(&pctl->stat) & PCTL_STAT_MSK)
411a75d2fbeSKever Yang != ACCESS)
412a75d2fbeSKever Yang ;
413a75d2fbeSKever Yang /* wait DLL lock */
414a75d2fbeSKever Yang while ((readl(&publ->pgsr) & PGSR_DLDONE)
415a75d2fbeSKever Yang != PGSR_DLDONE)
416a75d2fbeSKever Yang ;
417a75d2fbeSKever Yang /*
418a75d2fbeSKever Yang * if at low power state,need wakeup first,
419a75d2fbeSKever Yang * and then enter the config
420a75d2fbeSKever Yang * so here no break.
421a75d2fbeSKever Yang */
422a75d2fbeSKever Yang case ACCESS:
423a75d2fbeSKever Yang /* no break */
424a75d2fbeSKever Yang case INIT_MEM:
425a75d2fbeSKever Yang writel(CFG_STATE, &pctl->sctl);
426a75d2fbeSKever Yang while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
427a75d2fbeSKever Yang ;
428a75d2fbeSKever Yang break;
429a75d2fbeSKever Yang case CONFIG:
430a75d2fbeSKever Yang return;
431a75d2fbeSKever Yang default:
432a75d2fbeSKever Yang break;
433a75d2fbeSKever Yang }
434a75d2fbeSKever Yang }
435a75d2fbeSKever Yang }
436a75d2fbeSKever Yang
set_bandwidth_ratio(const struct chan_info * chan,int channel,u32 n,struct rk3288_grf * grf)437a75d2fbeSKever Yang static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
438a75d2fbeSKever Yang u32 n, struct rk3288_grf *grf)
439a75d2fbeSKever Yang {
440a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl = chan->pctl;
441a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
442a75d2fbeSKever Yang struct rk3288_msch *msch = chan->msch;
443a75d2fbeSKever Yang
444a75d2fbeSKever Yang if (n == 1) {
445a75d2fbeSKever Yang setbits_le32(&pctl->ppcfg, 1);
446a75d2fbeSKever Yang rk_setreg(&grf->soc_con0, 1 << (8 + channel));
447a75d2fbeSKever Yang setbits_le32(&msch->ddrtiming, 1 << 31);
448a75d2fbeSKever Yang /* Data Byte disable*/
449a75d2fbeSKever Yang clrbits_le32(&publ->datx8[2].dxgcr, 1);
450a75d2fbeSKever Yang clrbits_le32(&publ->datx8[3].dxgcr, 1);
451a75d2fbeSKever Yang /* disable DLL */
452a75d2fbeSKever Yang setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
453a75d2fbeSKever Yang setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
454a75d2fbeSKever Yang } else {
455a75d2fbeSKever Yang clrbits_le32(&pctl->ppcfg, 1);
456a75d2fbeSKever Yang rk_clrreg(&grf->soc_con0, 1 << (8 + channel));
457a75d2fbeSKever Yang clrbits_le32(&msch->ddrtiming, 1 << 31);
458a75d2fbeSKever Yang /* Data Byte enable*/
459a75d2fbeSKever Yang setbits_le32(&publ->datx8[2].dxgcr, 1);
460a75d2fbeSKever Yang setbits_le32(&publ->datx8[3].dxgcr, 1);
461a75d2fbeSKever Yang
462a75d2fbeSKever Yang /* enable DLL */
463a75d2fbeSKever Yang clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
464a75d2fbeSKever Yang clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
465a75d2fbeSKever Yang /* reset DLL */
466a75d2fbeSKever Yang clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
467a75d2fbeSKever Yang clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
468a75d2fbeSKever Yang udelay(10);
469a75d2fbeSKever Yang setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
470a75d2fbeSKever Yang setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
471a75d2fbeSKever Yang }
472a75d2fbeSKever Yang setbits_le32(&pctl->dfistcfg0, 1 << 2);
473a75d2fbeSKever Yang }
474a75d2fbeSKever Yang
data_training(const struct chan_info * chan,int channel,struct rk3288_sdram_params * sdram_params)475a75d2fbeSKever Yang static int data_training(const struct chan_info *chan, int channel,
476a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
477a75d2fbeSKever Yang {
478a75d2fbeSKever Yang unsigned int j;
479a75d2fbeSKever Yang int ret = 0;
480a75d2fbeSKever Yang u32 rank;
481a75d2fbeSKever Yang int i;
482a75d2fbeSKever Yang u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
483a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
484a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl = chan->pctl;
485a75d2fbeSKever Yang
486a75d2fbeSKever Yang /* disable auto refresh */
487a75d2fbeSKever Yang writel(0, &pctl->trefi);
488a75d2fbeSKever Yang
489a75d2fbeSKever Yang if (sdram_params->base.dramtype != LPDDR3)
490a75d2fbeSKever Yang setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
491a75d2fbeSKever Yang rank = sdram_params->ch[channel].rank | 1;
492a75d2fbeSKever Yang for (j = 0; j < ARRAY_SIZE(step); j++) {
493a75d2fbeSKever Yang /*
494a75d2fbeSKever Yang * trigger QSTRN and RVTRN
495a75d2fbeSKever Yang * clear DTDONE status
496a75d2fbeSKever Yang */
497a75d2fbeSKever Yang setbits_le32(&publ->pir, PIR_CLRSR);
498a75d2fbeSKever Yang
499a75d2fbeSKever Yang /* trigger DTT */
500a75d2fbeSKever Yang setbits_le32(&publ->pir,
501a75d2fbeSKever Yang PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
502a75d2fbeSKever Yang PIR_CLRSR);
503a75d2fbeSKever Yang udelay(1);
504a75d2fbeSKever Yang /* wait echo byte DTDONE */
505a75d2fbeSKever Yang while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
506a75d2fbeSKever Yang != rank)
507a75d2fbeSKever Yang ;
508a75d2fbeSKever Yang while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
509a75d2fbeSKever Yang != rank)
510a75d2fbeSKever Yang ;
511a75d2fbeSKever Yang if (!(readl(&pctl->ppcfg) & 1)) {
512a75d2fbeSKever Yang while ((readl(&publ->datx8[2].dxgsr[0])
513a75d2fbeSKever Yang & rank) != rank)
514a75d2fbeSKever Yang ;
515a75d2fbeSKever Yang while ((readl(&publ->datx8[3].dxgsr[0])
516a75d2fbeSKever Yang & rank) != rank)
517a75d2fbeSKever Yang ;
518a75d2fbeSKever Yang }
519a75d2fbeSKever Yang if (readl(&publ->pgsr) &
520a75d2fbeSKever Yang (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
521a75d2fbeSKever Yang ret = -1;
522a75d2fbeSKever Yang break;
523a75d2fbeSKever Yang }
524a75d2fbeSKever Yang }
525a75d2fbeSKever Yang /* send some auto refresh to complement the lost while DTT */
526a75d2fbeSKever Yang for (i = 0; i < (rank > 1 ? 8 : 4); i++)
527a75d2fbeSKever Yang send_command(pctl, rank, REF_CMD, 0);
528a75d2fbeSKever Yang
529a75d2fbeSKever Yang if (sdram_params->base.dramtype != LPDDR3)
530a75d2fbeSKever Yang clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
531a75d2fbeSKever Yang
532a75d2fbeSKever Yang /* resume auto refresh */
533a75d2fbeSKever Yang writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
534a75d2fbeSKever Yang
535a75d2fbeSKever Yang return ret;
536a75d2fbeSKever Yang }
537a75d2fbeSKever Yang
move_to_access_state(const struct chan_info * chan)538a75d2fbeSKever Yang static void move_to_access_state(const struct chan_info *chan)
539a75d2fbeSKever Yang {
540a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
541a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl = chan->pctl;
542a75d2fbeSKever Yang unsigned int state;
543a75d2fbeSKever Yang
544a75d2fbeSKever Yang while (1) {
545a75d2fbeSKever Yang state = readl(&pctl->stat) & PCTL_STAT_MSK;
546a75d2fbeSKever Yang
547a75d2fbeSKever Yang switch (state) {
548a75d2fbeSKever Yang case LOW_POWER:
549a75d2fbeSKever Yang if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
550a75d2fbeSKever Yang LP_TRIG_MASK) == 1)
551a75d2fbeSKever Yang return;
552a75d2fbeSKever Yang
553a75d2fbeSKever Yang writel(WAKEUP_STATE, &pctl->sctl);
554a75d2fbeSKever Yang while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
555a75d2fbeSKever Yang ;
556a75d2fbeSKever Yang /* wait DLL lock */
557a75d2fbeSKever Yang while ((readl(&publ->pgsr) & PGSR_DLDONE)
558a75d2fbeSKever Yang != PGSR_DLDONE)
559a75d2fbeSKever Yang ;
560a75d2fbeSKever Yang break;
561a75d2fbeSKever Yang case INIT_MEM:
562a75d2fbeSKever Yang writel(CFG_STATE, &pctl->sctl);
563a75d2fbeSKever Yang while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
564a75d2fbeSKever Yang ;
565a75d2fbeSKever Yang case CONFIG:
566a75d2fbeSKever Yang writel(GO_STATE, &pctl->sctl);
567a75d2fbeSKever Yang while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
568a75d2fbeSKever Yang ;
569a75d2fbeSKever Yang break;
570a75d2fbeSKever Yang case ACCESS:
571a75d2fbeSKever Yang return;
572a75d2fbeSKever Yang default:
573a75d2fbeSKever Yang break;
574a75d2fbeSKever Yang }
575a75d2fbeSKever Yang }
576a75d2fbeSKever Yang }
577a75d2fbeSKever Yang
dram_cfg_rbc(const struct chan_info * chan,u32 chnum,struct rk3288_sdram_params * sdram_params)578a75d2fbeSKever Yang static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
579a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
580a75d2fbeSKever Yang {
581a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
582a75d2fbeSKever Yang
583a75d2fbeSKever Yang if (sdram_params->ch[chnum].bk == 3)
584a75d2fbeSKever Yang clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
585a75d2fbeSKever Yang 1 << PDQ_SHIFT);
586a75d2fbeSKever Yang else
587a75d2fbeSKever Yang clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
588a75d2fbeSKever Yang
589a75d2fbeSKever Yang writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
590a75d2fbeSKever Yang }
591a75d2fbeSKever Yang
dram_all_config(const struct dram_info * dram,struct rk3288_sdram_params * sdram_params)592a75d2fbeSKever Yang static void dram_all_config(const struct dram_info *dram,
593a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
594a75d2fbeSKever Yang {
595a75d2fbeSKever Yang unsigned int chan;
596a75d2fbeSKever Yang u32 sys_reg = 0;
597a75d2fbeSKever Yang
598a75d2fbeSKever Yang sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
599a75d2fbeSKever Yang sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
600a75d2fbeSKever Yang for (chan = 0; chan < sdram_params->num_channels; chan++) {
601a75d2fbeSKever Yang const struct rk3288_sdram_channel *info =
602a75d2fbeSKever Yang &sdram_params->ch[chan];
603a75d2fbeSKever Yang
604a75d2fbeSKever Yang sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
605a75d2fbeSKever Yang sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
606a75d2fbeSKever Yang sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
607a75d2fbeSKever Yang sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
608a75d2fbeSKever Yang sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
609a75d2fbeSKever Yang sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
610a75d2fbeSKever Yang sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
611a75d2fbeSKever Yang sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
612a75d2fbeSKever Yang sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
613a75d2fbeSKever Yang
614a75d2fbeSKever Yang dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
615a75d2fbeSKever Yang }
616a75d2fbeSKever Yang writel(sys_reg, &dram->pmu->sys_reg[2]);
617a75d2fbeSKever Yang rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
618a75d2fbeSKever Yang }
619a75d2fbeSKever Yang
sdram_rank_bw_detect(struct dram_info * dram,int channel,struct rk3288_sdram_params * sdram_params)620a75d2fbeSKever Yang static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
621a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
622a75d2fbeSKever Yang {
623a75d2fbeSKever Yang int reg;
624a75d2fbeSKever Yang int need_trainig = 0;
625a75d2fbeSKever Yang const struct chan_info *chan = &dram->chan[channel];
626a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
627a75d2fbeSKever Yang
628a75d2fbeSKever Yang if (data_training(chan, channel, sdram_params) < 0) {
629a75d2fbeSKever Yang reg = readl(&publ->datx8[0].dxgsr[0]);
630a75d2fbeSKever Yang /* Check the result for rank 0 */
631a75d2fbeSKever Yang if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
632a75d2fbeSKever Yang debug("data training fail!\n");
633a75d2fbeSKever Yang return -EIO;
634a75d2fbeSKever Yang } else if ((channel == 1) &&
635a75d2fbeSKever Yang (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
636a75d2fbeSKever Yang sdram_params->num_channels = 1;
637a75d2fbeSKever Yang }
638a75d2fbeSKever Yang
639a75d2fbeSKever Yang /* Check the result for rank 1 */
640a75d2fbeSKever Yang if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
641a75d2fbeSKever Yang sdram_params->ch[channel].rank = 1;
642a75d2fbeSKever Yang clrsetbits_le32(&publ->pgcr, 0xF << 18,
643a75d2fbeSKever Yang sdram_params->ch[channel].rank << 18);
644a75d2fbeSKever Yang need_trainig = 1;
645a75d2fbeSKever Yang }
646a75d2fbeSKever Yang reg = readl(&publ->datx8[2].dxgsr[0]);
647a75d2fbeSKever Yang if (reg & (1 << 4)) {
648a75d2fbeSKever Yang sdram_params->ch[channel].bw = 1;
649a75d2fbeSKever Yang set_bandwidth_ratio(chan, channel,
650a75d2fbeSKever Yang sdram_params->ch[channel].bw,
651a75d2fbeSKever Yang dram->grf);
652a75d2fbeSKever Yang need_trainig = 1;
653a75d2fbeSKever Yang }
654a75d2fbeSKever Yang }
655a75d2fbeSKever Yang /* Assume the Die bit width are the same with the chip bit width */
656a75d2fbeSKever Yang sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
657a75d2fbeSKever Yang
658a75d2fbeSKever Yang if (need_trainig &&
659a75d2fbeSKever Yang (data_training(chan, channel, sdram_params) < 0)) {
660a75d2fbeSKever Yang if (sdram_params->base.dramtype == LPDDR3) {
661a75d2fbeSKever Yang ddr_phy_ctl_reset(dram->cru, channel, 1);
662a75d2fbeSKever Yang udelay(10);
663a75d2fbeSKever Yang ddr_phy_ctl_reset(dram->cru, channel, 0);
664a75d2fbeSKever Yang udelay(10);
665a75d2fbeSKever Yang }
666a75d2fbeSKever Yang debug("2nd data training failed!");
667a75d2fbeSKever Yang return -EIO;
668a75d2fbeSKever Yang }
669a75d2fbeSKever Yang
670a75d2fbeSKever Yang return 0;
671a75d2fbeSKever Yang }
672a75d2fbeSKever Yang
sdram_col_row_detect(struct dram_info * dram,int channel,struct rk3288_sdram_params * sdram_params)673a75d2fbeSKever Yang static int sdram_col_row_detect(struct dram_info *dram, int channel,
674a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
675a75d2fbeSKever Yang {
676a75d2fbeSKever Yang int row, col;
677a75d2fbeSKever Yang unsigned int addr;
678a75d2fbeSKever Yang const struct chan_info *chan = &dram->chan[channel];
679a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl = chan->pctl;
680a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
681a75d2fbeSKever Yang int ret = 0;
682a75d2fbeSKever Yang
683a75d2fbeSKever Yang /* Detect col */
684a75d2fbeSKever Yang for (col = 11; col >= 9; col--) {
685a75d2fbeSKever Yang writel(0, CONFIG_SYS_SDRAM_BASE);
686a75d2fbeSKever Yang addr = CONFIG_SYS_SDRAM_BASE +
687a75d2fbeSKever Yang (1 << (col + sdram_params->ch[channel].bw - 1));
688a75d2fbeSKever Yang writel(TEST_PATTEN, addr);
689a75d2fbeSKever Yang if ((readl(addr) == TEST_PATTEN) &&
690a75d2fbeSKever Yang (readl(CONFIG_SYS_SDRAM_BASE) == 0))
691a75d2fbeSKever Yang break;
692a75d2fbeSKever Yang }
693a75d2fbeSKever Yang if (col == 8) {
694a75d2fbeSKever Yang printf("Col detect error\n");
695a75d2fbeSKever Yang ret = -EINVAL;
696a75d2fbeSKever Yang goto out;
697a75d2fbeSKever Yang } else {
698a75d2fbeSKever Yang sdram_params->ch[channel].col = col;
699a75d2fbeSKever Yang }
700a75d2fbeSKever Yang
701a75d2fbeSKever Yang move_to_config_state(publ, pctl);
702a75d2fbeSKever Yang writel(4, &chan->msch->ddrconf);
703a75d2fbeSKever Yang move_to_access_state(chan);
704a75d2fbeSKever Yang /* Detect row*/
705a75d2fbeSKever Yang for (row = 16; row >= 12; row--) {
706a75d2fbeSKever Yang writel(0, CONFIG_SYS_SDRAM_BASE);
707a75d2fbeSKever Yang addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
708a75d2fbeSKever Yang writel(TEST_PATTEN, addr);
709a75d2fbeSKever Yang if ((readl(addr) == TEST_PATTEN) &&
710a75d2fbeSKever Yang (readl(CONFIG_SYS_SDRAM_BASE) == 0))
711a75d2fbeSKever Yang break;
712a75d2fbeSKever Yang }
713a75d2fbeSKever Yang if (row == 11) {
714a75d2fbeSKever Yang printf("Row detect error\n");
715a75d2fbeSKever Yang ret = -EINVAL;
716a75d2fbeSKever Yang } else {
717a75d2fbeSKever Yang sdram_params->ch[channel].cs1_row = row;
718a75d2fbeSKever Yang sdram_params->ch[channel].row_3_4 = 0;
719a75d2fbeSKever Yang debug("chn %d col %d, row %d\n", channel, col, row);
720a75d2fbeSKever Yang sdram_params->ch[channel].cs0_row = row;
721a75d2fbeSKever Yang }
722a75d2fbeSKever Yang
723a75d2fbeSKever Yang out:
724a75d2fbeSKever Yang return ret;
725a75d2fbeSKever Yang }
726a75d2fbeSKever Yang
sdram_get_biu_config(struct rk3288_sdram_params * sdram_params)727*5d4a323cSTang Yun ping static int sdram_get_biu_config(struct rk3288_sdram_params *sdram_params)
728a75d2fbeSKever Yang {
729a75d2fbeSKever Yang int i, tmp, size, ret = 0;
730a75d2fbeSKever Yang
731a75d2fbeSKever Yang tmp = sdram_params->ch[0].col - 9;
732a75d2fbeSKever Yang tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
733a75d2fbeSKever Yang tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
734a75d2fbeSKever Yang size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
735a75d2fbeSKever Yang for (i = 0; i < size; i++)
736a75d2fbeSKever Yang if (tmp == ddrconf_table[i])
737a75d2fbeSKever Yang break;
738a75d2fbeSKever Yang if (i >= size) {
739*5d4a323cSTang Yun ping printf("biu config not found\n");
740a75d2fbeSKever Yang ret = -EINVAL;
741a75d2fbeSKever Yang } else {
742a75d2fbeSKever Yang sdram_params->base.ddrconfig = i;
743a75d2fbeSKever Yang }
744a75d2fbeSKever Yang
745a75d2fbeSKever Yang return ret;
746a75d2fbeSKever Yang }
747a75d2fbeSKever Yang
sdram_get_stride(struct rk3288_sdram_params * sdram_params)748a75d2fbeSKever Yang static int sdram_get_stride(struct rk3288_sdram_params *sdram_params)
749a75d2fbeSKever Yang {
750a75d2fbeSKever Yang int stride = -1;
751a75d2fbeSKever Yang int ret = 0;
752a75d2fbeSKever Yang long cap = sdram_params->num_channels * (1u <<
753a75d2fbeSKever Yang (sdram_params->ch[0].cs0_row +
754a75d2fbeSKever Yang sdram_params->ch[0].col +
755a75d2fbeSKever Yang (sdram_params->ch[0].rank - 1) +
756a75d2fbeSKever Yang sdram_params->ch[0].bw +
757a75d2fbeSKever Yang 3 - 20));
758a75d2fbeSKever Yang
759a75d2fbeSKever Yang switch (cap) {
760a75d2fbeSKever Yang case 512:
761a75d2fbeSKever Yang stride = 0;
762a75d2fbeSKever Yang break;
763a75d2fbeSKever Yang case 1024:
764a75d2fbeSKever Yang stride = 5;
765a75d2fbeSKever Yang break;
766a75d2fbeSKever Yang case 2048:
767a75d2fbeSKever Yang stride = 9;
768a75d2fbeSKever Yang break;
769a75d2fbeSKever Yang case 4096:
770a75d2fbeSKever Yang stride = 0xd;
771a75d2fbeSKever Yang break;
772a75d2fbeSKever Yang default:
773a75d2fbeSKever Yang stride = -1;
774a75d2fbeSKever Yang printf("could not find correct stride, cap error!\n");
775a75d2fbeSKever Yang ret = -EINVAL;
776a75d2fbeSKever Yang break;
777a75d2fbeSKever Yang }
778a75d2fbeSKever Yang sdram_params->base.stride = stride;
779a75d2fbeSKever Yang
780a75d2fbeSKever Yang return ret;
781a75d2fbeSKever Yang }
782a75d2fbeSKever Yang
sdram_init(struct dram_info * dram,struct rk3288_sdram_params * sdram_params)783a75d2fbeSKever Yang static int sdram_init(struct dram_info *dram,
784a75d2fbeSKever Yang struct rk3288_sdram_params *sdram_params)
785a75d2fbeSKever Yang {
786a75d2fbeSKever Yang int channel;
787a75d2fbeSKever Yang int zqcr;
788a75d2fbeSKever Yang int ret;
789a75d2fbeSKever Yang
790a75d2fbeSKever Yang debug("%s start\n", __func__);
791a75d2fbeSKever Yang if ((sdram_params->base.dramtype == DDR3 &&
792a75d2fbeSKever Yang sdram_params->base.ddr_freq > 800000000) ||
793a75d2fbeSKever Yang (sdram_params->base.dramtype == LPDDR3 &&
794a75d2fbeSKever Yang sdram_params->base.ddr_freq > 533000000)) {
795a75d2fbeSKever Yang debug("SDRAM frequency is too high!");
796a75d2fbeSKever Yang return -E2BIG;
797a75d2fbeSKever Yang }
798a75d2fbeSKever Yang
799a75d2fbeSKever Yang debug("ddr clk dpll\n");
800a75d2fbeSKever Yang ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
801a75d2fbeSKever Yang debug("ret=%d\n", ret);
802a75d2fbeSKever Yang if (ret) {
803a75d2fbeSKever Yang debug("Could not set DDR clock\n");
804a75d2fbeSKever Yang return ret;
805a75d2fbeSKever Yang }
806a75d2fbeSKever Yang
807a75d2fbeSKever Yang for (channel = 0; channel < 2; channel++) {
808a75d2fbeSKever Yang const struct chan_info *chan = &dram->chan[channel];
809a75d2fbeSKever Yang struct rk3288_ddr_pctl *pctl = chan->pctl;
810a75d2fbeSKever Yang struct rk3288_ddr_publ *publ = chan->publ;
811a75d2fbeSKever Yang
812a75d2fbeSKever Yang /* map all the 4GB space to the current channel */
813a75d2fbeSKever Yang if (channel)
814a75d2fbeSKever Yang rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
815a75d2fbeSKever Yang else
816a75d2fbeSKever Yang rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);
817a75d2fbeSKever Yang phy_pctrl_reset(dram->cru, publ, channel);
818a75d2fbeSKever Yang phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
819a75d2fbeSKever Yang
820a75d2fbeSKever Yang dfi_cfg(pctl, sdram_params->base.dramtype);
821a75d2fbeSKever Yang
822a75d2fbeSKever Yang pctl_cfg(channel, pctl, sdram_params, dram->grf);
823a75d2fbeSKever Yang
824a75d2fbeSKever Yang phy_cfg(chan, channel, sdram_params);
825a75d2fbeSKever Yang
826a75d2fbeSKever Yang phy_init(publ);
827a75d2fbeSKever Yang
828a75d2fbeSKever Yang writel(POWER_UP_START, &pctl->powctl);
829a75d2fbeSKever Yang while (!(readl(&pctl->powstat) & POWER_UP_DONE))
830a75d2fbeSKever Yang ;
831a75d2fbeSKever Yang
832a75d2fbeSKever Yang memory_init(publ, sdram_params->base.dramtype);
833a75d2fbeSKever Yang move_to_config_state(publ, pctl);
834a75d2fbeSKever Yang
835a75d2fbeSKever Yang if (sdram_params->base.dramtype == LPDDR3) {
836a75d2fbeSKever Yang send_command(pctl, 3, DESELECT_CMD, 0);
837a75d2fbeSKever Yang udelay(1);
838a75d2fbeSKever Yang send_command(pctl, 3, PREA_CMD, 0);
839a75d2fbeSKever Yang udelay(1);
840a75d2fbeSKever Yang send_command_op(pctl, 3, MRS_CMD, 63, 0xfc);
841a75d2fbeSKever Yang udelay(1);
842a75d2fbeSKever Yang send_command_op(pctl, 3, MRS_CMD, 1,
843a75d2fbeSKever Yang sdram_params->phy_timing.mr[1]);
844a75d2fbeSKever Yang udelay(1);
845a75d2fbeSKever Yang send_command_op(pctl, 3, MRS_CMD, 2,
846a75d2fbeSKever Yang sdram_params->phy_timing.mr[2]);
847a75d2fbeSKever Yang udelay(1);
848a75d2fbeSKever Yang send_command_op(pctl, 3, MRS_CMD, 3,
849a75d2fbeSKever Yang sdram_params->phy_timing.mr[3]);
850a75d2fbeSKever Yang udelay(1);
851a75d2fbeSKever Yang }
852a75d2fbeSKever Yang
853a75d2fbeSKever Yang /* Using 32bit bus width for detect */
854a75d2fbeSKever Yang sdram_params->ch[channel].bw = 2;
855a75d2fbeSKever Yang set_bandwidth_ratio(chan, channel,
856a75d2fbeSKever Yang sdram_params->ch[channel].bw, dram->grf);
857a75d2fbeSKever Yang /*
858a75d2fbeSKever Yang * set cs, using n=3 for detect
859a75d2fbeSKever Yang * CS0, n=1
860a75d2fbeSKever Yang * CS1, n=2
861a75d2fbeSKever Yang * CS0 & CS1, n = 3
862a75d2fbeSKever Yang */
863a75d2fbeSKever Yang sdram_params->ch[channel].rank = 2,
864a75d2fbeSKever Yang clrsetbits_le32(&publ->pgcr, 0xF << 18,
865a75d2fbeSKever Yang (sdram_params->ch[channel].rank | 1) << 18);
866a75d2fbeSKever Yang
867a75d2fbeSKever Yang /* DS=40ohm,ODT=155ohm */
868a75d2fbeSKever Yang zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
869a75d2fbeSKever Yang 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
870a75d2fbeSKever Yang 0x19 << PD_OUTPUT_SHIFT;
871a75d2fbeSKever Yang writel(zqcr, &publ->zq1cr[0]);
872a75d2fbeSKever Yang writel(zqcr, &publ->zq0cr[0]);
873a75d2fbeSKever Yang
874a75d2fbeSKever Yang if (sdram_params->base.dramtype == LPDDR3) {
875a75d2fbeSKever Yang /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
876a75d2fbeSKever Yang udelay(10);
877a75d2fbeSKever Yang send_command_op(pctl,
878a75d2fbeSKever Yang sdram_params->ch[channel].rank | 1,
879a75d2fbeSKever Yang MRS_CMD, 11,
880a75d2fbeSKever Yang sdram_params->base.odt ? 3 : 0);
881a75d2fbeSKever Yang if (channel == 0) {
882a75d2fbeSKever Yang writel(0, &pctl->mrrcfg0);
883a75d2fbeSKever Yang send_command_op(pctl, 1, MRR_CMD, 8, 0);
884a75d2fbeSKever Yang /* S8 */
885a75d2fbeSKever Yang if ((readl(&pctl->mrrstat0) & 0x3) != 3) {
886a75d2fbeSKever Yang debug("failed!");
887a75d2fbeSKever Yang return -EREMOTEIO;
888a75d2fbeSKever Yang }
889a75d2fbeSKever Yang }
890a75d2fbeSKever Yang }
891a75d2fbeSKever Yang
892a75d2fbeSKever Yang /* Detect the rank and bit-width with data-training */
893a75d2fbeSKever Yang sdram_rank_bw_detect(dram, channel, sdram_params);
894a75d2fbeSKever Yang
895a75d2fbeSKever Yang if (sdram_params->base.dramtype == LPDDR3) {
896a75d2fbeSKever Yang u32 i;
897a75d2fbeSKever Yang writel(0, &pctl->mrrcfg0);
898a75d2fbeSKever Yang for (i = 0; i < 17; i++)
899a75d2fbeSKever Yang send_command_op(pctl, 1, MRR_CMD, i, 0);
900a75d2fbeSKever Yang }
901a75d2fbeSKever Yang writel(15, &chan->msch->ddrconf);
902a75d2fbeSKever Yang move_to_access_state(chan);
903a75d2fbeSKever Yang /* DDR3 and LPDDR3 are always 8 bank, no need detect */
904a75d2fbeSKever Yang sdram_params->ch[channel].bk = 3;
905a75d2fbeSKever Yang /* Detect Col and Row number*/
906a75d2fbeSKever Yang ret = sdram_col_row_detect(dram, channel, sdram_params);
907a75d2fbeSKever Yang if (ret)
908a75d2fbeSKever Yang goto error;
909a75d2fbeSKever Yang }
910*5d4a323cSTang Yun ping /* Find BIU DDR configuration */
911*5d4a323cSTang Yun ping ret = sdram_get_biu_config(sdram_params);
912a75d2fbeSKever Yang if (ret)
913a75d2fbeSKever Yang goto error;
914a75d2fbeSKever Yang /* Find stride setting */
915a75d2fbeSKever Yang ret = sdram_get_stride(sdram_params);
916a75d2fbeSKever Yang if (ret)
917a75d2fbeSKever Yang goto error;
918a75d2fbeSKever Yang
919a75d2fbeSKever Yang dram_all_config(dram, sdram_params);
920a75d2fbeSKever Yang debug("%s done\n", __func__);
921a75d2fbeSKever Yang
922a75d2fbeSKever Yang return 0;
923a75d2fbeSKever Yang error:
924a75d2fbeSKever Yang printf("DRAM init failed!\n");
925a75d2fbeSKever Yang hang();
926a75d2fbeSKever Yang }
927a75d2fbeSKever Yang
928a75d2fbeSKever Yang # ifdef CONFIG_ROCKCHIP_FAST_SPL
veyron_init(struct dram_info * priv)929a75d2fbeSKever Yang static int veyron_init(struct dram_info *priv)
930a75d2fbeSKever Yang {
931a75d2fbeSKever Yang struct udevice *pmic;
932a75d2fbeSKever Yang int ret;
933a75d2fbeSKever Yang
934a75d2fbeSKever Yang ret = uclass_first_device_err(UCLASS_PMIC, &pmic);
935a75d2fbeSKever Yang if (ret)
936a75d2fbeSKever Yang return ret;
937a75d2fbeSKever Yang
938a75d2fbeSKever Yang /* Slowly raise to max CPU voltage to prevent overshoot */
939a75d2fbeSKever Yang ret = rk8xx_spl_configure_buck(pmic, 1, 1200000);
940a75d2fbeSKever Yang if (ret)
941a75d2fbeSKever Yang return ret;
942a75d2fbeSKever Yang udelay(175);/* Must wait for voltage to stabilize, 2mV/us */
943a75d2fbeSKever Yang ret = rk8xx_spl_configure_buck(pmic, 1, 1400000);
944a75d2fbeSKever Yang if (ret)
945a75d2fbeSKever Yang return ret;
946a75d2fbeSKever Yang udelay(100);/* Must wait for voltage to stabilize, 2mV/us */
947a75d2fbeSKever Yang
948a75d2fbeSKever Yang rk3288_clk_configure_cpu(priv->cru, priv->grf);
949a75d2fbeSKever Yang
950a75d2fbeSKever Yang return 0;
951a75d2fbeSKever Yang }
952a75d2fbeSKever Yang # endif
953a75d2fbeSKever Yang
setup_sdram(struct udevice * dev)954a75d2fbeSKever Yang static int setup_sdram(struct udevice *dev)
955a75d2fbeSKever Yang {
956a75d2fbeSKever Yang struct dram_info *priv = dev_get_priv(dev);
957a75d2fbeSKever Yang struct rk3288_sdram_params *params = dev_get_platdata(dev);
958a75d2fbeSKever Yang
959a75d2fbeSKever Yang # ifdef CONFIG_ROCKCHIP_FAST_SPL
960a75d2fbeSKever Yang if (priv->is_veyron) {
961a75d2fbeSKever Yang int ret;
962a75d2fbeSKever Yang
963a75d2fbeSKever Yang ret = veyron_init(priv);
964a75d2fbeSKever Yang if (ret)
965a75d2fbeSKever Yang return ret;
966a75d2fbeSKever Yang }
967a75d2fbeSKever Yang # endif
968a75d2fbeSKever Yang
969a75d2fbeSKever Yang return sdram_init(priv, params);
970a75d2fbeSKever Yang }
971a75d2fbeSKever Yang
rk3288_dmc_ofdata_to_platdata(struct udevice * dev)972a75d2fbeSKever Yang static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
973a75d2fbeSKever Yang {
974a75d2fbeSKever Yang #if !CONFIG_IS_ENABLED(OF_PLATDATA)
975a75d2fbeSKever Yang struct rk3288_sdram_params *params = dev_get_platdata(dev);
976a75d2fbeSKever Yang int ret;
977a75d2fbeSKever Yang
978a75d2fbeSKever Yang /* Rk3288 supports dual-channel, set default channel num to 2 */
979a75d2fbeSKever Yang params->num_channels = 2;
980a75d2fbeSKever Yang ret = dev_read_u32_array(dev, "rockchip,pctl-timing",
981a75d2fbeSKever Yang (u32 *)¶ms->pctl_timing,
982a75d2fbeSKever Yang sizeof(params->pctl_timing) / sizeof(u32));
983a75d2fbeSKever Yang if (ret) {
984a75d2fbeSKever Yang debug("%s: Cannot read rockchip,pctl-timing\n", __func__);
985a75d2fbeSKever Yang return -EINVAL;
986a75d2fbeSKever Yang }
987a75d2fbeSKever Yang ret = dev_read_u32_array(dev, "rockchip,phy-timing",
988a75d2fbeSKever Yang (u32 *)¶ms->phy_timing,
989a75d2fbeSKever Yang sizeof(params->phy_timing) / sizeof(u32));
990a75d2fbeSKever Yang if (ret) {
991a75d2fbeSKever Yang debug("%s: Cannot read rockchip,phy-timing\n", __func__);
992a75d2fbeSKever Yang return -EINVAL;
993a75d2fbeSKever Yang }
994a75d2fbeSKever Yang ret = dev_read_u32_array(dev, "rockchip,sdram-params",
995a75d2fbeSKever Yang (u32 *)¶ms->base,
996a75d2fbeSKever Yang sizeof(params->base) / sizeof(u32));
997a75d2fbeSKever Yang if (ret) {
998a75d2fbeSKever Yang debug("%s: Cannot read rockchip,sdram-params\n", __func__);
999a75d2fbeSKever Yang return -EINVAL;
1000a75d2fbeSKever Yang }
1001a75d2fbeSKever Yang #ifdef CONFIG_ROCKCHIP_FAST_SPL
1002a75d2fbeSKever Yang struct dram_info *priv = dev_get_priv(dev);
1003a75d2fbeSKever Yang
1004a75d2fbeSKever Yang priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron");
1005a75d2fbeSKever Yang #endif
1006a75d2fbeSKever Yang ret = regmap_init_mem(dev, ¶ms->map);
1007a75d2fbeSKever Yang if (ret)
1008a75d2fbeSKever Yang return ret;
1009a75d2fbeSKever Yang #endif
1010a75d2fbeSKever Yang
1011a75d2fbeSKever Yang return 0;
1012a75d2fbeSKever Yang }
1013a75d2fbeSKever Yang #endif /* CONFIG_SPL_BUILD */
1014a75d2fbeSKever Yang
1015a75d2fbeSKever Yang #if CONFIG_IS_ENABLED(OF_PLATDATA)
conv_of_platdata(struct udevice * dev)1016a75d2fbeSKever Yang static int conv_of_platdata(struct udevice *dev)
1017a75d2fbeSKever Yang {
1018a75d2fbeSKever Yang struct rk3288_sdram_params *plat = dev_get_platdata(dev);
1019a75d2fbeSKever Yang struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
1020a75d2fbeSKever Yang int ret;
1021a75d2fbeSKever Yang
1022a75d2fbeSKever Yang memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
1023a75d2fbeSKever Yang sizeof(plat->pctl_timing));
1024a75d2fbeSKever Yang memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
1025a75d2fbeSKever Yang sizeof(plat->phy_timing));
1026a75d2fbeSKever Yang memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
1027a75d2fbeSKever Yang /* Rk3288 supports dual-channel, set default channel num to 2 */
1028a75d2fbeSKever Yang plat->num_channels = 2;
1029a75d2fbeSKever Yang ret = regmap_init_mem_platdata(dev, of_plat->reg,
1030a75d2fbeSKever Yang ARRAY_SIZE(of_plat->reg) / 2,
1031a75d2fbeSKever Yang &plat->map);
1032a75d2fbeSKever Yang if (ret)
1033a75d2fbeSKever Yang return ret;
1034a75d2fbeSKever Yang
1035a75d2fbeSKever Yang return 0;
1036a75d2fbeSKever Yang }
1037a75d2fbeSKever Yang #endif
1038a75d2fbeSKever Yang
rk3288_dmc_probe(struct udevice * dev)1039a75d2fbeSKever Yang static int rk3288_dmc_probe(struct udevice *dev)
1040a75d2fbeSKever Yang {
1041a75d2fbeSKever Yang #ifdef CONFIG_SPL_BUILD
1042a75d2fbeSKever Yang struct rk3288_sdram_params *plat = dev_get_platdata(dev);
1043a75d2fbeSKever Yang struct udevice *dev_clk;
1044a75d2fbeSKever Yang struct regmap *map;
1045a75d2fbeSKever Yang int ret;
1046a75d2fbeSKever Yang #endif
1047a75d2fbeSKever Yang struct dram_info *priv = dev_get_priv(dev);
1048a75d2fbeSKever Yang
1049a75d2fbeSKever Yang priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
1050a75d2fbeSKever Yang #ifdef CONFIG_SPL_BUILD
1051a75d2fbeSKever Yang #if CONFIG_IS_ENABLED(OF_PLATDATA)
1052a75d2fbeSKever Yang ret = conv_of_platdata(dev);
1053a75d2fbeSKever Yang if (ret)
1054a75d2fbeSKever Yang return ret;
1055a75d2fbeSKever Yang #endif
1056a75d2fbeSKever Yang map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
1057a75d2fbeSKever Yang if (IS_ERR(map))
1058a75d2fbeSKever Yang return PTR_ERR(map);
1059a75d2fbeSKever Yang priv->chan[0].msch = regmap_get_range(map, 0);
1060a75d2fbeSKever Yang priv->chan[1].msch = (struct rk3288_msch *)
1061a75d2fbeSKever Yang (regmap_get_range(map, 0) + 0x80);
1062a75d2fbeSKever Yang
1063a75d2fbeSKever Yang priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1064a75d2fbeSKever Yang priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
1065a75d2fbeSKever Yang
1066a75d2fbeSKever Yang priv->chan[0].pctl = regmap_get_range(plat->map, 0);
1067a75d2fbeSKever Yang priv->chan[0].publ = regmap_get_range(plat->map, 1);
1068a75d2fbeSKever Yang priv->chan[1].pctl = regmap_get_range(plat->map, 2);
1069a75d2fbeSKever Yang priv->chan[1].publ = regmap_get_range(plat->map, 3);
1070a75d2fbeSKever Yang
1071a75d2fbeSKever Yang ret = rockchip_get_clk(&dev_clk);
1072a75d2fbeSKever Yang if (ret)
1073a75d2fbeSKever Yang return ret;
1074a75d2fbeSKever Yang priv->ddr_clk.id = CLK_DDR;
1075a75d2fbeSKever Yang ret = clk_request(dev_clk, &priv->ddr_clk);
1076a75d2fbeSKever Yang if (ret)
1077a75d2fbeSKever Yang return ret;
1078a75d2fbeSKever Yang
1079a75d2fbeSKever Yang priv->cru = rockchip_get_cru();
1080a75d2fbeSKever Yang if (IS_ERR(priv->cru))
1081a75d2fbeSKever Yang return PTR_ERR(priv->cru);
1082a75d2fbeSKever Yang ret = setup_sdram(dev);
1083a75d2fbeSKever Yang if (ret)
1084a75d2fbeSKever Yang return ret;
1085a75d2fbeSKever Yang #else
1086a75d2fbeSKever Yang priv->info.base = CONFIG_SYS_SDRAM_BASE;
1087a75d2fbeSKever Yang priv->info.size = rockchip_sdram_size(
1088a75d2fbeSKever Yang (phys_addr_t)&priv->pmu->sys_reg[2]);
1089a75d2fbeSKever Yang #endif
1090a75d2fbeSKever Yang
1091a75d2fbeSKever Yang return 0;
1092a75d2fbeSKever Yang }
1093a75d2fbeSKever Yang
rk3288_dmc_get_info(struct udevice * dev,struct ram_info * info)1094a75d2fbeSKever Yang static int rk3288_dmc_get_info(struct udevice *dev, struct ram_info *info)
1095a75d2fbeSKever Yang {
1096a75d2fbeSKever Yang struct dram_info *priv = dev_get_priv(dev);
1097a75d2fbeSKever Yang
1098a75d2fbeSKever Yang *info = priv->info;
1099a75d2fbeSKever Yang
1100a75d2fbeSKever Yang return 0;
1101a75d2fbeSKever Yang }
1102a75d2fbeSKever Yang
1103a75d2fbeSKever Yang static struct ram_ops rk3288_dmc_ops = {
1104a75d2fbeSKever Yang .get_info = rk3288_dmc_get_info,
1105a75d2fbeSKever Yang };
1106a75d2fbeSKever Yang
1107a75d2fbeSKever Yang static const struct udevice_id rk3288_dmc_ids[] = {
1108a75d2fbeSKever Yang { .compatible = "rockchip,rk3288-dmc" },
1109a75d2fbeSKever Yang { }
1110a75d2fbeSKever Yang };
1111a75d2fbeSKever Yang
1112a75d2fbeSKever Yang U_BOOT_DRIVER(dmc_rk3288) = {
1113a75d2fbeSKever Yang .name = "rockchip_rk3288_dmc",
1114a75d2fbeSKever Yang .id = UCLASS_RAM,
1115a75d2fbeSKever Yang .of_match = rk3288_dmc_ids,
1116a75d2fbeSKever Yang .ops = &rk3288_dmc_ops,
1117a75d2fbeSKever Yang #ifdef CONFIG_SPL_BUILD
1118a75d2fbeSKever Yang .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata,
1119a75d2fbeSKever Yang #endif
1120a75d2fbeSKever Yang .probe = rk3288_dmc_probe,
1121a75d2fbeSKever Yang .priv_auto_alloc_size = sizeof(struct dram_info),
1122a75d2fbeSKever Yang #ifdef CONFIG_SPL_BUILD
1123a75d2fbeSKever Yang .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params),
1124a75d2fbeSKever Yang #endif
1125a75d2fbeSKever Yang };
1126