summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/armv7/lib/Makefile.inc2
-rw-r--r--src/cpu/samsung/exynos5250/Kconfig4
-rw-r--r--src/cpu/samsung/exynos5250/Makefile.inc6
-rw-r--r--src/cpu/samsung/exynos5250/clock_init.c36
-rw-r--r--src/cpu/samsung/s5p-common/Makefile.inc3
-rw-r--r--src/mainboard/google/snow/bootblock.c277
6 files changed, 55 insertions, 273 deletions
diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc
index 2470db2e80..e0445ceea2 100644
--- a/src/arch/armv7/lib/Makefile.inc
+++ b/src/arch/armv7/lib/Makefile.inc
@@ -1,3 +1,5 @@
+bootblock-y += syslib.c
+
romstage-y += cache_v7.c
romstage-y += cache-cp15.c
romstage-y += div0.c
diff --git a/src/cpu/samsung/exynos5250/Kconfig b/src/cpu/samsung/exynos5250/Kconfig
index 41a1446ef2..ec1d7af558 100644
--- a/src/cpu/samsung/exynos5250/Kconfig
+++ b/src/cpu/samsung/exynos5250/Kconfig
@@ -18,7 +18,7 @@ config SATA_AHCI
#
# 0x0202_0000: vendor-provided BL1
# 0x0202_3400: bootblock, assume up to 32KB in size
-# 0x0202_2600: ID section, assume 2KB in size. This will be
+# 0x0202_7000: ID section, assume 2KB in size. This will be
# within the bootblock section.
# 0x0203_0000: romstage, assume up to 128KB in size.
# 0x0207_7f00: stack pointer
@@ -38,7 +38,7 @@ config BOOTBLOCK_BASE
config ID_SECTION_BASE
hex
- default 0x02026000
+ default 0x02027000
config ROMSTAGE_BASE
hex
diff --git a/src/cpu/samsung/exynos5250/Makefile.inc b/src/cpu/samsung/exynos5250/Makefile.inc
index 6eee50328f..db28221179 100644
--- a/src/cpu/samsung/exynos5250/Makefile.inc
+++ b/src/cpu/samsung/exynos5250/Makefile.inc
@@ -3,6 +3,12 @@
# image outside of CBFS
#INTERMEDIATE += exynos5250_add_bl1
+# Clock init is done in bootblock to support UART output for
+# debugging. We may add a Kconfig option to disable clock init
+# in the bootblock and try moving it entirely into romstage.
+bootblock-y += clock_init.c
+bootblock-y += clock.c
+
romstage-y += clock.c
romstage-y += clock_init.c
romstage-y += exynos_cache.c
diff --git a/src/cpu/samsung/exynos5250/clock_init.c b/src/cpu/samsung/exynos5250/clock_init.c
index 421d880fa7..53bab1a53a 100644
--- a/src/cpu/samsung/exynos5250/clock_init.c
+++ b/src/cpu/samsung/exynos5250/clock_init.c
@@ -597,6 +597,38 @@ static int autodetect_memory(void)
#ifdef CONFIG_SPL_BUILD
+#define SIGNATURE 0xdeadbeef
+
+/* Parameters of early board initialization in SPL */
+static struct spl_machine_param machine_param = {
+ .signature = SIGNATURE,
+ .version = 1,
+ .params = "vmubfasirMw",
+ .size = sizeof(machine_param),
+
+ .mem_iv_size = 0x1f,
+ .mem_type = DDR_MODE_DDR3,
+
+ /*
+ * Set uboot_size to 0x100000 bytes.
+ *
+ * This is an overly conservative value chosen to accommodate all
+ * possible U-Boot image. You are advised to set this value to a
+ * smaller realistic size via scripts that modifies the .machine_param
+ * section of output U-Boot image.
+ */
+ .uboot_size = 0x100000,
+
+ .boot_source = BOOT_MODE_OM,
+ .frequency_mhz = 800,
+ .arm_freq_mhz = 1700,
+ .serial_base = 0x12c30000,
+ .i2c_base = 0x12c60000,
+// .board_rev_gpios = GPIO_D00 | (GPIO_D01 << 16),
+ .mem_manuf = MEM_MANUF_SAMSUNG,
+// .bad_wake_gpio = GPIO_Y10,
+};
+
/**
* Get the required memory type and speed (SPL version).
*
@@ -608,7 +640,7 @@ int clock_get_mem_selection(enum ddr_mode *mem_type,
{
struct spl_machine_param *params;
- params = spl_get_machine_params();
+ params = &machine_param;
*mem_type = params->mem_type;
*frequency_mhz = params->frequency_mhz;
*arm_freq = params->arm_freq_mhz;
@@ -719,7 +751,7 @@ struct arm_clk_ratios *get_arm_ratios(void)
return arm_ratio;
}
- die("get_arm_ratios: Failed to find ratio\n");
+// die("get_arm_ratios: Failed to find ratio\n");
return NULL;
}
diff --git a/src/cpu/samsung/s5p-common/Makefile.inc b/src/cpu/samsung/s5p-common/Makefile.inc
index 7de3c285d2..df67573b84 100644
--- a/src/cpu/samsung/s5p-common/Makefile.inc
+++ b/src/cpu/samsung/s5p-common/Makefile.inc
@@ -1,3 +1,6 @@
+bootblock-y += pwm.c
+bootblock-y += timer.c
+
romstage-y += cpu_info.c
romstage-y += pwm.c # needed by timer.c
romstage-y += s5p_gpio.c
diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c
index 7609410c3a..fd3c505b1e 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -42,112 +42,6 @@
#define EXYNOS5_CLOCK_BASE 0x10010000
-void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
- unsigned shift;
- unsigned mask = 0xff;
- u32 *reg;
-
- reg = &clk->div_peric1;
- shift = 24;
- clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift);
-}
-
-void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
- unsigned shift;
- unsigned mask = 0xff;
- u32 *reg;
-
- reg = &clk->div_peric1;
- shift = 16;
- clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift);
-}
-
-/**
- * Linearly searches for the most accurate main and fine stage clock scalars
- * (divisors) for a specified target frequency and scalar bit sizes by checking
- * all multiples of main_scalar_bits values. Will always return scalars up to or
- * slower than target.
- *
- * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
- * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
- * @param input_freq Clock frequency to be scaled in Hz
- * @param target_freq Desired clock frequency in Hz
- * @param best_fine_scalar Pointer to store the fine stage divisor
- *
- * @return best_main_scalar Main scalar for desired frequency or -1 if none
- * found
- */
-static int clock_calc_best_scalar(unsigned int main_scaler_bits,
- unsigned int fine_scalar_bits, unsigned int input_rate,
- unsigned int target_rate, unsigned int *best_fine_scalar)
-{
- int i;
- int best_main_scalar = -1;
- unsigned int best_error = target_rate;
- const unsigned int cap = (1 << fine_scalar_bits) - 1;
- const unsigned int loops = 1 << main_scaler_bits;
-
-#if 0
- debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
- target_rate, cap);
-
- assert(best_fine_scalar != NULL);
- assert(main_scaler_bits <= fine_scalar_bits);
-#endif
-
- *best_fine_scalar = 1;
-
- if (input_rate == 0 || target_rate == 0)
- return -1;
-
- if (target_rate >= input_rate)
- return 1;
-
- for (i = 1; i <= loops; i++) {
- const unsigned int effective_div = MAX(MIN(input_rate / i /
- target_rate, cap), 1);
- const unsigned int effective_rate = input_rate / i /
- effective_div;
- const int error = target_rate - effective_rate;
-
-#if 0
- debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
- effective_rate, error);
-#endif
-
- if (error >= 0 && error <= best_error) {
- best_error = error;
- best_main_scalar = i;
- *best_fine_scalar = effective_div;
- }
- }
-
- return best_main_scalar;
-}
-
-int clock_set_rate(enum periph_id periph_id, unsigned int rate)
-{
- int main;
- unsigned int fine;
-
- main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
- if (main < 0) {
-// debug("%s: Cannot set clock rate for periph %d",
-// __func__, periph_id);
- return -1;
- }
- clock_ll_set_ratio(-1, main - 1);
- clock_ll_set_pre_ratio(-1, fine - 1);
-
- return 0;
-}
-
struct gpio_info {
unsigned int reg_addr; /* Address of register for this part */
unsigned int max_gpio; /* Maximum GPIO in this part */
@@ -234,163 +128,6 @@ static uint32_t uart3_base = CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
#define CONFIG_SYS_CLK_FREQ 24000000
-/* exynos5: return pll clock frequency */
-unsigned long get_pll_clk(int pllreg);
-unsigned long get_pll_clk(int pllreg)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
- unsigned long r, m, p, s, k = 0, mask, fout;
- unsigned int freq;
-
- switch (pllreg) {
- case APLL:
- r = readl(&clk->apll_con0);
- break;
- case BPLL:
- r = readl(&clk->bpll_con0);
- break;
- case MPLL:
- r = readl(&clk->mpll_con0);
- break;
- case EPLL:
- r = readl(&clk->epll_con0);
- k = readl(&clk->epll_con1);
- break;
- case VPLL:
- r = readl(&clk->vpll_con0);
- k = readl(&clk->vpll_con1);
- break;
- default:
-// printk(BIOS_DEBUG, "Unsupported PLL (%d)\n", pllreg);
- return 0;
- }
-
- /*
- * APLL_CON: MIDV [25:16]
- * MPLL_CON: MIDV [25:16]
- * EPLL_CON: MIDV [24:16]
- * VPLL_CON: MIDV [24:16]
- */
- if (pllreg == APLL || pllreg == BPLL || pllreg == MPLL)
- mask = 0x3ff;
- else
- mask = 0x1ff;
-
- m = (r >> 16) & mask;
-
- /* PDIV [13:8] */
- p = (r >> 8) & 0x3f;
- /* SDIV [2:0] */
- s = r & 0x7;
-
- freq = CONFIG_SYS_CLK_FREQ;
-
- if (pllreg == EPLL) {
- k = k & 0xffff;
- /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
- fout = (m + k / 65536) * (freq / (p * (1 << s)));
- } else if (pllreg == VPLL) {
- k = k & 0xfff;
- /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
- fout = (m + k / 1024) * (freq / (p * (1 << s)));
- } else {
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- fout = m * (freq / (p * (1 << s)));
- }
-
- return fout;
-}
-
-/* src_bit div_bit prediv_bit */
-static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
- {0, 4, 0, -1},
- {4, 4, 4, -1},
- {8, 4, 8, -1},
- {12, 4, 12, -1},
- {0, 4, 0, 8},
- {4, 4, 16, 24},
- {8, 4, 0, 8},
- {12, 4, 16, 24},
- {-1, -1, -1, -1},
- {16, 4, 0, 8}, /* PERIPH_ID_SROMC */
- {20, 4, 16, 24},
- {24, 4, 0, 8},
- {0, 4, 0, 4},
- {4, 4, 12, 16},
- {-1, 4, -1, -1},
- {-1, 4, -1, -1},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {-1, 4, 24, 0},
- {24, 4, 0, -1},
- {24, 4, 0, -1},
- {24, 4, 0, -1},
- {24, 4, 0, -1},
- {24, 4, 0, -1},
- {-1, -1, -1, -1},
- {-1, -1, -1, -1},
- {-1, -1, -1, -1}, /* PERIPH_ID_I2S1 */
- {24, 1, 20, -1}, /* PERIPH_ID_SATA */
-};
-
-static unsigned long my_clock_get_periph_rate(enum periph_id peripheral)
-{
-// struct exynos5_clock *clk =
-// (struct exynos5_clock *)samsung_get_base_clock();
- struct exynos5_clock *clk =
- (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
- struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
-// struct clk_bit_info bit_info = { 12, 4, 12, -1 };
- unsigned long sclk, sub_clk;
- unsigned int src, div, sub_div;
-
- switch (peripheral) {
- case PERIPH_ID_UART0:
- case PERIPH_ID_UART1:
- case PERIPH_ID_UART2:
- case PERIPH_ID_UART3:
- src = readl(&clk->src_peric0);
- div = readl(&clk->div_peric0);
- break;
- case PERIPH_ID_I2C0:
- case PERIPH_ID_I2C1:
- case PERIPH_ID_I2C2:
- case PERIPH_ID_I2C3:
- case PERIPH_ID_I2C4:
- case PERIPH_ID_I2C5:
- case PERIPH_ID_I2C6:
- case PERIPH_ID_I2C7:
- src = 0;
- sclk = get_pll_clk(MPLL);
- sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) & 0x7) + 1;
- div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) & 0x7) + 1;
- return (sclk / sub_div) / div;
- default:
- return -1;
- };
-
- src = (src >> bit_info->src_bit) & ((1 << bit_info->n_src_bits) - 1);
- if (src == SRC_MPLL)
- sclk = get_pll_clk(MPLL);
- else if (src == SRC_EPLL)
- sclk = get_pll_clk(EPLL);
- else if (src == SRC_VPLL)
- sclk = get_pll_clk(VPLL);
- else
- return 0;
-
- sub_div = (div >> bit_info->div_bit) & 0xf;
- sub_clk = sclk / (sub_div + 1);
-
- return sub_clk;
-}
-
static void serial_setbrg_dev(void)
{
// struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
@@ -401,7 +138,7 @@ static void serial_setbrg_dev(void)
// enum periph_id periph;
// periph = exynos5_get_periph_id(base_port);
- uclk = my_clock_get_periph_rate(PERIPH_ID_UART3);
+ uclk = clock_get_periph_rate(PERIPH_ID_UART3);
val = uclk / baudrate;
writel(val / 16 - 1, &uart->ubrdiv);
@@ -569,7 +306,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
{
unsigned long freq, pres = 16, div;
- freq = my_clock_get_periph_rate(PERIPH_ID_I2C0);
+ freq = clock_get_periph_rate(PERIPH_ID_I2C0);
/* calculate prescaler and divisor values */
if ((freq / pres / (16 + 1)) > speed)
/* set prescaler to 512 */
@@ -1222,7 +959,8 @@ static void power_init(void)
REG_ENABLE, MAX77686_MV);
}
-struct mem_timings mem_timings[] = {
+/* FIXME(dhendrix): this will be removed in a follow-up patch */
+struct mem_timings my_mem_timings[] = {
{
.mem_manuf = MEM_MANUF_ELPIDA,
.mem_type = DDR_MODE_DDR3,
@@ -1330,7 +1068,8 @@ struct mem_timings mem_timings[] = {
},
};
-struct arm_clk_ratios arm_clk_ratios[] = {
+/* FIXME(dhendrix): this will be removed in a follow-up patch */
+struct arm_clk_ratios my_arm_clk_ratios[] = {
{
.arm_freq_mhz = 1700,
@@ -1354,8 +1093,8 @@ static void clock_init(void)
struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
struct exynos5_mct_regs *mct_regs =
(struct exynos5_mct_regs *)EXYNOS5_MULTI_CORE_TIMER_BASE;
- struct mem_timings *mem = &mem_timings[0];
- struct arm_clk_ratios *arm_clk_ratio = &arm_clk_ratios[0];
+ struct mem_timings *mem = &my_mem_timings[0];
+ struct arm_clk_ratios *arm_clk_ratio = &my_arm_clk_ratios[0];
u32 val, tmp;
/* Turn on the MCT as early as possible. */