ram: starfive: add ddr driver
Add driver for StarFive JH7110 to support ddr initialization in SPL. Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com> Tested-by: Conor Dooley <conor.dooley@microchip.com>
This commit is contained in:
parent
732f01aabf
commit
60abbadfc0
10 changed files with 3202 additions and 1 deletions
|
@ -112,3 +112,4 @@ source "drivers/ram/rockchip/Kconfig"
|
|||
source "drivers/ram/sifive/Kconfig"
|
||||
source "drivers/ram/stm32mp1/Kconfig"
|
||||
source "drivers/ram/octeon/Kconfig"
|
||||
source "drivers/ram/starfive/Kconfig"
|
||||
|
|
|
@ -20,5 +20,7 @@ obj-$(CONFIG_K3_DDRSS) += k3-ddrss/
|
|||
obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
|
||||
|
||||
obj-$(CONFIG_RAM_SIFIVE) += sifive/
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += starfive/
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_OCTEON) += octeon/
|
||||
|
|
5
drivers/ram/starfive/Kconfig
Normal file
5
drivers/ram/starfive/Kconfig
Normal file
|
@ -0,0 +1,5 @@
|
|||
config SPL_STARFIVE_DDR
|
||||
bool "StarFive DDR driver in SPL"
|
||||
depends on SPL_RAM && STARFIVE_JH7110
|
||||
help
|
||||
This enables DDR support for the platforms based on StarFive JH7110 SoC.
|
11
drivers/ram/starfive/Makefile
Normal file
11
drivers/ram/starfive/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2022 StarFive, Inc
|
||||
#
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += ddrphy_start.o
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += ddrphy_train.o
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += starfive_ddr.o
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += ddrphy_utils.o
|
||||
obj-$(CONFIG_SPL_STARFIVE_DDR) += ddrcsr_boot.o
|
||||
endif
|
339
drivers/ram/starfive/ddrcsr_boot.c
Normal file
339
drivers/ram/starfive/ddrcsr_boot.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/regs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <wait_bit.h>
|
||||
|
||||
#include "starfive_ddr.h"
|
||||
|
||||
#define REGOFFSET(offset) ((offset) / 4)
|
||||
|
||||
static const struct ddr_reg_cfg ddr_csr_cfg[] = {
|
||||
{0x0, 0x0, 0x00000001, REGSETALL},
|
||||
{0xf00, 0x0, 0x40001030, (OFFSET_SEL | F_SET | REG4G | REG8G)},
|
||||
{0xf00, 0x0, 0x40001030, (OFFSET_SEL | F_SET | REG2G)},
|
||||
{0xf04, 0x0, 0x00000001, (OFFSET_SEL | F_SET | REG4G | REG8G)},
|
||||
{0xf04, 0x0, 0x00800001, (OFFSET_SEL | F_SET | REG2G)},
|
||||
{0xf10, 0x0, 0x00400000, (OFFSET_SEL | REGSETALL)},
|
||||
{0xf14, 0x0, 0x043fffff, (OFFSET_SEL | REGSETALL)},
|
||||
{0xf18, 0x0, 0x00000000, (OFFSET_SEL | REGSETALL)},
|
||||
{0xf30, 0x0, 0x1f000041, (OFFSET_SEL | REGSETALL)},
|
||||
{0xf34, 0x0, 0x1f000041, (OFFSET_SEL | F_SET | REG4G | REG8G)},
|
||||
{0x110, 0x0, 0xc0000001, (OFFSET_SEL | REGSETALL)},
|
||||
{0x114, 0x0, 0xffffffff, (OFFSET_SEL | REGSETALL)},
|
||||
{0x10c, 0x0, 0x00000505, REGSETALL},
|
||||
{0x11c, 0x0, 0x00000000, REGSETALL},
|
||||
{0x500, 0x0, 0x00000201, REGSETALL},
|
||||
{0x514, 0x0, 0x00000100, REGSETALL},
|
||||
{0x6a8, 0x0, 0x00040000, REGSETALL},
|
||||
{0xea8, 0x0, 0x00040000, REGSETALL},
|
||||
{0x504, 0x0, 0x40000000, REGSETALL}
|
||||
};
|
||||
|
||||
static const struct ddr_reg_cfg ddr_csr_cfg1[] = {
|
||||
{0x310, 0x0, 0x00020000, REGSETALL},
|
||||
{0x310, 0x0, 0x00020001, REGSETALL},
|
||||
{0x600, 0x0, 0x002e0176, REGSETALL},
|
||||
{0x604, 0x0, 0x002e0176, REGSETALL},
|
||||
{0x608, 0x0, 0x001700bb, REGSETALL},
|
||||
{0x60c, 0x0, 0x000b005d, REGSETALL},
|
||||
{0x610, 0x0, 0x0005002e, REGSETALL},
|
||||
{0x614, 0x0, 0x00020017, REGSETALL},
|
||||
{0x618, 0x0, 0x00020017, REGSETALL},
|
||||
{0x61c, 0x0, 0x00020017, REGSETALL},
|
||||
{0x678, 0x0, 0x00000019, REGSETALL},
|
||||
{0x100, 0x0, 0x000000f8, REGSETALL},
|
||||
{0x620, 0x0, 0x03030404, REGSETALL},
|
||||
{0x624, 0x0, 0x04030505, REGSETALL},
|
||||
{0x628, 0x0, 0x07030884, REGSETALL},
|
||||
{0x62c, 0x0, 0x13150401, REGSETALL},
|
||||
{0x630, 0x0, 0x17150604, REGSETALL},
|
||||
{0x634, 0x0, 0x00110000, REGSETALL},
|
||||
{0x638, 0x0, 0x200a0a08, REGSETALL},
|
||||
{0x63c, 0x0, 0x1730f803, REGSETALL},
|
||||
{0x640, 0x0, 0x000a0c00, REGSETALL},
|
||||
{0x644, 0x0, 0xa005000a, REGSETALL},
|
||||
{0x648, 0x0, 0x00000000, REGSETALL},
|
||||
{0x64c, 0x0, 0x00081306, REGSETALL},
|
||||
{0x650, 0x0, 0x04070304, REGSETALL},
|
||||
{0x654, 0x0, 0x00000404, REGSETALL},
|
||||
{0x658, 0x0, 0x00000060, REGSETALL},
|
||||
{0x65c, 0x0, 0x00030008, REGSETALL},
|
||||
{0x660, 0x0, 0x00000000, REGSETALL},
|
||||
{0x680, 0x0, 0x00000603, REGSETALL},
|
||||
{0x684, 0x0, 0x01000202, REGSETALL},
|
||||
{0x688, 0x0, 0x0413040d, REGSETALL},
|
||||
{0x68c, 0x0, 0x20002420, REGSETALL},
|
||||
{0x690, 0x0, 0x00140000, REGSETALL},
|
||||
{0x69c, 0x0, 0x01240074, REGSETALL},
|
||||
{0x6a0, 0x0, 0x00000000, REGSETALL},
|
||||
{0x6a4, 0x0, 0x20240c00, REGSETALL},
|
||||
{0x6a8, 0x0, 0x00040000, REGSETALL},
|
||||
{0x4, 0x0, 0x30010006, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10010006, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x30020000, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10020000, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x30030031, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10030031, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x300b0033, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x100b0033, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x30160016, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10160016, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x10, 0x0, 0x00000010, REGSETALL},
|
||||
{0x14, 0x0, 0x00000001, REGSETALL},
|
||||
};
|
||||
|
||||
static const struct ddr_reg_cfg ddr_csr_cfg2[] = {
|
||||
{0xb8, 0xf0ffffff, 0x3000000, REGCLRSETALL},
|
||||
{0x84, 0xFEFFFFFF, 0x0, REGCLRSETALL},
|
||||
{0xb0, 0xFFFEFFFF, 0x0, REGCLRSETALL},
|
||||
{0xb0, 0xFEFFFFFF, 0x0, REGCLRSETALL},
|
||||
{0xb4, 0xffffffff, 0x1, REGCLRSETALL},
|
||||
{0x248, 0xffffffff, 0x3000000, REGCLRSETALL},
|
||||
{0x24c, 0xffffffff, 0x300, REGCLRSETALL},
|
||||
{0x24c, 0xffffffff, 0x3000000, REGCLRSETALL},
|
||||
{0xb0, 0xffffffff, 0x100, REGCLRSETALL},
|
||||
{0xb8, 0xFFF0FFFF, 0x30000, REGCLRSETALL},
|
||||
{0x84, 0xFFFEFFFF, 0x0, REGCLRSETALL},
|
||||
{0xac, 0xFFFEFFFF, 0x0, REGCLRSETALL},
|
||||
{0xac, 0xFEFFFFFF, 0x0, REGCLRSETALL},
|
||||
{0xb0, 0xffffffff, 0x1, REGCLRSETALL},
|
||||
{0x248, 0xffffffff, 0x30000, REGCLRSETALL},
|
||||
{0x24c, 0xffffffff, 0x3, REGCLRSETALL},
|
||||
{0x24c, 0xffffffff, 0x30000, REGCLRSETALL},
|
||||
{0x250, 0xffffffff, 0x3000000, REGCLRSETALL},
|
||||
{0x254, 0xffffffff, 0x3000000, REGCLRSETALL},
|
||||
{0x258, 0xffffffff, 0x3000000, REGCLRSETALL},
|
||||
{0xac, 0xffffffff, 0x100, REGCLRSETALL},
|
||||
{0x10c, 0xFFFFF0FF, 0x300, REGCLRSETALL},
|
||||
{0x110, 0xFFFFFEFF, 0x0, REGCLRSETALL},
|
||||
{0x11c, 0xFFFEFFFF, 0x0, REGCLRSETALL},
|
||||
{0x11c, 0xFEFFFFFF, 0x0, REGCLRSETALL},
|
||||
{0x120, 0xffffffff, 0x100, REGCLRSETALL},
|
||||
{0x2d0, 0xffffffff, 0x300, REGCLRSETALL},
|
||||
{0x2dc, 0xffffffff, 0x300, REGCLRSETALL},
|
||||
{0x2e8, 0xffffffff, 0x300, REGCLRSETALL},
|
||||
};
|
||||
|
||||
static const struct ddr_reg_cfg ddr_csr_cfg3[] = {
|
||||
{0x100, 0x0, 0x000000e0, REGSETALL},
|
||||
{0x620, 0x0, 0x04041417, REGSETALL},
|
||||
{0x624, 0x0, 0x09110609, REGSETALL},
|
||||
{0x628, 0x0, 0x442d0994, REGSETALL},
|
||||
{0x62c, 0x0, 0x271e102b, REGSETALL},
|
||||
{0x630, 0x0, 0x291b140a, REGSETALL},
|
||||
{0x634, 0x0, 0x001c0000, REGSETALL},
|
||||
{0x638, 0x0, 0x200f0f08, REGSETALL},
|
||||
{0x63c, 0x0, 0x29420a06, REGSETALL},
|
||||
{0x640, 0x0, 0x019e1fc1, REGSETALL},
|
||||
{0x644, 0x0, 0x10cb0196, REGSETALL},
|
||||
{0x648, 0x0, 0x00000000, REGSETALL},
|
||||
{0x64c, 0x0, 0x00082714, REGSETALL},
|
||||
{0x650, 0x0, 0x16442f0d, REGSETALL},
|
||||
{0x654, 0x0, 0x00001916, REGSETALL},
|
||||
{0x658, 0x0, 0x00000060, REGSETALL},
|
||||
{0x65c, 0x0, 0x00600020, REGSETALL},
|
||||
{0x660, 0x0, 0x00000000, REGSETALL},
|
||||
{0x680, 0x0, 0x0c00040f, REGSETALL},
|
||||
{0x684, 0x0, 0x03000604, REGSETALL},
|
||||
{0x688, 0x0, 0x0515040d, REGSETALL},
|
||||
{0x68c, 0x0, 0x20002c20, REGSETALL},
|
||||
{0x690, 0x0, 0x00140000, REGSETALL},
|
||||
{0x69c, 0x0, 0x01240074, REGSETALL},
|
||||
{0x6a0, 0x0, 0x00000000, REGSETALL},
|
||||
{0x6a4, 0x0, 0x202c0c00, REGSETALL},
|
||||
{0x6a8, 0x0, 0x00040000, REGSETALL},
|
||||
{0x4, 0x0, 0x30010036, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10010036, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x3002001b, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10010036, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x30030031, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10030031, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x300b0066, (F_SET | REG4G)},
|
||||
{0x4, 0x0, 0x300b0036, (F_SET | REG8G)},
|
||||
{0x4, 0x0, 0x100b0066, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x4, 0x0, 0x30160016, (F_SET | REG4G | REG8G)},
|
||||
{0x4, 0x0, 0x10160016, (F_SET | REG2G)},
|
||||
{0xc, 0x0, 0x00000002, REGSETALL},
|
||||
{0x410, 0x0, 0x00101010, REGSETALL},
|
||||
{0x420, 0x0, 0x0c181006, REGSETALL},
|
||||
{0x424, 0x0, 0x20200820, REGSETALL},
|
||||
{0x428, 0x0, 0x80000020, REGSETALL},
|
||||
{0x0, 0x0, 0x00000001, REGSETALL},
|
||||
{0x108, 0x0, 0x00003000, REGSETALL},
|
||||
{0x704, 0x0, 0x00000007, REGSETALL | OFFSET_SEL},
|
||||
{0x330, 0x0, 0x09313fff, (F_SET | REG4G | REG8G)},
|
||||
{0x330, 0x0, 0x09311fff, (F_SET | REG2G)},
|
||||
{0x508, 0x0, 0x00000033, (F_SET | REG4G | REG8G)},
|
||||
{0x508, 0x0, 0x00000013, (F_SET | REG2G)},
|
||||
{0x324, 0x0, 0x00002000, REGSETALL},
|
||||
{0x104, 0x0, 0x90000000, REGSETALL},
|
||||
{0x510, 0x0, 0x00000100, REGSETALL},
|
||||
{0x514, 0x0, 0x00000000, REGSETALL},
|
||||
{0x700, 0x0, 0x00000003, REGSETALL | OFFSET_SEL},
|
||||
{0x514, 0x0, 0x00000600, REGSETALL},
|
||||
{0x20, 0x0, 0x00000001, REGSETALL},
|
||||
};
|
||||
|
||||
static void ddr_csr_set(u32 *csrreg, u32 *secreg, const struct ddr_reg_cfg *data,
|
||||
u32 len, u32 mask)
|
||||
{
|
||||
u32 *addr;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!(data[i].flag & mask))
|
||||
continue;
|
||||
|
||||
if (data[i].flag & OFFSET_SEL)
|
||||
addr = secreg + REGOFFSET(data[i].offset);
|
||||
else
|
||||
addr = csrreg + REGOFFSET(data[i].offset);
|
||||
|
||||
if (data[i].flag & F_CLRSET)
|
||||
DDR_REG_TRIGGER(addr, data[i].mask, data[i].val);
|
||||
else
|
||||
out_le32(addr, data[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
|
||||
{
|
||||
u32 len;
|
||||
u32 val;
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
switch (size) {
|
||||
case DDR_SIZE_2G:
|
||||
mask = REG2G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_4G:
|
||||
mask = REG4G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_8G:
|
||||
mask = REG8G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_16G:
|
||||
default:
|
||||
return;
|
||||
};
|
||||
|
||||
len = ARRAY_SIZE(ddr_csr_cfg);
|
||||
ddr_csr_set(csrreg, secreg, ddr_csr_cfg, len, mask);
|
||||
|
||||
ret = wait_for_bit_le32(csrreg + REGOFFSET(0x504), BIT(31),
|
||||
true, 1000, false);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
out_le32(csrreg + REGOFFSET(0x504), 0x0);
|
||||
out_le32(csrreg + REGOFFSET(0x50c), 0x0);
|
||||
udelay(300);
|
||||
out_le32(csrreg + REGOFFSET(0x50c), 0x1);
|
||||
mdelay(3);
|
||||
|
||||
switch (size) {
|
||||
case DDR_SIZE_2G:
|
||||
out_le32(csrreg + REGOFFSET(0x10), 0x1c);
|
||||
break;
|
||||
|
||||
case DDR_SIZE_8G:
|
||||
case DDR_SIZE_4G:
|
||||
out_le32(csrreg + REGOFFSET(0x10), 0x3c);
|
||||
break;
|
||||
|
||||
case DDR_SIZE_16G:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
out_le32(csrreg + REGOFFSET(0x14), 0x1);
|
||||
udelay(4);
|
||||
|
||||
len = ARRAY_SIZE(ddr_csr_cfg1);
|
||||
ddr_csr_set(csrreg, secreg, ddr_csr_cfg1, len, mask);
|
||||
|
||||
udelay(4);
|
||||
out_le32(csrreg + REGOFFSET(0x10), 0x11);
|
||||
out_le32(csrreg + REGOFFSET(0x14), 0x1);
|
||||
|
||||
switch (size) {
|
||||
case DDR_SIZE_4G:
|
||||
case DDR_SIZE_8G:
|
||||
out_le32(csrreg + REGOFFSET(0x10), 0x20);
|
||||
out_le32(csrreg + REGOFFSET(0x14), 0x1);
|
||||
udelay(4);
|
||||
out_le32(csrreg + REGOFFSET(0x10), 0x21);
|
||||
out_le32(csrreg + REGOFFSET(0x14), 0x1);
|
||||
break;
|
||||
|
||||
case DDR_SIZE_2G:
|
||||
case DDR_SIZE_16G:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
out_le32(csrreg + REGOFFSET(0x514), 0x0);
|
||||
ret = wait_for_bit_le32(csrreg + REGOFFSET(0x518), BIT(1),
|
||||
true, 1000, false);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
val = in_le32(csrreg + REGOFFSET(0x518));
|
||||
while ((val & 0x2) != 0x0) {
|
||||
val = in_le32(phyreg + 1);
|
||||
|
||||
if ((val & 0x20) == 0x20) {
|
||||
switch (val & 0x1f) {
|
||||
case 0: /* ddrc_clock=12M */
|
||||
DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
|
||||
break;
|
||||
case 1: /* ddrc_clock=200M */
|
||||
DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV8);
|
||||
break;
|
||||
case 2: /* ddrc_clock=800M */
|
||||
DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
out_le32(phyreg + 2, 0x1);
|
||||
ret = wait_for_bit_le32(phyreg + 2, BIT(0), false, 1000, false);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
udelay(1);
|
||||
val = in_le32(csrreg + REGOFFSET(0x518));
|
||||
};
|
||||
|
||||
val = in_le32(phyreg + 2048 + 83);
|
||||
val = in_le32(phyreg + 2048 + 84);
|
||||
out_le32(phyreg + 2048 + 84, val & 0xF8000000);
|
||||
|
||||
len = ARRAY_SIZE(ddr_csr_cfg2);
|
||||
ddr_csr_set(phyreg + PHY_BASE_ADDR, secreg, ddr_csr_cfg2, len, mask);
|
||||
|
||||
len = ARRAY_SIZE(ddr_csr_cfg3);
|
||||
ddr_csr_set(csrreg, secreg, ddr_csr_cfg3, len, mask);
|
||||
}
|
279
drivers/ram/starfive/ddrphy_start.c
Normal file
279
drivers/ram/starfive/ddrphy_start.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "starfive_ddr.h"
|
||||
|
||||
static const struct ddr_reg_cfg ddr_start_cfg[] = {
|
||||
{89, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{78, 0xfffffcff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{345, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{334, 0xfffffcff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{601, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{590, 0xfffffcff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{857, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{846, 0xfffffcff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1793, 0xfffffeff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1793, 0xfffcffff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{125, 0xfff0ffff, 0x00010000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{102, 0xfffffffc, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{105, 0xffffffe0, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{92, 0xfffffffe, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{94, 0xffffe0ff, 0x00000200, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{96, 0xfffff0ff, 0x00000400, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{89, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{381, 0xfff0ffff, 0x00010000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{358, 0xfffffffc, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{361, 0xffffffe0, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{348, 0xfffffffe, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{350, 0xffffe0ff, 0x00000200, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{352, 0xfffff0ff, 0x00000400, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{345, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{637, 0xfff0ffff, 0x00010000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{614, 0xfffffffc, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{617, 0xffffffe0, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{604, 0xfffffffe, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{606, 0xffffe0ff, 0x00000200, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{608, 0xfffff0ff, 0x00000400, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{601, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{893, 0xfff0ffff, 0x00010000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{870, 0xfffffffc, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{873, 0xffffffe0, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{860, 0xfffffffe, 0x00000001, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{862, 0xffffe0ff, 0x00000200, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{864, 0xfffff0ff, 0x00000400, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{857, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1895, 0xffffe000, 0x00001342, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1835, 0xfffff0ff, 0x00000200, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1793, 0xfffffeff, 0x00000100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{62, 0xfffffeff, 0x0, REGCLRSETALL},
|
||||
{66, 0xfffffeff, 0x0, REGCLRSETALL},
|
||||
{166, 0xffffff80, 0x00000001, REGCLRSETALL},
|
||||
{62, 0xfff0ffff, 0x00010000, REGCLRSETALL},
|
||||
{62, 0xf0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{166, 0xffff80ff, 0x00000100, REGCLRSETALL},
|
||||
{179, 0xff80ffff, 0x00010000, REGCLRSETALL},
|
||||
{67, 0xffe0ffff, 0x00010000, REGCLRSETALL},
|
||||
{67, 0xe0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{179, 0x80ffffff, 0x01000000, REGCLRSETALL},
|
||||
{166, 0xff80ffff, 0x00010000, REGCLRSETALL},
|
||||
{62, 0xfff0ffff, 0x00010000, REGCLRSETALL},
|
||||
{62, 0xf0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{166, 0x80ffffff, 0x01000000, REGCLRSETALL},
|
||||
{182, 0xff80ffff, 0x00010000, REGCLRSETALL},
|
||||
{67, 0xffe0ffff, 0x00010000, REGCLRSETALL},
|
||||
{67, 0xe0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{182, 0x80ffffff, 0x01000000, REGCLRSETALL},
|
||||
{167, 0xffffff80, 0x00000017, REGCLRSETALL},
|
||||
{62, 0xfff0ffff, 0x00010000, REGCLRSETALL},
|
||||
{62, 0xf0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{167, 0xffff80ff, 0x00001700, REGCLRSETALL},
|
||||
{185, 0xff80ffff, 0x00200000, REGCLRSETALL},
|
||||
{67, 0xffe0ffff, 0x00010000, REGCLRSETALL},
|
||||
{67, 0xe0ffffff, 0x01000000, REGCLRSETALL},
|
||||
{185, 0x80ffffff, 0x20000000, REGCLRSETALL},
|
||||
{10, 0xffffffe0, 0x00000002, REGCLRSETALL},
|
||||
{0, 0xfffffffe, 0x00000001, REGCLRSETALL},
|
||||
{11, 0xfffffff0, 0x00000005, (F_CLRSET | REG2G)},
|
||||
{247, 0xffffffff, 0x00000008, REGCLRSETALL},
|
||||
{249, 0xffffffff, 0x00000800, REGCLRSETALL},
|
||||
{252, 0xffffffff, 0x00000008, REGCLRSETALL},
|
||||
{254, 0xffffffff, 0x00000800, REGCLRSETALL},
|
||||
{281, 0xffffffff, 0x33000000, REGCLRSETALL},
|
||||
{305, 0xffffffff, 0x33000000, REGCLRSETALL},
|
||||
{329, 0xffffffff, 0x33000000, REGCLRSETALL},
|
||||
{353, 0xffffffff, 0x33000000, REGCLRSETALL},
|
||||
{289, 0xffffffff, 0x36000000, (F_CLRSET | REG8G)},
|
||||
{313, 0xffffffff, 0x36000000, (F_CLRSET | REG8G)},
|
||||
{337, 0xffffffff, 0x36000000, (F_CLRSET | REG8G)},
|
||||
{361, 0xffffffff, 0x36000000, (F_CLRSET | REG8G)},
|
||||
{289, 0xffffffff, 0x66000000, (F_CLRSET | REG2G | REG4G)},
|
||||
{313, 0xffffffff, 0x66000000, (F_CLRSET | REG2G | REG4G)},
|
||||
{337, 0xffffffff, 0x66000000, (F_CLRSET | REG2G | REG4G)},
|
||||
{361, 0xffffffff, 0x66000000, (F_CLRSET | REG2G | REG4G)},
|
||||
{282, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{306, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{330, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{354, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{290, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{314, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{338, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{362, 0xffffffff, 0x00160000, REGCLRSETALL},
|
||||
{282, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{306, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{330, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{354, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{290, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{314, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{338, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{362, 0xffffff00, 0x17, REGCLRSETALL},
|
||||
{282, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{306, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{330, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{354, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{290, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{314, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{338, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{362, 0xffff00ff, 0x2000, REGCLRSETALL},
|
||||
{65, 0xffffffff, 0x00000100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{321, 0xffffffff, 0x00000100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{577, 0xffffffff, 0x00000100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{833, 0xffffffff, 0x00000100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{96, 0x0, 0x300, (OFFSET_SEL | REGADDSETALL)},
|
||||
{352, 0x0, 0x300, (OFFSET_SEL | REGADDSETALL)},
|
||||
{608, 0x0, 0x300, (OFFSET_SEL | REGADDSETALL)},
|
||||
{864, 0x0, 0x300, (OFFSET_SEL | REGADDSETALL)},
|
||||
{96, 0xff00ffff, 0x00120000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{352, 0xff00ffff, 0x00120000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{608, 0xff00ffff, 0x00120000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{864, 0xff00ffff, 0x00120000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{33, 0xffffff00, 0x0040, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{289, 0xffffff00, 0x0040, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{545, 0xffffff00, 0x0040, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{801, 0xffffff00, 0x0040, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1038, 0xfcffffff, 0x03000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1294, 0xfcffffff, 0x03000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1550, 0xfcffffff, 0x03000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{83, 0xffc0ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{339, 0xffc0ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{595, 0xffc0ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{851, 0xffc0ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1062, 0xf800ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1318, 0xf800ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1574, 0xf800ffff, 0x70000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1892, 0xfffc0000, 0x15547, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1893, 0xfffc0000, 0x7, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1852, 0xffffe000, 0x07a, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1853, 0xffffffff, 0x0100, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1822, 0xffffffff, 0xFF, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1896, 0xfffffc00, 0x03d5, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{91, 0xfc00ffff, 0x03d50000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{347, 0xfc00ffff, 0x03d50000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{603, 0xfc00ffff, 0x03d50000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{859, 0xfc00ffff, 0x03d50000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1912, 0x0, 0xcc3bfc7, (OFFSET_SEL | REGSETALL)},
|
||||
{1913, 0x0, 0xff8f, (OFFSET_SEL | REGSETALL)},
|
||||
{1914, 0x0, 0x33f07ff, (OFFSET_SEL | REGSETALL)},
|
||||
{1915, 0x0, 0xc3c37ff, (OFFSET_SEL | REGSETALL)},
|
||||
{1916, 0x0, 0x1fffff10, (OFFSET_SEL | REGSETALL)},
|
||||
{1917, 0x0, 0x230070, (OFFSET_SEL | REGSETALL)},
|
||||
{1918, 0x0, 0x3ff7ffff, (OFFSET_SEL | REG4G | REG2G | F_SET)},
|
||||
{1918, 0x0, 0x3ff7ffff, (OFFSET_SEL | REG8G | F_SET)},
|
||||
{1919, 0x0, 0xe10, (OFFSET_SEL | REGSETALL)},
|
||||
{1920, 0x0, 0x1fffffff, (OFFSET_SEL | REGSETALL)},
|
||||
{1921, 0x0, 0x188411, (OFFSET_SEL | REGSETALL)},
|
||||
{1922, 0x0, 0x1fffffff, (OFFSET_SEL | REGSETALL)},
|
||||
{1923, 0x0, 0x180400, (OFFSET_SEL | REGSETALL)},
|
||||
{1924, 0x0, 0x1fffffff, (OFFSET_SEL | REGSETALL)},
|
||||
{1925, 0x0, 0x180400, (OFFSET_SEL | REGSETALL)},
|
||||
{1926, 0x0, 0x1fffffcf, (OFFSET_SEL | REGSETALL)},
|
||||
{1927, 0x0, 0x188400, (OFFSET_SEL | REGSETALL)},
|
||||
{1928, 0x0, 0x1fffffff, (OFFSET_SEL | REGSETALL)},
|
||||
{1929, 0x0, 0x4188411, (OFFSET_SEL | REGSETALL)},
|
||||
{1837, 0x0, 0x24410, (OFFSET_SEL | REGSETALL)},
|
||||
{1840, 0x0, 0x24410, (OFFSET_SEL | REGSETALL)},
|
||||
{1842, 0x0, 0x2ffff, (OFFSET_SEL | REGSETALL)},
|
||||
{76, 0xff0000f8, 0x00ff8f07, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{332, 0xff0000f8, 0x00ff8f07, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{588, 0xff0000f8, 0x00ff8f07, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{844, 0xff0000f8, 0x00ff8f07, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{77, 0xffff0000, 0xff8f, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{333, 0xffff0000, 0xff8f, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{589, 0xffff0000, 0xff8f, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{845, 0xffff0000, 0xff8f, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1062, 0xffffff00, 0xff, (OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
|
||||
{1318, 0xffffff00, 0xff, (OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
|
||||
{1574, 0xffffff00, 0xff, (OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
|
||||
{1062, 0xffffff00, 0xfb, (OFFSET_SEL | REG8G | F_CLRSET)},
|
||||
{1318, 0xffffff00, 0xfb, (OFFSET_SEL | REG8G | F_CLRSET)},
|
||||
{1574, 0xffffff00, 0xfb, (OFFSET_SEL | REG8G | F_CLRSET)},
|
||||
{1028, 0xffffffff, 0x1000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1284, 0xffffffff, 0x1000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1540, 0xffffffff, 0x1000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1848, 0x0, 0x3cf07f8, (OFFSET_SEL | REGSETALL)},
|
||||
{1849, 0x0, 0x3f, (OFFSET_SEL | REGSETALL)},
|
||||
{1850, 0x0, 0x1fffff, (OFFSET_SEL | REGSETALL)},
|
||||
{1851, 0x0, 0x060000, (OFFSET_SEL | REGSETALL)},
|
||||
{130, 0x0000ffff, 0xffff0000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{386, 0x0000ffff, 0xffff0000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{642, 0x0000ffff, 0xffff0000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{898, 0x0000ffff, 0xffff0000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{131, 0xfffffff0, 0xf, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{387, 0xfffffff0, 0xf, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{643, 0xfffffff0, 0xf, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{899, 0xfffffff0, 0xf, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{29, 0xc0ffffff, 0x10000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{285, 0xc0ffffff, 0x10000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{541, 0xc0ffffff, 0x10000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{797, 0xc0ffffff, 0x10000000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{30, 0xffffffff, 0x00080000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{286, 0xffffffff, 0x00080000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{542, 0xffffffff, 0x00080000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{798, 0xffffffff, 0x00080000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{31, 0xffffffc0, 0x00000010, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{287, 0xffffffc0, 0x00000010, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{543, 0xffffffc0, 0x00000010, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{799, 0xffffffc0, 0x00000010, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1071, 0xfffffff0, 0x00000008, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1327, 0xfffffff0, 0x00000008, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1583, 0xfffffff0, 0x00000008, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1808, 0xfffffff0, 0x00000008, (OFFSET_SEL | REGCLRSETALL)},
|
||||
{1896, 0xfff0ffff, 0x00080000, (OFFSET_SEL | REGCLRSETALL)},
|
||||
};
|
||||
|
||||
void ddr_reg_set(u32 *reg, const struct ddr_reg_cfg *data,
|
||||
u32 len, u32 mask)
|
||||
{
|
||||
u32 *addr;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!(data[i].flag & mask))
|
||||
continue;
|
||||
|
||||
if (data[i].flag & OFFSET_SEL)
|
||||
addr = reg + PHY_AC_BASE_ADDR + data[i].offset;
|
||||
else
|
||||
addr = reg + PHY_BASE_ADDR + data[i].offset;
|
||||
|
||||
if (data[i].flag & F_CLRSET)
|
||||
DDR_REG_TRIGGER(addr, data[i].mask, data[i].val);
|
||||
else if (data[i].flag & F_SET)
|
||||
out_le32(addr, data[i].val);
|
||||
else
|
||||
out_le32(addr, in_le32(addr) + data[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
|
||||
{
|
||||
u32 len;
|
||||
u32 mask;
|
||||
|
||||
switch (size) {
|
||||
case DDR_SIZE_2G:
|
||||
mask = REG2G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_4G:
|
||||
mask = REG4G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_8G:
|
||||
mask = REG8G;
|
||||
break;
|
||||
|
||||
case DDR_SIZE_16G:
|
||||
default:
|
||||
return;
|
||||
};
|
||||
|
||||
len = ARRAY_SIZE(ddr_start_cfg);
|
||||
ddr_reg_set(phyreg, ddr_start_cfg, len, mask);
|
||||
out_le32(phyreg, 0x01);
|
||||
}
|
383
drivers/ram/starfive/ddrphy_train.c
Normal file
383
drivers/ram/starfive/ddrphy_train.c
Normal file
|
@ -0,0 +1,383 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static const u32 ddr_train_data[] = {
|
||||
0xb00,
|
||||
0x101,
|
||||
0x640000,
|
||||
0x1,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1,
|
||||
0x7,
|
||||
0x10002,
|
||||
0x300080f,
|
||||
0x1,
|
||||
0x5,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1010000,
|
||||
0x280a0000,
|
||||
0x0,
|
||||
0x1,
|
||||
0x3200000f,
|
||||
0x0,
|
||||
0x0,
|
||||
0x10102,
|
||||
0x1,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xaa,
|
||||
0x55,
|
||||
0xb5,
|
||||
0x4a,
|
||||
0x56,
|
||||
0xa9,
|
||||
0xa9,
|
||||
0xb5,
|
||||
0x1000000,
|
||||
0x1000000,
|
||||
0x0,
|
||||
0xf0f0000,
|
||||
0x14,
|
||||
0x7d0,
|
||||
0x300,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1000000,
|
||||
0x10101,
|
||||
0x0,
|
||||
0x30000,
|
||||
0x100,
|
||||
0x170f,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xa140a01,
|
||||
0x204010a,
|
||||
0x2080510,
|
||||
0x40400,
|
||||
0x1000101,
|
||||
0x10100,
|
||||
0x2040f00,
|
||||
0x34000000,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1000000,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x10100,
|
||||
0x80101,
|
||||
0x2000200,
|
||||
0x1000100,
|
||||
0x1000000,
|
||||
0x2000200,
|
||||
0x200,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xe000004,
|
||||
0xc0d100f,
|
||||
0xa09080b,
|
||||
0x2010000,
|
||||
0x80103,
|
||||
0x200,
|
||||
0x0,
|
||||
0xf000000,
|
||||
0x4,
|
||||
0xa,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x30100,
|
||||
0x1010001,
|
||||
0x10200,
|
||||
0x4000103,
|
||||
0x1050001,
|
||||
0x10600,
|
||||
0x107,
|
||||
0x0,
|
||||
0x0,
|
||||
0x10001,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x10000,
|
||||
0x4,
|
||||
0x0,
|
||||
0x10000,
|
||||
0x0,
|
||||
0x3c0003,
|
||||
0x80100a0,
|
||||
0x16,
|
||||
0x2c,
|
||||
0x33,
|
||||
0x20043,
|
||||
0x2000200,
|
||||
0x4,
|
||||
0x60c,
|
||||
0xa1400,
|
||||
0x280000,
|
||||
0x6,
|
||||
0x46,
|
||||
0x70,
|
||||
0x610,
|
||||
0x12b,
|
||||
0x4001035,
|
||||
0x1010404,
|
||||
0x1e01,
|
||||
0x1e001e,
|
||||
0x1000100,
|
||||
0x100,
|
||||
0x0,
|
||||
0x5060403,
|
||||
0x1011108,
|
||||
0x1010101,
|
||||
0xf0a0a,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4000000,
|
||||
0x4021008,
|
||||
0x4020206,
|
||||
0xc0034,
|
||||
0x100038,
|
||||
0x17003f,
|
||||
0x10001,
|
||||
0x10001,
|
||||
0x10005,
|
||||
0x20064,
|
||||
0x100010b,
|
||||
0x60006,
|
||||
0x650100,
|
||||
0x1000065,
|
||||
0x10c010c,
|
||||
0x1e1a1e1a,
|
||||
0x1011e1a,
|
||||
0xa070601,
|
||||
0xa07060d,
|
||||
0x100b080d,
|
||||
0xc00f,
|
||||
0xc01000,
|
||||
0xc01000,
|
||||
0x21000,
|
||||
0x120005,
|
||||
0x190064,
|
||||
0x10b,
|
||||
0x1100,
|
||||
0x1e1a0056,
|
||||
0x6000101,
|
||||
0x130204,
|
||||
0x1e1a0058,
|
||||
0x1000101,
|
||||
0x230408,
|
||||
0x1e1a005e,
|
||||
0x9000101,
|
||||
0x610,
|
||||
0x4040800,
|
||||
0x40100,
|
||||
0x3000277,
|
||||
0xa032001,
|
||||
0xa0a,
|
||||
0x80908,
|
||||
0x901,
|
||||
0x1100315c,
|
||||
0xa062002,
|
||||
0xa0a,
|
||||
0x141708,
|
||||
0x150d,
|
||||
0x2d00838e,
|
||||
0xf102004,
|
||||
0xf0b,
|
||||
0x8c,
|
||||
0x578,
|
||||
0xc20,
|
||||
0x7940,
|
||||
0x206a,
|
||||
0x14424,
|
||||
0x730006,
|
||||
0x3030133,
|
||||
0x4,
|
||||
0x0,
|
||||
0x4,
|
||||
0x1,
|
||||
0x5,
|
||||
0x2,
|
||||
0x6,
|
||||
0x50,
|
||||
0x1,
|
||||
0x5,
|
||||
0x28,
|
||||
0x73,
|
||||
0xd6,
|
||||
0x1,
|
||||
0x5,
|
||||
0x6b,
|
||||
0x1000133,
|
||||
0x140040,
|
||||
0x10001,
|
||||
0x1900040,
|
||||
0x1000c,
|
||||
0x42b0040,
|
||||
0x320,
|
||||
0x360014,
|
||||
0x1010101,
|
||||
0x2020101,
|
||||
0x8080404,
|
||||
0x67676767,
|
||||
0x67676767,
|
||||
0x67676767,
|
||||
0x67676767,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x5500,
|
||||
0x5a00,
|
||||
0x55003c,
|
||||
0x0,
|
||||
0x3c00005a,
|
||||
0x5500,
|
||||
0x5a00,
|
||||
0x55003c,
|
||||
0x0,
|
||||
0x3c00005a,
|
||||
0x18171615,
|
||||
0x14131211,
|
||||
0x7060504,
|
||||
0x3020100,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1000000,
|
||||
0x4020201,
|
||||
0x80804,
|
||||
0x0,
|
||||
0x4,
|
||||
0x0,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x14,
|
||||
0x9,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x34,
|
||||
0x1b,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x4,
|
||||
0x0,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x14,
|
||||
0x9,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x34,
|
||||
0x1b,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x4,
|
||||
0x0,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x14,
|
||||
0x9,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x34,
|
||||
0x1b,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x4,
|
||||
0x0,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x14,
|
||||
0x9,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
0x0,
|
||||
0x34,
|
||||
0x1b,
|
||||
0x31,
|
||||
0x31,
|
||||
0x0,
|
||||
0x0,
|
||||
0x4d4d,
|
||||
};
|
||||
|
||||
void ddr_phy_train(u32 *phyreg)
|
||||
{
|
||||
u32 i, len;
|
||||
|
||||
len = ARRAY_SIZE(ddr_train_data);
|
||||
for (i = 0; i < len; i++)
|
||||
out_le32(phyreg + i, ddr_train_data[i]);
|
||||
}
|
1955
drivers/ram/starfive/ddrphy_utils.c
Normal file
1955
drivers/ram/starfive/ddrphy_utils.c
Normal file
File diff suppressed because it is too large
Load diff
161
drivers/ram/starfive/starfive_ddr.c
Normal file
161
drivers/ram/starfive/starfive_ddr.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/regs.h>
|
||||
#include <asm/io.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/delay.h>
|
||||
#include <ram.h>
|
||||
#include <reset.h>
|
||||
|
||||
#include "starfive_ddr.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct starfive_ddr_priv {
|
||||
struct udevice *dev;
|
||||
struct ram_info info;
|
||||
void __iomem *ctrlreg;
|
||||
void __iomem *phyreg;
|
||||
struct reset_ctl_bulk rst;
|
||||
struct clk clk;
|
||||
u32 fre;
|
||||
};
|
||||
|
||||
static int starfive_ddr_setup(struct udevice *dev, struct starfive_ddr_priv *priv)
|
||||
{
|
||||
enum ddr_size_t size;
|
||||
|
||||
switch (priv->info.size) {
|
||||
case SZ_2G:
|
||||
size = DDR_SIZE_2G;
|
||||
break;
|
||||
|
||||
case SZ_4G:
|
||||
size = DDR_SIZE_4G;
|
||||
break;
|
||||
|
||||
case 0x200000000:
|
||||
size = DDR_SIZE_8G;
|
||||
break;
|
||||
|
||||
case 0x400000000:
|
||||
default:
|
||||
pr_err("unsupport size %lx\n", priv->info.size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ddr_phy_train(priv->phyreg + (PHY_BASE_ADDR << 2));
|
||||
ddr_phy_util(priv->phyreg + (PHY_AC_BASE_ADDR << 2));
|
||||
ddr_phy_start(priv->phyreg, size);
|
||||
|
||||
DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
|
||||
ddrcsr_boot(priv->ctrlreg, priv->ctrlreg + SEC_CTRL_ADDR,
|
||||
priv->phyreg, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int starfive_ddr_probe(struct udevice *dev)
|
||||
{
|
||||
struct starfive_ddr_priv *priv = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
u64 rate;
|
||||
int ret;
|
||||
|
||||
/* Read memory base and size from DT */
|
||||
fdtdec_setup_mem_size_base();
|
||||
priv->info.base = gd->ram_base;
|
||||
priv->info.size = gd->ram_size;
|
||||
|
||||
priv->dev = dev;
|
||||
addr = dev_read_addr_index(dev, 0);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->ctrlreg = (void __iomem *)addr;
|
||||
addr = dev_read_addr_index(dev, 1);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->phyreg = (void __iomem *)addr;
|
||||
ret = dev_read_u32(dev, "clock-frequency", &priv->fre);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (priv->fre) {
|
||||
case 2133:
|
||||
rate = 1066000000;
|
||||
break;
|
||||
|
||||
case 2800:
|
||||
rate = 1400000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("Unknown DDR frequency %d\n", priv->fre);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
ret = reset_get_bulk(dev, &priv->rst);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_deassert_bulk(&priv->rst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->clk);
|
||||
if (ret)
|
||||
goto err_free_reset;
|
||||
|
||||
ret = clk_set_rate(&priv->clk, rate);
|
||||
if (ret < 0)
|
||||
goto err_free_reset;
|
||||
|
||||
ret = starfive_ddr_setup(dev, priv);
|
||||
printf("DDR version: dc2e84f0.\n");
|
||||
|
||||
return ret;
|
||||
|
||||
err_free_reset:
|
||||
reset_release_bulk(&priv->rst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int starfive_ddr_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct starfive_ddr_priv *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops starfive_ddr_ops = {
|
||||
.get_info = starfive_ddr_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id starfive_ddr_ids[] = {
|
||||
{ .compatible = "starfive,jh7110-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(starfive_ddr) = {
|
||||
.name = "starfive_ddr",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = starfive_ddr_ids,
|
||||
.ops = &starfive_ddr_ops,
|
||||
.probe = starfive_ddr_probe,
|
||||
.priv_auto = sizeof(struct starfive_ddr_priv),
|
||||
};
|
65
drivers/ram/starfive/starfive_ddr.h
Normal file
65
drivers/ram/starfive/starfive_ddr.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
|
||||
*/
|
||||
|
||||
#ifndef __STARFIVE_DDR_H__
|
||||
#define __STARFIVE_DDR_H__
|
||||
|
||||
#define SEC_CTRL_ADDR 0x1000
|
||||
#define PHY_BASE_ADDR 0x800
|
||||
#define PHY_AC_BASE_ADDR 0x1000
|
||||
|
||||
#define DDR_BUS_MASK GENMASK(29, 24)
|
||||
#define DDR_AXI_MASK BIT(31)
|
||||
#define DDR_BUS_OFFSET 0xAC
|
||||
#define DDR_AXI_OFFSET 0xB0
|
||||
|
||||
#define DDR_BUS_OSC_DIV2 0
|
||||
#define DDR_BUS_PLL1_DIV2 1
|
||||
#define DDR_BUS_PLL1_DIV4 2
|
||||
#define DDR_BUS_PLL1_DIV8 3
|
||||
#define DDR_AXI_DISABLE 0
|
||||
#define DDR_AXI_ENABLE 1
|
||||
|
||||
#define OFFSET_SEL BIT(31)
|
||||
#define REG2G BIT(30)
|
||||
#define REG4G BIT(29)
|
||||
#define REG8G BIT(28)
|
||||
#define F_ADDSET BIT(2)
|
||||
#define F_SET BIT(1)
|
||||
#define F_CLRSET BIT(0)
|
||||
#define REGALL (REG2G | REG4G | REG8G)
|
||||
#define REGSETALL (F_SET | REGALL)
|
||||
#define REGCLRSETALL (F_CLRSET | REGALL)
|
||||
#define REGADDSETALL (F_ADDSET | REGALL)
|
||||
|
||||
struct ddr_reg_cfg {
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
u32 flag;
|
||||
};
|
||||
|
||||
enum ddr_size_t {
|
||||
DDR_SIZE_2G,
|
||||
DDR_SIZE_4G,
|
||||
DDR_SIZE_8G,
|
||||
DDR_SIZE_16G,
|
||||
};
|
||||
|
||||
void ddr_phy_train(u32 *phyreg);
|
||||
void ddr_phy_util(u32 *phyreg);
|
||||
void ddr_phy_start(u32 *phyreg, enum ddr_size_t size);
|
||||
void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size);
|
||||
|
||||
#define DDR_REG_TRIGGER(addr, mask, value) \
|
||||
out_le32((addr), (in_le32(addr) & (mask)) | (value))
|
||||
|
||||
#define DDR_REG_SET(type, val) \
|
||||
clrsetbits_le32(JH7110_SYS_CRG + DDR_##type##_OFFSET, \
|
||||
DDR_##type##_MASK, \
|
||||
((val) << __ffs(DDR_##type##_MASK)) & DDR_##type##_MASK)
|
||||
|
||||
#endif /*__STARFIVE_DDR_H__*/
|
Loading…
Reference in a new issue