diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc index 56a1bb72aa..0cb5737f25 100644 --- a/src/arch/armv7/lib/Makefile.inc +++ b/src/arch/armv7/lib/Makefile.inc @@ -1,6 +1,5 @@ #FIXME: cache_v7 and cache-cp15 will go away eventually -bootblock-y += syslib.c bootblock-$(CONFIG_EARLY_CONSOLE) += early_console.c bootblock-y += cache.c @@ -13,7 +12,6 @@ ramstage-y += div0.c #ramstage-y += interrupts.c #ramstage-y += memcpy.S #ramstage-y += memset.S -ramstage-y += syslib.c ramstage-y += cache.c ramstage-y += mmu.c diff --git a/src/cpu/samsung/exynos5-common/timer.c b/src/cpu/samsung/exynos5-common/timer.c index 6cd5f5dd35..ca15501bb7 100644 --- a/src/cpu/samsung/exynos5-common/timer.c +++ b/src/cpu/samsung/exynos5-common/timer.c @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include #include @@ -117,12 +119,17 @@ unsigned long timer_get_us(void) } /* delay x useconds */ -void __udelay(unsigned long usec) +void udelay(unsigned long usec) { - unsigned long count_value; + unsigned long start; - count_value = timer_get_us_down(); - while ((int)(count_value - timer_get_us_down()) < (int)usec) + start = timer_us(); + if ((start + usec) < start){ + printk(BIOS_EMERG, "udelay: %08lx is impossibly large\n", + usec); + usec = 1000000; + } + while ((timer_us() - start) < usec) ; } diff --git a/src/cpu/samsung/exynos5250/Makefile.inc b/src/cpu/samsung/exynos5250/Makefile.inc index 74bc871f36..1046b8bc0b 100644 --- a/src/cpu/samsung/exynos5250/Makefile.inc +++ b/src/cpu/samsung/exynos5250/Makefile.inc @@ -3,7 +3,7 @@ # image outside of CBFS #INTERMEDIATE += exynos5250_add_bl1 -bootblock-y += pinmux.c +bootblock-y += pinmux.c mct.c # Clock is required for UART bootblock-$(CONFIG_EARLY_CONSOLE) += clock_init.c bootblock-$(CONFIG_EARLY_CONSOLE) += clock.c @@ -16,6 +16,7 @@ romstage-y += pinmux.c # required by s3c24x0_i2c (exynos5-common) and uart. romstage-y += dmc_common.c romstage-y += dmc_init_ddr3.c romstage-y += power.c +romstage-y += mct.c romstage-$(CONFIG_EARLY_CONSOLE) += soc.c romstage-$(CONFIG_EARLY_CONSOLE) += uart.c @@ -27,6 +28,7 @@ ramstage-y += power.c ramstage-y += soc.c ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c ramstage-y += cpu.c +ramstage-y += mct.c #ramstage-$(CONFIG_SATA_AHCI) += sata.c diff --git a/src/cpu/samsung/exynos5250/clk.h b/src/cpu/samsung/exynos5250/clk.h index dbddce0c6d..4785894668 100644 --- a/src/cpu/samsung/exynos5250/clk.h +++ b/src/cpu/samsung/exynos5250/clk.h @@ -25,6 +25,11 @@ #include #include + +#define MCT_ADDRESS 0x101c0000 + +#define MCT_HZ 24000000 + /* * Set mshci controller instances clock drivder * diff --git a/src/cpu/samsung/exynos5250/clock_init.c b/src/cpu/samsung/exynos5250/clock_init.c index 618fdb6a86..c8479deef5 100644 --- a/src/cpu/samsung/exynos5250/clock_init.c +++ b/src/cpu/samsung/exynos5250/clock_init.c @@ -452,16 +452,3 @@ void clock_init_dp_clock(void) setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1); } -/* - * This is a custom implementation for the udelay(), as we do not the timer - * initialise during the SPL boot. We are assuming the cpu takes 3 instruction - * pre cycle. This is based on the implementation of sdelay() function. - */ -void udelay(unsigned usec) -{ - unsigned long count; - - /* TODO(alim.akhtar@samsung.com): Comment on why divided by 30000000 */ - count = usec * (get_pll_clk(APLL) / (3 * 10000000)); - sdelay(count); -} diff --git a/src/cpu/samsung/exynos5250/mct.c b/src/cpu/samsung/exynos5250/mct.c new file mode 100644 index 0000000000..ddabbf7957 --- /dev/null +++ b/src/cpu/samsung/exynos5250/mct.c @@ -0,0 +1,117 @@ +/* + * Copyright 2013 Google Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include "clk.h" + +struct __attribute__((packed)) mct_regs +{ + uint32_t mct_cfg; + uint8_t reserved0[0xfc]; + uint32_t g_cnt_l; + uint32_t g_cnt_u; + uint8_t reserved1[0x8]; + uint32_t g_cnt_wstat; + uint8_t reserved2[0xec]; + uint32_t g_comp0_l; + uint32_t g_comp0_u; + uint32_t g_comp0_addr_incr; + uint8_t reserved3[0x4]; + uint32_t g_comp1_l; + uint32_t g_comp1_u; + uint32_t g_comp1_addr_incr; + uint8_t reserved4[0x4]; + uint32_t g_comp2_l; + uint32_t g_comp2_u; + uint32_t g_comp2_addr_incr; + uint8_t reserved5[0x4]; + uint32_t g_comp3_l; + uint32_t g_comp3_u; + uint32_t g_comp3_addr_incr; + uint8_t reserved6[0x4]; + uint32_t g_tcon; + uint32_t g_int_cstat; + uint32_t g_int_enb; + uint32_t g_wstat; + uint8_t reserved7[0xb0]; + uint32_t l0_tcntb; + uint32_t l0_tcnto; + uint32_t l0_icntb; + uint32_t l0_icnto; + uint32_t l0_frcntb; + uint32_t l0_frcnto; + uint8_t reserved8[0x8]; + uint32_t l0_tcon; + uint8_t reserved9[0xc]; + uint32_t l0_int_cstat; + uint32_t l0_int_enb; + uint8_t reserved10[0x8]; + uint32_t l0_wstat; + uint8_t reserved11[0xbc]; + uint32_t l1_tcntb; + uint32_t l1_tcnto; + uint32_t l1_icntb; + uint32_t l1_icnto; + uint32_t l1_frcntb; + uint32_t l1_frcnto; + uint8_t reserved12[0x8]; + uint32_t l1_tcon; + uint8_t reserved13[0xc]; + uint32_t l1_int_cstat; + uint32_t l1_int_enb; + uint8_t reserved14[0x8]; + uint32_t l1_wstat; +}; + +static int enabled = 0; +static struct mct_regs *const mct = + (struct mct_regs *)MCT_ADDRESS; + +static uint64_t timer_raw_value(void) +{ + if (!enabled) { + writel(readl(&mct->g_tcon) | (0x1 << 8), &mct->g_tcon); + enabled = 1; + } + + uint64_t upper = readl(&mct->g_cnt_u); + uint64_t lower = readl(&mct->g_cnt_l); + + return (upper << 32) | lower; +} + +void timer_start(void) +{ + writel(readl(&mct->g_tcon) | (0x1 << 8), &mct->g_tcon); + enabled = 1; +} + +u32 timer_us(void) +{ + uint64_t raw = timer_raw_value(); + static uint32_t ticks_per_microsecond = MCT_HZ/1000000; + uint32_t usec = raw / ticks_per_microsecond; + return usec; +} + diff --git a/src/include/time.h b/src/include/time.h new file mode 100644 index 0000000000..2cfcb356c4 --- /dev/null +++ b/src/include/time.h @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#ifndef TIME_H +#define TIME_H + +void timer_start(void); +u32 timer_us(void); + +#endif /* TIME_H */ diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index 2df0e4ef61..d2e0b50b54 100644 --- a/src/mainboard/google/snow/bootblock.c +++ b/src/mainboard/google/snow/bootblock.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,11 @@ void bootblock_mainboard_init(void); void bootblock_mainboard_init(void) { + /* kick off the microsecond timer. We want to do this as early + * as we can. + */ + timer_start(); + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE); #if CONFIG_EARLY_CONSOLE exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c index 7a26ed9b50..dda4e7ca60 100644 --- a/src/mainboard/google/snow/romstage.c +++ b/src/mainboard/google/snow/romstage.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include