summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock_am33xx.c5
-rw-r--r--arch/arm/cpu/armv7/am33xx/elm.c2
-rw-r--r--arch/arm/cpu/armv7/config.mk6
-rw-r--r--arch/arm/cpu/armv7/exynos/clock.c167
-rw-r--r--arch/arm/cpu/armv7/exynos/soc.c36
-rw-r--r--arch/arm/cpu/armv7/mx5/lowlevel_init.S8
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c12
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c4
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c29
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S10
-rw-r--r--arch/arm/cpu/armv7/omap-common/u-boot-spl.lds2
-rw-r--r--arch/arm/cpu/armv7/omap3/board.c31
-rw-r--r--arch/arm/cpu/armv7/omap3/sys_info.c4
-rw-r--r--arch/arm/cpu/armv7/omap4/emif.c1
-rw-r--r--arch/arm/cpu/armv7/omap4/hw_data.c8
-rw-r--r--arch/arm/cpu/armv7/omap5/emif.c1
-rw-r--r--arch/arm/cpu/armv7/s5p-common/pwm.c42
-rw-r--r--arch/arm/cpu/armv7/s5p-common/timer.c117
-rw-r--r--arch/arm/cpu/armv7/socfpga/u-boot-spl.lds2
-rw-r--r--arch/arm/cpu/armv7/start.S29
20 files changed, 352 insertions, 164 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index afc0d92059..a1efc7520a 100644
--- a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
+++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
@@ -195,6 +195,11 @@ static void enable_per_clocks(void)
while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
;
+ /* MMC1 */
+ writel(PRCM_MOD_EN, &cmper->mmc1clkctrl);
+ while (readl(&cmper->mmc1clkctrl) != PRCM_MOD_EN)
+ ;
+
/* i2c0 */
writel(PRCM_MOD_EN, &cmwkup->wkup_i2c0ctrl);
while (readl(&cmwkup->wkup_i2c0ctrl) != PRCM_MOD_EN)
diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c
index 9eed23d75a..41df612956 100644
--- a/arch/arm/cpu/armv7/am33xx/elm.c
+++ b/arch/arm/cpu/armv7/am33xx/elm.c
@@ -33,7 +33,7 @@
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch/cpu.h>
-#include <asm/arch/omap_gpmc.h>
+#include <asm/omap_gpmc.h>
#include <asm/arch/elm.h>
#define ELM_DEFAULT_POLY (0)
diff --git a/arch/arm/cpu/armv7/config.mk b/arch/arm/cpu/armv7/config.mk
index 9c3e2f3ce4..56b8053770 100644
--- a/arch/arm/cpu/armv7/config.mk
+++ b/arch/arm/cpu/armv7/config.mk
@@ -40,5 +40,11 @@ PF_NO_UNALIGNED := $(call cc-option, -mno-unaligned-access,)
PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED)
ifneq ($(CONFIG_IMX_CONFIG),)
+ifdef CONFIG_SPL
+ifdef CONFIG_SPL_BUILD
+ALL-y += $(OBJTREE)/SPL
+endif
+else
ALL-y += $(obj)u-boot.imx
endif
+endif
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 956427c9eb..223660aab6 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -27,6 +27,49 @@
#include <asm/arch/clk.h>
#include <asm/arch/periph.h>
+/* *
+ * This structure is to store the src bit, div bit and prediv bit
+ * positions of the peripheral clocks of the src and div registers
+ */
+struct clk_bit_info {
+ int8_t src_bit;
+ int8_t div_bit;
+ int8_t prediv_bit;
+};
+
+/* src_bit div_bit prediv_bit */
+static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
+ {0, 0, -1},
+ {4, 4, -1},
+ {8, 8, -1},
+ {12, 12, -1},
+ {0, 0, 8},
+ {4, 16, 24},
+ {8, 0, 8},
+ {12, 16, 24},
+ {-1, -1, -1},
+ {16, 0, 8},
+ {20, 16, 24},
+ {24, 0, 8},
+ {0, 0, 4},
+ {4, 12, 16},
+ {-1, -1, -1},
+ {-1, -1, -1},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {-1, 24, 0},
+ {24, 0, -1},
+ {24, 0, -1},
+ {24, 0, -1},
+ {24, 0, -1},
+ {24, 0, -1},
+};
+
/* Epll Clock division values to achive different frequency output */
static struct set_epll_con_val exynos5_epll_div[] = {
{ 192000000, 0, 48, 3, 1, 0 },
@@ -201,6 +244,107 @@ static unsigned long exynos5_get_pll_clk(int pllreg)
return fout;
}
+static unsigned long exynos5_get_periph_rate(int peripheral)
+{
+ struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
+ unsigned long sclk, sub_clk;
+ unsigned int src, div, sub_div;
+ struct exynos5_clock *clk =
+ (struct exynos5_clock *)samsung_get_base_clock();
+
+ 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_PWM0:
+ case PERIPH_ID_PWM1:
+ case PERIPH_ID_PWM2:
+ case PERIPH_ID_PWM3:
+ case PERIPH_ID_PWM4:
+ src = readl(&clk->src_peric0);
+ div = readl(&clk->div_peric3);
+ break;
+ case PERIPH_ID_SPI0:
+ case PERIPH_ID_SPI1:
+ src = readl(&clk->src_peric1);
+ div = readl(&clk->div_peric1);
+ break;
+ case PERIPH_ID_SPI2:
+ src = readl(&clk->src_peric1);
+ div = readl(&clk->div_peric2);
+ break;
+ case PERIPH_ID_SPI3:
+ case PERIPH_ID_SPI4:
+ src = readl(&clk->sclk_src_isp);
+ div = readl(&clk->sclk_div_isp);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ case PERIPH_ID_SDMMC2:
+ case PERIPH_ID_SDMMC3:
+ src = readl(&clk->src_fsys);
+ div = readl(&clk->div_fsys1);
+ 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:
+ sclk = exynos5_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:
+ debug("%s: invalid peripheral %d", __func__, peripheral);
+ return -1;
+ };
+
+ src = (src >> bit_info->src_bit) & 0xf;
+
+ switch (src) {
+ case EXYNOS_SRC_MPLL:
+ sclk = exynos5_get_pll_clk(MPLL);
+ break;
+ case EXYNOS_SRC_EPLL:
+ sclk = exynos5_get_pll_clk(EPLL);
+ break;
+ case EXYNOS_SRC_VPLL:
+ sclk = exynos5_get_pll_clk(VPLL);
+ break;
+ default:
+ return 0;
+ }
+
+ /* Ratio clock division for this peripheral */
+ sub_div = (div >> bit_info->div_bit) & 0xf;
+ sub_clk = sclk / (sub_div + 1);
+
+ /* Pre-ratio clock division for SDMMC0 and 2 */
+ if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
+ div = (div >> bit_info->prediv_bit) & 0xff;
+ return sub_clk / (div + 1);
+ }
+
+ return sub_clk;
+}
+
+unsigned long clock_get_periph_rate(int peripheral)
+{
+ if (cpu_is_exynos5())
+ return exynos5_get_periph_rate(peripheral);
+ else
+ return 0;
+}
+
/* exynos4: return ARM clock frequency */
static unsigned long exynos4_get_arm_clk(void)
{
@@ -324,27 +468,6 @@ static unsigned long exynos4x12_get_pwm_clk(void)
return pclk;
}
-/* exynos5: return pwm clock frequency */
-static unsigned long exynos5_get_pwm_clk(void)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)samsung_get_base_clock();
- unsigned long pclk, sclk;
- unsigned int ratio;
-
- /*
- * CLK_DIV_PERIC3
- * PWM_RATIO [3:0]
- */
- ratio = readl(&clk->div_peric3);
- ratio = ratio & 0xf;
- sclk = get_pll_clk(MPLL);
-
- pclk = sclk / (ratio + 1);
-
- return pclk;
-}
-
/* exynos4: return uart clock frequency */
static unsigned long exynos4_get_uart_clk(int dev_index)
{
@@ -1210,7 +1333,7 @@ unsigned long get_i2c_clk(void)
unsigned long get_pwm_clk(void)
{
if (cpu_is_exynos5())
- return exynos5_get_pwm_clk();
+ return clock_get_periph_rate(PERIPH_ID_PWM0);
else {
if (proid_is_exynos4412())
return exynos4x12_get_pwm_clk();
diff --git a/arch/arm/cpu/armv7/exynos/soc.c b/arch/arm/cpu/armv7/exynos/soc.c
index ab65b8d3a8..e948e4c638 100644
--- a/arch/arm/cpu/armv7/exynos/soc.c
+++ b/arch/arm/cpu/armv7/exynos/soc.c
@@ -23,6 +23,14 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/system.h>
+
+enum l2_cache_params {
+ CACHE_TAG_RAM_SETUP = (1 << 9),
+ CACHE_DATA_RAM_SETUP = (1 << 5),
+ CACHE_TAG_RAM_LATENCY = (2 << 6),
+ CACHE_DATA_RAM_LATENCY = (2 << 0)
+};
void reset_cpu(ulong addr)
{
@@ -36,3 +44,31 @@ void enable_caches(void)
dcache_enable();
}
#endif
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+/*
+ * Set L2 cache parameters
+ */
+static void exynos5_set_l2cache_params(void)
+{
+ unsigned int val = 0;
+
+ asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r"(val));
+
+ val |= CACHE_TAG_RAM_SETUP |
+ CACHE_DATA_RAM_SETUP |
+ CACHE_TAG_RAM_LATENCY |
+ CACHE_DATA_RAM_LATENCY;
+
+ asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val));
+}
+
+/*
+ * Sets L2 cache related parameters before enabling data cache
+ */
+void v7_outer_cache_enable(void)
+{
+ if (cpu_is_exynos5())
+ exynos5_set_l2cache_params();
+}
+#endif
diff --git a/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/arch/arm/cpu/armv7/mx5/lowlevel_init.S
index 6d9396a976..dfce0ca83e 100644
--- a/arch/arm/cpu/armv7/mx5/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/mx5/lowlevel_init.S
@@ -309,8 +309,7 @@ setup_pll_func:
ldr r0, =CCM_BASE_ADDR
ldr r1, =0x00015154
str r1, [r0, #CLKCTL_CBCMR]
- ldr r1, =0x02888945
- orr r1, r1, #(1 << 16)
+ ldr r1, =0x02898945
str r1, [r0, #CLKCTL_CBCDR]
/* make sure change is effective */
1: ldr r1, [r0, #CLKCTL_CDHIPR]
@@ -321,10 +320,7 @@ setup_pll_func:
/* Switch peripheral to PLL2 */
ldr r0, =CCM_BASE_ADDR
- ldr r1, =0x00808145
- orr r1, r1, #(2 << 10)
- orr r1, r1, #(0 << 16)
- orr r1, r1, #(1 << 19)
+ ldr r1, =0x00888945
str r1, [r0, #CLKCTL_CBCDR]
ldr r1, =0x00016154
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 193ba1240f..2ea8ca3bd3 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -61,6 +61,18 @@ u32 get_cpu_rev(void)
return (type << 12) | (reg + 0x10);
}
+#ifdef CONFIG_REVISION_TAG
+u32 __weak get_board_rev(void)
+{
+ u32 cpurev = get_cpu_rev();
+ u32 type = ((cpurev >> 12) & 0xff);
+ if (type == MXC_CPU_MX6SOLO)
+ cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
+
+ return cpurev;
+}
+#endif
+
void init_aips(void)
{
struct aipstz_regs *aips1, *aips2;
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 9ed18995ea..2b955c7c00 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -612,7 +612,7 @@ void freq_update_core(void)
/*
* Putting EMIF in HW_AUTO is seen to be causing issues with
- * EMIF clocks and the master DLL. Put EMIF in SW_WKUP
+ * EMIF clocks and the master DLL. Keep EMIF in SW_WKUP
* in OMAP5430 ES1.0 silicon
*/
if (omap_rev != OMAP5430_ES1_0) {
@@ -659,7 +659,7 @@ void setup_clocks_for_console(void)
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
MODULE_CLKCTRL_MODULEMODE_SHIFT);
- clrsetbits_le32((*prcm)->cm_l4per_uart3_clkctrl,
+ clrsetbits_le32((*prcm)->cm_l4per_uart4_clkctrl,
MODULE_CLKCTRL_MODULEMODE_MASK,
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
MODULE_CLKCTRL_MODULEMODE_SHIFT);
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 9eb1279d41..cdb4439721 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -655,20 +655,27 @@ static u32 get_ddr_phy_ctrl_1(u32 freq, u8 RL)
return phy;
}
-static u32 get_emif_mem_size(struct emif_device_details *devices)
+static u32 get_emif_mem_size(u32 base)
{
u32 size_mbytes = 0, temp;
+ struct emif_device_details dev_details;
+ struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
+ u32 emif_nr = emif_num(base);
- if (!devices)
- return 0;
+ emif_reset_phy(base);
+ dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0,
+ &cs0_dev_details);
+ dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1,
+ &cs1_dev_details);
+ emif_reset_phy(base);
- if (devices->cs0_device_details) {
- temp = devices->cs0_device_details->density;
+ if (dev_details.cs0_device_details) {
+ temp = dev_details.cs0_device_details->density;
size_mbytes += lpddr2_density_2_size_in_mbytes[temp];
}
- if (devices->cs1_device_details) {
- temp = devices->cs1_device_details->density;
+ if (dev_details.cs1_device_details) {
+ temp = dev_details.cs1_device_details->density;
size_mbytes += lpddr2_density_2_size_in_mbytes[temp];
}
/* convert to bytes */
@@ -1040,13 +1047,9 @@ static void do_sdram_init(u32 base)
/* Return if no devices on this EMIF */
if (!dev_details.cs0_device_details &&
!dev_details.cs1_device_details) {
- emif_sizes[emif_nr - 1] = 0;
return;
}
- if (!in_sdram)
- emif_sizes[emif_nr - 1] = get_emif_mem_size(&dev_details);
-
/*
* Get device timings:
* - Default timings specified by JESD209-2 if
@@ -1108,8 +1111,8 @@ void dmm_init(u32 base)
mapped_size = 0;
section_cnt = 3;
sys_addr = CONFIG_SYS_SDRAM_BASE;
- emif1_size = emif_sizes[0];
- emif2_size = emif_sizes[1];
+ emif1_size = get_emif_mem_size(EMIF1_BASE);
+ emif2_size = get_emif_mem_size(EMIF2_BASE);
debug("emif1_size 0x%x emif2_size 0x%x\n", emif1_size, emif2_size);
if (!emif1_size && !emif2_size)
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index b933fe8437..90b3c8aea4 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -60,10 +60,14 @@ ENTRY(save_boot_params)
ldr r3, =boot_params
strb r2, [r3, #BOOT_DEVICE_OFFSET] @ spl_boot_device <- r1
- /* boot mode is passed only for devices that can raw/fat mode */
- cmp r2, #BOOT_DEVICE_XIP
+ /*
+ * boot mode is only valid for device that can be raw or FAT booted.
+ * in other cases it may be fatal to look. While platforms differ
+ * in the values used for each MMC slot, they are contiguous.
+ */
+ cmp r2, #MMC_BOOT_DEVICES_START
blt 2f
- cmp r2, #BOOT_DEVICE_MMC2
+ cmp r2, #MMC_BOOT_DEVICES_END
bgt 2f
/* Store the boot mode (raw/FAT) in omap_bootmode */
ldr r2, [r0, #DEV_DESC_PTR_OFFSET] @ get the device descriptor ptr
diff --git a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
index efae381bdb..bd218c07da 100644
--- a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
+++ b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
@@ -38,7 +38,7 @@ SECTIONS
.text :
{
__start = .;
- arch/arm/cpu/armv7/start.o (.text)
+ arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
} >.sram
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index c6d9a425a5..b72fadc257 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -328,14 +328,25 @@ void abort(void)
*****************************************************************************/
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
- if (argc != 2)
+ if (argc < 2 || argc > 3)
goto usage;
- if (strncmp(argv[1], "hw", 2) == 0)
- omap_nand_switch_ecc(1);
- else if (strncmp(argv[1], "sw", 2) == 0)
- omap_nand_switch_ecc(0);
- else
+
+ if (strncmp(argv[1], "hw", 2) == 0) {
+ if (argc == 2) {
+ omap_nand_switch_ecc(1, 1);
+ } else {
+ if (strncmp(argv[2], "hamming", 7) == 0)
+ omap_nand_switch_ecc(1, 1);
+ else if (strncmp(argv[2], "bch8", 4) == 0)
+ omap_nand_switch_ecc(1, 8);
+ else
+ goto usage;
+ }
+ } else if (strncmp(argv[1], "sw", 2) == 0) {
+ omap_nand_switch_ecc(0, 0);
+ } else {
goto usage;
+ }
return 0;
@@ -345,9 +356,13 @@ usage:
}
U_BOOT_CMD(
- nandecc, 2, 1, do_switch_ecc,
+ nandecc, 3, 1, do_switch_ecc,
"switch OMAP3 NAND ECC calculation algorithm",
- "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm"
+ "hw [hamming|bch8] - Switch between NAND hardware 1-bit hamming and"
+ " 8-bit BCH\n"
+ " ecc calculation (second parameter may"
+ " be omitted).\n"
+ "nandecc sw - Switch to NAND software ecc algorithm."
);
#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c
index 3c80113502..08a63d266e 100644
--- a/arch/arm/cpu/armv7/omap3/sys_info.c
+++ b/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -299,9 +299,9 @@ int print_cpuinfo (void)
}
if ((get_cpu_rev() >= CPU_3XX_ES31) &&
(get_sku_id() == SKUID_CLK_720MHZ))
- max_clk = "720 mHz";
+ max_clk = "720 MHz";
else
- max_clk = "600 mHz";
+ max_clk = "600 MHz";
break;
case CPU_AM35XX:
diff --git a/arch/arm/cpu/armv7/omap4/emif.c b/arch/arm/cpu/armv7/omap4/emif.c
index ca4823dd79..53f60635b1 100644
--- a/arch/arm/cpu/armv7/omap4/emif.c
+++ b/arch/arm/cpu/armv7/omap4/emif.c
@@ -33,7 +33,6 @@
#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
u32 *const T_num = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_NUM;
u32 *const T_den = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_DEN;
-u32 *const emif_sizes = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_SIZE;
#endif
#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
diff --git a/arch/arm/cpu/armv7/omap4/hw_data.c b/arch/arm/cpu/armv7/omap4/hw_data.c
index 7551b9861e..04977b4f2b 100644
--- a/arch/arm/cpu/armv7/omap4/hw_data.c
+++ b/arch/arm/cpu/armv7/omap4/hw_data.c
@@ -216,14 +216,14 @@ struct dplls omap4460_dplls = {
struct pmic_data twl6030_4430es1 = {
.base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV,
- .step = 12660, /* 10 mV represented in uV */
+ .step = 12660, /* 12.66 mV represented in uV */
/* The code starts at 1 not 0 */
.start_code = 1,
};
struct pmic_data twl6030 = {
.base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV,
- .step = 12660, /* 10 mV represented in uV */
+ .step = 12660, /* 12.66 mV represented in uV */
/* The code starts at 1 not 0 */
.start_code = 1,
};
@@ -271,11 +271,11 @@ struct vcores_data omap4460_volts = {
.core.value = 1200,
.core.addr = SMPS_REG_ADDR_VCORE1,
- .core.pmic = &tps62361,
+ .core.pmic = &twl6030,
.mm.value = 1200,
.mm.addr = SMPS_REG_ADDR_VCORE2,
- .mm.pmic = &tps62361,
+ .mm.pmic = &twl6030,
};
/*
diff --git a/arch/arm/cpu/armv7/omap5/emif.c b/arch/arm/cpu/armv7/omap5/emif.c
index 8019ffe3d3..3f37abdf83 100644
--- a/arch/arm/cpu/armv7/omap5/emif.c
+++ b/arch/arm/cpu/armv7/omap5/emif.c
@@ -34,7 +34,6 @@
#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg))
static u32 *const T_num = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_T_NUM;
static u32 *const T_den = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_T_DEN;
-static u32 *const emif_sizes = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_SIZE;
#endif
#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
index 44d7bc360e..6f401b8d9e 100644
--- a/arch/arm/cpu/armv7/s5p-common/pwm.c
+++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -70,7 +70,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
return tin_parent_rate / 16;
}
-#define NS_IN_HZ (1000000000UL)
+#define NS_IN_SEC 1000000000UL
int pwm_config(int pwm_id, int duty_ns, int period_ns)
{
@@ -79,7 +79,7 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
unsigned int offset;
unsigned long tin_rate;
unsigned long tin_ns;
- unsigned long period;
+ unsigned long frequency;
unsigned long tcon;
unsigned long tcnt;
unsigned long tcmp;
@@ -89,34 +89,24 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
* fact that anything faster than 1GHz is easily representable
* by 32bits.
*/
- if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+ if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0)
return -ERANGE;
if (duty_ns > period_ns)
return -EINVAL;
- period = NS_IN_HZ / period_ns;
+ frequency = NS_IN_SEC / period_ns;
/* Check to see if we are changing the clock rate of the PWM */
- tin_rate = pwm_calc_tin(pwm_id, period);
+ tin_rate = pwm_calc_tin(pwm_id, frequency);
- tin_ns = NS_IN_HZ / tin_rate;
+ tin_ns = NS_IN_SEC / tin_rate;
tcnt = period_ns / tin_ns;
/* Note, counters count down */
tcmp = duty_ns / tin_ns;
tcmp = tcnt - tcmp;
- /*
- * the pwm hw only checks the compare register after a decrement,
- * so the pin never toggles if tcmp = tcnt
- */
- if (tcmp == tcnt)
- tcmp--;
-
- if (tcmp < 0)
- tcmp = 0;
-
/* Update the PWM register block. */
offset = pwm_id * 3;
if (pwm_id < 4) {
@@ -143,7 +133,7 @@ int pwm_init(int pwm_id, int div, int invert)
u32 val;
const struct s5p_timer *pwm =
(struct s5p_timer *)samsung_get_base_timer();
- unsigned long timer_rate_hz;
+ unsigned long ticks_per_period;
unsigned int offset, prescaler;
/*
@@ -167,14 +157,24 @@ int pwm_init(int pwm_id, int div, int invert)
val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
writel(val, &pwm->tcfg1);
- timer_rate_hz = get_pwm_clk() / ((prescaler + 1) *
- (div + 1));
+ if (pwm_id == 4) {
+ /*
+ * TODO(sjg): Use this as a countdown timer for now. We count
+ * down from the maximum value to 0, then reset.
+ */
+ ticks_per_period = -1UL;
+ } else {
+ const unsigned long pwm_hz = 1000;
+ unsigned long timer_rate_hz = get_pwm_clk() /
+ ((prescaler + 1) * (1 << div));
- timer_rate_hz = timer_rate_hz / CONFIG_SYS_HZ;
+ ticks_per_period = timer_rate_hz / pwm_hz;
+ }
/* set count value */
offset = pwm_id * 3;
- writel(timer_rate_hz, &pwm->tcntb0 + offset);
+
+ writel(ticks_per_period, &pwm->tcntb0 + offset);
val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
if (invert && (pwm_id < 4))
diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index e78c716d3f..6a0fa5862e 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -39,13 +39,33 @@ static inline struct s5p_timer *s5p_get_base_timer(void)
return (struct s5p_timer *)samsung_get_base_timer();
}
+/**
+ * Read the countdown timer.
+ *
+ * This operates at 1MHz and counts downwards. It will wrap about every
+ * hour (2^32 microseconds).
+ *
+ * @return current value of timer
+ */
+static unsigned long timer_get_us_down(void)
+{
+ struct s5p_timer *const timer = s5p_get_base_timer();
+
+ return readl(&timer->tcnto4);
+}
+
int timer_init(void)
{
/* PWM Timer 4 */
- pwm_init(4, MUX_DIV_2, 0);
- pwm_config(4, 0, 0);
+ pwm_init(4, MUX_DIV_4, 0);
+ pwm_config(4, 100000, 100000);
pwm_enable(4);
+ /* Use this as the current monotonic time in us */
+ gd->arch.timer_reset_value = 0;
+
+ /* Use this as the last timer value we saw */
+ gd->arch.lastinc = timer_get_us_down();
reset_timer_masked();
return 0;
@@ -56,81 +76,52 @@ int timer_init(void)
*/
unsigned long get_timer(unsigned long base)
{
- return get_timer_masked() - base;
-}
+ ulong now = timer_get_us_down();
+
+ /*
+ * Increment the time by the amount elapsed since the last read.
+ * The timer may have wrapped around, but it makes no difference to
+ * our arithmetic here.
+ */
+ gd->arch.timer_reset_value += gd->arch.lastinc - now;
+ gd->arch.lastinc = now;
-/* delay x useconds */
-void __udelay(unsigned long usec)
-{
- struct s5p_timer *const timer = s5p_get_base_timer();
- unsigned long tmo, tmp, count_value;
-
- count_value = readl(&timer->tcntb4);
-
- if (usec >= 1000) {
- /*
- * if "big" number, spread normalization
- * to seconds
- * 1. start to normalize for usec to ticks per sec
- * 2. find number of "ticks" to wait to achieve target
- * 3. finish normalize.
- */
- tmo = usec / 1000;
- tmo *= (CONFIG_SYS_HZ * count_value);
- tmo /= 1000;
- } else {
- /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CONFIG_SYS_HZ * count_value;
- tmo /= (1000 * 1000);
- }
-
- /* get current timestamp */
- tmp = get_current_tick();
-
- /* if setting this fordward will roll time stamp */
- /* reset "advancing" timestamp to 0, set lastinc value */
- /* else, set advancing stamp wake up time */
- if ((tmo + tmp + 1) < tmp)
- reset_timer_masked();
- else
- tmo += tmp;
-
- /* loop till event */
- while (get_current_tick() < tmo)
- ; /* nop */
+ /* Divide by 1000 to convert from us to ms */
+ return gd->arch.timer_reset_value / 1000 - base;
}
-void reset_timer_masked(void)
+unsigned long timer_get_us(void)
{
- struct s5p_timer *const timer = s5p_get_base_timer();
+ static unsigned long base_time_us;
- /* reset time */
- gd->arch.lastinc = readl(&timer->tcnto4);
- gd->arch.tbl = 0;
+ struct s5p_timer *const timer =
+ (struct s5p_timer *)samsung_get_base_timer();
+ unsigned long now_downward_us = readl(&timer->tcnto4);
+
+ if (!base_time_us)
+ base_time_us = now_downward_us;
+
+ /* Note that this timer counts downward. */
+ return base_time_us - now_downward_us;
}
-unsigned long get_timer_masked(void)
+/* delay x useconds */
+void __udelay(unsigned long usec)
{
- struct s5p_timer *const timer = s5p_get_base_timer();
- unsigned long count_value = readl(&timer->tcntb4);
+ unsigned long count_value;
- return get_current_tick() / count_value;
+ count_value = timer_get_us_down();
+ while ((int)(count_value - timer_get_us_down()) < (int)usec)
+ ;
}
-unsigned long get_current_tick(void)
+void reset_timer_masked(void)
{
struct s5p_timer *const timer = s5p_get_base_timer();
- unsigned long now = readl(&timer->tcnto4);
- unsigned long count_value = readl(&timer->tcntb4);
-
- if (gd->arch.lastinc >= now)
- gd->arch.tbl += gd->arch.lastinc - now;
- else
- gd->arch.tbl += gd->arch.lastinc + count_value - now;
-
- gd->arch.lastinc = now;
- return gd->arch.tbl;
+ /* reset time */
+ gd->arch.lastinc = readl(&timer->tcnto4);
+ gd->arch.tbl = 0;
}
/*
diff --git a/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds b/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
index 79cc93cb57..15f8c01a9a 100644
--- a/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
+++ b/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
@@ -27,7 +27,7 @@ SECTIONS
. = ALIGN(4);
.text :
{
- arch/arm/cpu/armv7/start.o (.text)
+ arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
} >.sdram
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 36a4c3cfda..61da7acde9 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -81,7 +81,11 @@ _end_vect:
.globl _TEXT_BASE
_TEXT_BASE:
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
+ .word CONFIG_SPL_TEXT_BASE
+#else
.word CONFIG_SYS_TEXT_BASE
+#endif
/*
* These are defined in the board-specific linker script.
@@ -90,9 +94,9 @@ _TEXT_BASE:
_bss_start_ofs:
.word __bss_start - _start
-.global _image_copy_end_ofs
+.globl _image_copy_end_ofs
_image_copy_end_ofs:
- .word __image_copy_end - _start
+ .word __image_copy_end - _start
.globl _bss_end_ofs
_bss_end_ofs:
@@ -161,28 +165,23 @@ reset:
#ifndef CONFIG_SPL_BUILD
/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
+ * void relocate_code(addr_moni)
*
+ * This function relocates the monitor code.
*/
ENTRY(relocate_code)
- mov r4, r0 /* save addr_sp */
- mov r5, r1 /* save addr of gd */
- mov r6, r2 /* save addr of destination */
+ mov r6, r0 /* save addr of destination */
adr r0, _start
- cmp r0, r6
- moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */
+ subs r9, r6, r0 /* r9 <- relocation offset */
beq relocate_done /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy_loop */
ldr r3, _image_copy_end_ofs
add r2, r0, r3 /* r2 <- source end address */
copy_loop:
- ldmia r0!, {r9-r10} /* copy from source address [r0] */
- stmia r1!, {r9-r10} /* copy to target address [r1] */
+ ldmia r0!, {r10-r11} /* copy from source address [r0] */
+ stmia r1!, {r10-r11} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop
@@ -190,7 +189,6 @@ copy_loop:
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
- sub r9, r6, r0 /* r9 <- relocation offset */
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
add r10, r10, r0 /* r10 <- sym table in FLASH */
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
@@ -465,9 +463,10 @@ ENDPROC(cpu_init_crit)
@ spots for abort stack
str lr, [r0] @ save caller lr in position 0
@ of saved stack
- mrs r0, spsr @ get the spsr
+ mrs lr, spsr @ get the spsr
str lr, [r0, #4] @ save spsr in position 1 of
@ saved stack
+ ldr lr, [r0] @ restore lr
ldr r0, [r13] @ restore r0
add r13, r13, #4 @ pop stack entry
.endm
OpenPOWER on IntegriCloud