174803decSYouMin Chen // SPDX-License-Identifier: GPL-2.0 274803decSYouMin Chen /* 374803decSYouMin Chen * (C) Copyright 2018 Rockchip Electronics Co., Ltd. 474803decSYouMin Chen */ 574803decSYouMin Chen 674803decSYouMin Chen #include <common.h> 774803decSYouMin Chen #include <ram.h> 874803decSYouMin Chen #include <asm/io.h> 9e1f97ec3SYouMin Chen #include <asm/arch/sdram.h> 105685f66aSYouMin Chen #include <asm/arch/sdram_common.h> 1174803decSYouMin Chen #include <asm/arch/sdram_phy_px30.h> 1274803decSYouMin Chen 1374803decSYouMin Chen static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq) 1474803decSYouMin Chen { 1574803decSYouMin Chen u32 tmp; 1674803decSYouMin Chen u32 i, j; 17*bbf5a1e4SYouMin Chen u32 dqs_dll_freq; 1874803decSYouMin Chen 1974803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4); 2074803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3); 2174803decSYouMin Chen for (i = 0; i < 4; i++) { 2274803decSYouMin Chen j = 0x26 + i * 0x10; 2374803decSYouMin Chen setbits_le32(PHY_REG(phy_base, j), 1 << 4); 2474803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3); 2574803decSYouMin Chen } 2674803decSYouMin Chen 27*bbf5a1e4SYouMin Chen if (freq <= 400) 2874803decSYouMin Chen /* DLL bypass */ 2974803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); 3074803decSYouMin Chen else 3174803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); 3274803decSYouMin Chen 33*bbf5a1e4SYouMin Chen #ifdef CONFIG_ROCKCHIP_RK3328 34*bbf5a1e4SYouMin Chen dqs_dll_freq = 680; 35*bbf5a1e4SYouMin Chen #else 36*bbf5a1e4SYouMin Chen dqs_dll_freq = 801; 37*bbf5a1e4SYouMin Chen #endif 38*bbf5a1e4SYouMin Chen 39*bbf5a1e4SYouMin Chen if (freq <= dqs_dll_freq) 4074803decSYouMin Chen tmp = 2; 4174803decSYouMin Chen else 4274803decSYouMin Chen tmp = 1; 4374803decSYouMin Chen 4474803decSYouMin Chen for (i = 0; i < 4; i++) { 4574803decSYouMin Chen j = 0x28 + i * 0x10; 4674803decSYouMin Chen writel(tmp, PHY_REG(phy_base, j)); 4774803decSYouMin Chen } 4874803decSYouMin Chen } 4974803decSYouMin Chen 5074803decSYouMin Chen static void sdram_phy_set_ds_odt(void __iomem *phy_base, 5174803decSYouMin Chen u32 dram_type) 5274803decSYouMin Chen { 5374803decSYouMin Chen u32 cmd_drv, clk_drv, dqs_drv, dqs_odt; 5474803decSYouMin Chen u32 i, j; 5574803decSYouMin Chen 5674803decSYouMin Chen if (dram_type == DDR3) { 5774803decSYouMin Chen cmd_drv = PHY_DDR3_RON_RTT_34ohm; 5874803decSYouMin Chen clk_drv = PHY_DDR3_RON_RTT_45ohm; 5974803decSYouMin Chen dqs_drv = PHY_DDR3_RON_RTT_34ohm; 6074803decSYouMin Chen dqs_odt = PHY_DDR3_RON_RTT_225ohm; 6174803decSYouMin Chen } else { 6274803decSYouMin Chen cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; 6374803decSYouMin Chen clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm; 6474803decSYouMin Chen dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; 6574803decSYouMin Chen if (dram_type == LPDDR2) 6674803decSYouMin Chen dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE; 6774803decSYouMin Chen else 6874803decSYouMin Chen dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm; 6974803decSYouMin Chen } 7074803decSYouMin Chen /* DS */ 7174803decSYouMin Chen writel(cmd_drv, PHY_REG(phy_base, 0x11)); 7274803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3); 7374803decSYouMin Chen writel(clk_drv, PHY_REG(phy_base, 0x16)); 7474803decSYouMin Chen writel(clk_drv, PHY_REG(phy_base, 0x18)); 7574803decSYouMin Chen 7674803decSYouMin Chen for (i = 0; i < 4; i++) { 7774803decSYouMin Chen j = 0x20 + i * 0x10; 7874803decSYouMin Chen writel(dqs_drv, PHY_REG(phy_base, j)); 7974803decSYouMin Chen writel(dqs_drv, PHY_REG(phy_base, j + 0xf)); 8074803decSYouMin Chen /* ODT */ 8174803decSYouMin Chen writel(dqs_odt, PHY_REG(phy_base, j + 0x1)); 8274803decSYouMin Chen writel(dqs_odt, PHY_REG(phy_base, j + 0xe)); 8374803decSYouMin Chen } 8474803decSYouMin Chen } 8574803decSYouMin Chen 8674803decSYouMin Chen void phy_soft_reset(void __iomem *phy_base) 8774803decSYouMin Chen { 8874803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2); 8974803decSYouMin Chen udelay(1); 9074803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET); 9174803decSYouMin Chen udelay(5); 9274803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET); 9374803decSYouMin Chen udelay(1); 9474803decSYouMin Chen } 9574803decSYouMin Chen 9674803decSYouMin Chen void phy_dram_set_bw(void __iomem *phy_base, u32 bw) 9774803decSYouMin Chen { 9874803decSYouMin Chen if (bw == 2) { 9974803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); 10074803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 10174803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 10274803decSYouMin Chen } else if (bw == 1) { 10374803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); 10474803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 10574803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 10674803decSYouMin Chen } else if (bw == 0) { 10774803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); 10874803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); 10974803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 11074803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 11174803decSYouMin Chen } 11274803decSYouMin Chen 11374803decSYouMin Chen phy_soft_reset(phy_base); 11474803decSYouMin Chen } 11574803decSYouMin Chen 11674803decSYouMin Chen int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype) 11774803decSYouMin Chen { 11874803decSYouMin Chen u32 ret; 11974803decSYouMin Chen u32 odt_val; 12074803decSYouMin Chen u32 i, j; 12174803decSYouMin Chen 12274803decSYouMin Chen odt_val = readl(PHY_REG(phy_base, 0x2e)); 12374803decSYouMin Chen 12474803decSYouMin Chen for (i = 0; i < 4; i++) { 12574803decSYouMin Chen j = 0x20 + i * 0x10; 12674803decSYouMin Chen writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1)); 12774803decSYouMin Chen writel(0, PHY_REG(phy_base, j + 0xe)); 12874803decSYouMin Chen } 12974803decSYouMin Chen 13074803decSYouMin Chen if (dramtype == DDR4) { 13174803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0); 13274803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0); 13374803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0); 13474803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0); 13574803decSYouMin Chen } 13674803decSYouMin Chen /* choose training cs */ 13774803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs)); 13874803decSYouMin Chen /* enable gate training */ 13974803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1); 14074803decSYouMin Chen udelay(50); 14174803decSYouMin Chen ret = readl(PHY_REG(phy_base, 0xff)); 14274803decSYouMin Chen /* disable gate training */ 14374803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0); 144*bbf5a1e4SYouMin Chen #ifndef CONFIG_ROCKCHIP_RK3328 14574803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 2), 0x30); 146*bbf5a1e4SYouMin Chen #endif 14774803decSYouMin Chen 14874803decSYouMin Chen if (dramtype == DDR4) { 14974803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2); 15074803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2); 15174803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2); 15274803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2); 15374803decSYouMin Chen } 15474803decSYouMin Chen 15574803decSYouMin Chen if (ret & 0x10) { 15674803decSYouMin Chen ret = -1; 15774803decSYouMin Chen } else { 15874803decSYouMin Chen ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4); 15974803decSYouMin Chen ret = (ret == 0) ? 0 : -1; 16074803decSYouMin Chen } 16174803decSYouMin Chen 16274803decSYouMin Chen for (i = 0; i < 4; i++) { 16374803decSYouMin Chen j = 0x20 + i * 0x10; 16474803decSYouMin Chen writel(odt_val, PHY_REG(phy_base, j + 0x1)); 16574803decSYouMin Chen writel(odt_val, PHY_REG(phy_base, j + 0xe)); 16674803decSYouMin Chen } 16774803decSYouMin Chen return ret; 16874803decSYouMin Chen } 16974803decSYouMin Chen 17074803decSYouMin Chen void phy_cfg(void __iomem *phy_base, 17174803decSYouMin Chen struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew, 17274803decSYouMin Chen struct sdram_base_params *base, u32 bw) 17374803decSYouMin Chen { 17474803decSYouMin Chen u32 i; 17574803decSYouMin Chen 17674803decSYouMin Chen sdram_phy_dll_bypass_set(phy_base, base->ddr_freq); 17774803decSYouMin Chen for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) { 17874803decSYouMin Chen writel(phy_regs->phy[i][1], 17974803decSYouMin Chen phy_base + phy_regs->phy[i][0]); 18074803decSYouMin Chen } 18174803decSYouMin Chen if (bw == 2) { 18274803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); 18374803decSYouMin Chen } else if (bw == 1) { 18474803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); 18574803decSYouMin Chen /* disable DQS2,DQS3 tx dll for saving power */ 18674803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 18774803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 18874803decSYouMin Chen } else { 18974803decSYouMin Chen clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); 19074803decSYouMin Chen /* disable DQS2,DQS3 tx dll for saving power */ 19174803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); 19274803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); 19374803decSYouMin Chen clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); 19474803decSYouMin Chen } 19574803decSYouMin Chen sdram_phy_set_ds_odt(phy_base, base->dramtype); 19674803decSYouMin Chen 19774803decSYouMin Chen /* deskew */ 19874803decSYouMin Chen setbits_le32(PHY_REG(phy_base, 2), 8); 19974803decSYouMin Chen sdram_copy_to_reg(PHY_REG(phy_base, 0xb0), 20074803decSYouMin Chen &skew->a0_a1_skew[0], 15 * 4); 20174803decSYouMin Chen sdram_copy_to_reg(PHY_REG(phy_base, 0x70), 20274803decSYouMin Chen &skew->cs0_dm0_skew[0], 44 * 4); 20374803decSYouMin Chen sdram_copy_to_reg(PHY_REG(phy_base, 0xc0), 20474803decSYouMin Chen &skew->cs1_dm0_skew[0], 44 * 4); 20574803decSYouMin Chen } 20674803decSYouMin Chen 207