summaryrefslogtreecommitdiff
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/Makefile2
-rw-r--r--arch/arm/cpu/armv7/am33xx/Makefile3
-rw-r--r--arch/arm/cpu/armv7/am33xx/board.c4
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock_am33xx.c (renamed from arch/arm/cpu/armv7/am33xx/clock.c)38
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock_ti814x.c406
-rw-r--r--arch/arm/cpu/armv7/am33xx/ddr.c104
-rw-r--r--arch/arm/cpu/armv7/am33xx/elm.c2
-rw-r--r--arch/arm/cpu/armv7/am33xx/emif4.c57
-rw-r--r--arch/arm/cpu/armv7/am33xx/mem.c2
-rw-r--r--arch/arm/cpu/armv7/am33xx/sys_info.c5
-rw-r--r--arch/arm/cpu/armv7/am33xx/u-boot-spl.lds2
-rw-r--r--arch/arm/cpu/armv7/cache_v7.c3
-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/power.c45
-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/omap-common/Makefile2
-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/hwinit-common.c35
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S11
-rw-r--r--arch/arm/cpu/armv7/omap-common/timer.c1
-rw-r--r--arch/arm/cpu/armv7/omap-common/u-boot-spl.lds4
-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.c111
-rw-r--r--arch/arm/cpu/armv7/socfpga/u-boot-spl.lds4
-rw-r--r--arch/arm/cpu/armv7/start.S38
33 files changed, 982 insertions, 234 deletions
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index 4668b3cf2..7a8c2d0e5 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -32,7 +32,7 @@ COBJS += cache_v7.o
COBJS += cpu.o
COBJS += syslib.o
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI814X),)
SOBJS += lowlevel_init.o
endif
diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile
index 70c443edb..c97e30d44 100644
--- a/arch/arm/cpu/armv7/am33xx/Makefile
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -16,7 +16,8 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).o
-COBJS += clock.o
+COBJS-$(CONFIG_AM33XX) += clock_am33xx.o
+COBJS-$(CONFIG_TI814X) += clock_ti814x.o
COBJS += sys_info.o
COBJS += mem.o
COBJS += ddr.o
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index e35a3e3a7..885fb2d20 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -141,11 +141,11 @@ int arch_misc_init(void)
{
#ifdef CONFIG_AM335X_USB0
musb_register(&otg0_plat, &otg0_board_data,
- (void *)AM335X_USB0_OTG_BASE);
+ (void *)USB0_OTG_BASE);
#endif
#ifdef CONFIG_AM335X_USB1
musb_register(&otg1_plat, &otg1_board_data,
- (void *)AM335X_USB1_OTG_BASE);
+ (void *)USB1_OTG_BASE);
#endif
return 0;
}
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index d7d98d111..a1efc7520 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
@@ -1,9 +1,9 @@
/*
- * clock.c
+ * clock_am33xx.c
*
* clocks for AM33XX based boards
*
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -42,6 +42,35 @@
#define CPGMAC0_IDLE 0x30000
#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
+#define OSC (V_OSCK/1000000)
+
+#define MPUPLL_M CONFIG_SYS_MPUCLK
+#define MPUPLL_N (OSC-1)
+#define MPUPLL_M2 1
+
+/* Core PLL Fdll = 1 GHZ, */
+#define COREPLL_M 1000
+#define COREPLL_N (OSC-1)
+
+#define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */
+#define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */
+#define COREPLL_M6 4 /* CORE_CLKOUTM6 = 500 MHZ */
+
+/*
+ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
+ * frequency needs to be set to 960 MHZ. Hence,
+ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
+ */
+#define PERPLL_M 960
+#define PERPLL_N (OSC-1)
+#define PERPLL_M2 5
+
+/* DDR Freq is 266 MHZ for now */
+/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
+#define DDRPLL_M 266
+#define DDRPLL_N (OSC-1)
+#define DDRPLL_M2 1
+
const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
@@ -166,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/clock_ti814x.c b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
new file mode 100644
index 000000000..cb4210f6e
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
@@ -0,0 +1,406 @@
+/*
+ * clock_ti814x.c
+ *
+ * Clocks for TI814X based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+/* PRCM */
+#define PRCM_MOD_EN 0x2
+
+/* CLK_SRC */
+#define OSC_SRC0 0
+#define OSC_SRC1 1
+
+#define L3_OSC_SRC OSC_SRC0
+
+#define OSC_0_FREQ 20
+
+#define DCO_HS2_MIN 500
+#define DCO_HS2_MAX 1000
+#define DCO_HS1_MIN 1000
+#define DCO_HS1_MAX 2000
+
+#define SELFREQDCO_HS2 0x00000801
+#define SELFREQDCO_HS1 0x00001001
+
+#define MPU_N 0x1
+#define MPU_M 0x3C
+#define MPU_M2 1
+#define MPU_CLKCTRL 0x1
+
+#define L3_N 19
+#define L3_M 880
+#define L3_M2 4
+#define L3_CLKCTRL 0x801
+
+#define DDR_N 19
+#define DDR_M 666
+#define DDR_M2 2
+#define DDR_CLKCTRL 0x801
+
+/* ADPLLJ register values */
+#define ADPLLJ_CLKCTRL_HS2 0x00000801 /* HS2 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_HS1 0x00001001 /* HS1 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_CLKDCOLDOEN (1 << 29)
+#define ADPLLJ_CLKCTRL_IDLE (1 << 23)
+#define ADPLLJ_CLKCTRL_CLKOUTEN (1 << 20)
+#define ADPLLJ_CLKCTRL_CLKOUTLDOEN (1 << 19)
+#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ (1 << 17)
+#define ADPLLJ_CLKCTRL_LPMODE (1 << 12)
+#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN (1 << 11)
+#define ADPLLJ_CLKCTRL_REGM4XEN (1 << 10)
+#define ADPLLJ_CLKCTRL_TINITZ (1 << 0)
+#define ADPLLJ_CLKCTRL_CLKDCO (ADPLLJ_CLKCTRL_CLKDCOLDOEN | \
+ ADPLLJ_CLKCTRL_CLKOUTEN | \
+ ADPLLJ_CLKCTRL_CLKOUTLDOEN | \
+ ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ)
+
+#define ADPLLJ_STATUS_PHASELOCK (1 << 10)
+#define ADPLLJ_STATUS_FREQLOCK (1 << 9)
+#define ADPLLJ_STATUS_PHSFRQLOCK (ADPLLJ_STATUS_PHASELOCK | \
+ ADPLLJ_STATUS_FREQLOCK)
+#define ADPLLJ_STATUS_BYPASSACK (1 << 8)
+#define ADPLLJ_STATUS_BYPASS (1 << 0)
+#define ADPLLJ_STATUS_BYPASSANDACK (ADPLLJ_STATUS_BYPASSACK | \
+ ADPLLJ_STATUS_BYPASS)
+
+#define ADPLLJ_TENABLE_ENB (1 << 0)
+#define ADPLLJ_TENABLEDIV_ENB (1 << 0)
+
+#define ADPLLJ_M2NDIV_M2SHIFT 16
+
+#define MPU_PLL_BASE (PLL_SUBSYS_BASE + 0x048)
+#define L3_PLL_BASE (PLL_SUBSYS_BASE + 0x110)
+#define DDR_PLL_BASE (PLL_SUBSYS_BASE + 0x290)
+
+struct ad_pll {
+ unsigned int pwrctrl;
+ unsigned int clkctrl;
+ unsigned int tenable;
+ unsigned int tenablediv;
+ unsigned int m2ndiv;
+ unsigned int mn2div;
+ unsigned int fracdiv;
+ unsigned int bwctrl;
+ unsigned int fracctrl;
+ unsigned int status;
+ unsigned int m3div;
+ unsigned int rampctrl;
+};
+
+#define OSC_SRC_CTRL (PLL_SUBSYS_BASE + 0x2C0)
+
+/* PRCM */
+#define CM_DEFAULT_BASE (PRCM_BASE + 0x0500)
+
+struct cm_def {
+ unsigned int resv0[2];
+ unsigned int l3fastclkstctrl;
+ unsigned int resv1[1];
+ unsigned int pciclkstctrl;
+ unsigned int resv2[1];
+ unsigned int ducaticlkstctrl;
+ unsigned int resv3[1];
+ unsigned int emif0clkctrl;
+ unsigned int emif1clkctrl;
+ unsigned int dmmclkctrl;
+ unsigned int fwclkctrl;
+ unsigned int resv4[10];
+ unsigned int usbclkctrl;
+ unsigned int resv5[1];
+ unsigned int sataclkctrl;
+ unsigned int resv6[4];
+ unsigned int ducaticlkctrl;
+ unsigned int pciclkctrl;
+};
+
+#define CM_ALWON_BASE (PRCM_BASE + 0x1400)
+
+struct cm_alwon {
+ unsigned int l3slowclkstctrl;
+ unsigned int ethclkstctrl;
+ unsigned int l3medclkstctrl;
+ unsigned int mmu_clkstctrl;
+ unsigned int mmucfg_clkstctrl;
+ unsigned int ocmc0clkstctrl;
+ unsigned int vcpclkstctrl;
+ unsigned int mpuclkstctrl;
+ unsigned int sysclk4clkstctrl;
+ unsigned int sysclk5clkstctrl;
+ unsigned int sysclk6clkstctrl;
+ unsigned int rtcclkstctrl;
+ unsigned int l3fastclkstctrl;
+ unsigned int resv0[67];
+ unsigned int mcasp0clkctrl;
+ unsigned int mcasp1clkctrl;
+ unsigned int mcasp2clkctrl;
+ unsigned int mcbspclkctrl;
+ unsigned int uart0clkctrl;
+ unsigned int uart1clkctrl;
+ unsigned int uart2clkctrl;
+ unsigned int gpio0clkctrl;
+ unsigned int gpio1clkctrl;
+ unsigned int i2c0clkctrl;
+ unsigned int i2c1clkctrl;
+ unsigned int mcasp345clkctrl;
+ unsigned int atlclkctrl;
+ unsigned int mlbclkctrl;
+ unsigned int pataclkctrl;
+ unsigned int resv1[1];
+ unsigned int uart3clkctrl;
+ unsigned int uart4clkctrl;
+ unsigned int uart5clkctrl;
+ unsigned int wdtimerclkctrl;
+ unsigned int spiclkctrl;
+ unsigned int mailboxclkctrl;
+ unsigned int spinboxclkctrl;
+ unsigned int mmudataclkctrl;
+ unsigned int resv2[2];
+ unsigned int mmucfgclkctrl;
+ unsigned int resv3[2];
+ unsigned int ocmc0clkctrl;
+ unsigned int vcpclkctrl;
+ unsigned int resv4[2];
+ unsigned int controlclkctrl;
+ unsigned int resv5[2];
+ unsigned int gpmcclkctrl;
+ unsigned int ethernet0clkctrl;
+ unsigned int resv6[1];
+ unsigned int mpuclkctrl;
+ unsigned int debugssclkctrl;
+ unsigned int l3clkctrl;
+ unsigned int l4hsclkctrl;
+ unsigned int l4lsclkctrl;
+ unsigned int rtcclkctrl;
+ unsigned int tpccclkctrl;
+ unsigned int tptc0clkctrl;
+ unsigned int tptc1clkctrl;
+ unsigned int tptc2clkctrl;
+ unsigned int tptc3clkctrl;
+ unsigned int resv7[4];
+ unsigned int dcan01clkctrl;
+ unsigned int mmchs0clkctrl;
+ unsigned int mmchs1clkctrl;
+ unsigned int mmchs2clkctrl;
+ unsigned int custefuseclkctrl;
+};
+
+
+const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
+const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
+
+/*
+ * Enable the peripheral clock for required peripherals
+ */
+static void enable_per_clocks(void)
+{
+ /* UART0 */
+ writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
+ while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
+ ;
+
+ /* HSMMC1 */
+ writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl);
+ while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN)
+ ;
+}
+
+/*
+ * select the HS1 or HS2 for DCO Freq
+ * return : CLKCTRL
+ */
+static u32 pll_dco_freq_sel(u32 clkout_dco)
+{
+ if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX)
+ return SELFREQDCO_HS2;
+ else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX)
+ return SELFREQDCO_HS1;
+ else
+ return -1;
+}
+
+/*
+ * select the sigma delta config
+ * return: sigma delta val
+ */
+static u32 pll_sigma_delta_val(u32 clkout_dco)
+{
+ u32 sig_val = 0;
+ float frac_div;
+
+ frac_div = (float) clkout_dco / 250;
+ frac_div = frac_div + 0.90;
+ sig_val = (int)frac_div;
+ sig_val = sig_val << 24;
+
+ return sig_val;
+}
+
+/*
+ * configure individual ADPLLJ
+ */
+static void pll_config(u32 base, u32 n, u32 m, u32 m2,
+ u32 clkctrl_val, int adpllj)
+{
+ const struct ad_pll *adpll = (struct ad_pll *)base;
+ u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0;
+ u32 sig_val = 0, hs_mod = 0;
+
+ m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n;
+ mn2val = m;
+
+ /* calculate clkout_dco */
+ clkout_dco = ((OSC_0_FREQ / (n+1)) * m);
+
+ /* sigma delta & Hs mode selection skip for ADPLLS*/
+ if (adpllj) {
+ sig_val = pll_sigma_delta_val(clkout_dco);
+ hs_mod = pll_dco_freq_sel(clkout_dco);
+ }
+
+ /* by-pass pll */
+ read_clkctrl = readl(&adpll->clkctrl);
+ writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl);
+ while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK)
+ != ADPLLJ_STATUS_BYPASSANDACK)
+ ;
+
+ /* clear TINITZ */
+ read_clkctrl = readl(&adpll->clkctrl);
+ writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+ /*
+ * ref_clk = 20/(n + 1);
+ * clkout_dco = ref_clk * m;
+ * clk_out = clkout_dco/m2;
+ */
+ read_clkctrl = readl(&adpll->clkctrl) &
+ ~(ADPLLJ_CLKCTRL_LPMODE |
+ ADPLLJ_CLKCTRL_DRIFTGUARDIAN |
+ ADPLLJ_CLKCTRL_REGM4XEN);
+ writel(m2nval, &adpll->m2ndiv);
+ writel(mn2val, &adpll->mn2div);
+
+ /* Skip for modena(ADPLLS) */
+ if (adpllj) {
+ writel(sig_val, &adpll->fracdiv);
+ writel((read_clkctrl | hs_mod), &adpll->clkctrl);
+ }
+
+ /* Load M2, N2 dividers of ADPLL */
+ writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+ writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+
+ /* Load M, N dividers of ADPLL */
+ writel(ADPLLJ_TENABLE_ENB, &adpll->tenable);
+ writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable);
+
+ /* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */
+ read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO;
+ if (adpllj)
+ writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO),
+ &adpll->clkctrl);
+
+ /* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */
+ read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE;
+ writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+ /* Wait for phase and freq lock */
+ while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) !=
+ ADPLLJ_STATUS_PHSFRQLOCK)
+ ;
+}
+
+static void unlock_pll_control_mmr(void)
+{
+ /* TRM 2.10.1.4 and 3.2.7-3.2.11 */
+ writel(0x1EDA4C3D, 0x481C5040);
+ writel(0x2FF1AC2B, 0x48140060);
+ writel(0xF757FDC0, 0x48140064);
+ writel(0xE2BC3A6D, 0x48140068);
+ writel(0x1EBF131D, 0x4814006c);
+ writel(0x6F361E05, 0x48140070);
+}
+
+static void mpu_pll_config(void)
+{
+ pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0);
+}
+
+static void l3_pll_config(void)
+{
+ u32 l3_osc_src, rd_osc_src = 0;
+
+ l3_osc_src = L3_OSC_SRC;
+ rd_osc_src = readl(OSC_SRC_CTRL);
+
+ if (OSC_SRC0 == l3_osc_src)
+ writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL);
+ else
+ writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL);
+
+ pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1);
+}
+
+void ddr_pll_config(unsigned int ddrpll_m)
+{
+ pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1);
+}
+
+void enable_emif_clocks(void) {};
+
+void enable_dmm_clocks(void)
+{
+ writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
+ writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
+ writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
+ while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN)
+ ;
+ writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
+ while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN)
+ ;
+ while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
+ ;
+ writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
+ while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN)
+ ;
+ writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
+ while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
+ ;
+}
+
+/*
+ * Configure the PLL/PRCM for necessary peripherals
+ */
+void pll_init()
+{
+ unlock_pll_control_mmr();
+
+ /* Enable the control module */
+ writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
+
+ mpu_pll_config();
+
+ l3_pll_config();
+
+ /* Enable the required peripherals */
+ enable_per_clocks();
+}
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
index 448cc4015..d1e2fd3f2 100644
--- a/arch/arm/cpu/armv7/am33xx/ddr.c
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -24,15 +24,20 @@ http://www.ti.com/
/**
* Base address for EMIF instances
*/
-static struct emif_reg_struct *emif_reg = {
- (struct emif_reg_struct *)EMIF4_0_CFG_BASE};
+static struct emif_reg_struct *emif_reg[2] = {
+ (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
+ (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
/**
- * Base address for DDR instance
+ * Base addresses for DDR PHY cmd/data regs
*/
-static struct ddr_regs *ddr_reg[2] = {
- (struct ddr_regs *)DDR_PHY_BASE_ADDR,
- (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
+static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
+ (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
+ (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+
+static struct ddr_data_regs *ddr_data_reg[2] = {
+ (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
+ (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
/**
* Base address for ddr io control instances
@@ -43,7 +48,7 @@ static struct ddr_cmdtctrl *ioctrl_reg = {
/**
* Configure SDRAM
*/
-void config_sdram(const struct emif_regs *regs)
+void config_sdram(const struct emif_regs *regs, int nr)
{
if (regs->zq_config) {
/*
@@ -51,68 +56,85 @@ void config_sdram(const struct emif_regs *regs)
* about 570us for a delay, which will be long enough
* to configure things.
*/
- writel(0x2800, &emif_reg->emif_sdram_ref_ctrl);
- writel(regs->zq_config, &emif_reg->emif_zq_config);
+ writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl);
+ writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+ writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+ writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+ writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
}
- writel(regs->sdram_config, &emif_reg->emif_sdram_config);
- writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl);
- writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl_shdw);
+ writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+ writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+ writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
}
/**
* Set SDRAM timings
*/
-void set_sdram_timings(const struct emif_regs *regs)
+void set_sdram_timings(const struct emif_regs *regs, int nr)
{
- writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1);
- writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1_shdw);
- writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2);
- writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2_shdw);
- writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3);
- writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3_shdw);
+ writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1);
+ writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw);
+ writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2);
+ writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw);
+ writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3);
+ writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
}
/**
* Configure DDR PHY
*/
-void config_ddr_phy(const struct emif_regs *regs)
+void config_ddr_phy(const struct emif_regs *regs, int nr)
{
- writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1);
- writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1_shdw);
+ writel(regs->emif_ddr_phy_ctlr_1,
+ &emif_reg[nr]->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_ddr_phy_ctlr_1,
+ &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
}
/**
* Configure DDR CMD control registers
*/
-void config_cmd_ctrl(const struct cmd_control *cmd)
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
{
- writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
- writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
- writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
+ writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
+ writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff);
+ writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
- writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
- writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
- writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
+ writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
+ writel(cmd->cmd1dldiff, &ddr_cmd_reg[nr]->cm1dldiff);
+ writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
- writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
- writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
- writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
+ writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
+ writel(cmd->cmd2dldiff, &ddr_cmd_reg[nr]->cm2dldiff);
+ writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
}
/**
* Configure DDR DATA registers
*/
-void config_ddr_data(int macrono, const struct ddr_data *data)
+void config_ddr_data(const struct ddr_data *data, int nr)
{
- writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0);
- writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0);
- writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0);
- writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0);
- writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0);
- writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0);
- writel(data->datauserank0delay, &ddr_reg[macrono]->dt0rdelays0);
- writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0);
+ int i;
+
+ for (i = 0; i < DDR_DATA_REGS_NR; i++) {
+ writel(data->datardsratio0,
+ &(ddr_data_reg[nr]+i)->dt0rdsratio0);
+ writel(data->datawdsratio0,
+ &(ddr_data_reg[nr]+i)->dt0wdsratio0);
+ writel(data->datawiratio0,
+ &(ddr_data_reg[nr]+i)->dt0wiratio0);
+ writel(data->datagiratio0,
+ &(ddr_data_reg[nr]+i)->dt0giratio0);
+ writel(data->datafwsratio0,
+ &(ddr_data_reg[nr]+i)->dt0fwsratio0);
+ writel(data->datawrsratio0,
+ &(ddr_data_reg[nr]+i)->dt0wrsratio0);
+ writel(data->datauserank0delay,
+ &(ddr_data_reg[nr]+i)->dt0rdelays0);
+ writel(data->datadldiff0,
+ &(ddr_data_reg[nr]+i)->dt0dldiff0);
+ }
}
void config_io_ctrl(unsigned long val)
diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c
index 9eed23d75..41df61295 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/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c
index 01e3a5204..aa84e9617 100644
--- a/arch/arm/cpu/armv7/am33xx/emif4.c
+++ b/arch/arm/cpu/armv7/am33xx/emif4.c
@@ -44,44 +44,65 @@ void dram_init_banksize(void)
#ifdef CONFIG_SPL_BUILD
-static struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+static struct dmm_lisa_map_regs *hw_lisa_map_regs =
+ (struct dmm_lisa_map_regs *)DMM_BASE;
+static struct vtp_reg *vtpreg[2] = {
+ (struct vtp_reg *)VTP0_CTRL_ADDR,
+ (struct vtp_reg *)VTP1_CTRL_ADDR};
+#ifdef CONFIG_AM33XX
static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+#endif
+
+void config_dmm(const struct dmm_lisa_map_regs *regs)
+{
+ enable_dmm_clocks();
+
+ writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
+ writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
+ writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
+ writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
-static void config_vtp(void)
+ writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3);
+ writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2);
+ writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1);
+ writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0);
+}
+
+static void config_vtp(int nr)
{
- writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
- &vtpreg->vtp0ctrlreg);
- writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
- &vtpreg->vtp0ctrlreg);
- writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
- &vtpreg->vtp0ctrlreg);
+ writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+ &vtpreg[nr]->vtp0ctrlreg);
+ writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
+ &vtpreg[nr]->vtp0ctrlreg);
+ writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN,
+ &vtpreg[nr]->vtp0ctrlreg);
/* Poll for READY */
- while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+ while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) !=
VTP_CTRL_READY)
;
}
void config_ddr(unsigned int pll, unsigned int ioctrl,
const struct ddr_data *data, const struct cmd_control *ctrl,
- const struct emif_regs *regs)
+ const struct emif_regs *regs, int nr)
{
enable_emif_clocks();
ddr_pll_config(pll);
- config_vtp();
- config_cmd_ctrl(ctrl);
-
- config_ddr_data(0, data);
- config_ddr_data(1, data);
+ config_vtp(nr);
+ config_cmd_ctrl(ctrl, nr);
+ config_ddr_data(data, nr);
+#ifdef CONFIG_AM33XX
config_io_ctrl(ioctrl);
/* Set CKE to be controlled by EMIF/DDR PHY */
writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+#endif
/* Program EMIF instance */
- config_ddr_phy(regs);
- set_sdram_timings(regs);
- config_sdram(regs);
+ config_ddr_phy(regs, nr);
+ set_sdram_timings(regs, nr);
+ config_sdram(regs, nr);
}
#endif
diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c
index b8f54abae..b86b0ded3 100644
--- a/arch/arm/cpu/armv7/am33xx/mem.c
+++ b/arch/arm/cpu/armv7/am33xx/mem.c
@@ -83,7 +83,7 @@ void gpmc_init(void)
/* global settings */
writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000100, &gpmc_cfg->irqstatus);
- writel(0x00000200, &gpmc_cfg->irqenable);
+ writel(0x00000100, &gpmc_cfg->irqenable);
writel(0x00000012, &gpmc_cfg->config);
/*
* Disable the GPMC0 config set by ROM code
diff --git a/arch/arm/cpu/armv7/am33xx/sys_info.c b/arch/arm/cpu/armv7/am33xx/sys_info.c
index 507b6180e..5fd8b47b2 100644
--- a/arch/arm/cpu/armv7/am33xx/sys_info.c
+++ b/arch/arm/cpu/armv7/am33xx/sys_info.c
@@ -98,6 +98,9 @@ int print_cpuinfo(void)
case AM335X:
cpu_s = "AM335X";
break;
+ case TI81XX:
+ cpu_s = "TI81XX";
+ break;
default:
cpu_s = "Unknown cpu type";
break;
@@ -120,7 +123,7 @@ int print_cpuinfo(void)
sec_s = "?";
}
- printf("AM%s-%s rev %d\n",
+ printf("%s-%s rev %d\n",
cpu_s, sec_s, get_cpu_rev());
/* TODO: Print ARM and DDR frequencies */
diff --git a/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds b/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
index 69f6d48da..b6a929ff7 100644
--- a/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
+++ b/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
@@ -62,6 +62,6 @@ SECTIONS
__bss_start = .;
*(.bss*)
. = ALIGN(4);
- __bss_end__ = .;
+ __bss_end = .;
} >.sdram
}
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 5f6d0396f..8748c145c 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
{
}
+void arm_init_domains(void)
+{
+}
#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF
diff --git a/arch/arm/cpu/armv7/config.mk b/arch/arm/cpu/armv7/config.mk
index 9c3e2f3ce..56b805377 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 956427c9e..223660aab 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/power.c b/arch/arm/cpu/armv7/exynos/power.c
index d4bce6d4d..6375a81fd 100644
--- a/arch/arm/cpu/armv7/exynos/power.c
+++ b/arch/arm/cpu/armv7/exynos/power.c
@@ -95,3 +95,48 @@ void set_dp_phy_ctrl(unsigned int enable)
if (cpu_is_exynos5())
exynos5_dp_phy_control(enable);
}
+
+static void exynos5_set_ps_hold_ctrl(void)
+{
+ struct exynos5_power *power =
+ (struct exynos5_power *)samsung_get_base_power();
+
+ /* Set PS-Hold high */
+ setbits_le32(&power->ps_hold_control,
+ EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
+}
+
+void set_ps_hold_ctrl(void)
+{
+ if (cpu_is_exynos5())
+ exynos5_set_ps_hold_ctrl();
+}
+
+
+static void exynos5_set_xclkout(void)
+{
+ struct exynos5_power *power =
+ (struct exynos5_power *)samsung_get_base_power();
+
+ /* use xxti for xclk out */
+ clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
+ PMU_DEBUG_XXTI);
+}
+
+void set_xclkout(void)
+{
+ if (cpu_is_exynos5())
+ exynos5_set_xclkout();
+}
+
+/* Enables hardware tripping to power off the system when TMU fails */
+void set_hw_thermal_trip(void)
+{
+ if (cpu_is_exynos5()) {
+ struct exynos5_power *power =
+ (struct exynos5_power *)samsung_get_base_power();
+
+ /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
+ setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
+ }
+}
diff --git a/arch/arm/cpu/armv7/exynos/soc.c b/arch/arm/cpu/armv7/exynos/soc.c
index ab65b8d3a..e948e4c63 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 6d9396a97..dfce0ca83 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/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 0efc80dde..55e82ba36 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -36,7 +36,7 @@ COBJS += emif-common.o
COBJS += vc.o
endif
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
COBJS += boot-common.o
SOBJS += lowlevel_init.o
endif
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 9ed18995e..2b955c7c0 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 9eb1279d4..cdb443972 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/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 05ff2e868..70d16a816 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -34,6 +34,12 @@
#include <asm/emif.h>
#include <asm/omap_common.h>
#include <linux/compiler.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define ARMV7_DCACHE_WRITEBACK 0xe
+#define ARMV7_DOMAIN_CLIENT 1
+#define ARMV7_DOMAIN_MASK (0x3 << 0)
DECLARE_GLOBAL_DATA_PTR;
@@ -269,4 +275,33 @@ void enable_caches(void)
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
+
+void dram_bank_mmu_setup(int bank)
+{
+ bd_t *bd = gd->bd;
+ int i;
+
+ u32 start = bd->bi_dram[bank].start >> 20;
+ u32 size = bd->bi_dram[bank].size >> 20;
+ u32 end = start + size;
+
+ debug("%s: bank: %d\n", __func__, bank);
+ for (i = start; i < end; i++)
+ set_section_dcache(i, ARMV7_DCACHE_WRITEBACK);
+
+}
+
+void arm_init_domains(void)
+{
+ u32 reg;
+
+ reg = get_dacr();
+ /*
+ * Set DOMAIN to client access so that all permissions
+ * set in pagetables are validated by the mmu.
+ */
+ reg &= ~ARMV7_DOMAIN_MASK;
+ reg |= ARMV7_DOMAIN_CLIENT;
+ set_dacr(reg);
+}
#endif
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 358107776..90b3c8aea 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -26,6 +26,7 @@
* MA 02111-1307 USA
*/
+#include <config.h>
#include <asm/arch/omap.h>
#include <asm/arch/spl.h>
#include <linux/linkage.h>
@@ -59,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/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c
index 36bea5f94..507f6873e 100644
--- a/arch/arm/cpu/armv7/omap-common/timer.c
+++ b/arch/arm/cpu/armv7/omap-common/timer.c
@@ -34,6 +34,7 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/arch/cpu.h>
DECLARE_GLOBAL_DATA_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 88f40698b..bd218c07d 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
@@ -58,6 +58,6 @@ SECTIONS
__bss_start = .;
*(.bss*)
. = ALIGN(4);
- __bss_end__ = .;
+ __bss_end = .;
} >.sdram
}
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index c6d9a425a..b72fadc25 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 3c8011350..08a63d266 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 ca4823dd7..53f60635b 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 7551b9861..04977b4f2 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 8019ffe3d..3f37abdf8 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 44d7bc360..6f401b8d9 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 e78c716d3..6a0fa5862 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,48 +76,43 @@ 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;
+
+ /* Divide by 1000 to convert from us to ms */
+ return gd->arch.timer_reset_value / 1000 - base;
}
-/* delay x useconds */
-void __udelay(unsigned long usec)
+unsigned long timer_get_us(void)
{
- struct s5p_timer *const timer = s5p_get_base_timer();
- unsigned long tmo, tmp, count_value;
+ static unsigned long base_time_us;
- count_value = readl(&timer->tcntb4);
+ struct s5p_timer *const timer =
+ (struct s5p_timer *)samsung_get_base_timer();
+ unsigned long now_downward_us = readl(&timer->tcnto4);
- 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);
- }
+ if (!base_time_us)
+ base_time_us = now_downward_us;
- /* get current timestamp */
- tmp = get_current_tick();
+ /* Note that this timer counts downward. */
+ return base_time_us - now_downward_us;
+}
- /* 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;
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+ unsigned long count_value;
- /* loop till event */
- while (get_current_tick() < tmo)
- ; /* nop */
+ count_value = timer_get_us_down();
+ while ((int)(count_value - timer_get_us_down()) < (int)usec)
+ ;
}
void reset_timer_masked(void)
@@ -109,30 +124,6 @@ void reset_timer_masked(void)
gd->arch.tbl = 0;
}
-unsigned long get_timer_masked(void)
-{
- struct s5p_timer *const timer = s5p_get_base_timer();
- unsigned long count_value = readl(&timer->tcntb4);
-
- return get_current_tick() / count_value;
-}
-
-unsigned long get_current_tick(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;
-}
-
/*
* This function is derived from PowerPC code (read timebase as long long).
* On ARM it just returns the timer value.
diff --git a/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds b/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
index 7cd409cca..15f8c01a9 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
@@ -46,7 +46,7 @@ SECTIONS
__bss_start = .;
*(.bss*)
. = ALIGN(4);
- __bss_end__ = .;
+ __bss_end = .;
} >.sdram
. = ALIGN(8);
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 30f02d394..61da7acde 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,13 +94,13 @@ _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:
- .word __bss_end__ - _start
+ .word __bss_end - _start
.globl _end_ofs
_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 */
@@ -254,7 +252,6 @@ ENTRY(c_runtime_cpu_setup)
#if !defined(CONFIG_TEGRA)
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
- add r0, r0, r9
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif /* !Tegra */
@@ -310,6 +307,12 @@ ENTRY(cpu_init_cp15)
#endif
mcr p15, 0, r0, c1, c0, 0
+#ifdef CONFIG_ARM_ERRATA_716044
+ mrc p15, 0, r0, c1, c0, 0 @ read system control register
+ orr r0, r0, #1 << 11 @ set bit #11
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+#endif
+
#ifdef CONFIG_ARM_ERRATA_742230
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 4 @ set bit #4
@@ -460,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