summaryrefslogtreecommitdiff
path: root/src/soc/rockchip
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/rockchip')
-rw-r--r--src/soc/rockchip/rk3288/Makefile.inc1
-rw-r--r--src/soc/rockchip/rk3288/cbmem.c4
-rw-r--r--src/soc/rockchip/rk3288/include/soc/sdram.h1
-rw-r--r--src/soc/rockchip/rk3288/sdram.c95
-rw-r--r--src/soc/rockchip/rk3288/soc.c5
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)