1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) Copyright 2018 Rockchip Electronics Co., Ltd. 4 */ 5 6#include <common.h> 7#include <ram.h> 8#include <asm/io.h> 9#include <asm/arch-rockchip/sdram.h> 10#include <asm/arch-rockchip/sdram_common.h> 11#include <asm/arch-rockchip/sdram_phy_px30.h> 12#include <linux/delay.h> 13 14static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq) 15{ 16 u32 tmp; 17 u32 i, j; 18 u32 dqs_dll_freq; 19 20 setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4); 21 clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3); 22 for (i = 0; i < 4; i++) { 23 j = 0x26 + i * 0x10; 24 setbits_le32(PHY_REG(phy_base, j), 1 << 4); 25 clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3); 26 } 27 28 if (freq <= 400) 29 /* DLL bypass */ 30 setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); 31 else 32 clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); 33 34 #ifdef CONFIG_ROCKCHIP_RK3328 35 dqs_dll_freq = 680; 36 #else 37 dqs_dll_freq = 801; 38 #endif 39 40 if (freq <= dqs_dll_freq) 41 tmp = 2; 42 else 43 tmp = 1; 44 45 for (i = 0; i < 4; i++) { 46 j = 0x28 + i * 0x10; 47 writel(tmp, PHY_REG(phy_base, j)); 48 } 49} 50 51static void sdram_phy_set_ds_odt(void __iomem *phy_base, 52 u32 dram_type) 53{ 54 u32 cmd_drv, clk_drv, dqs_drv, dqs_odt; 55 u32 i, j; 56 57 if (dram_type == DDR3) { 58 cmd_drv = PHY_DDR3_RON_RTT_34ohm; 59 clk_drv = PHY_DDR3_RON_RTT_45ohm; 60 dqs_drv = PHY_DDR3_RON_RTT_34ohm; 61 dqs_odt = PHY_DDR3_RON_RTT_225ohm; 62 } else { 63 cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; 64 clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm; 65 dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; 66 if (dram_type == LPDDR2) 67 dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE; 68 else 69 dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm; 70 } 71 /* DS */ 72 writel(cmd_drv, PHY_REG(phy_base, 0x11)); 73 clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3); 74 writel(clk_drv, PHY_REG(phy_base, 0x16)); 75 writel(clk_drv, PHY_REG(phy_base, 0x18)); 76 77 for (i = 0; i < 4; i++) { 78 j = 0x20 + i * 0x10; 79 writel(dqs_drv, PHY_REG(phy_base, j)); 80 writel(dqs_drv, PHY_REG(phy_base, j + 0xf)); 81 /* ODT */ 82 writel(dqs_odt, PHY_REG(phy_base, j + 0x1)); 83 writel(dqs_odt, PHY_REG(phy_base, j + 0xe)); 84 } 85} 86 87void phy_soft_reset(void __iomem *phy_base) 88{ 89 clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2); 90 udelay(1); 91 setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET); 92 udelay(5); 93 setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET); 94 udelay(1); 95} 96 97void phy_dram_set_bw(void __iomem *phy_base, u32 bw) 98{ 99 if (bw == 2) { 100 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); 101 setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 102 setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 103 } else if (bw == 1) { 104 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); 105 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 106 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 107 } else if (bw == 0) { 108 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); 109 clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); 110 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 111 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 112 } 113 114 phy_soft_reset(phy_base); 115} 116 117int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype) 118{ 119 u32 ret; 120 u32 odt_val; 121 u32 i, j; 122 123 odt_val = readl(PHY_REG(phy_base, 0x2e)); 124 125 for (i = 0; i < 4; i++) { 126 j = 0x20 + i * 0x10; 127 writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1)); 128 writel(0, PHY_REG(phy_base, j + 0xe)); 129 } 130 131 if (dramtype == DDR4) { 132 clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0); 133 clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0); 134 clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0); 135 clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0); 136 } 137 /* choose training cs */ 138 clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs)); 139 /* enable gate training */ 140 clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1); 141 udelay(50); 142 ret = readl(PHY_REG(phy_base, 0xff)); 143 /* disable gate training */ 144 clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0); 145 #ifndef CONFIG_ROCKCHIP_RK3328 146 clrbits_le32(PHY_REG(phy_base, 2), 0x30); 147 #endif 148 149 if (dramtype == DDR4) { 150 clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2); 151 clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2); 152 clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2); 153 clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2); 154 } 155 156 if (ret & 0x10) { 157 ret = -1; 158 } else { 159 ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4); 160 ret = (ret == 0) ? 0 : -1; 161 } 162 163 for (i = 0; i < 4; i++) { 164 j = 0x20 + i * 0x10; 165 writel(odt_val, PHY_REG(phy_base, j + 0x1)); 166 writel(odt_val, PHY_REG(phy_base, j + 0xe)); 167 } 168 return ret; 169} 170 171void phy_cfg(void __iomem *phy_base, 172 struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew, 173 struct sdram_base_params *base, u32 bw) 174{ 175 u32 i; 176 177 sdram_phy_dll_bypass_set(phy_base, base->ddr_freq); 178 for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) { 179 writel(phy_regs->phy[i][1], 180 phy_base + phy_regs->phy[i][0]); 181 } 182 if (bw == 2) { 183 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); 184 } else if (bw == 1) { 185 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); 186 /* disable DQS2,DQS3 tx dll for saving power */ 187 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 188 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 189 } else { 190 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); 191 /* disable DQS2,DQS3 tx dll for saving power */ 192 clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); 193 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 194 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 195 } 196 sdram_phy_set_ds_odt(phy_base, base->dramtype); 197 198 /* deskew */ 199 setbits_le32(PHY_REG(phy_base, 2), 8); 200 sdram_copy_to_reg(PHY_REG(phy_base, 0xb0), 201 &skew->a0_a1_skew[0], 15 * 4); 202 sdram_copy_to_reg(PHY_REG(phy_base, 0x70), 203 &skew->cs0_dm0_skew[0], 44 * 4); 204 sdram_copy_to_reg(PHY_REG(phy_base, 0xc0), 205 &skew->cs1_dm0_skew[0], 44 * 4); 206} 207