diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c b/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c index 60a84ef..5371be6 100644 --- a/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c +++ b/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6q_nitrogen6x_start - get_runtime_offset(); @@ -22,7 +23,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6dl_nitrogen6x_start - get_runtime_offset(); diff --git a/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c b/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c index b1ce4e9..914c275 100644 --- a/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c +++ b/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c @@ -21,6 +21,7 @@ #include #include #include +#include static void sdram_init(void) { @@ -142,7 +143,7 @@ unsigned long sdram = 0x10000000; void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00940000 - 8); diff --git a/arch/arm/boards/dfi-fs700-m60/lowlevel.c b/arch/arm/boards/dfi-fs700-m60/lowlevel.c index 541e6c1..81b3530 100644 --- a/arch/arm/boards/dfi-fs700-m60/lowlevel.c +++ b/arch/arm/boards/dfi-fs700-m60/lowlevel.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -106,7 +107,7 @@ void *fdt; int i; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00940000 - 8); @@ -125,7 +126,7 @@ void *fdt; int i; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00940000 - 8); @@ -148,7 +149,7 @@ void *fdt; int i; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c index 64edd61..c4ef287 100644 --- a/arch/arm/boards/embest-riotboard/lowlevel.c +++ b/arch/arm/boards/embest-riotboard/lowlevel.c @@ -30,7 +30,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); if (IS_ENABLED(CONFIG_DEBUG_LL)) { writel(0x4, 0x020e016c); diff --git a/arch/arm/boards/freescale-mx6-arm2/lowlevel.c b/arch/arm/boards/freescale-mx6-arm2/lowlevel.c index 53783bb..5676711 100644 --- a/arch/arm/boards/freescale-mx6-arm2/lowlevel.c +++ b/arch/arm/boards/freescale-mx6-arm2/lowlevel.c @@ -2,9 +2,10 @@ #include #include #include +#include void __naked barebox_arm_reset_vector(void) { - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); barebox_arm_entry(0x10000000, SZ_2G, NULL); } diff --git a/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c b/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c index a154381..1b47965 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6q_sabrelite_start - get_runtime_offset(); @@ -22,7 +23,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6dl_sabrelite_start - get_runtime_offset(); diff --git a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c index 325de84..bf18459 100644 --- a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c +++ b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6q_sabresd_start - get_runtime_offset(); diff --git a/arch/arm/boards/gk802/lowlevel.c b/arch/arm/boards/gk802/lowlevel.c index bfedfb6..de744a2 100644 --- a/arch/arm/boards/gk802/lowlevel.c +++ b/arch/arm/boards/gk802/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6q_gk802_start - get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c index daf9709..02de84c 100644 --- a/arch/arm/boards/guf-santaro/lowlevel.c +++ b/arch/arm/boards/guf-santaro/lowlevel.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -33,7 +34,7 @@ void *fdt; int i; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c index 64312b0..b31638c 100644 --- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c @@ -59,7 +59,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c index 0159d9f..55aae00 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c @@ -61,7 +61,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); @@ -77,7 +77,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); @@ -93,7 +93,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); @@ -106,7 +106,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); @@ -119,7 +119,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/boards/solidrun-hummingboard/lowlevel.c b/arch/arm/boards/solidrun-hummingboard/lowlevel.c index 8710d85..eb52838 100644 --- a/arch/arm/boards/solidrun-hummingboard/lowlevel.c +++ b/arch/arm/boards/solidrun-hummingboard/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6dl_hummingboard_start - get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_512M, fdt); diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c index aed95e6..d2eea16 100644 --- a/arch/arm/boards/tqma6x/lowlevel.c +++ b/arch/arm/boards/tqma6x/lowlevel.c @@ -45,7 +45,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); @@ -66,7 +66,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/boards/udoo/lowlevel.c b/arch/arm/boards/udoo/lowlevel.c index 5eac7a3..3d9fc68 100644 --- a/arch/arm/boards/udoo/lowlevel.c +++ b/arch/arm/boards/udoo/lowlevel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -9,7 +10,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); fdt = __dtb_imx6q_udoo_start - get_runtime_offset(); diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c index a2c0874..74f3a77 100644 --- a/arch/arm/boards/variscite-mx6/lowlevel.c +++ b/arch/arm/boards/variscite-mx6/lowlevel.c @@ -61,7 +61,7 @@ { void *fdt; - arm_cpu_lowlevel_init(); + imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); diff --git a/arch/arm/include/asm/errata.h b/arch/arm/include/asm/errata.h new file mode 100644 index 0000000..e2ffd87 --- /dev/null +++ b/arch/arm/include/asm/errata.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 Lucas Stach, Pengutronix + * + * 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. + */ + +static inline void enable_arm_errata_716044_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c1, c0, 0\n" + "orr r0, r0, #1 << 11\n" + "mcr p15, 0, r0, c1, c0, 0\n" + ); +} + +static inline void enable_arm_errata_742230_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c15, c0, 1\n" + "orr r0, r0, #1 << 4\n" + "mcr p15, 0, r0, c15, c0, 1\n" + ); +} + +static inline void enable_arm_errata_743622_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c15, c0, 1\n" + "orr r0, r0, #1 << 6\n" + "mcr p15, 0, r0, c15, c0, 1\n" + ); +} + +static inline void enable_arm_errata_751472_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c15, c0, 1\n" + "orr r0, r0, #1 << 11\n" + "mcr p15, 0, r0, c15, c0, 1\n" + ); +} + +static inline void enable_arm_errata_761320_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c15, c0, 1\n" + "orr r0, r0, #1 << 21\n" + "mcr p15, 0, r0, c15, c0, 1\n" + ); +} + +static inline void enable_arm_errata_794072_war(void) +{ + __asm__ __volatile__ ( + "mrc p15, 0, r0, c15, c0, 1\n" + "orr r0, r0, #1 << 4\n" + "mcr p15, 0, r0, c15, c0, 1\n" + ); +} diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 03e5b10..1d311a4 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_BAREBOX_UPDATE_IMX_EXTERNAL_NAND) += imx-bbu-external-nand.o obj-$(CONFIG_BAREBOX_UPDATE_IMX6_NAND) += imx6-bbu-nand.o pbl-y += esdctl.o +lwl-y += cpu_init.o diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c new file mode 100644 index 0000000..68eacf7 --- /dev/null +++ b/arch/arm/mach-imx/cpu_init.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Lucas Stach, Pengutronix + * + * 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 +#include + +void imx6_cpu_lowlevel_init(void) +{ + arm_cpu_lowlevel_init(); + + enable_arm_errata_742230_war(); + enable_arm_errata_743622_war(); + enable_arm_errata_751472_war(); + enable_arm_errata_761320_war(); + enable_arm_errata_794072_war(); +} diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index 506b1da..505a542 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -33,6 +33,8 @@ int imx53_devices_init(void); int imx6_devices_init(void); +void imx6_cpu_lowlevel_init(void); + /* There's a off-by-one betweem the gpio bank number and the gpiochip */ /* range e.g. GPIO_1_5 is gpio 5 under linux */ #define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) diff --git a/arch/arm/mach-tegra/tegra_maincomplex_init.c b/arch/arm/mach-tegra/tegra_maincomplex_init.c index 17490a4..4a362dd 100644 --- a/arch/arm/mach-tegra/tegra_maincomplex_init.c +++ b/arch/arm/mach-tegra/tegra_maincomplex_init.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,23 @@ arm_cpu_lowlevel_init(); + chiptype = tegra_get_chiptype(); + + /* enable ARM errata workarounds early */ + switch (chiptype) { + case TEGRA20: + enable_arm_errata_716044_war(); + enable_arm_errata_742230_war(); + enable_arm_errata_751472_war(); + break; + case TEGRA30: + enable_arm_errata_743622_war(); + enable_arm_errata_751472_war(); + break; + default: + break; + } + /* switch to PLLX */ writel(CRC_CCLK_BURST_POLICY_SYS_STATE_RUN << CRC_CCLK_BURST_POLICY_SYS_STATE_SHIFT | @@ -38,8 +56,6 @@ TEGRA_CLK_RESET_BASE + CRC_CCLK_BURST_POLICY); writel(CRC_SUPER_CDIV_ENB, TEGRA_CLK_RESET_BASE + CRC_SUPER_CCLK_DIV); - chiptype = tegra_get_chiptype(); - if (chiptype >= TEGRA114) { asm("mrc p15, 1, %0, c9, c0, 2" : : "r" (reg)); reg &= ~7; @@ -51,6 +67,7 @@ case TEGRA20: rambase = 0x0; ramsize = tegra20_get_ramsize(); + break; case TEGRA30: case TEGRA124: