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:
Yanhong Wang 2023-03-29 11:42:16 +08:00 committed by Leo Yu-Chi Liang
parent 732f01aabf
commit 60abbadfc0
10 changed files with 3202 additions and 1 deletions

View file

@ -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"

View file

@ -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/

View 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.

View 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

View 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);
}

View 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);
}

View 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]);
}

File diff suppressed because it is too large Load diff

View 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),
};

View 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__*/