#include <common.h>
#include <asm/armv7.h>
+#include <asm/bootm.h>
#include <asm/pl310.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <stdbool.h>
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
+#include <asm/bootm.h>
+#include <dm.h>
+#include <imx_thermal.h>
enum ldo_reg {
LDO_ARM,
u32 fpga_rev;
};
+#if defined(CONFIG_IMX6_THERMAL)
+static const struct imx_thermal_plat imx6_thermal_plat = {
+ .regs = (void *)ANATOP_BASE_ADDR,
+ .fuse_bank = 1,
+ .fuse_word = 6,
+};
+
+U_BOOT_DEVICE(imx6_thermal) = {
+ .name = "imx_thermal",
+ .platdata = &imx6_thermal_plat,
+};
+#endif
+
+u32 get_nr_cpus(void)
+{
+ struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
+ return readl(&scu->config) & 3;
+}
+
u32 get_cpu_rev(void)
{
struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR;
aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR;
#ifdef CONFIG_MX6SX
- aips3 = (struct aipstz_regs *)AIPS3_BASE_ADDR;
+ aips3 = (struct aipstz_regs *)AIPS3_CONFIG_BASE_ADDR;
#endif
/*
struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
+#ifdef CONFIG_MX6SX
+ struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR;
+ writew(enable, &wdog3->wmcr);
+#endif
+
/* Write to the PDE (Power Down Enable) bit */
writew(enable, &wdog1->wmcr);
writew(enable, &wdog2->wmcr);
writel(0, &mxc_ccm->ccdr);
}
+static void init_bandgap(void)
+{
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ /*
+ * Ensure the bandgap has stabilized.
+ */
+ while (!(readl(&anatop->ana_misc0) & 0x80))
+ ;
+ /*
+ * For best noise performance of the analog blocks using the
+ * outputs of the bandgap, the reftop_selfbiasoff bit should
+ * be set.
+ */
+ writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
+}
+
+
+#ifdef CONFIG_MX6SL
+static void set_preclk_from_osc(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ u32 reg;
+
+ reg = readl(&mxc_ccm->cscmr1);
+ reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK;
+ writel(reg, &mxc_ccm->cscmr1);
+}
+#endif
+
int arch_cpu_init(void)
{
init_aips();
/* Need to clear MMDC_CHx_MASK to make warm reset work. */
clear_mmdc_ch_mask();
+ /*
+ * Disable self-bias circuit in the analog bandap.
+ * The self-bias circuit is used by the bandgap during startup.
+ * This bit should be set after the bandgap has initialized.
+ */
+ init_bandgap();
+
/*
* When low freq boot is enabled, ROM will not set AHB
* freq, so we need to ensure AHB freq is 132MHz in such
if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
set_ahb_rate(132000000);
+ /* Set perclk to source from OSC 24MHz */
+#if defined(CONFIG_MX6SL)
+ set_preclk_from_osc();
+#endif
+
imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
#ifdef CONFIG_APBH_DMA
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+ enum dcache_option option = DCACHE_WRITETHROUGH;
+#else
+ enum dcache_option option = DCACHE_WRITEBACK;
+#endif
+
/* Avoid random hang when download by usb */
invalidate_dcache_all();
+
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
+
+ /* Enable caching on OCRAM and ROM */
+ mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
+ ROMCP_ARB_END_ADDR,
+ option);
+ mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
+ IRAM_SIZE,
+ option);
}
#endif
/*
* cfg_val will be used for
* Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
- * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
- * to SBMR1, which will determine the boot device.
+ * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0]
+ * instead of SBMR1 to determine the boot device.
*/
const struct boot_mode soc_boot_modes[] = {
{"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
/* reserved value should start rom usb */
{"usb", MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)},
{"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
- {"escpi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
- {"escpi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
- {"escpi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
- {"escpi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
+ {"ecspi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
+ {"ecspi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
+ {"ecspi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
+ {"ecspi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
/* 4 bit bus width */
{"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
{"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
void s_init(void)
{
struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
- int is_6q = is_cpu_type(MXC_CPU_MX6Q);
+ struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
u32 mask480;
u32 mask528;
-
+ u32 reg, periph1, periph2;
if (is_cpu_type(MXC_CPU_MX6SX))
return;
ANATOP_PFD_CLKGATE_MASK(1) |
ANATOP_PFD_CLKGATE_MASK(2) |
ANATOP_PFD_CLKGATE_MASK(3);
- mask528 = ANATOP_PFD_CLKGATE_MASK(0) |
- ANATOP_PFD_CLKGATE_MASK(1) |
+ mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
ANATOP_PFD_CLKGATE_MASK(3);
- /*
- * Don't reset PFD2 on DL/S
- */
- if (is_6q)
+ reg = readl(&ccm->cbcmr);
+ periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
+ >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
+ periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
+ >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
+
+ /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
+ if ((periph2 != 0x2) && (periph1 != 0x2))
+ mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
+
+ if ((periph2 != 0x1) && (periph1 != 0x1) &&
+ (periph2 != 0x3) && (periph1 != 0x3))
mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
+
writel(mask480, &anatop->pfd_480_set);
writel(mask528, &anatop->pfd_528_set);
writel(mask480, &anatop->pfd_480_clr);
}
#endif
+ /* Must disable the L2 before changing the latency parameters */
+ clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+
writel(0x132, &pl310->pl310_tag_latency_ctrl);
writel(0x132, &pl310->pl310_data_latency_ctrl);