diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/rockchip/rk3288/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/cbmem.c | 4 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/include/soc/sdram.h | 1 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/sdram.c | 95 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/soc.c | 5 |
5 files changed, 79 insertions, 27 deletions
diff --git a/src/soc/rockchip/rk3288/Makefile.inc b/src/soc/rockchip/rk3288/Makefile.inc index c7e52a9f3e..c4a77e0fcd 100644 --- a/src/soc/rockchip/rk3288/Makefile.inc +++ b/src/soc/rockchip/rk3288/Makefile.inc @@ -57,6 +57,7 @@ ramstage-y += timer.c ramstage-y += i2c.c ramstage-y += clock.c ramstage-y += spi.c +ramstage-y += sdram.c ramstage-y += gpio.c ramstage-y += rk808.c ramstage-y += pwm.c diff --git a/src/soc/rockchip/rk3288/cbmem.c b/src/soc/rockchip/rk3288/cbmem.c index 2eed97281a..38ea365469 100644 --- a/src/soc/rockchip/rk3288/cbmem.c +++ b/src/soc/rockchip/rk3288/cbmem.c @@ -20,9 +20,9 @@ #include <cbmem.h> #include <stddef.h> #include <symbols.h> +#include <soc/sdram.h> void *cbmem_top(void) { - return _dram + (size_t)CONFIG_DRAM_SIZE_MB*MiB; + return _dram + sdram_size_mb()*MiB; } - diff --git a/src/soc/rockchip/rk3288/include/soc/sdram.h b/src/soc/rockchip/rk3288/include/soc/sdram.h index 16e4f81713..8f37cb7574 100644 --- a/src/soc/rockchip/rk3288/include/soc/sdram.h +++ b/src/soc/rockchip/rk3288/include/soc/sdram.h @@ -98,5 +98,6 @@ struct rk3288_sdram_params { void sdram_init(const struct rk3288_sdram_params *sdram_params); u32 sdram_get_ram_code(void); +size_t sdram_size_mb(void); const struct rk3288_sdram_params *get_sdram_config(void); #endif diff --git a/src/soc/rockchip/rk3288/sdram.c b/src/soc/rockchip/rk3288/sdram.c index cda36be05d..2698024435 100644 --- a/src/soc/rockchip/rk3288/sdram.c +++ b/src/soc/rockchip/rk3288/sdram.c @@ -489,18 +489,27 @@ static struct rk3288_msch_regs * const rk3288_msch[2] = { * [3:2] bw_ch0 * [1:0] dbw_ch0 */ -#define SYS_REG_DDRTYPE(n) ((n) << 13) -#define SYS_REG_NUM_CH(n) (((n) - 1) << 12) -#define SYS_REG_ROW_3_4(n, ch) ((n) << (30 + (ch))) -#define SYS_REG_CHINFO(ch) (1 << (28 + (ch))) -#define SYS_REG_RANK(n, ch) (((n) - 1) << (11 + ((ch) * 16))) -#define SYS_REG_COL(n, ch) (((n) - 9) << (9 + ((ch) * 16))) -#define SYS_REG_BK(n, ch) (((n) == 3 ? 0 : 1) \ +#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch))) +#define SYS_REG_DEC_ROW_3_4(n, ch) ((n >> (30 + ch)) & 0x1) +#define SYS_REG_ENC_CHINFO(ch) (1 << (28 + (ch))) +#define SYS_REG_ENC_DDRTYPE(n) ((n) << 13) +#define SYS_REG_ENC_NUM_CH(n) (((n) - 1) << 12) +#define SYS_REG_DEC_NUM_CH(n) (1 + ((n >> 12) & 0x1)) +#define SYS_REG_ENC_RANK(n, ch) (((n) - 1) << (11 + ((ch) * 16))) +#define SYS_REG_DEC_RANK(n, ch) (1 + ((n >> (11 + 16 * ch)) & 0x1)) +#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << (9 + ((ch) * 16))) +#define SYS_REG_DEC_COL(n, ch) (9 + ((n >> (9 + 16 * ch)) & 0x3)) +#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) \ << (8 + ((ch) * 16))) -#define SYS_REG_CS0_ROW(n, ch) (((n) - 13) << (6 + ((ch) * 16))) -#define SYS_REG_CS1_ROW(n, ch) (((n) - 13) << (4 + ((ch) * 16))) -#define SYS_REG_BW(n, ch) ((2 >> (n)) << (2 + ((ch) * 16))) -#define SYS_REG_DBW(n, ch) ((2 >> (n)) << (0 + ((ch) * 16))) +#define SYS_REG_DEC_BK(n, ch) (3 - ((n >> (8 + 16 * ch)) & 0x1)) +#define SYS_REG_ENC_CS0_ROW(n, ch) (((n) - 13) << (6 + ((ch) * 16))) +#define SYS_REG_DEC_CS0_ROW(n, ch) (13 + ((n >> (6 + 16 * ch)) & 0x3)) +#define SYS_REG_ENC_CS1_ROW(n, ch) (((n) - 13) << (4 + ((ch) * 16))) +#define SYS_REG_DEC_CS1_ROW(n, ch) (13 + ((n >> (4 + 16 * ch)) & 0x3)) +#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << (2 + ((ch) * 16))) +#define SYS_REG_DEC_BW(n, ch) (2 >> ((n >> (2 + 16 * ch)) & 0x3)) +#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + ((ch) * 16))) +#define SYS_REG_DEC_DBW(n, ch) (2 >> ((n >> (0 + 16 * ch)) & 0x3)) static void copy_to_reg(u32 *dest, const u32 *src, u32 n) { @@ -942,20 +951,20 @@ static void dram_all_config(const struct rk3288_sdram_params *sdram_params) u32 sys_reg = 0; unsigned int channel; - sys_reg |= SYS_REG_DDRTYPE(sdram_params->dramtype); - sys_reg |= SYS_REG_NUM_CH(sdram_params->num_channels); + sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype); + sys_reg |= SYS_REG_ENC_NUM_CH(sdram_params->num_channels); for (channel = 0; channel < sdram_params->num_channels; channel++) { const struct rk3288_sdram_channel *info = &(sdram_params->ch[channel]); - sys_reg |= SYS_REG_ROW_3_4(info->row_3_4, channel); - sys_reg |= SYS_REG_CHINFO(channel); - sys_reg |= SYS_REG_RANK(info->rank, channel); - sys_reg |= SYS_REG_COL(info->col, channel); - sys_reg |= SYS_REG_BK(info->bk, channel); - sys_reg |= SYS_REG_CS0_ROW(info->cs0_row, channel); - sys_reg |= SYS_REG_CS1_ROW(info->cs1_row, channel); - sys_reg |= SYS_REG_BW(info->bw, channel); - sys_reg |= SYS_REG_DBW(info->dbw, channel); + sys_reg |= SYS_REG_ENC_ROW_3_4(info->row_3_4, channel); + sys_reg |= SYS_REG_ENC_CHINFO(channel); + sys_reg |= SYS_REG_ENC_RANK(info->rank, channel); + sys_reg |= SYS_REG_ENC_COL(info->col, channel); + sys_reg |= SYS_REG_ENC_BK(info->bk, channel); + sys_reg |= SYS_REG_ENC_CS0_ROW(info->cs0_row, channel); + sys_reg |= SYS_REG_ENC_CS1_ROW(info->cs1_row, channel); + sys_reg |= SYS_REG_ENC_BW(info->bw, channel); + sys_reg |= SYS_REG_ENC_DBW(info->dbw, channel); dram_cfg_rbc(channel, sdram_params); } @@ -1076,3 +1085,45 @@ void sdram_init(const struct rk3288_sdram_params *sdram_params) dram_all_config(sdram_params); printk(BIOS_INFO, "Finish SDRAM initialization...\n"); } + +size_t sdram_size_mb(void) +{ + u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4; + size_t chipsize_mb = 0; + static size_t size_mb = 0; + u32 ch; + + if (!size_mb) { + + u32 sys_reg = readl(&rk3288_pmu->sys_reg[2]); + u32 ch_num = SYS_REG_DEC_NUM_CH(sys_reg); + + for (ch = 0; ch < ch_num; ch++) { + rank = SYS_REG_DEC_RANK(sys_reg, ch); + col = SYS_REG_DEC_COL(sys_reg, ch); + bk = SYS_REG_DEC_BK(sys_reg, ch); + cs0_row = SYS_REG_DEC_CS0_ROW(sys_reg, ch); + cs1_row = SYS_REG_DEC_CS1_ROW(sys_reg, ch); + bw = SYS_REG_DEC_BW(sys_reg, ch); + row_3_4 = SYS_REG_DEC_ROW_3_4(sys_reg, ch); + + chipsize_mb = (1 << (cs0_row + col + bk + bw - 20)); + + if (rank > 1) + chipsize_mb += chipsize_mb >> + (cs0_row - cs1_row); + if (row_3_4) + chipsize_mb = chipsize_mb * 3 / 4; + size_mb += chipsize_mb; + } + + /* + * we use the 0x00000000~0xfeffffff space + * since 0xff000000~0xffffffff is soc register space + * so we reserve it + */ + size_mb = MIN(size_mb, 0xff000000/MiB); + } + + return size_mb; +} diff --git a/src/soc/rockchip/rk3288/soc.c b/src/soc/rockchip/rk3288/soc.c index fa26c6db36..ec04f9ccd7 100644 --- a/src/soc/rockchip/rk3288/soc.c +++ b/src/soc/rockchip/rk3288/soc.c @@ -25,6 +25,7 @@ #include <gpio.h> #include <soc/display.h> #include <soc/soc.h> +#include <soc/sdram.h> #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -35,9 +36,7 @@ static void soc_init(device_t dev) { - ram_resource(dev, 0, (uintptr_t)_dram/KiB, - CONFIG_DRAM_SIZE_MB*(MiB/KiB)); - + ram_resource(dev, 0, (uintptr_t)_dram/KiB, sdram_size_mb()*(MiB/KiB)); if (vboot_skip_display_init()) printk(BIOS_INFO, "Skipping display init.\n"); #if !IS_ENABLED(CONFIG_SKIP_DISPLAY_INIT_HACK) |