Merge branch 'CR_6604_1G_DDR_SYNC_samin.guo' into 'jh7110-master'

CR6604:dram: jh7110:  sync from devkits/vf2

See merge request sdk/u-boot!59
This commit is contained in:
andy.hu 2023-07-20 03:27:38 +00:00
commit 24704a41a8
9 changed files with 2809 additions and 108 deletions

View file

@ -2,63 +2,33 @@
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <fdtdec.h>
#include <init.h>
#include <linux/sizes.h>
#ifdef CONFIG_ID_EEPROM
#include <asm/arch/eeprom.h>
#define STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET 91
#endif
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_ID_EEPROM
static bool check_eeprom_dram_info(phys_size_t size)
__weak int board_ddr_size(void)
{
switch (size) {
case 0x40000000:
case 0x80000000:
case 0x100000000:
case 0x200000000:
case 0x400000000:
return true;
default:
return false;
}
return 0;
}
static void resize_ddr_from_eeprom(void)
{
u32 offset = STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET;
phys_size_t size;
u32 len = 1;
u8 data = 0;
int ret;
/* read memory size info */
ret = get_data_from_eeprom(offset, len, &data);
if (ret == len) {
size = ((phys_size_t)hextoul(&data, NULL)) << 30;
if (check_eeprom_dram_info(size))
gd->ram_size = size;
}
}
#endif /* CONFIG_ID_EEPROM */
int dram_init(void)
{
int ret;
phys_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
return ret;
/* resize ddr size */
size = board_ddr_size();
if (size > 0)
gd->ram_size = size << 30;
#ifdef CONFIG_ID_EEPROM
resize_ddr_from_eeprom();
#endif
return 0;
}

View file

@ -289,6 +289,14 @@ int board_late_init(void)
struct udevice *dev;
int ret;
/*
* save the memory info by environment variable in u-boot,
* It will used to update the memory configuration in dts,
* which passed to kernel lately.
*/
env_set_hex("memory_addr", gd->ram_base);
env_set_hex("memory_size", gd->ram_size);
ret = uclass_get_device(UCLASS_VIDEO, 0, &dev);
if (ret)
return ret;
@ -302,3 +310,50 @@ err:
}
#ifdef CONFIG_ID_EEPROM
#include <asm/arch/eeprom.h>
#define STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET 91
static bool check_eeprom_dram_info(ulong size)
{
switch (size) {
case 1:
case 2:
case 4:
case 8:
case 16:
return true;
default:
return false;
}
}
static int resize_ddr_from_eeprom(void)
{
ulong size;
u32 len = 1;
u8 data = 0;
int ret;
/* read memory size info */
ret = get_data_from_eeprom(STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET, len, &data);
if (ret == len) {
size = hextoul(&data, NULL);
if (check_eeprom_dram_info(size))
return size;
}
return 0;
}
#else
static int resize_ddr_from_eeprom(void)
{
return 0;
}
#endif /* CONFIG_ID_EEPROM */
int board_ddr_size(void)
{
return resize_ddr_from_eeprom();
}

View file

