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