rk3288: detect sdram size at runtime

we use Kconfig define sdram size before, but there may use
different sdram size in the same overlay, so we must detect
sdram size at runtime now. If we use 4G byte sdram, we can
use[0x00000000:0xff000000], since the [0xff000000:0xffffffff]
is the register space.

BUG=chrome-os-partner:35521
TEST=Boot from mighty
BRANCH=None

Change-Id: Ib32aed50c9cae6db495ff3bab28266de91f3e73b
Signed-off-by: huang lin <hl@rock-chips.com>
Reviewed-on: https://chromium-review.googlesource.com/243139
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/src/mainboard/google/veyron_brain/Kconfig b/src/mainboard/google/veyron_brain/Kconfig
index a54db4a..3cdfeeb 100644
--- a/src/mainboard/google/veyron_brain/Kconfig
+++ b/src/mainboard/google/veyron_brain/Kconfig
@@ -57,10 +57,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_brain/romstage.c b/src/mainboard/google/veyron_brain/romstage.c
index e41f2eb..65d353a 100644
--- a/src/mainboard/google/veyron_brain/romstage.c
+++ b/src/mainboard/google/veyron_brain/romstage.c
@@ -95,7 +95,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_danger/Kconfig b/src/mainboard/google/veyron_danger/Kconfig
index 30ab571..4ecb7cc 100644
--- a/src/mainboard/google/veyron_danger/Kconfig
+++ b/src/mainboard/google/veyron_danger/Kconfig
@@ -57,10 +57,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_danger/romstage.c b/src/mainboard/google/veyron_danger/romstage.c
index b073c34..e22a04e 100644
--- a/src/mainboard/google/veyron_danger/romstage.c
+++ b/src/mainboard/google/veyron_danger/romstage.c
@@ -104,7 +104,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_jerry/Kconfig b/src/mainboard/google/veyron_jerry/Kconfig
index 169902c..8361013 100644
--- a/src/mainboard/google/veyron_jerry/Kconfig
+++ b/src/mainboard/google/veyron_jerry/Kconfig
@@ -69,10 +69,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_jerry/romstage.c b/src/mainboard/google/veyron_jerry/romstage.c
index b073c34..e22a04e 100644
--- a/src/mainboard/google/veyron_jerry/romstage.c
+++ b/src/mainboard/google/veyron_jerry/romstage.c
@@ -104,7 +104,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_mighty/Kconfig b/src/mainboard/google/veyron_mighty/Kconfig
index 650cb08..be33aac 100644
--- a/src/mainboard/google/veyron_mighty/Kconfig
+++ b/src/mainboard/google/veyron_mighty/Kconfig
@@ -69,10 +69,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_mighty/romstage.c b/src/mainboard/google/veyron_mighty/romstage.c
index b073c34..e22a04e 100644
--- a/src/mainboard/google/veyron_mighty/romstage.c
+++ b/src/mainboard/google/veyron_mighty/romstage.c
@@ -104,7 +104,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_pinky/Kconfig b/src/mainboard/google/veyron_pinky/Kconfig
index bd490e4..a67a04a 100644
--- a/src/mainboard/google/veyron_pinky/Kconfig
+++ b/src/mainboard/google/veyron_pinky/Kconfig
@@ -69,10 +69,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_pinky/romstage.c b/src/mainboard/google/veyron_pinky/romstage.c
index d7532d7..81a412e 100644
--- a/src/mainboard/google/veyron_pinky/romstage.c
+++ b/src/mainboard/google/veyron_pinky/romstage.c
@@ -112,7 +112,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_rialto/Kconfig b/src/mainboard/google/veyron_rialto/Kconfig
index 37ae690..a0b16f0 100644
--- a/src/mainboard/google/veyron_rialto/Kconfig
+++ b/src/mainboard/google/veyron_rialto/Kconfig
@@ -64,10 +64,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 1024
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_rialto/romstage.c b/src/mainboard/google/veyron_rialto/romstage.c
index b073c34..e22a04e 100644
--- a/src/mainboard/google/veyron_rialto/romstage.c
+++ b/src/mainboard/google/veyron_rialto/romstage.c
@@ -104,7 +104,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/mainboard/google/veyron_speedy/Kconfig b/src/mainboard/google/veyron_speedy/Kconfig
index 0646ea7..64ff56a 100644
--- a/src/mainboard/google/veyron_speedy/Kconfig
+++ b/src/mainboard/google/veyron_speedy/Kconfig
@@ -69,10 +69,6 @@
         hex
         default 2
 
-config DRAM_SIZE_MB
-	int
-	default 2048
-
 config DRIVER_TPM_I2C_BUS
 	hex
 	default 0x1
diff --git a/src/mainboard/google/veyron_speedy/romstage.c b/src/mainboard/google/veyron_speedy/romstage.c
index b073c34..e22a04e 100644
--- a/src/mainboard/google/veyron_speedy/romstage.c
+++ b/src/mainboard/google/veyron_speedy/romstage.c
@@ -104,7 +104,7 @@
 
 	/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
 	mmu_config_range((uintptr_t)_dram/MiB,
-			 CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
+			 sdram_size_mb(), DCACHE_WRITEBACK);
 	mmu_config_range((uintptr_t)_dma_coherent/MiB,
 			 _dma_coherent_size/MiB, DCACHE_OFF);
 
diff --git a/src/soc/rockchip/rk3288/Makefile.inc b/src/soc/rockchip/rk3288/Makefile.inc
index 2019281..86d3b5c 100644
--- a/src/soc/rockchip/rk3288/Makefile.inc
+++ b/src/soc/rockchip/rk3288/Makefile.inc
@@ -59,6 +59,7 @@
 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 2eed972..38ea365 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 16e4f81..8f37cb7 100644
--- a/src/soc/rockchip/rk3288/include/soc/sdram.h
+++ b/src/soc/rockchip/rk3288/include/soc/sdram.h
@@ -98,5 +98,6 @@
 
 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 cda36be..2698024 100644
--- a/src/soc/rockchip/rk3288/sdram.c
+++ b/src/soc/rockchip/rk3288/sdram.c
@@ -489,18 +489,27 @@
  * [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 @@
 	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 @@
 	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 519351c..2133c19 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)