xref: /rk3399_rockchip-uboot/drivers/ram/rockchip/sdram_rv1108.c (revision d5f538dc02e53c7267fcd4a914104071fca889b5)
1 /*
2  * Copyright (C) 2018 Rockchip Electronics Co., Ltd
3  * Author: Zhihuan He <huan.he@rock-chips.com>
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/root.h>
9 #include <dt-structs.h>
10 #include <regmap.h>
11 #include <asm/io.h>
12 #include <asm/types.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/arch/sdram_rv1108.h>
15 #include <asm/arch/timer.h>
16 #include <asm/arch/sdram_common.h>
17 
18 struct dram_info info;
19 
20 struct rockchip_dmc_plat {
21 #if CONFIG_IS_ENABLED(OF_PLATDATA)
22 	struct dtd_rockchip_rv1108_dmc dtplat;
23 #else
24 	struct sdram_params params;
25 #endif
26 	struct regmap *map;
27 };
28 
29 void enable_ddr_io_ret(struct dram_info *priv)
30 {
31 	writel(DDR_IO_RET_EN, &priv->pmu->sft_con);
32 	rk_clrsetreg(&priv->pmu_grf->soc_con[0],
33 		     DDRPHY_BUFFEREN_CORE_MASK,
34 		     DDRPHY_BUFFEREN_CORE_EN);
35 }
36 
37 void rkdclk_init(struct dram_info *priv,
38 		 struct sdram_params *params_priv)
39 {
40 	rk_clrsetreg(&priv->cru->pll[1].con3, WORK_MODE_MASK,
41 		     WORK_MODE_SLOW << WORK_MODE_SHIFT);
42 	rk_clrsetreg(&priv->cru->pll[1].con3, GLOBAL_POWER_DOWN_MASK,
43 		     GLOBAL_POWER_DOWN << GLOBAL_POWER_DOWN_SHIFT);
44 	rk_clrsetreg(&priv->cru->pll[1].con3, DSMPD_MASK,
45 		     INTEGER_MODE << DSMPD_SHIFT);
46 	rk_clrsetreg(&priv->cru->pll[1].con0, FBDIV_MASK,
47 		     params_priv->dpll_init_cfg.fbdiv << FBDIV_SHIFT);
48 	rk_clrsetreg(&priv->cru->pll[1].con1,
49 		     POSTDIV2_MASK | POSTDIV1_MASK | REFDIV_MASK,
50 		     params_priv->dpll_init_cfg.postdiv2 << POSTDIV2_SHIFT |
51 		     params_priv->dpll_init_cfg.postdiv1 << POSTDIV1_SHIFT |
52 		     params_priv->dpll_init_cfg.refdiv << REFDIV_SHIFT);
53 	rk_clrsetreg(&priv->cru->pll[1].con3, GLOBAL_POWER_DOWN_MASK,
54 		     GLOBAL_POWER_UP << GLOBAL_POWER_DOWN_SHIFT);
55 	while (!(readl(&priv->cru->pll[1].con2) & (1u << LOCK_STA_SHIFT)))
56 		udelay(1);
57 
58 	rk_clrsetreg(&priv->cru->clksel_con[4], CLK_DDR_PLL_SEL_MASK |
59 		     CLK_DDR_DIV_CON_MASK, 0 << CLK_DDR_PLL_SEL_SHIFT |
60 		     0 << CLK_DDR_DIV_CON_SHIFT);
61 	rk_clrsetreg(&priv->cru->pll[1].con3, WORK_MODE_MASK,
62 		     WORK_MODE_NORMAL << WORK_MODE_SHIFT);
63 }
64 
65 void phy_pctrl_reset_cru(struct dram_info *priv)
66 {
67 	rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK |
68 		     DDRUPCTL_NSRSTN_REQ_MASK,
69 		     DDRUPCTL_PSRSTN_REQ << DDRUPCTL_PSRSTN_REQ_SHIFT |
70 		     DDRUPCTL_NSRSTN_REQ << DDRUPCTL_NSRSTN_REQ_SHIFT);
71 	rk_clrsetreg(&priv->cru->softrst_con[1],
72 		     DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK |
73 		     DDRPHY_PSRSTN_REQ_MASK,
74 		     DDRPHY_SRSTN_CLKDIV_REQ << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT |
75 		     DDRPHY_SRSTN_REQ << DDRPHY_SRSTN_REQ_SHIFT |
76 		     DDRPHY_PSRSTN_REQ << DDRPHY_PSRSTN_REQ_SHIFT);
77 
78 	udelay(10);
79 
80 	rk_clrsetreg(&priv->cru->softrst_con[1],
81 		     DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK |
82 		     DDRPHY_PSRSTN_REQ_MASK,
83 		     DDRPHY_SRSTN_CLKDIV_DIS << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT |
84 		     DDRPHY_PSRSTN_DIS << DDRPHY_PSRSTN_REQ_SHIFT |
85 		     DDRPHY_SRSTN_DIS << DDRPHY_SRSTN_REQ_SHIFT);
86 	udelay(10);
87 
88 	rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK |
89 		     DDRUPCTL_NSRSTN_REQ_MASK,
90 		     DDRUPCTL_PSRSTN_DIS << DDRUPCTL_PSRSTN_REQ_SHIFT |
91 		     DDRUPCTL_NSRSTN_DIS << DDRUPCTL_NSRSTN_REQ_SHIFT);
92 	udelay(10);
93 }
94 
95 void set_bw_grf(struct dram_info *priv)
96 {
97 	rk_clrsetreg(&priv->grf->soc_con0,
98 		     MSCH_MAINPARTIALPOP_MASK,
99 		     MSCH_MAINPARTIALPOP);
100 }
101 
102 void pctl_cfg_grf(struct dram_info *priv)
103 {
104 	writel(RK_SETBITS(MSCH_MAINDDR3 | MSCH_MAINPARTIALPOP),
105 	       &priv->grf->soc_con0);
106 }
107 
108 void *get_base_addr(unsigned int *reg, unsigned int offset)
109 {
110 	u32 p = *(reg + 2 * offset);
111 
112 	return (void *)p;
113 }
114 
115 void sdram_init(void)
116 {
117 	int ret;
118 	struct dram_info *sdram_priv = &info;
119 	struct driver_info *info =
120 		ll_entry_start(struct driver_info, driver_info);
121 #if CONFIG_IS_ENABLED(OF_PLATDATA)
122 	struct dtd_rockchip_rv1108_dmc *dtplat = (void *)info->platdata;
123 	struct sdram_params *params = (void *)dtplat->rockchip_sdram_params;
124 
125 	sdram_priv->pctl = get_base_addr((void *)dtplat->reg, 0);
126 	sdram_priv->phy = get_base_addr((void *)dtplat->reg, 1);
127 	sdram_priv->service_msch = get_base_addr((void *)dtplat->reg, 2);
128 	sdram_priv->grf = get_base_addr((void *)dtplat->reg, 3);
129 	sdram_priv->pmu_grf = get_base_addr((void *)dtplat->reg, 4);
130 	sdram_priv->cru = get_base_addr((void *)dtplat->reg, 5);
131 	sdram_priv->pmu = get_base_addr((void *)dtplat->reg, 6);
132 #else
133 	struct sdram_params *params = (void *)info->platdata;
134 #endif
135 	ret = rv1108_sdram_init(sdram_priv, params);
136 	if (ret)
137 		debug("rv1108_sdram_init() fail!");
138 }
139