1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-10-02 16:01:30 +02:00
Files
u-boot-megous/drivers/ram/rockchip/sdram_phy_px30.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

207 lines
5.6 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* (C) Copyright 2018 Rockchip Electronics Co., Ltd.
*/
#include <common.h>
#include <ram.h>
#include <asm/io.h>
#include <asm/arch-rockchip/sdram.h>
#include <asm/arch-rockchip/sdram_common.h>
#include <asm/arch-rockchip/sdram_phy_px30.h>
#include <linux/delay.h>
static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
{
u32 tmp;
u32 i, j;
u32 dqs_dll_freq;
setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
for (i = 0; i < 4; i++) {
j = 0x26 + i * 0x10;
setbits_le32(PHY_REG(phy_base, j), 1 << 4);
clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
}
if (freq <= 400)
/* DLL bypass */
setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
else
clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
#ifdef CONFIG_ROCKCHIP_RK3328
dqs_dll_freq = 680;
#else
dqs_dll_freq = 801;
#endif
if (freq <= dqs_dll_freq)
tmp = 2;
else
tmp = 1;
for (i = 0; i < 4; i++) {
j = 0x28 + i * 0x10;
writel(tmp, PHY_REG(phy_base, j));
}
}
static void sdram_phy_set_ds_odt(void __iomem *phy_base,
u32 dram_type)
{
u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
u32 i, j;
if (dram_type == DDR3) {
cmd_drv = PHY_DDR3_RON_RTT_34ohm;
clk_drv = PHY_DDR3_RON_RTT_45ohm;
dqs_drv = PHY_DDR3_RON_RTT_34ohm;
dqs_odt = PHY_DDR3_RON_RTT_225ohm;
} else {
cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
if (dram_type == LPDDR2)
dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
else
dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
}
/* DS */
writel(cmd_drv, PHY_REG(phy_base, 0x11));
clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
writel(clk_drv, PHY_REG(phy_base, 0x16));
writel(clk_drv, PHY_REG(phy_base, 0x18));
for (i = 0; i < 4; i++) {
j = 0x20 + i * 0x10;
writel(dqs_drv, PHY_REG(phy_base, j));
writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
/* ODT */
writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
}
}
void phy_soft_reset(void __iomem *phy_base)
{
clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
udelay(1);
setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
udelay(5);
setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
udelay(1);
}
void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
{
if (bw == 2) {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
} else if (bw == 1) {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
} else if (bw == 0) {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
}
phy_soft_reset(phy_base);
}
int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
{
u32 ret;
u32 odt_val;
u32 i, j;
odt_val = readl(PHY_REG(phy_base, 0x2e));
for (i = 0; i < 4; i++) {
j = 0x20 + i * 0x10;
writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
writel(0, PHY_REG(phy_base, j + 0xe));
}
if (dramtype == DDR4) {
clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
}
/* choose training cs */
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
/* enable gate training */
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
udelay(50);
ret = readl(PHY_REG(phy_base, 0xff));
/* disable gate training */
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
#ifndef CONFIG_ROCKCHIP_RK3328
clrbits_le32(PHY_REG(phy_base, 2), 0x30);
#endif
if (dramtype == DDR4) {
clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
}
if (ret & 0x10) {
ret = -1;
} else {
ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
ret = (ret == 0) ? 0 : -1;
}
for (i = 0; i < 4; i++) {
j = 0x20 + i * 0x10;
writel(odt_val, PHY_REG(phy_base, j + 0x1));
writel(odt_val, PHY_REG(phy_base, j + 0xe));
}
return ret;
}
void phy_cfg(void __iomem *phy_base,
struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
struct sdram_base_params *base, u32 bw)
{
u32 i;
sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
writel(phy_regs->phy[i][1],
phy_base + phy_regs->phy[i][0]);
}
if (bw == 2) {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
} else if (bw == 1) {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
/* disable DQS2,DQS3 tx dll for saving power */
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
} else {
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
/* disable DQS2,DQS3 tx dll for saving power */
clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
}
sdram_phy_set_ds_odt(phy_base, base->dramtype);
/* deskew */
setbits_le32(PHY_REG(phy_base, 2), 8);
sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
&skew->a0_a1_skew[0], 15 * 4);
sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
&skew->cs0_dm0_skew[0], 44 * 4);
sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
&skew->cs1_dm0_skew[0], 44 * 4);
}