@ -12,7 +12,100 @@
#define REGOFFSET(offset) ((offset) / 4)
static struct ddr_reg_cfg ddr_csr_cfg[] = {
static struct ddr_reg_cfg ddr4_csr_cfg[] = {
{0x0, 0x0, 0x00000405, REGSETALL},
{0xf00, 0x0, 0x40000010, (OFFSET_SEL | REGSETALL)},
{0xf04, 0x0, 0x04800001, (OFFSET_SEL | REGSETALL)},
{0xf10, 0x0, 0x00400000, (OFFSET_SEL | REGSETALL)},
{0xf14, 0x0, 0x043fffff, (OFFSET_SEL | REGSETALL)},
{0xf18, 0x0, 0x00000000, (OFFSET_SEL | REGSETALL)},
{0xf30, 0x0, 0x1f001041, (OFFSET_SEL | REGSETALL)},
{0x110, 0x0, 0xc0000001, (OFFSET_SEL | REGSETALL)},
{0x114, 0x0, 0xffffffff, (OFFSET_SEL | REGSETALL)},
{0x10c, 0x0, 0x00000f0f, 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 struct ddr_reg_cfg ddr4_csr_cfg1[] = {
{0x310, 0x0, 0x00020000, REGSETALL},
{0x310, 0x0, 0x00020001, REGSETALL},
{0x600, 0x0, 0x00170176, REGSETALL},
{0x604, 0x0, 0x000b00bb, REGSETALL},
{0x608, 0x0, 0x0005005d, REGSETALL},
{0x60c, 0x0, 0x0002002e, REGSETALL},
{0x678, 0x0, 0x00000019, REGSETALL},
{0x100, 0x0, 0x00000008, REGSETALL},
{0x620, 0x0, 0x0b000f0f, REGSETALL},
{0x624, 0x0, 0x06070b07, REGSETALL},
{0x628, 0x0, 0x3123088f, REGSETALL},
{0x62c, 0x0, 0x23160620, REGSETALL},
{0x630, 0x0, 0x1900140f, REGSETALL},
{0x634, 0x0, 0x800b0208, REGSETALL},
{0x638, 0x0, 0x001c1c00, REGSETALL},
{0x63c, 0x0, 0x1a000a06, REGSETALL},
{0x640, 0x0, 0x025600ff, REGSETALL},
{0x644, 0x0, 0x124b024b, REGSETALL},
{0x648, 0x0, 0x40012000, REGSETALL},
{0x64c, 0x0, 0x00082310, REGSETALL},
{0x6c0, 0x0, 0x001b0706, REGSETALL},
{0x6c4, 0x0, 0x0000181c, REGSETALL},
{0x650, 0x0, 0x00000000, REGSETALL},
{0x654, 0x0, 0x00000000, REGSETALL},
{0x658, 0x0, 0x00000060, REGSETALL},
{0x65c, 0x0, 0x00800200, REGSETALL},
{0x660, 0x0, 0x00000000, REGSETALL},
{0x680, 0x0, 0x0f000410, REGSETALL},
{0x684, 0x0, 0x08000b03, REGSETALL},
{0x688, 0x0, 0x04080415, REGSETALL},
{0x68c, 0x0, 0x20002520, REGSETALL},
{0x690, 0x0, 0x00140000, REGSETALL},
{0x69c, 0x0, 0x01240074, REGSETALL},
{0x6a0, 0x0, 0x00000000, REGSETALL},
{0x6a4, 0x0, 0x20250c00, REGSETALL},
{0x6a8, 0x0, 0x00040000, REGSETALL},
{0x4, 0x0, 0x10030000, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x1006081e, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x10050441, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x10040000, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x10020010, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x10010001, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x4, 0x0, 0x10000734, REGSETALL},
{0xc, 0x0, 0x00000002, REGSETALL},
{0x10, 0x0, 0x00000011, REGSETALL},
{0x14, 0x0, 0x00000001, REGSETALL},
};
static struct ddr_reg_cfg ddr4_csr_cfg3[] = {
{0x410, 0x0, 0x00101010, REGSETALL},
{0x420, 0x0, 0x0c181006, REGSETALL},
{0x424, 0x0, 0x20200820, REGSETALL},
{0x428, 0x0, 0x80000020, REGSETALL},
{0x0, 0x0, 0x00000005, REGSETALL},
{0x108, 0x0, 0x00001000, REGSETALL},
{0x704, 0x0, 0x00000007, REGSETALL | OFFSET_SEL},
{0x330, 0x0, 0x09311fff, REGSETALL},
{0x508, 0x0, 0x00000003, REGSETALL},
{0x324, 0x0, 0x00002000, REGSETALL},
{0x104, 0x0, 0x80000000, REGSETALL},
{0x510, 0x0, 0x00000100, REGSETALL},
{0x514, 0x0, 0x00000000, REGSETALL},
{0x700, 0x0, 0x00000003, REGSETALL | OFFSET_SEL},
{0x514, 0x0, 0x00000600, REGSETALL},
{0x20, 0x0, 0x00000001, REGSETALL},
};
static struct ddr_reg_cfg lpddr4_csr_cfg[] = {
{0x0, 0x0, 0x00000001, REGSETALL},
{0xf00, 0x0, 0x40001030, (OFFSET_SEL | F_SET | REG4G | REG8G)},
{0xf00, 0x0, 0x40001010, (OFFSET_SEL | F_SET | REG2G)},
@ -36,7 +129,7 @@ static struct ddr_reg_cfg ddr_csr_cfg[] = {
{0x504, 0x0, 0x40000000, REGSETALL}
};
static struct ddr_reg_cfg ddr_csr_cfg1[] = {
static struct ddr_reg_cfg lpddr4_csr_cfg1[] = {
{0x310, 0x0, 0x00020000, REGSETALL},
{0x310, 0x0, 0x00020001, REGSETALL},
{0x600, 0x0, 0x002e0176, REGSETALL},
@ -126,7 +219,7 @@ static struct ddr_reg_cfg ddr_csr_cfg2[] = {
{0x2e8, 0xffffffff, 0x300, REGCLRSETALL},
};
static struct ddr_reg_cfg ddr_csr_cfg3[] = {
static struct ddr_reg_cfg lpddr4_csr_cfg3[] = {
{0x100, 0x0, 0x000000e0, REGSETALL},
{0x620, 0x0, 0x04041417, REGSETALL},
{0x624, 0x0, 0x09110609, REGSETALL},
@ -217,6 +310,8 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
u32 len;
u32 val;
u32 mask;
bool ddr4flag;
struct ddr_reg_cfg *data;
switch (size) {
case DDR_SIZE_1G:
@ -240,8 +335,27 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
return;
};
len = sizeof(ddr_csr_cfg)/sizeof(struct ddr_reg_cfg);
ddr_csr_set(csrreg, secreg, ddr_csr_cfg, len, mask);
switch (starfive_ddr_type) {
case DDR_TYPE_DDR4:
ddr4flag = true;
break;
case DDR_TYPE_LPDDR4:
ddr4flag = false;
break;
case DDR_TYPE_LPDDR3:
case DDR_TYPE_DDR3:
default:
return;
}
if (ddr4flag) {
len = sizeof(ddr4_csr_cfg) / sizeof(struct ddr_reg_cfg);
data = ddr4_csr_cfg;
} else {
len = sizeof(lpddr4_csr_cfg) / sizeof(struct ddr_reg_cfg);
data = lpddr4_csr_cfg;
}
ddr_csr_set(csrreg, secreg, data, len, mask);
do {
udelay(1);
@ -270,28 +384,34 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
udelay(4);
len = sizeof(ddr_csr_cfg1)/sizeof(struct ddr_reg_cfg);
ddr_csr_set(csrreg, secreg, ddr_csr_cfg1, len, mask);
if (ddr4flag) {
len = sizeof(ddr4_csr_cfg1) / sizeof(struct ddr_reg_cfg);
ddr_csr_set(csrreg, secreg, ddr4_csr_cfg1, len, mask);
udelay(1);
} else {
len = sizeof(lpddr4_csr_cfg1) / sizeof(struct ddr_reg_cfg);
ddr_csr_set(csrreg, secreg, lpddr4_csr_cfg1, len, mask);
udelay(4);
out_le32(csrreg + REGOFFSET(0x10), 0x00000011);
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
switch (size) {
case DDR_SIZE_4G:
case DDR_SIZE_8G:
out_le32(csrreg + REGOFFSET(0x10), 0x00000020);
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
udelay(4);
out_le32(csrreg + REGOFFSET(0x10), 0x00000021);
out_le32(csrreg + REGOFFSET(0x10), 0x00000011);
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
break;
case DDR_SIZE_1G:
case DDR_SIZE_2G:
case DDR_SIZE_16G:
default:
break;
};
switch (size) {
case DDR_SIZE_4G:
case DDR_SIZE_8G:
out_le32(csrreg + REGOFFSET(0x10), 0x00000020);
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
udelay(4);
out_le32(csrreg + REGOFFSET(0x10), 0x00000021);
out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
break;
case DDR_SIZE_1G:
case DDR_SIZE_2G:
case DDR_SIZE_16G:
default:
break;
};
}
out_le32(csrreg + REGOFFSET(0x514), 0x00000000);
do {
@ -299,41 +419,53 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
val = in_le32(csrreg + REGOFFSET(0x518));
} while ((val & 0x2) != 0x2);
val = in_le32(csrreg + REGOFFSET(0x518));
while ((val & 0x2) != 0x0) {
val = in_le32(phyreg + 1);
if ((val & 0x20) == 0x20) {
switch (val & 0x0000001f) {
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);
do {
udelay(2);
val = in_le32(phyreg + 2);
} while ((val & 0x00000001) != 0x00000000);
}
udelay(1);
if (ddr4flag) {
do {
udelay(1);
val = in_le32(csrreg + REGOFFSET(0x518));
} while (val & 0x2);
} else {
val = in_le32(csrreg + REGOFFSET(0x518));
};
while (val & 0x2) {
val = in_le32(phyreg + 1);
if (val & 0x20) {
switch (val & 0x0000001f) {
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);
do {
udelay(2);
val = in_le32(phyreg + 2);
} while ((val & 0x00000001) != 0x00000000);
}
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 = sizeof(ddr_csr_cfg2)/sizeof(struct ddr_reg_cfg);
len = sizeof(ddr_csr_cfg2) / sizeof(struct ddr_reg_cfg);
ddr_csr_set((phyreg + PHY_BASE_ADDR), secreg, ddr_csr_cfg2, len, mask);
len = sizeof(ddr_csr_cfg3)/sizeof(struct ddr_reg_cfg);
ddr_csr_set(csrreg, secreg, ddr_csr_cfg3, len, mask);
if (ddr4flag) {
len = sizeof(ddr4_csr_cfg3) / sizeof(struct ddr_reg_cfg);
data = ddr4_csr_cfg3;
} else {
len = sizeof(lpddr4_csr_cfg3) / sizeof(struct ddr_reg_cfg);
data = lpddr4_csr_cfg3;
}
ddr_csr_set(csrreg, secreg, data, len, mask);
}

View file

@ -9,7 +9,116 @@
#include "starfive_ddr.h"
static struct ddr_reg_cfg ddr_start_cfg[] = {
static struct ddr_reg_cfg ddr4_start_cfg[] = {
{67, 0xffe0ffff, 0x00010000, REGCLRSETALL},
{67, 0xe0ffffff, 0x01000000, REGCLRSETALL},
{179, 0xff80ffff, 0x001c0000, REGCLRSETALL},
{179, 0x80ffffff, 0x1c000000, REGCLRSETALL},
{182, 0xff80ffff, 0x001c0000, REGCLRSETALL},
{182, 0x80ffffff, 0x1c000000, REGCLRSETALL},
{185, 0xff80ffff, 0x001c0000, REGCLRSETALL},
{185, 0x80ffffff, 0x1c000000, REGCLRSETALL},
{0, 0xffffffff, 0x01, REGCLRSETALL},
{11, 0xfffffff0, 0x1, 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)},
{180, 0xffffffff, 0x0100, REGCLRSETALL},
{183, 0xffffffff, 0x0100, REGCLRSETALL},
{186, 0xffffffff, 0x0100, 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, 0x0a287, (OFFSET_SEL | REGCLRSETALL)},
{1864, 0xffffff00, 0x34, (OFFSET_SEL | REGCLRSETALL)},
{1893, 0xfffc0000, 0x7, (OFFSET_SEL | REGCLRSETALL)},
{1852, 0xffffe000, 0x058, (OFFSET_SEL | REGCLRSETALL)},
{1822, 0xffffffff, 0xFF, (OFFSET_SEL | REGCLRSETALL)},
{1896, 0xfffffc00, 0x02ca, (OFFSET_SEL | REGCLRSETALL)},
{91, 0xfc00ffff, 0x02ed0000, (OFFSET_SEL | REGCLRSETALL)},
{347, 0xfc00ffff, 0x02ed0000, (OFFSET_SEL | REGCLRSETALL)},
{603, 0xfc00ffff, 0x02ed0000, (OFFSET_SEL | REGCLRSETALL)},
{859, 0xfc00ffff, 0x02ed0000, (OFFSET_SEL | REGCLRSETALL)},
{1912, 0x0, 0xcc2bfc7, (OFFSET_SEL | REGSETALL)},
{1913, 0x0, 0xff8f, (OFFSET_SEL | REGSETALL)},
{1914, 0x0, 0x33f077f, (OFFSET_SEL | REGSETALL)},
{1915, 0x0, 0xc3c377f, (OFFSET_SEL | REGSETALL)},
{1916, 0x0, 0x1fff7f30, (OFFSET_SEL | REGSETALL)},
{1917, 0x0, 0x2ec010, (OFFSET_SEL | REGSETALL)},
{1918, 0x0, 0x3fc77ffb, (OFFSET_SEL | REGSETALL)},
{1919, 0x0, 0xe10, (OFFSET_SEL | REGSETALL)},
{1920, 0x0, 0x1fff7fff, (OFFSET_SEL | REGSETALL)},
{1921, 0x0, 0x188411, (OFFSET_SEL | REGSETALL)},
{1922, 0x0, 0x1fff7fff, (OFFSET_SEL | REGSETALL)},
{1923, 0x0, 0x180400, (OFFSET_SEL | REGSETALL)},
{1924, 0x0, 0x1fff7fff, (OFFSET_SEL | REGSETALL)},
{1925, 0x0, 0x180400, (OFFSET_SEL | REGSETALL)},
{1926, 0x0, 0x07ff7ffb, (OFFSET_SEL | REGSETALL)},
{1927, 0x0, 0x188400, (OFFSET_SEL | REGSETALL)},
{1928, 0x0, 0x1fff7fff, (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, 0x00f7ff07, (OFFSET_SEL | REGCLRSETALL)},
{332, 0xff0000f8, 0x00f7ff07, (OFFSET_SEL | REGCLRSETALL)},
{588, 0xff0000f8, 0x00f7ff07, (OFFSET_SEL | REGCLRSETALL)},
{844, 0xff0000f8, 0x00f7ff07, (OFFSET_SEL | REGCLRSETALL)},
{77, 0xffff0000, 0xfcff, (OFFSET_SEL | REGCLRSETALL)},
{333, 0xffff0000, 0xfcff, (OFFSET_SEL | REGCLRSETALL)},
{589, 0xffff0000, 0xfcff, (OFFSET_SEL | REGCLRSETALL)},
{845, 0xffff0000, 0xfcff, (OFFSET_SEL | REGCLRSETALL)},
{1062, 0xffffff00, 0xbb, (OFFSET_SEL | REGCLRSETALL)},
{1318, 0xffffff00, 0xbb, (OFFSET_SEL | REGCLRSETALL)},
{1574, 0xffffff00, 0xbb, (OFFSET_SEL | REGCLRSETALL)},
{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, 0x1dffff, (OFFSET_SEL | REGSETALL)},
{1851, 0x0, 0x190000, (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)},
};
static struct ddr_reg_cfg lpddr4_start_cfg[] = {
{89, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
{78, 0xfffffcff, 0x0, (OFFSET_SEL | REGCLRSETALL)},
{345, 0xffffff00, 0x00000051, (OFFSET_SEL | REGCLRSETALL)},
@ -254,6 +363,7 @@ void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
{
u32 len;
u32 mask;
struct ddr_reg_cfg *data;
switch (size) {
case DDR_SIZE_1G:
@ -277,7 +387,21 @@ void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
return;
};
len = sizeof(ddr_start_cfg) / sizeof(struct ddr_reg_cfg);
ddr_reg_set(phyreg, ddr_start_cfg, len, mask);
switch (starfive_ddr_type) {
case DDR_TYPE_DDR4:
len = sizeof(ddr4_start_cfg) / sizeof(struct ddr_reg_cfg);
data = ddr4_start_cfg;
break;
case DDR_TYPE_LPDDR4:
len = sizeof(lpddr4_start_cfg) / sizeof(struct ddr_reg_cfg);
data = lpddr4_start_cfg;
break;
case DDR_TYPE_LPDDR3:
case DDR_TYPE_DDR3:
default:
return;
}
ddr_reg_set(phyreg, data, len, mask);
out_le32(phyreg, 0x01);
}

View file

@ -8,7 +8,376 @@
#include <common.h>
#include <asm/io.h>
static u32 ddr_train_data[] = {
#include "starfive_ddr.h"
static u32 ddr4_train_data[] = {
0xa00,
0x101,
0x640000,
0x1,
0x0,
0x0,
0x0,
0x0,
0x1,
0x7,
0x10000,
0x10003,
0x1,
0x5,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x280d0000,
0x0,
0x1,
0x32000003,
0x0,
0x0,
0x60602,
0x1,
0x0,
0x0,
0x0,
0x55,
0xaa,
0xad,
0x52,
0x6a,
0x95,
0x95,
0xad,
0x1000000,
0x1000000,
0x0,
0x3030000,
0x14,
0x7d0,
0x300,
0x0,
0x0,
0x1000000,
0x10101,
0x0,
0x30000,
0x10100,
0x1703,
0x0,
0x0,
0x0,
0xa140a01,
0x204010a,
0x2080510,
0x40400,
0x101,
0x10100,
0x2040300,
0x34000000,
0x0,
0x0,
0x1000000,
0x0,
0x0,
0x0,
0x6,
0x100,
0x40000,
0x2000200,
0x1000100,
0x1000000,
0x2000200,
0x200,
0x0,
0x0,
0x0,
0xe000003,
0xc0d100f,
0xa09080b,
0x2010000,
0x80103,
0x10200,
0x0,
0x3000000,
0xd6,
0x216,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x30100,
0x1010001,
0x10200,
0x4000103,
0x1050001,
0x10600,
0x107,
0x0,
0x0,
0x10000,
0x0,
0x0,
0x0,
0x0,
0x10000,
0x4,
0x0,
0x0,
0x0,
0xa000a0,
0x1a1a00a0,
0x1a,
0x35,
0x35,
0x40035,
0x4000400,
0xca04000b,
0x4000b20,
0xb20ca,
0x20ca04,
0x24b,
0x207b,
0x24b,
0x207b,
0x24b,
0x400207b,
0x1010404,
0x1801,
0x180018,
0x10e010e,
0x10e,
0x0,
0x5000000,
0x1010505,
0x1010101,
0x191919,
0x0,
0x0,
0x11000000,
0xc0c1111,
0x303030c,
0xc0034,
0xc0034,
0xc0034,
0x0,
0x0,
0xa,
0xa,
0x100000a,
0x0,
0x100,
0x1000000,
0x0,
0x1e1a1e1a,
0x1011e1a,
0x100b0801,
0x100b080f,
0x100b080f,
0xc00f,
0xc01000,
0xc01000,
0x191000,
0x19010b,
0x19010b,
0x101010b,
0x1f01,
0x1e1a0055,
0x7000001,
0x1f0c11,
0x1e1a0055,
0x7000001,
0x1f0c11,
0x1e1a0055,
0x7000001,
0xc11,
0xf0f0800,
0x100806,
0x2301071c,
0x8002000,
0x1d1d190b,
0x60f0f08,
0x1008,
0x2301071c,
0x8002000,
0x1d1d190b,
0x60f0f08,
0x1008,
0x2301071c,
0x8002000,
0x1d1d190b,
0x40f6,
0x2899c,
0x40f6,
0x2899c,
0x40f6,
0x2899c,
0x3000300,
0x3030300,
0x30003,
0x3000300,
0xb,
0x0,
0x0,
0x0,
0x256,
0xb,
0x0,
0x0,
0x0,
0x256,
0xb,
0x0,
0x0,
0x0,
0x2000256,
0x80,
0x20000,
0x80,
0x20000,
0x80,
0x0,
0x0,
0x2020202,
0x2040108,
0x8010402,
0x67676767,
0x67676767,
0x67676767,
0x67676767,
0x1010101,
0x0,
0x0,
0x0,
0x0,
0x5500,
0x5a00,
0x55003c,
0x0,
0x3c00005a,
0x5500,
0x5a00,
0x55003c,
0x0,
0x3c00005a,
0x18171615,
0x14131211,
0x7060504,
0x3020100,
0x0,
0x0,
0x0,
0x1000000,
0x4020201,
0x80804,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
0x634,
0x201,
0x10,
0x200,
0x0,
0x481,
0x800,
0x4d4d,
};
static u32 lpddr4_train_data[] = {
0xb00,
0x101,
0x640000,
@ -377,9 +746,24 @@ static u32 ddr_train_data[] = {
void ddr_phy_train(u32 *phyreg)
{
u32 i, len;
u32 *data;
switch (starfive_ddr_type) {
case DDR_TYPE_DDR4:
len = sizeof(ddr4_train_data) / sizeof(u32);
data = ddr4_train_data;
break;
case DDR_TYPE_LPDDR4:
len = sizeof(lpddr4_train_data) / sizeof(u32);
data = lpddr4_train_data;
break;
case DDR_TYPE_LPDDR3:
case DDR_TYPE_DDR3:
default:
return;
}
len = sizeof(ddr_train_data) / sizeof(u32);
for (i = 0; i < len; i++)
out_le32(phyreg + i, ddr_train_data[i]);
out_le32(phyreg + i, data[i]);
}

File diff suppressed because it is too large Load diff

View file

@ -33,9 +33,17 @@ struct starfive_ddr_priv {
u32 fre;
};
enum ddr_type_t starfive_ddr_type;
__weak int starfive_get_ddr_type(void)
{
return -EINVAL;
}
static int starfive_ddr_setup(struct udevice *dev, struct starfive_ddr_priv *priv)
{
enum ddr_size_t size;
int ret;
switch (priv->info.size) {
case 0x40000000:
@ -56,11 +64,35 @@ static int starfive_ddr_setup(struct udevice *dev, struct starfive_ddr_priv *pri
return -1;
}
starfive_ddr_type = DDR_TYPE_LPDDR4; /*set default ddr type */
ret = starfive_get_ddr_type();
if (ret >= 0) {
switch (ret) {
case 0x0:
starfive_ddr_type = DDR_TYPE_LPDDR4;
break;
case 0x1:
starfive_ddr_type = DDR_TYPE_DDR4;
break;
case 0x2:
starfive_ddr_type = DDR_TYPE_LPDDR3;
break;
case 0x3:
starfive_ddr_type = DDR_TYPE_DDR3;
break;
default:
pr_err("unsupport ddr type %d\n", ret);
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);
if (starfive_ddr_type == DDR_TYPE_LPDDR4)
DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
ddrcsr_boot(priv->ctrlreg, priv->ctrlreg + SEC_CTRL_ADDR,
priv->phyreg, size);
@ -126,8 +158,11 @@ static int starfive_ddr_probe(struct udevice *dev)
reset_deassert(&priv->rst_axi);
ret = starfive_ddr_setup(dev, priv);
printf("DDR: %ldG version: g8ad50857.\n", priv->info.size/1024/1024/1024);
goto init_end;
printf("%sDDR4: %ldG version: g8ad50857.\n",
starfive_ddr_type == DDR_TYPE_LPDDR4 ? "LP":"",
priv->info.size/1024/1024/1024);
goto init_end;
err_osc:
reset_free(&priv->rst_osc);
err_axi:

View file

@ -54,6 +54,16 @@ enum ddr_size_t {
DDR_SIZE_16G,
};
enum ddr_type_t {
DDR_TYPE_LPDDR4,
DDR_TYPE_DDR4,
DDR_TYPE_LPDDR3,
DDR_TYPE_DDR3,
DDR_TYPE_UNKNOWN,
};
extern enum ddr_type_t starfive_ddr_type;
void ddr_phy_train(u32 *phyreg);
void ddr_phy_util(u32 *phyreg);
void ddr_phy_start(u32 *phyreg, enum ddr_size_t size);

View file

@ -156,6 +156,41 @@
"fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x1>;" \
"fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x1>;\0"
#define CMA_SIZE_SET \
"cma_start=70000000\0" \
"cma_1g=b000000\0" \
"cma_2g=20000000\0" \
"cma_4g=40000000\0" \
"cma_8g=60000000\0" \
"cma_node=/reserved-memory/linux,cma\0" \
"cma_ddr1g_set=" \
"fdt set ${cma_node} size <0x0 0x${cma_1g}>;" \
"fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_1g}>;\0" \
"cma_ddr2g_set=" \
"fdt set ${cma_node} size <0x0 0x${cma_2g}>;" \
"fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_2g}>;\0" \
"cma_ddr4g_set=" \
"fdt set ${cma_node} size <0x0 0x${cma_4g}>;" \
"fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_4g}>;\0" \
"cma_ddr8g_set=" \
"fdt set ${cma_node} size <0x0 0x${cma_8g}>;" \
"fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_8g}>;\0" \
"cma_resize=" \
"if test ${memory_size} -eq 40000000; then " \
"run cma_ddr1g_set;" \
"elif test ${memory_size} -eq 80000000; then " \
"run cma_ddr2g_set;" \
"elif test ${memory_size} -eq 100000000; then " \
"run cma_ddr4g_set;" \
"elif test ${memory_size} -ge 200000000; then " \
"run cma_ddr8g_set;" \
"fi; \0 "
#define EVB_MEM_SET \
"evb_mem_set=" \
"fdt memory ${memory_addr} ${memory_size};" \
"run cma_resize; \0"
#define CHIPA_SET \
"chipa_set=" \
"if test ${chip_vision} = B; then " \
@ -166,6 +201,7 @@
"run chipa_set;\0" \
"chipa_set_linux=" \
"fdt addr ${fdt_addr_r};" \
"run evb_mem_set;" \
"run chipa_set;\0"
#define PARTS_DEFAULT \
@ -196,6 +232,8 @@
CPU_SPEED_1250_SET \
CPU_SPEED_1500_SET \
CPU_FREQ_VOL_SET \
EVB_MEM_SET \
CMA_SIZE_SET \
"type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \
"type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \
"type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \