diff options
Diffstat (limited to 'arch')
120 files changed, 3195 insertions, 222 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 50f30958ba..d836f66854 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -158,6 +158,7 @@ config ARCH_ROCKCHIP select GPIOLIB select PINCTRL select PINCTRL_ROCKCHIP + select OFTREE select HAVE_PBL_MULTI_IMAGES select HAS_DEBUG_LL select ARCH_HAS_L2X0 @@ -278,7 +279,7 @@ config AEABI config THUMB2_BAREBOX select ARM_ASM_UNIFIED select AEABI - depends on !ARCH_TEGRA + depends on !ARCH_TEGRA && !ARCH_AT91 depends on CPU_V7 && !CPU_32v4T && !CPU_32v5 && !CPU_32v6 bool "Compile barebox in thumb-2 mode (read help)" help diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index d6fc17cc25..013229db71 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_MACH_AT91SAM9X5EK) += at91sam9x5ek/ obj-$(CONFIG_MACH_BEAGLE) += beagle/ obj-$(CONFIG_MACH_BEAGLEBONE) += beaglebone/ obj-$(CONFIG_MACH_CANON_A1100) += canon-a1100/ +obj-$(CONFIG_MACH_CM_FX6) += cm-fx6/ obj-$(CONFIG_MACH_NITROGEN6X) += boundarydevices-nitrogen6x/ obj-$(CONFIG_MACH_CCMX51) += ccxmx51/ obj-$(CONFIG_MACH_CFA10036) += crystalfontz-cfa10036/ diff --git a/arch/arm/boards/animeo_ip/init.c b/arch/arm/boards/animeo_ip/init.c index 0fda01363c..2069ab3764 100644 --- a/arch/arm/boards/animeo_ip/init.c +++ b/arch/arm/boards/animeo_ip/init.c @@ -346,6 +346,7 @@ static void animeo_ip_shutdown(void) animeo_ip_shutdown_uart(IOMEM(AT91SAM9260_BASE_US0)); animeo_ip_shutdown_uart(IOMEM(AT91SAM9260_BASE_US1)); } +postdevshutdown_exitcall(animeo_ip_shutdown); static int animeo_ip_console_init(void) { @@ -353,7 +354,6 @@ static int animeo_ip_console_init(void) usart0 = at91_register_uart(1, ATMEL_UART_RTS); usart1 = at91_register_uart(2, ATMEL_UART_RTS); - board_shutdown = animeo_ip_shutdown; barebox_set_model("Somfy Animeo IP"); barebox_set_hostname("animeoip"); diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c index 5e569bcc9a..c866043e8b 100644 --- a/arch/arm/boards/chumby_falconwing/falconwing.c +++ b/arch/arm/boards/chumby_falconwing/falconwing.c @@ -83,7 +83,7 @@ static struct imx_fb_platformdata fb_mode = { .mode_list = &falconwing_vmode, .mode_cnt = 1, /* the NMA35 is a 24 bit display, but only 18 bits are connected */ - .ld_intf_width = STMLCDIF_18BIT, + .ld_intf_width = 18, .enable = chumby_fb_enable, .fixed_screen = (void *)(0x40000000 + SZ_64M - MAX_FB_SIZE), .fixed_screen_size = MAX_FB_SIZE, diff --git a/arch/arm/boards/cm-fx6/Makefile b/arch/arm/boards/cm-fx6/Makefile new file mode 100644 index 0000000000..3a773bbf7b --- /dev/null +++ b/arch/arm/boards/cm-fx6/Makefile @@ -0,0 +1,3 @@ +obj-y += board.o +extra-y += flash-header-mx6-cm-fx6.dcd.S flash-header-mx6-cm-fx6.dcd +lwl-y += lowlevel.o diff --git a/arch/arm/boards/cm-fx6/board.c b/arch/arm/boards/cm-fx6/board.c new file mode 100644 index 0000000000..edef18f8ac --- /dev/null +++ b/arch/arm/boards/cm-fx6/board.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2015 Sascha Hauer, 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 <common.h> +#include <init.h> +#include <environment.h> +#include <mach/imx6-regs.h> +#include <mach/bbu.h> +#include <asm/armlinux.h> +#include <linux/phy.h> +#include <mach/generic.h> +#include <linux/sizes.h> +#include <mach/imx6.h> +#include <net.h> + +static int phy_fixup(struct phy_device *phydev) +{ + unsigned short val; + + /* Ar8031 phy SmartEEE feature cause link status generates glitch, + * which cause ethernet link down/up issue, so disable SmartEEE + */ + phy_write(phydev, 0xd, 0x3); + phy_write(phydev, 0xe, 0x805d); + phy_write(phydev, 0xd, 0x4003); + val = phy_read(phydev, 0xe); + val &= ~(0x1 << 8); + phy_write(phydev, 0xe, val); + + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ + phy_write(phydev, 0xd, 0x7); + phy_write(phydev, 0xe, 0x8016); + phy_write(phydev, 0xd, 0x4007); + + val = phy_read(phydev, 0xe); + val &= 0xffe3; + val |= 0x18; + phy_write(phydev, 0xe, val); + + /* introduce tx clock delay */ + phy_write(phydev, 0x1d, 0x5); + val = phy_read(phydev, 0x1e); + val |= 0x0100; + phy_write(phydev, 0x1e, val); + + return 0; +} + +#define PHY_ID_AR8031 0x004dd074 + +static int cm_fx6_eeprom_init(void) +{ + struct cdev *cdev; + u8 mac[6]; + int ret; + + if (!of_machine_is_compatible("compulab,cm-fx6")) + return 0; + + cdev = cdev_by_name("eeprom0"); + if (!cdev) + return -ENODEV; + + ret = cdev_read(cdev, mac, 6, 4, 0); + if (ret < 0) + return ret; + + eth_register_ethaddr(0, mac); + + return 0; +} +late_initcall(cm_fx6_eeprom_init); + +static int cm_fx6_devices_init(void) +{ + if (!of_machine_is_compatible("compulab,cm-fx6")) + return 0; + + if (IS_ENABLED(CONFIG_PHYLIB)) + phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, phy_fixup); + + imx6_bbu_internal_spi_i2c_register_handler("spiflash", "/dev/m25p0", + BBU_HANDLER_FLAG_DEFAULT); + + return 0; +} +coredevice_initcall(cm_fx6_devices_init); diff --git a/arch/arm/boards/cm-fx6/flash-header-mx6-cm-fx6.imxcfg b/arch/arm/boards/cm-fx6/flash-header-mx6-cm-fx6.imxcfg new file mode 100644 index 0000000000..400a870154 --- /dev/null +++ b/arch/arm/boards/cm-fx6/flash-header-mx6-cm-fx6.imxcfg @@ -0,0 +1,3 @@ +soc imx6 +loadaddr 0x00907000 +dcdofs 0x400 diff --git a/arch/arm/boards/cm-fx6/lowlevel.c b/arch/arm/boards/cm-fx6/lowlevel.c new file mode 100644 index 0000000000..fd86e159aa --- /dev/null +++ b/arch/arm/boards/cm-fx6/lowlevel.c @@ -0,0 +1,369 @@ +#define pr_fmt(fmt) "cm-fx6: " fmt + +#include <common.h> +#include <linux/sizes.h> +#include <mach/generic.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <debug_ll.h> +#include <io.h> +#include <mach/imx6-mmdc.h> +#include <mach/imx6-ddr-regs.h> +#include <mach/imx6.h> +#include <mach/xload.h> +#include <mach/esdctl.h> +#include <serial/imx-uart.h> + +enum ddr_config { + DDR_16BIT_256MB, + DDR_32BIT_512MB, + DDR_32BIT_1GB, + DDR_64BIT_1GB, + DDR_64BIT_2GB, + DDR_64BIT_4GB, + DDR_UNKNOWN, +}; + +static void __udelay(int us) +{ + volatile int i; + + for (i = 0; i < us * 4; i++); +} + +/* + * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to + * Freescale QRM, but this is exactly the value used by the automatic + * calibration script and it works also in all our tests, so we leave + * it as is at this point. + */ +#define CM_FX6_DDR_IOMUX_CFG \ + .dram_sdqs0 = 0x00000038, \ + .dram_sdqs1 = 0x00000038, \ + .dram_sdqs2 = 0x00000038, \ + .dram_sdqs3 = 0x00000038, \ + .dram_sdqs4 = 0x00000038, \ + .dram_sdqs5 = 0x00000038, \ + .dram_sdqs6 = 0x00000038, \ + .dram_sdqs7 = 0x00000038, \ + .dram_dqm0 = 0x00000038, \ + .dram_dqm1 = 0x00000038, \ + .dram_dqm2 = 0x00000038, \ + .dram_dqm3 = 0x00000038, \ + .dram_dqm4 = 0x00000038, \ + .dram_dqm5 = 0x00000038, \ + .dram_dqm6 = 0x00000038, \ + .dram_dqm7 = 0x00000038, \ + .dram_cas = 0x00000038, \ + .dram_ras = 0x00000038, \ + .dram_sdclk_0 = 0x00000038, \ + .dram_sdclk_1 = 0x00000038, \ + .dram_sdcke0 = 0x00003000, \ + .dram_sdcke1 = 0x00003000, \ + .dram_reset = 0x00000038, \ + .dram_sdba2 = 0x00000000, \ + .dram_sdodt0 = 0x00000038, \ + .dram_sdodt1 = 0x00000038, + +#define CM_FX6_GPR_IOMUX_CFG \ + .grp_b0ds = 0x00000038, \ + .grp_b1ds = 0x00000038, \ + .grp_b2ds = 0x00000038, \ + .grp_b3ds = 0x00000038, \ + .grp_b4ds = 0x00000038, \ + .grp_b5ds = 0x00000038, \ + .grp_b6ds = 0x00000038, \ + .grp_b7ds = 0x00000038, \ + .grp_addds = 0x00000038, \ + .grp_ddrmode_ctl = 0x00020000, \ + .grp_ddrpke = 0x00000000, \ + .grp_ddrmode = 0x00020000, \ + .grp_ctlds = 0x00000038, \ + .grp_ddr_type = 0x000C0000, + +static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { CM_FX6_DDR_IOMUX_CFG }; +static struct mx6sdl_iomux_grp_regs grp_iomux_s = { CM_FX6_GPR_IOMUX_CFG }; +static struct mx6dq_iomux_ddr_regs ddr_iomux_q = { CM_FX6_DDR_IOMUX_CFG }; +static struct mx6dq_iomux_grp_regs grp_iomux_q = { CM_FX6_GPR_IOMUX_CFG }; + +static struct mx6_mmdc_calibration cm_fx6_calib_s = { + .p0_mpwldectrl0 = 0x005B0061, + .p0_mpwldectrl1 = 0x004F0055, + .p0_mpdgctrl0 = 0x0314030C, + .p0_mpdgctrl1 = 0x025C0268, + .p0_mprddlctl = 0x42464646, + .p0_mpwrdlctl = 0x36322C34, +}; + +static struct mx6_ddr_sysinfo cm_fx6_sysinfo_s = { + .cs1_mirror = 1, + .cs_density = 16, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 1, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = { + .mem_speed = 800, + .density = 4, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1800, + .trcmin = 5200, + .trasmin = 3600, + .SRT = 0, +}; + +static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset) +{ + if (reset) + ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; + + switch (dram_config) { + case DDR_16BIT_256MB: + cm_fx6_sysinfo_s.dsize = 0; + cm_fx6_sysinfo_s.ncs = 1; + break; + case DDR_32BIT_512MB: + cm_fx6_sysinfo_s.dsize = 1; + cm_fx6_sysinfo_s.ncs = 1; + break; + case DDR_32BIT_1GB: + cm_fx6_sysinfo_s.dsize = 1; + cm_fx6_sysinfo_s.ncs = 2; + break; + default: + pr_err("Tried to setup invalid DDR configuration\n"); + hang(); + } + + mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s); + __udelay(100); +} + +static struct mx6_mmdc_calibration cm_fx6_calib_q = { + .p0_mpwldectrl0 = 0x00630068, + .p0_mpwldectrl1 = 0x0068005D, + .p0_mpdgctrl0 = 0x04140428, + .p0_mpdgctrl1 = 0x037C037C, + .p0_mprddlctl = 0x3C30303A, + .p0_mpwrdlctl = 0x3A344038, + .p1_mpwldectrl0 = 0x0035004C, + .p1_mpwldectrl1 = 0x00170026, + .p1_mpdgctrl0 = 0x0374037C, + .p1_mpdgctrl1 = 0x0350032C, + .p1_mprddlctl = 0x30322A3C, + .p1_mpwrdlctl = 0x48304A3E, +}; + +static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = { + .cs_density = 16, + .cs1_mirror = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 1, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = { + .mem_speed = 1066, + .density = 4, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1324, + .trcmin = 59500, + .trasmin = 9750, + .SRT = 0, +}; + +static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset) +{ + if (reset) + ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; + + cm_fx6_ddr3_cfg_q.rowaddr = 14; + switch (dram_config) { + case DDR_16BIT_256MB: + cm_fx6_sysinfo_q.dsize = 0; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_32BIT_512MB: + cm_fx6_sysinfo_q.dsize = 1; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_64BIT_1GB: + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_64BIT_2GB: + cm_fx6_sysinfo_q.cs_density = 8; + cm_fx6_ddr3_cfg_q.density = 2; + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 2; + break; + case DDR_64BIT_4GB: + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 2; + cm_fx6_ddr3_cfg_q.rowaddr = 15; + break; + default: + pr_err("Tried to setup invalid DDR configuration\n"); + hang(); + } + + mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q); + __udelay(100); +} + +static unsigned long cm_fx6_spl_dram_init(void) +{ + unsigned long bank1_size, bank2_size; + int cpu_type = __imx6_cpu_type(); + + if (cpu_type == IMX6_CPUTYPE_IMX6S) { + mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s); + + spl_mx6s_dram_init(DDR_32BIT_1GB, false); + bank1_size = get_ram_size((long int *)0x10000000, 0x80000000); + bank2_size = get_ram_size((long int *)0x80000000, 0x80000000); + if (bank1_size == 0x20000000) { + if (bank2_size == 0x20000000) + return SZ_1G; + + spl_mx6s_dram_init(DDR_32BIT_512MB, true); + return SZ_512M; + } + + spl_mx6s_dram_init(DDR_16BIT_256MB, true); + bank1_size = get_ram_size((long int *)0x10000000, 0x80000000); + if (bank1_size == 0x10000000) + return SZ_256M; + } else if (cpu_type == IMX6_CPUTYPE_IMX6D || cpu_type == IMX6_CPUTYPE_IMX6Q) { + mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q); + + spl_mx6q_dram_init(DDR_64BIT_4GB, false); + bank1_size = get_ram_size((long int *)0x10000000, 0x80000000); + if (bank1_size == 0x80000000) + return SZ_2G; + + if (bank1_size == 0x40000000) { + bank2_size = get_ram_size((long int *)0x90000000, + 0x40000000); + if (bank2_size == 0x40000000) { + /* Don't do a full reset here */ + spl_mx6q_dram_init(DDR_64BIT_2GB, false); + return SZ_2G; + } else { + spl_mx6q_dram_init(DDR_64BIT_1GB, true); + return SZ_1G; + } + } + + spl_mx6q_dram_init(DDR_32BIT_512MB, true); + bank1_size = get_ram_size((long int *)0x10000000, 0x80000000); + if (bank1_size == 0x20000000) + return SZ_512M; + + spl_mx6q_dram_init(DDR_16BIT_256MB, true); + bank1_size = get_ram_size((long int *)0x10000000, 0x80000000); + if (bank1_size == 0x10000000) + return SZ_256M; + } + + return 0; +} + +static inline void setup_uart(void) +{ + void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; + + writel(0x4, iomuxbase + 0x01f8); + + imx6_ungate_all_peripherals(); + imx6_uart_setup((void *)MX6_UART4_BASE_ADDR); + pbl_set_putc(imx_uart_putc, (void *)MX6_UART4_BASE_ADDR); + + pr_debug("\n"); +} + +static void cm_fx6_init(void) +{ + unsigned long sdram_size; + + setup_uart(); + + if (get_pc() > 0x10000000) + return; + + sdram_size = cm_fx6_spl_dram_init(); + + pr_debug("SDRAM init finished. SDRAM size 0x%08lx\n", sdram_size); + + imx6_esdhc_start_image(2); + pr_info("Loading image from SPI flash\n"); + imx6_spi_start_image(0); +} + +extern char __dtb_imx6q_cm_fx6_start[]; +extern char __dtb_imx6dl_cm_fx6_start[]; + +static noinline void cm_fx6_start(void) +{ + int cpu_type = __imx6_cpu_type(); + + cm_fx6_init(); + + if (cpu_type == IMX6_CPUTYPE_IMX6S) + imx6q_barebox_entry(__dtb_imx6dl_cm_fx6_start); + else + imx6q_barebox_entry(__dtb_imx6q_cm_fx6_start); +} + +ENTRY_FUNCTION(start_imx6_cm_fx6, r0, r1, r2) +{ + arm_cpu_lowlevel_init(); + + relocate_to_current_adr(); + setup_c(); + barrier(); + + cm_fx6_start(); +} + +extern char __dtb_imx6q_utilite_start[]; +extern char __dtb_imx6dl_utilite_value_start[]; + +static noinline void utilite_start(void) +{ + int cpu_type = __imx6_cpu_type(); + + cm_fx6_init(); + + if (cpu_type == IMX6_CPUTYPE_IMX6S) + /* FIXME: This needs a specialized utilite value dts */ + imx6q_barebox_entry(__dtb_imx6dl_cm_fx6_start); + else + imx6q_barebox_entry(__dtb_imx6q_utilite_start); +} + +ENTRY_FUNCTION(start_imx6_utilite, r0, r1, r2) +{ + arm_cpu_lowlevel_init(); + + relocate_to_current_adr(); + setup_c(); + barrier(); + + utilite_start(); +} diff --git a/arch/arm/boards/datamodul-edm-qmx6/board.c b/arch/arm/boards/datamodul-edm-qmx6/board.c index 81356e61c0..96c7fbe4bf 100644 --- a/arch/arm/boards/datamodul-edm-qmx6/board.c +++ b/arch/arm/boards/datamodul-edm-qmx6/board.c @@ -38,7 +38,6 @@ #include <mach/devices-imx6.h> #include <mach/imx6-regs.h> #include <mach/iomux-mx6.h> -#include <mach/imx6-mmdc.h> #include <mach/generic.h> #include <mach/imx6.h> #include <mach/bbu.h> diff --git a/arch/arm/boards/dfi-fs700-m60/lowlevel.c b/arch/arm/boards/dfi-fs700-m60/lowlevel.c index b9b498e463..a22f66a11b 100644 --- a/arch/arm/boards/dfi-fs700-m60/lowlevel.c +++ b/arch/arm/boards/dfi-fs700-m60/lowlevel.c @@ -19,7 +19,6 @@ #include <asm/mmu.h> #include <asm/barebox-arm-head.h> #include <asm/barebox-arm.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6-regs.h> #include <mach/generic.h> diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c index 59010da511..d26bc98bbb 100644 --- a/arch/arm/boards/embest-riotboard/lowlevel.c +++ b/arch/arm/boards/embest-riotboard/lowlevel.c @@ -7,7 +7,6 @@ #include <asm/sections.h> #include <asm/cache.h> #include <asm/mmu.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6.h> extern char __dtb_imx6s_riotboard_start[]; diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c index d77a6c7156..fc1237588f 100644 --- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c +++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c @@ -226,7 +226,7 @@ static struct imx_fb_platformdata mx28_evk_fb_pdata = { .mode_list = mx28_evk_vmodes, .mode_cnt = ARRAY_SIZE(mx28_evk_vmodes), .dotclk_delay = 0, /* no adaption required */ - .ld_intf_width = STMLCDIF_24BIT, /* full 24 bit */ + .ld_intf_width = 24, .bits_per_pixel = 32, .fixed_screen = NULL, .enable = mx28_evk_fb_enable, diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c index edf081140c..d40f99bb93 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/board.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c @@ -164,8 +164,8 @@ static int sabrelite_devices_init(void) armlinux_set_architecture(3769); - imx6_bbu_internal_spi_i2c_register_handler("spiflash", "/dev/m25p0.barebox", - BBU_HANDLER_FLAG_DEFAULT); + imx6_bbu_internal_spi_i2c_register_handler("spiflash", + "/dev/spinor0.barebox", BBU_HANDLER_FLAG_DEFAULT); return 0; } diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c index 67fd50849d..f40f0d1591 100644 --- a/arch/arm/boards/guf-neso/board.c +++ b/arch/arm/boards/guf-neso/board.c @@ -110,7 +110,7 @@ static struct imx_fb_platform_data neso_fb_data = { .framebuffer_ovl = (void *)0xa7f00000, }; -#ifdef CONFIG_USB +#if defined(CONFIG_USB) && defined(CONFIG_USB_ULPI) static void neso_usbh_init(void) { uint32_t temp; @@ -130,7 +130,11 @@ static void neso_usbh_init(void) gpio_set_value(USBH2_PHY_CS_GPIO, 0); mdelay(10); ulpi_setup((void *)(MX27_USB_OTG_BASE_ADDR + 0x570), 1); + add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, + MX27_USB_OTG_BASE_ADDR + 0x400, NULL); } +#else +static void neso_usbh_init(void) { } #endif static int neso_devices_init(void) @@ -266,10 +270,7 @@ static int neso_devices_init(void) imx27_add_nand(&nand_info); imx27_add_fb(&neso_fb_data); -#ifdef CONFIG_USB neso_usbh_init(); - add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, MX27_USB_OTG_BASE_ADDR + 0x400, NULL); -#endif imx27_add_fec(&fec_info); diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c index 9b86d1c883..d67607b717 100644 --- a/arch/arm/boards/karo-tx28/tx28-stk5.c +++ b/arch/arm/boards/karo-tx28/tx28-stk5.c @@ -195,7 +195,7 @@ static struct imx_fb_platformdata tx28_fb_pdata = { .mode_list = tx28evk_vmodes, .mode_cnt = ARRAY_SIZE(tx28evk_vmodes), .dotclk_delay = 0, /* no adaption required */ - .ld_intf_width = STMLCDIF_24BIT, /* full 24 bit */ + .ld_intf_width = 24, .fixed_screen = (void *)(0x40000000 + SZ_128M - MAX_FB_SIZE), .fixed_screen_size = MAX_FB_SIZE, .enable = tx28_fb_enable, diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg index 481e085477..62a24ed0df 100644 --- a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib-1bank.imxcfg @@ -1,5 +1,7 @@ -#define SETUP_1GIB_2GIB \ +#define SETUP_MDCFG0 \ wm 32 0x021b000c 0x54597955; \ + +#define SETUP_MDOR_MDASP_MDCTL \ wm 32 0x021b0030 0x00591023; \ wm 32 0x021b0040 0x00000027; \ wm 32 0x021b0000 0x831a0000 diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg index b21bd894b0..bab726d147 100644 --- a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-1gib.imxcfg @@ -1,5 +1,7 @@ -#define SETUP_1GIB_2GIB \ +#define SETUP_MDCFG0 \ wm 32 0x021b000c 0x3a3f7975; \ + +#define SETUP_MDOR_MDASP_MDCTL \ wm 32 0x021b0030 0x003f1023; \ wm 32 0x021b0040 0x00000017; \ wm 32 0x021b0000 0xc21a0000 diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg index 858b6d754b..512f6cbd47 100644 --- a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3-2gib.imxcfg @@ -1,6 +1,7 @@ - -#define SETUP_1GIB_2GIB \ +#define SETUP_MDCFG0 \ wm 32 0x021b000c 0x54597955; \ + +#define SETUP_MDOR_MDASP_MDCTL \ wm 32 0x021b0030 0x00591023; \ wm 32 0x021b0040 0x00000027; \ wm 32 0x021b0000 0xc31a0000 diff --git a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h index aecaf160bb..a03b8dc0fa 100644 --- a/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h +++ b/arch/arm/boards/phytec-phycard-imx6/flash-header-phytec-pcaaxl3.h @@ -58,7 +58,8 @@ wm 32 0x021b002c 0x000026d2 wm 32 0x021b0008 0x09444040 wm 32 0x021b0004 0x00025576 -SETUP_1GIB_2GIB +SETUP_MDCFG0 +SETUP_MDOR_MDASP_MDCTL wm 32 0x021b001c 0x04088032 wm 32 0x021b001c 0x0408803a diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c index d85a1ab0a1..09ab6452ba 100644 --- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c @@ -21,7 +21,6 @@ #include <asm/sections.h> #include <asm/cache.h> #include <asm/mmu.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6.h> static inline void setup_uart(void) diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg index e414b6e612..75dc982432 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib-1bank.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x565c9b85 -#define SETUP_1GIB_2GIB_4GIB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000027; \ wm 32 0x021b0000 0x831a0000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib.imxcfg index f6061f25b4..1f1fbe542c 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-1gib.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x3c409b85 -#define SETUP_1GIB_2GIB_4GIB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000017; \ wm 32 0x021b0000 0xc21a0000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-2gib.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-2gib.imxcfg index 2bfa836c4f..aa01c056be 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-2gib.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-2gib.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x565c9b85 -#define SETUP_1GIB_2GIB_4GIB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000027; \ wm 32 0x021b0000 0xC31A0000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-4gib.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-4gib.imxcfg index 491f89357c..c8d33cfacc 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-4gib.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02-4gib.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x8c929b85 -#define SETUP_1GIB_2GIB_4GIB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000047; \ wm 32 0x021b0000 0xC41A0000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02.h b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02.h index 98b3c1869b..93291e9836 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02.h +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02.h @@ -78,7 +78,7 @@ wm 32 0x021b001c 0x00008000 wm 32 0x021b002c 0x000026d2 wm 32 0x021b0030 0x003F1023 -SETUP_1GIB_2GIB_4GIB +SETUP_MDASP_MDCTL wm 32 0x021b001c 0x04088032 wm 32 0x021b001c 0x0408803a diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg index dfd4336f06..e76867004a 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl-1gib.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x8c929b85 -#define SETUP_S_DL_512MB_1GB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000017; \ wm 32 0x021b0000 0xc21a0000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl.h b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl.h index 8fbd66141a..337488bdf0 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl.h +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02dl.h @@ -78,7 +78,7 @@ wm 32 0x021b001c 0x00008000 wm 32 0x021b002c 0x000026d2 wm 32 0x021b0030 0x003F1023 -SETUP_S_DL_512MB_1GB +SETUP_MDASP_MDCTL wm 32 0x021b001c 0x04088032 wm 32 0x021b001c 0x0408803a diff --git a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02s-512mb.imxcfg b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02s-512mb.imxcfg index 2e428f9fd0..6a46cd958f 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02s-512mb.imxcfg +++ b/arch/arm/boards/phytec-phyflex-imx6/flash-header-phytec-pfla02s-512mb.imxcfg @@ -1,7 +1,7 @@ #define SETUP_MDCFG0 \ wm 32 0x021b000c 0x565c9b85 -#define SETUP_S_DL_512MB_1GB \ +#define SETUP_MDASP_MDCTL \ wm 32 0x021b0040 0x00000017; \ wm 32 0x021b0000 0x83190000 diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c index cd37f88e05..82c0244631 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c @@ -22,7 +22,6 @@ #include <asm/sections.h> #include <asm/cache.h> #include <asm/mmu.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6.h> static inline void setup_uart(void) diff --git a/arch/arm/boards/phytec-som-am335x/lowlevel.c b/arch/arm/boards/phytec-som-am335x/lowlevel.c index 948bfa5147..64c1c53f67 100644 --- a/arch/arm/boards/phytec-som-am335x/lowlevel.c +++ b/arch/arm/boards/phytec-som-am335x/lowlevel.c @@ -124,13 +124,19 @@ PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_128mb, am335x_phytec_phycore_s PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_256mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J128M16125IT_256MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_512mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J256M16HA15EIT_512MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_2x512mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J512M8125IT_2x512MB); +PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_1024mb, am335x_phytec_phycore_som_mlo, PHYCORE_IM8G16D3FBBG15EI_1024MB); PHYTEC_ENTRY(start_am33xx_phytec_phycore_sdram, am335x_phytec_phycore_som); PHYTEC_ENTRY(start_am33xx_phytec_phycore_no_spi_sdram, am335x_phytec_phycore_som_no_spi); +PHYTEC_ENTRY(start_am33xx_phytec_phycore_no_eeprom_sdram, am335x_phytec_phycore_som_no_eeprom); +PHYTEC_ENTRY(start_am33xx_phytec_phycore_no_spi_no_eeprom_sdram, am335x_phytec_phycore_som_no_spi_no_eeprom); /* phyflex-som */ PHYTEC_ENTRY_MLO(start_am33xx_phytec_phyflex_sram_256mb, am335x_phytec_phyflex_som_mlo, PHYFLEX_MT41K128M16JT_256MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phyflex_sram_512mb, am335x_phytec_phyflex_som_mlo, PHYFLEX_MT41K256M16HA_512MB); PHYTEC_ENTRY(start_am33xx_phytec_phyflex_sdram, am335x_phytec_phyflex_som); +PHYTEC_ENTRY(start_am33xx_phytec_phyflex_no_spi_sdram, am335x_phytec_phyflex_som_no_spi); +PHYTEC_ENTRY(start_am33xx_phytec_phyflex_no_eeprom_sdram, am335x_phytec_phyflex_som_no_eeprom); +PHYTEC_ENTRY(start_am33xx_phytec_phyflex_no_spi_no_eeprom_sdram, am335x_phytec_phyflex_som_no_spi_no_eeprom); /* phycard-som */ PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycard_sram_256mb, am335x_phytec_phycard_som_mlo, PHYCARD_NT5CB128M16BP_256MB); diff --git a/arch/arm/boards/phytec-som-am335x/ram-timings.h b/arch/arm/boards/phytec-som-am335x/ram-timings.h index 3dcee207ee..698b0732b0 100644 --- a/arch/arm/boards/phytec-som-am335x/ram-timings.h +++ b/arch/arm/boards/phytec-som-am335x/ram-timings.h @@ -29,6 +29,7 @@ enum { PHYCORE_MT41J64M1615IT_128MB, PHYCORE_MT41J256M16HA15EIT_512MB, PHYCORE_MT41J512M8125IT_2x512MB, + PHYCORE_IM8G16D3FBBG15EI_1024MB, PHYCARD_NT5CB128M16BP_256MB, }; @@ -133,7 +134,7 @@ struct am335x_sdram_timings physom_timings[] = { }, }, - /* 1024MB */ + /* 2x512MB */ [PHYCORE_MT41J512M8125IT_2x512MB] = { .regs = { .emif_read_latency = 0x7, @@ -152,6 +153,25 @@ struct am335x_sdram_timings physom_timings[] = { }, }, + /* 1024MB */ + [PHYCORE_IM8G16D3FBBG15EI_1024MB] = { + .regs = { + .emif_read_latency = 0x7, + .emif_tim1 = 0x0AAAE4DB, + .emif_tim2 = 0x268F7FDA, + .emif_tim3 = 0x501F88BF, + .sdram_config = 0x61C053B2, + .zq_config = 0x50074BE4, + .sdram_ref_ctrl = 0x00000C30 + }, + .data = { + .rd_slave_ratio0 = 0x33, + .wr_dqs_slave_ratio0 = 0x4a, + .fifo_we_slave_ratio0 = 0xa4, + .wr_slave_ratio0 = 0x85, + }, + }, + /* 256MB */ [PHYCARD_NT5CB128M16BP_256MB] = { .regs = { diff --git a/arch/arm/boards/tqma6x/board.c b/arch/arm/boards/tqma6x/board.c index 97cce60c70..9c52c8ae7a 100644 --- a/arch/arm/boards/tqma6x/board.c +++ b/arch/arm/boards/tqma6x/board.c @@ -38,7 +38,6 @@ #include <mach/devices-imx6.h> #include <mach/imx6-regs.h> #include <mach/iomux-mx6.h> -#include <mach/imx6-mmdc.h> #include <mach/generic.h> #include <mach/imx6.h> #include <mach/bbu.h> diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c index aec84b176b..52afee4b75 100644 --- a/arch/arm/boards/tqma6x/lowlevel.c +++ b/arch/arm/boards/tqma6x/lowlevel.c @@ -21,7 +21,6 @@ #include <asm/sections.h> #include <asm/cache.h> #include <asm/mmu.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6.h> extern char __dtb_imx6q_mba6x_start[]; diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c index b0b930d438..5cb738acb2 100644 --- a/arch/arm/boards/variscite-mx6/lowlevel.c +++ b/arch/arm/boards/variscite-mx6/lowlevel.c @@ -23,7 +23,6 @@ #include <asm/sections.h> #include <asm/cache.h> #include <asm/mmu.h> -#include <mach/imx6-mmdc.h> #include <mach/imx6.h> static inline void setup_uart(void) diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index 7dd6e6f240..ec91460533 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -24,6 +24,7 @@ CONFIG_MACH_EMBEST_RIOTBOARD=y CONFIG_MACH_UDOO=y CONFIG_MACH_VARISCITE_MX6=y CONFIG_MACH_GW_VENTANA=y +CONFIG_MACH_CM_FX6=y CONFIG_IMX_IIM=y CONFIG_IMX_IIM_FUSE_BLOW=y CONFIG_IMX_OCOTP=y diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index 946902d200..1e735d4a6d 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -7,7 +7,6 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_ARM_UNWIND=y # CONFIG_BANNER is not set CONFIG_MMU=y -CONFIG_TEXT_BASE=0xa3d00000 CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0x80000 CONFIG_MALLOC_SIZE=0x1000000 CONFIG_EXPERIMENTAL=y diff --git a/arch/arm/configs/rockchip_defconfig b/arch/arm/configs/rockchip_defconfig index e08699d1f5..b738620c68 100644 --- a/arch/arm/configs/rockchip_defconfig +++ b/arch/arm/configs/rockchip_defconfig @@ -80,14 +80,12 @@ CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_SERIAL_NS16550=y CONFIG_DRIVER_NET_ARC_EMAC=y CONFIG_SMSC_PHY=y -CONFIG_I2C=y CONFIG_I2C_GPIO=y CONFIG_MCI=y CONFIG_MCI_STARTUP=y CONFIG_MCI_MMC_BOOT_PARTITIONS=y CONFIG_MCI_DW=y CONFIG_MCI_DW_PIO=y -CONFIG_MFD_ACT8846=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_GPIO_OF=y diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c index badd676b0d..5e708023e4 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -93,7 +93,7 @@ void mmu_disable(void) * This function is called by shutdown_barebox to get a clean * memory/cache state. */ -void arch_shutdown(void) +static void arch_shutdown(void) { uint32_t r; @@ -108,6 +108,7 @@ void arch_shutdown(void) r |= PSR_I_BIT; __asm__ __volatile__("msr cpsr, %0" : : "r"(r)); } +archshutdown_exitcall(arch_shutdown); extern unsigned long arm_stack_top; diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 54578e9fa5..60880e4d20 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -9,6 +9,7 @@ obj- += dummy.o pbl-dtb-$(CONFIG_MACH_AFI_GF) += am335x-afi-gf.dtb.o pbl-dtb-$(CONFIG_MACH_BEAGLEBONE) += am335x-bone.dtb.o am335x-boneblack.dtb.o am335x-bone-common.dtb.o +pbl-dtb-$(CONFIG_MACH_CM_FX6) += imx6dl-cm-fx6.dtb.o imx6q-cm-fx6.dtb.o imx6q-utilite.dtb.o pbl-dtb-$(CONFIG_MACH_DFI_FS700_M60) += imx6q-dfi-fs700-m60-6q.dtb.o imx6dl-dfi-fs700-m60-6s.dtb.o pbl-dtb-$(CONFIG_MACH_DUCKBILL) += imx28-duckbill.dtb.o pbl-dtb-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += imx51-genesi-efika-sb.dtb.o @@ -33,7 +34,10 @@ pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o pbl-dtb-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += am335x-phytec-phyflex-som.dtb.o am335x-phytec-phyflex-som-mlo.dtb.o \ + am335x-phytec-phyflex-som-no-spi.dtb.o am335x-phytec-phyflex-som-no-eeprom.dtb.o \ + am335x-phytec-phyflex-som-no-spi-no-eeprom.dtb.o \ am335x-phytec-phycore-som.dtb.o am335x-phytec-phycore-som-no-spi.dtb.o am335x-phytec-phycore-som-mlo.dtb.o \ + am335x-phytec-phycore-som-no-eeprom.dtb.o am335x-phytec-phycore-som-no-spi-no-eeprom.dtb.o \ am335x-phytec-phycard-som.dtb.o am335x-phytec-phycard-som-mlo.dtb.o pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o imx6q-phytec-phyboard-alcor.dtb.o imx6dl-phytec-phyboard-subra.dtb.o pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o diff --git a/arch/arm/dts/am335x-bone-common.dts b/arch/arm/dts/am335x-bone-common.dts index 5d3d2ed5aa..91745d3f62 100644 --- a/arch/arm/dts/am335x-bone-common.dts +++ b/arch/arm/dts/am335x-bone-common.dts @@ -8,6 +8,7 @@ */ #include "am33xx.dtsi" +#include "am33xx-strip.dtsi" #include "am335x-bone-common.dtsi" / { diff --git a/arch/arm/dts/am335x-phytec-phycard-som.dtsi b/arch/arm/dts/am335x-phytec-phycard-som.dtsi index 1f1036f432..c0b2456636 100644 --- a/arch/arm/dts/am335x-phytec-phycard-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phycard-som.dtsi @@ -144,9 +144,9 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nandflash_pins_s0>; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ nand: nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; gpmc,device-nand = "true"; diff --git a/arch/arm/dts/am335x-phytec-phycore-som-no-eeprom.dts b/arch/arm/dts/am335x-phytec-phycore-som-no-eeprom.dts new file mode 100644 index 0000000000..3dd130e2b7 --- /dev/null +++ b/arch/arm/dts/am335x-phytec-phycore-som-no-eeprom.dts @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2015 Phytec Messtechnik GmbH + * Author: Teresa Remmet <t.remmet@phytec.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "am335x-phytec-phycore-som.dtsi" + +/ { + model = "Phytec phyCORE AM335x"; + compatible = "phytec,phycore-am335x-som", "phytec,am335x-som", "ti,am33xx"; +}; + +&spi0 { + status = "okay"; +}; diff --git a/arch/arm/dts/am335x-phytec-phycore-som-no-spi-no-eeprom.dts b/arch/arm/dts/am335x-phytec-phycore-som-no-spi-no-eeprom.dts new file mode 100644 index 0000000000..397be77076 --- /dev/null +++ b/arch/arm/dts/am335x-phytec-phycore-som-no-spi-no-eeprom.dts @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2015 Phytec Messtechnik GmbH + * Author: Teresa Remmet <t.remmet@phytec.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "am335x-phytec-phycore-som.dtsi" + +/ { + model = "Phytec phyCORE AM335x"; + compatible = "phytec,phycore-am335x-som", "phytec,am335x-som", "ti,am33xx"; +}; diff --git a/arch/arm/dts/am335x-phytec-phycore-som.dtsi b/arch/arm/dts/am335x-phytec-phycore-som.dtsi index ed8e257b59..ba0589cdc5 100644 --- a/arch/arm/dts/am335x-phytec-phycore-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phycore-som.dtsi @@ -162,7 +162,7 @@ pinctrl-0 = <&spi0_pins>; status = "disabled"; - flash: m25p80 { + flash: m25p80@0 { compatible = "m25p80"; spi-max-frequency = <48000000>; reg = <0>; @@ -228,9 +228,9 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nandflash_pins_s0>; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ nand: nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; gpmc,device-nand = "true"; diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-no-eeprom.dts b/arch/arm/dts/am335x-phytec-phyflex-som-no-eeprom.dts new file mode 100644 index 0000000000..0022e14750 --- /dev/null +++ b/arch/arm/dts/am335x-phytec-phyflex-som-no-eeprom.dts @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov <w.egorov@phytec.de> + * Teresa Remmet <t.remmet@phytec.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "am335x-phytec-phyflex-som.dtsi" + +/ { + model = "Phytec phyFLEX AM335x"; + compatible = "phytec,phyflex-am335x-som", "phytec,am335x-som", "ti,am33xx"; +}; + +&spi0 { + status = "okay"; +}; diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-no-spi-no-eeprom.dts b/arch/arm/dts/am335x-phytec-phyflex-som-no-spi-no-eeprom.dts new file mode 100644 index 0000000000..486aac6570 --- /dev/null +++ b/arch/arm/dts/am335x-phytec-phyflex-som-no-spi-no-eeprom.dts @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov <w.egorov@phytec.de> + * Teresa Remmet <t.remmet@phytec.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "am335x-phytec-phyflex-som.dtsi" + +/ { + model = "Phytec phyFLEX AM335x"; + compatible = "phytec,phyflex-am335x-som", "phytec,am335x-som", "ti,am33xx"; +}; diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-no-spi.dts b/arch/arm/dts/am335x-phytec-phyflex-som-no-spi.dts new file mode 100644 index 0000000000..5f3a1e08d0 --- /dev/null +++ b/arch/arm/dts/am335x-phytec-phyflex-som-no-spi.dts @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH + * Author: Wadim Egorov <w.egorov@phytec.de> + * Teresa Remmet <t.remmet@phytec.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "am335x-phytec-phyflex-som.dtsi" + +/ { + model = "Phytec phyFLEX AM335x"; + compatible = "phytec,phyflex-am335x-som", "phytec,am335x-som", "ti,am33xx"; +}; + +&at24c32 { + status = "okay"; +}; diff --git a/arch/arm/dts/am335x-phytec-phyflex-som.dtsi b/arch/arm/dts/am335x-phytec-phyflex-som.dtsi index fc9c9bafeb..6d488faa93 100644 --- a/arch/arm/dts/am335x-phytec-phyflex-som.dtsi +++ b/arch/arm/dts/am335x-phytec-phyflex-som.dtsi @@ -138,6 +138,7 @@ byte_len = <4096>; pagesize = <32>; reg = <0x52>; + status = "disabled"; }; }; @@ -151,7 +152,7 @@ pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; status = "disabled"; - flash: m25p80 { + flash: m25p80@0 { compatible = "m25p80"; spi-max-frequency = <48000000>; reg = <0>; @@ -240,9 +241,9 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nandflash_pins_s0>; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ nand: nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; gpmc,device-nand = "true"; diff --git a/arch/arm/dts/imx6dl-cm-fx6.dts b/arch/arm/dts/imx6dl-cm-fx6.dts new file mode 100644 index 0000000000..d33d14c613 --- /dev/null +++ b/arch/arm/dts/imx6dl-cm-fx6.dts @@ -0,0 +1,21 @@ +/* + * Copyright 2015 CompuLab Ltd. + * + * Author: Valentin Raevsky <valentin@compulab.co.il> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6qdl-cm-fx6.dtsi" + +/ { + model = "CompuLab CM-FX6"; + compatible = "compulab,cm-fx6", "fsl,imx6dl"; +}; diff --git a/arch/arm/dts/imx6q-cm-fx6.dts b/arch/arm/dts/imx6q-cm-fx6.dts new file mode 100644 index 0000000000..aaaa7189d8 --- /dev/null +++ b/arch/arm/dts/imx6q-cm-fx6.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2014 CompuLab Ltd. + * + * Author: Valentin Raevsky <valentin@compulab.co.il> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include <arm/imx6q.dtsi> +#include "imx6qdl-cm-fx6.dtsi" + +/ { + model = "CompuLab CM-FX6"; + compatible = "compulab,cm-fx6", "fsl,imx6q"; + + chosen { + stdout-path = &uart4; + }; +}; + +&sata { + status = "okay"; +}; diff --git a/arch/arm/dts/imx6q-dfi-fs700-m60-6q.dts b/arch/arm/dts/imx6q-dfi-fs700-m60-6q.dts index 1178e0b9ee..8ecd667e9e 100644 --- a/arch/arm/dts/imx6q-dfi-fs700-m60-6q.dts +++ b/arch/arm/dts/imx6q-dfi-fs700-m60-6q.dts @@ -14,6 +14,7 @@ /dts-v1/; #endif +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-dfi-fs700-m60.dtsi" diff --git a/arch/arm/dts/imx6q-embedsky-e9.dts b/arch/arm/dts/imx6q-embedsky-e9.dts index ab70d05ad9..4514d4e433 100644 --- a/arch/arm/dts/imx6q-embedsky-e9.dts +++ b/arch/arm/dts/imx6q-embedsky-e9.dts @@ -12,6 +12,7 @@ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6q-embedsky-e9.dtsi" diff --git a/arch/arm/dts/imx6q-guf-santaro.dts b/arch/arm/dts/imx6q-guf-santaro.dts index e4dc856bc2..d9bc7a53e9 100644 --- a/arch/arm/dts/imx6q-guf-santaro.dts +++ b/arch/arm/dts/imx6q-guf-santaro.dts @@ -13,6 +13,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" / { diff --git a/arch/arm/dts/imx6q-gw54xx.dts b/arch/arm/dts/imx6q-gw54xx.dts index ab518d66a7..8113542c66 100644 --- a/arch/arm/dts/imx6q-gw54xx.dts +++ b/arch/arm/dts/imx6q-gw54xx.dts @@ -10,6 +10,7 @@ */ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-gw54xx.dtsi" diff --git a/arch/arm/dts/imx6q-nitrogen6x.dts b/arch/arm/dts/imx6q-nitrogen6x.dts index a57866b2e9..d8906e6063 100644 --- a/arch/arm/dts/imx6q-nitrogen6x.dts +++ b/arch/arm/dts/imx6q-nitrogen6x.dts @@ -12,6 +12,7 @@ */ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-nitrogen6x.dtsi" diff --git a/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi index 78c33349dc..6435ab791d 100644 --- a/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi +++ b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi @@ -9,6 +9,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" / { diff --git a/arch/arm/dts/imx6q-phytec-pfla02.dtsi b/arch/arm/dts/imx6q-phytec-pfla02.dtsi index 0aec5d0352..b1172dc095 100644 --- a/arch/arm/dts/imx6q-phytec-pfla02.dtsi +++ b/arch/arm/dts/imx6q-phytec-pfla02.dtsi @@ -9,6 +9,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-phytec-pfla02.dtsi" diff --git a/arch/arm/dts/imx6q-sabrelite.dts b/arch/arm/dts/imx6q-sabrelite.dts index 96e4688be7..b6d1c09b77 100644 --- a/arch/arm/dts/imx6q-sabrelite.dts +++ b/arch/arm/dts/imx6q-sabrelite.dts @@ -11,12 +11,17 @@ */ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-sabrelite.dtsi" / { model = "Freescale i.MX6 Quad SABRE Lite Board"; compatible = "fsl,imx6q-sabrelite", "fsl,imx6q"; + + aliases { + spinor0 = &flash; + }; }; &sata { diff --git a/arch/arm/dts/imx6q-sabresd.dts b/arch/arm/dts/imx6q-sabresd.dts index 867e825c04..71ca855251 100644 --- a/arch/arm/dts/imx6q-sabresd.dts +++ b/arch/arm/dts/imx6q-sabresd.dts @@ -12,6 +12,7 @@ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-sabresd.dtsi" diff --git a/arch/arm/dts/imx6q-tqma6q.dtsi b/arch/arm/dts/imx6q-tqma6q.dtsi index 8d257f9b08..c2382b07db 100644 --- a/arch/arm/dts/imx6q-tqma6q.dtsi +++ b/arch/arm/dts/imx6q-tqma6q.dtsi @@ -9,6 +9,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-tqma6x.dtsi" diff --git a/arch/arm/dts/imx6q-udoo.dts b/arch/arm/dts/imx6q-udoo.dts index 5c79e9209b..c8a12a38dd 100644 --- a/arch/arm/dts/imx6q-udoo.dts +++ b/arch/arm/dts/imx6q-udoo.dts @@ -13,6 +13,7 @@ /dts-v1/; +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" #include "imx6qdl-udoo.dtsi" diff --git a/arch/arm/dts/imx6q-utilite.dts b/arch/arm/dts/imx6q-utilite.dts new file mode 100644 index 0000000000..14b65d64a7 --- /dev/null +++ b/arch/arm/dts/imx6q-utilite.dts @@ -0,0 +1,46 @@ +/dts-v1/; +#include <arm/imx6q.dtsi> +#include "imx6qdl-cm-fx6.dtsi" + +/ { + model = "CompuLab Utilite"; + compatible = "compulab,utilite", "compulab,cm-fx6", "fsl,imx6q"; + + chosen { + stdout-path = &uart4; + }; +}; + +&iomuxc { + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + >; + }; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + status = "okay"; +}; + +&hdmi { + status = "okay"; + ddc-i2c-bus = <&i2c2>; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&sata { + status = "okay"; +}; diff --git a/arch/arm/dts/imx6q-var-som.dtsi b/arch/arm/dts/imx6q-var-som.dtsi index bc23242e6e..792691191e 100644 --- a/arch/arm/dts/imx6q-var-som.dtsi +++ b/arch/arm/dts/imx6q-var-som.dtsi @@ -10,6 +10,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <arm/imx6q.dtsi> #include "imx6q.dtsi" / { diff --git a/arch/arm/dts/imx6q.dtsi b/arch/arm/dts/imx6q.dtsi index 9f41c0badf..c07583708d 100644 --- a/arch/arm/dts/imx6q.dtsi +++ b/arch/arm/dts/imx6q.dtsi @@ -1,5 +1,4 @@ #include "imx6qdl.dtsi" -#include <arm/imx6q.dtsi> / { aliases { diff --git a/arch/arm/dts/imx6qdl-cm-fx6.dtsi b/arch/arm/dts/imx6qdl-cm-fx6.dtsi new file mode 100644 index 0000000000..72d00f1b9e --- /dev/null +++ b/arch/arm/dts/imx6qdl-cm-fx6.dtsi @@ -0,0 +1,458 @@ +/* + * Copyright 2014 CompuLab Ltd. + * + * Author: Valentin Raevsky <valentin@compulab.co.il> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/ { + barebox_environment { + compatible = "barebox,environment"; + device-path = &barebox_env; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { + label = "Heartbeat"; + gpios = <&gpio2 31 0>; + linux,default-trigger = "heartbeat"; + }; + }; + + /* regulator for usb otg */ + reg_usb_otg_vbus: usb_otg_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 0>; + enable-active-high; + }; + + /* regulator1 for pcie power-on-gpio */ + pcie_power_on_gpio: regulator-pcie-power-on-gpio { + compatible = "regulator-fixed"; + regulator-name = "regulator-pcie-power-on-gpio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 24 0>; + enable-active-high; + }; + + /* regulator for usb hub1 */ + reg_usb_h1_vbus: usb_h1_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio7 8 0>; + enable-active-high; + }; + + /* regulator1 for wifi/bt */ + awnh387_npoweron: regulator-awnh387-npoweron { + compatible = "regulator-fixed"; + regulator-name = "regulator-awnh387-npoweron"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 12 0>; + enable-active-high; + }; + + /* regulator2 for wifi/bt */ + awnh387_wifi_nreset: regulator-awnh387-wifi-nreset { + compatible = "regulator-fixed"; + regulator-name = "regulator-awnh387-wifi-nreset"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio6 16 0>; + startup-delay-us = <10000>; + }; + + tsc2046reg: tsc2046-reg { + compatible = "regulator-fixed"; + regulator-name = "tsc2046-reg"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + hog { + pinctrl_hog: hoggrp { + fsl,pins = < + /* SATA PWR */ + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 + MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x80000000 + MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x80000000 + MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000 + /* SATA CTRL */ + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000 + MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x80000000 + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000 + /* POWER_BUTTON */ + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 + >; + }; + }; + + imx6q-cm-fx6 { + /* pins for eth0 */ + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + >; + }; + + pinctrl_ipu1_lcd: ipu1grp-lcd { + fsl,pins = < + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x38 + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x38 + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x38 + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x38 + MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000028 + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x38 + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x38 + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x38 + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x38 + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x38 + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x38 + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x38 + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x38 + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x38 + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x38 + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x38 + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x38 + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x38 + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x38 + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x38 + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x38 + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x38 + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x38 + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x38 + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x38 + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x38 + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x38 + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x38 + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x38 + >; + }; + + /* pins for spi */ + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x100b1 + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x100b1 + >; + }; + + /* pins for nand */ + pinctrl_gpmi_nand: gpminandgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1 + >; + }; + + /* pins for i2c2 */ + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + /* pins for i2c3 */ + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + /* pins for console */ + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + /* pins for usb hub1 */ + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x80000000 + >; + }; + + /* pins for usb otg */ + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 + >; + }; + + /* pins for wifi/bt */ + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; + + /* pins for wifi/bt */ + pinctrl_mrvl1: mrvl1grp { + fsl,pins = < + /* WIFI_PWR_RST */ + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000 + >; + }; + + /* pins for tsc2046 pendown */ + pinctrl_tsc2046: tsc2046grp { + fsl,pins = < + /* tsc2046 PENDOWN */ + MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x80000000 + >; + }; + + /* pins for pcie */ + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 + MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x80000000 + >; + }; + + /* pins for spdif */ + pinctrl_spdif: spdifgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 + MX6QDL_PAD_GPIO_19__SPDIF_OUT 0x1b0b0 + >; + }; + + /* pins for audmux */ + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__AUD4_RXC 0x17059 + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x17059 + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x17059 + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x17059 + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x17059 + /* master mode pin */ + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x17059 + >; + }; + }; +}; + +/* spi */ +&ecspi1 { + fsl,spi-num-chipselects = <2>; + cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + + flash: m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25px16", "st,m25p"; + spi-max-frequency = <20000000>; + reg = <0>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x100000>; + }; + + barebox_env: partition@100000 { + label = "barebox-environment"; + reg = <0x100000 0x40000>; + }; + }; + + /* touch controller */ + touch: tsc2046@1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tsc2046>; + + compatible = "ti,tsc2046"; + vcc-supply = <&tsc2046reg>; + + reg = <1>; /* CS1 */ + spi-max-frequency = <1500000>; + + interrupt-parent = <&gpio2>; + interrupts = <15 0>; + pendown-gpio = <&gpio2 15 0>; + + ti,x-min = /bits/ 16 <0x0>; + ti,x-max = /bits/ 16 <0x0fff>; + ti,y-min = /bits/ 16 <0x0>; + ti,y-max = /bits/ 16 <0x0fff>; + + ti,x-plate-ohms = /bits/ 16 <180>; + ti,pressure-max = /bits/ 16 <255>; + + ti,debounce-max = /bits/ 16 <30>; + ti,debounce-tol = /bits/ 16 <10>; + ti,debounce-rep = /bits/ 16 <1>; + + linux,wakeup; + }; +}; + +/* eth0 */ +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + status = "okay"; +}; + +/* nand */ +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + status = "okay"; + + partition@0 { + label = "linux"; + reg = <0x0 0x800000>; + }; + + partition@800000 { + label = "rootfs"; + reg = < 0x800000 0x0>; + }; +}; + +/* i2c3 */ +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + codec: wm8731@1a { + compatible = "wlf,wm8731"; + reg = <0x1a>; + clocks = <&clks 173>, <&clks 158>, <&clks 201>, <&clks 200>; + clock-names = "pll4", "imx-ssi.1", "cko", "cko2"; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio1 26 0>; + vdd-supply = <&pcie_power_on_gpio>; + status = "okay"; +}; + +/* console */ +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +/* usb otg */ +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + dr_mode = "otg"; + status = "okay"; +}; + +/* usb hub1 */ +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + status = "okay"; +}; + +/* wifi/bt */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_mrvl1>; + non-removable; + vmmc-supply = <&awnh387_npoweron>; + vmmc_aux-supply = <&awnh387_wifi_nreset>; + status = "okay"; +}; + +&ssi2 { + fsl,mode = "i2s-master"; + status = "okay"; +}; + +&spdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spdif>; + status = "okay"; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; diff --git a/arch/arm/include/asm/common.h b/arch/arm/include/asm/common.h index 9ff3b19c7b..07ae619cea 100644 --- a/arch/arm/include/asm/common.h +++ b/arch/arm/include/asm/common.h @@ -1,8 +1,6 @@ #ifndef __ASM_ARM_COMMON_H #define __ASM_ARM_COMMON_H -#define ARCH_SHUTDOWN - static inline unsigned long get_pc(void) { unsigned long pc; diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S index bb0354ae29..5344557860 100644 --- a/arch/arm/lib/barebox.lds.S +++ b/arch/arm/lib/barebox.lds.S @@ -90,6 +90,10 @@ SECTIONS .barebox_initcalls : { INITCALLS } __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + __usymtab_start = .; __usymtab : { BAREBOX_SYMS } __usymtab_end = .; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 631333f271..0de2d3e153 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -347,6 +347,10 @@ config MACH_GW_VENTANA select I2C select I2C_IMX +config MACH_CM_FX6 + bool "CM FX6" + select ARCH_IMX6 + endif # ---------------------------------------------------------- @@ -674,8 +678,10 @@ config IMX_OCOTP_WRITE prompt "Enable write support of i.MX6 CPUs OTP fuses" depends on IMX_OCOTP help - This adds write support to IMX6 On-Chip OTP registers. - Example of set MAC to 12:34:56:78:9A:BC (2 words with offset 0x22 * 4): + This adds write support to IMX6 On-Chip OTP registers. Example of set + MAC to 12:34:56:78:9A:BC (2 words with address 0x22 (OCOTP_MAC0) and + address 0x23 (OCOTP_MAC1)). To calculate the file offset multiply + the value of the address by 4. mw -l -d /dev/imx-ocotp 0x8C 0x00001234 mw -l -d /dev/imx-ocotp 0x88 0x56789ABC diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 458d7b45bb..db1cf7df08 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -18,9 +18,9 @@ obj-$(CONFIG_IMX_OCOTP) += ocotp.o obj-$(CONFIG_NAND_IMX) += nand.o lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-pfd.o clk-gate2.o clk-gate-exclusive.o -obj-y += devices.o imx.o esdctl.o -obj-y += boot.o +obj-y += devices.o imx.o +obj-pbl-y += esdctl.o boot.o obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o obj-$(CONFIG_BAREBOX_UPDATE_IMX_EXTERNAL_NAND) += imx-bbu-external-nand.o -pbl-y += esdctl.o lwl-y += cpu_init.o +pbl-y += xload-spi.o xload-esdhc.o xload-common.o diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index 4416011c22..376e370cf9 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -21,6 +21,7 @@ #include <mach/generic.h> #include <mach/imx25-regs.h> #include <mach/imx35-regs.h> +#include <mach/imx6-regs.h> /* [CTRL][TYPE] */ static const enum bootsource locations[4][4] = { @@ -214,10 +215,9 @@ void imx53_boot_save_loc(void __iomem *src_base) #define IMX6_SRC_SBMR1 0x04 #define IMX6_SRC_SBMR2 0x1c -void imx6_boot_save_loc(void __iomem *src_base) +void imx6_get_boot_source(enum bootsource *src, int *instance) { - enum bootsource src = BOOTSOURCE_UNKNOWN; - int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + void __iomem *src_base = IOMEM(MX6_SRC_BASE_ADDR); uint32_t sbmr1 = readl(src_base + IMX6_SRC_SBMR1); uint32_t sbmr2 = readl(src_base + IMX6_SRC_SBMR2); uint32_t boot_cfg_4_2_0; @@ -231,14 +231,12 @@ void imx6_boot_save_loc(void __iomem *src_base) case 2: /* internal boot */ goto internal_boot; case 1: /* Serial Downloader */ - src = BOOTSOURCE_SERIAL; + *src = BOOTSOURCE_SERIAL; break; case 3: /* reserved */ break; }; - bootsource_set(src); - return; internal_boot: @@ -246,28 +244,28 @@ internal_boot: /* BOOT_CFG1[7:4] */ switch ((sbmr1 >> 4) & 0xf) { case 2: - src = BOOTSOURCE_HD; + *src = BOOTSOURCE_HD; break; case 3: /* BOOT_CFG4[2:0] */ boot_cfg_4_2_0 = (sbmr1 >> 24) & 0x7; if (boot_cfg_4_2_0 > 4) { - src = BOOTSOURCE_I2C; - instance = boot_cfg_4_2_0 - 5; + *src = BOOTSOURCE_I2C; + *instance = boot_cfg_4_2_0 - 5; } else { - src = BOOTSOURCE_SPI; - instance = boot_cfg_4_2_0; + *src = BOOTSOURCE_SPI; + *instance = boot_cfg_4_2_0; } break; case 4: case 5: case 6: case 7: - src = BOOTSOURCE_MMC; + *src = BOOTSOURCE_MMC; /* BOOT_CFG2[4:3] */ - instance = (sbmr1 >> 11) & 0x3; + *instance = (sbmr1 >> 11) & 0x3; break; default: break; @@ -275,10 +273,18 @@ internal_boot: /* BOOT_CFG1[7:0] */ if (sbmr1 & (1 << 7)) - src = BOOTSOURCE_NAND; + *src = BOOTSOURCE_NAND; + + return; +} + +void imx6_boot_save_loc(void __iomem *src_base) +{ + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + + imx6_get_boot_source(&src, &instance); bootsource_set(src); bootsource_set_instance(instance); - - return; } diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c index a8ef854700..2f9f5e971e 100644 --- a/arch/arm/mach-imx/esdctl.c +++ b/arch/arm/mach-imx/esdctl.c @@ -576,3 +576,14 @@ void __noreturn imx53_barebox_entry(void *boarddata) barebox_arm_entry(base, size, boarddata); } + +void __noreturn imx6q_barebox_entry(void *boarddata) +{ + u64 size_cs0 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 0); + u64 size_cs1 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 1); + u64 total = size_cs0 + size_cs1; + + resource_size_t size = min(total, (u64)IMX6_MAX_SDRAM_SIZE); + + barebox_arm_entry(0x10000000, size, boarddata); +} diff --git a/arch/arm/mach-imx/imx6-mmdc.c b/arch/arm/mach-imx/imx6-mmdc.c index c460d9bc48..64fb62401d 100644 --- a/arch/arm/mach-imx/imx6-mmdc.c +++ b/arch/arm/mach-imx/imx6-mmdc.c @@ -18,6 +18,8 @@ #include <common.h> #include <io.h> #include <mach/imx6-mmdc.h> +#include <mach/imx6-regs.h> +#include <mach/imx6.h> int mmdc_do_write_level_calibration(void) { @@ -841,3 +843,545 @@ int mmdc_do_software_calibration(void) } #endif /* MMDC_SOFTWARE_CALIBRATION */ + +/* Configure MX6SX mmdc iomux */ +void mx6sx_dram_iocfg(unsigned width, + const struct mx6sx_iomux_ddr_regs *ddr, + const struct mx6sx_iomux_grp_regs *grp) +{ + struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux; + struct mx6sx_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE; + + /* DDR IO TYPE */ + writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type); + writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke); + + /* CLOCK */ + writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0); + + /* ADDRESS */ + writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas); + writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras); + writel(grp->grp_addds, &mx6_grp_iomux->grp_addds); + + /* Control */ + writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset); + writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2); + writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0); + writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1); + writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0); + writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1); + writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds); + + /* Data Strobes */ + writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl); + writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0); + writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1); + if (width >= 32) { + writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2); + writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3); + } + + /* Data */ + writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode); + writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds); + writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds); + if (width >= 32) { + writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds); + writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds); + } + writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0); + writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1); + if (width >= 32) { + writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2); + writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3); + } +} + +/* Configure MX6DQ mmdc iomux */ +void mx6dq_dram_iocfg(unsigned width, + const struct mx6dq_iomux_ddr_regs *ddr, + const struct mx6dq_iomux_grp_regs *grp) +{ + volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux; + volatile struct mx6dq_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6dq_iomux_ddr_regs *)MX6DQ_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6dq_iomux_grp_regs *)MX6DQ_IOM_GRP_BASE; + + /* DDR IO Type */ + mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; + mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; + + /* Clock */ + mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; + mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; + + /* Address */ + mx6_ddr_iomux->dram_cas = ddr->dram_cas; + mx6_ddr_iomux->dram_ras = ddr->dram_ras; + mx6_grp_iomux->grp_addds = grp->grp_addds; + + /* Control */ + mx6_ddr_iomux->dram_reset = ddr->dram_reset; + mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; + mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; + mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; + mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; + mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; + mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; + + /* Data Strobes */ + mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; + mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; + mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; + if (width >= 32) { + mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; + mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; + mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; + mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; + mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; + } + + /* Data */ + mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; + mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; + mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; + if (width >= 32) { + mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; + mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; + } + if (width >= 64) { + mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; + mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; + mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; + mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; + } + mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; + mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; + if (width >= 32) { + mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; + mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; + mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; + mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; + mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; + } +} + +/* Configure MX6SDL mmdc iomux */ +void mx6sdl_dram_iocfg(unsigned width, + const struct mx6sdl_iomux_ddr_regs *ddr, + const struct mx6sdl_iomux_grp_regs *grp) +{ + volatile struct mx6sdl_iomux_ddr_regs *mx6_ddr_iomux; + volatile struct mx6sdl_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6sdl_iomux_ddr_regs *)MX6SDL_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6sdl_iomux_grp_regs *)MX6SDL_IOM_GRP_BASE; + + /* DDR IO Type */ + mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; + mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; + + /* Clock */ + mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; + mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; + + /* Address */ + mx6_ddr_iomux->dram_cas = ddr->dram_cas; + mx6_ddr_iomux->dram_ras = ddr->dram_ras; + mx6_grp_iomux->grp_addds = grp->grp_addds; + + /* Control */ + mx6_ddr_iomux->dram_reset = ddr->dram_reset; + mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; + mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; + mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; + mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; + mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; + mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; + + /* Data Strobes */ + mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; + mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; + mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; + if (width >= 32) { + mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; + mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; + mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; + mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; + mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; + } + + /* Data */ + mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; + mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; + mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; + if (width >= 32) { + mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; + mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; + } + if (width >= 64) { + mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; + mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; + mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; + mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; + } + mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; + mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; + if (width >= 32) { + mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; + mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; + mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; + mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; + mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; + } +} + +static void __udelay(int us) +{ + volatile int i; + + for (i = 0; i < us * 1000; i++); +} + +/* + * Configure mx6 mmdc registers based on: + * - board-specific memory configuration + * - board-specific calibration data + * - ddr3 chip details + * + * The various calculations here are derived from the Freescale + * i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate MMDC + * configuration registers based on memory system and memory chip parameters. + * + * The defaults here are those which were specified in the spreadsheet. + * For details on each register, refer to the IMX6DQRM and/or IMX6SDLRM + * section titled MMDC initialization + */ +#define MR(val, ba, cmd, cs1) \ + ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) + +#define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1)) + +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, + const struct mx6_mmdc_calibration *calib, + const struct mx6_ddr3_cfg *ddr3_cfg) +{ + volatile struct mmdc_p_regs *mmdc0; + volatile struct mmdc_p_regs *mmdc1; + + u32 val; + u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd; + u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl; + u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */ + u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr; + u16 cs0_end; + u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */ + u8 coladdr; + int clkper; /* clock period in picoseconds */ + int clock; /* clock freq in MHz */ + int cs; + u16 mem_speed = ddr3_cfg->mem_speed; + + mmdc0 = (struct mmdc_p_regs *)MX6_MMDC_P0_BASE_ADDR; + mmdc1 = (struct mmdc_p_regs *)MX6_MMDC_P1_BASE_ADDR; + + /* Limit mem_speed for MX6D/MX6Q */ + if (cpu_mx6_is_mx6q() || cpu_mx6_is_mx6d()) { + if (mem_speed > 1066) + mem_speed = 1066; /* 1066 MT/s */ + + tcwl = 4; + } + /* Limit mem_speed for MX6S/MX6DL */ + else { + if (mem_speed > 800) + mem_speed = 800; /* 800 MT/s */ + + tcwl = 3; + } + + clock = mem_speed / 2; + /* + * Data rate of 1066 MT/s requires 533 MHz DDR3 clock, but MX6D/Q supports + * up to 528 MHz, so reduce the clock to fit chip specs + */ + if (cpu_mx6_is_mx6q() || cpu_mx6_is_mx6d()) { + if (clock > 528) + clock = 528; /* 528 MHz */ + } + + clkper = (1000 * 1000) / clock; /* pico seconds */ + todtlon = tcwl; + taxpd = tcwl; + tanpd = tcwl; + + switch (ddr3_cfg->density) { + case 1: /* 1Gb per chip */ + trfc = DIV_ROUND_UP(110000, clkper) - 1; + txs = DIV_ROUND_UP(120000, clkper) - 1; + break; + case 2: /* 2Gb per chip */ + trfc = DIV_ROUND_UP(160000, clkper) - 1; + txs = DIV_ROUND_UP(170000, clkper) - 1; + break; + case 4: /* 4Gb per chip */ + trfc = DIV_ROUND_UP(260000, clkper) - 1; + txs = DIV_ROUND_UP(270000, clkper) - 1; + break; + case 8: /* 8Gb per chip */ + trfc = DIV_ROUND_UP(350000, clkper) - 1; + txs = DIV_ROUND_UP(360000, clkper) - 1; + break; + default: + /* invalid density */ + pr_err("invalid chip density\n"); + hang(); + break; + } + txpr = txs; + + switch (mem_speed) { + case 800: + txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(40000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(50000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } + break; + case 1066: + txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 5625), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(37500, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 7500), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(50000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } + break; + default: + pr_err("invalid memory speed\n"); + hang(); + break; + } + txpdll = DIV_ROUND_UP(max(10 * clkper, 24000), clkper) - 1; + tcksre = DIV_ROUND_UP(max(5 * clkper, 10000), clkper); + taonpd = DIV_ROUND_UP(2000, clkper) - 1; + tcksrx = tcksre; + taofpd = taonpd; + twr = DIV_ROUND_UP(15000, clkper) - 1; + tmrd = DIV_ROUND_UP(max(12 * clkper, 15000), clkper) - 1; + trc = DIV_ROUND_UP(ddr3_cfg->trcmin, clkper / 10) - 1; + tras = DIV_ROUND_UP(ddr3_cfg->trasmin, clkper / 10) - 1; + tcl = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 3; + trp = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 1; + twtr = ROUND(max(4 * clkper, 7500) / clkper, 1) - 1; + trcd = trp; + trtp = twtr; + cs0_end = 4 * sysinfo->cs_density - 1 + 8; + + debug("density:%d Gb (%d Gb per chip)\n", + sysinfo->cs_density, ddr3_cfg->density); + debug("clock: %dMHz (%d ps)\n", clock, clkper); + debug("memspd:%d\n", mem_speed); + debug("tcke=%d\n", tcke); + debug("tcksrx=%d\n", tcksrx); + debug("tcksre=%d\n", tcksre); + debug("taofpd=%d\n", taofpd); + debug("taonpd=%d\n", taonpd); + debug("todtlon=%d\n", todtlon); + debug("tanpd=%d\n", tanpd); + debug("taxpd=%d\n", taxpd); + debug("trfc=%d\n", trfc); + debug("txs=%d\n", txs); + debug("txp=%d\n", txp); + debug("txpdll=%d\n", txpdll); + debug("tfaw=%d\n", tfaw); + debug("tcl=%d\n", tcl); + debug("trcd=%d\n", trcd); + debug("trp=%d\n", trp); + debug("trc=%d\n", trc); + debug("tras=%d\n", tras); + debug("twr=%d\n", twr); + debug("tmrd=%d\n", tmrd); + debug("tcwl=%d\n", tcwl); + debug("tdllk=%d\n", tdllk); + debug("trtp=%d\n", trtp); + debug("twtr=%d\n", twtr); + debug("trrd=%d\n", trrd); + debug("txpr=%d\n", txpr); + debug("cs0_end=%d\n", cs0_end); + debug("ncs=%d\n", sysinfo->ncs); + debug("Rtt_wr=%d\n", sysinfo->rtt_wr); + debug("Rtt_nom=%d\n", sysinfo->rtt_nom); + debug("SRT=%d\n", ddr3_cfg->SRT); + debug("tcl=%d\n", tcl); + debug("twr=%d\n", twr); + + /* + * board-specific configuration: + * These values are determined empirically and vary per board layout + * see: + * appnote, ddr3 spreadsheet + */ + mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0; + mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1; + mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0; + mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; + mmdc0->mprddlctl = calib->p0_mprddlctl; + mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; + if (sysinfo->dsize > 1) { + mmdc1->mpwldectrl0 = calib->p1_mpwldectrl0; + mmdc1->mpwldectrl1 = calib->p1_mpwldectrl1; + mmdc1->mpdgctrl0 = calib->p1_mpdgctrl0; + mmdc1->mpdgctrl1 = calib->p1_mpdgctrl1; + mmdc1->mprddlctl = calib->p1_mprddlctl; + mmdc1->mpwrdlctl = calib->p1_mpwrdlctl; + } + + /* Read data DQ Byte0-3 delay */ + mmdc0->mprddqby0dl = 0x33333333; + mmdc0->mprddqby1dl = 0x33333333; + if (sysinfo->dsize > 0) { + mmdc0->mprddqby2dl = 0x33333333; + mmdc0->mprddqby3dl = 0x33333333; + } + + if (sysinfo->dsize > 1) { + mmdc1->mprddqby0dl = 0x33333333; + mmdc1->mprddqby1dl = 0x33333333; + mmdc1->mprddqby2dl = 0x33333333; + mmdc1->mprddqby3dl = 0x33333333; + } + + /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ + val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; + mmdc0->mpodtctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpodtctrl = val; + + /* complete calibration */ + val = (1 << 11); /* Force measurement on delay-lines */ + mmdc0->mpmur0 = val; + if (sysinfo->dsize > 1) + mmdc1->mpmur0 = val; + + /* Step 1: configuration request */ + mmdc0->mdscr = (u32)(1 << 15); /* config request */ + + /* Step 2: Timing configuration */ + mmdc0->mdcfg0 = (trfc << 24) | (txs << 16) | (txp << 13) | + (txpdll << 9) | (tfaw << 4) | tcl; + mmdc0->mdcfg1 = (trcd << 29) | (trp << 26) | (trc << 21) | + (tras << 16) | (1 << 15) /* trpa */ | + (twr << 9) | (tmrd << 5) | tcwl; + mmdc0->mdcfg2 = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd; + mmdc0->mdotc = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | + (taxpd << 16) | (todtlon << 12) | (todt_idle_off << 4); + mmdc0->mdasp = cs0_end; /* CS addressing */ + + /* Step 3: Configure DDR type */ + mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | + (sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | + (sysinfo->ralat << 6); + + /* Step 4: Configure delay while leaving reset */ + mmdc0->mdor = (txpr << 16) | (sysinfo->sde_to_rst << 8) | + (sysinfo->rst_to_cke << 0); + + /* Step 5: Configure DDR physical parameters (density and burst len) */ + coladdr = ddr3_cfg->coladdr; + if (ddr3_cfg->coladdr == 8) /* 8-bit COL is 0x3 */ + coladdr += 4; + else if (ddr3_cfg->coladdr == 12) /* 12-bit COL is 0x4 */ + coladdr += 1; + mmdc0->mdctl = (ddr3_cfg->rowaddr - 11) << 24 | /* ROW */ + (coladdr - 9) << 20 | /* COL */ + (1 << 19) | /* Burst Length = 8 for DDR3 */ + (sysinfo->dsize << 16); /* DDR data bus size */ + + /* Step 6: Perform ZQ calibration */ + val = 0xa1390001; /* one-time HW ZQ calib */ + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpzqhwctrl = val; + + /* Step 7: Enable MMDC with desired chip select */ + mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */ + ((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ + + /* Step 8: Write Mode Registers to Init DDR3 devices */ + for (cs = 0; cs < sysinfo->ncs; cs++) { + /* MR2 */ + val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | + ((tcwl - 3) & 3) << 3; + debug("MR2 CS%d: 0x%08x\n", cs, (u32)MR(val, 2, 3, cs)); + mmdc0->mdscr = MR(val, 2, 3, cs); + /* MR3 */ + debug("MR3 CS%d: 0x%08x\n", cs, (u32)MR(0, 3, 3, cs)); + mmdc0->mdscr = MR(0, 3, 3, cs); + /* MR1 */ + val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 | + ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6; + debug("MR1 CS%d: 0x%08x\n", cs, (u32)MR(val, 1, 3, cs)); + mmdc0->mdscr = MR(val, 1, 3, cs); + /* MR0 */ + val = ((tcl - 1) << 4) | /* CAS */ + (1 << 8) | /* DLL Reset */ + ((twr - 3) << 9) | /* Write Recovery */ + (sysinfo->pd_fast_exit << 12); /* Precharge PD PLL on */ + debug("MR0 CS%d: 0x%08x\n", cs, (u32)MR(val, 0, 3, cs)); + mmdc0->mdscr = MR(val, 0, 3, cs); + /* ZQ calibration */ + val = (1 << 10); + mmdc0->mdscr = MR(val, 0, 4, cs); + } + + /* Step 10: Power down control and self-refresh */ + mmdc0->mdpdc = (tcke & 0x7) << 16 | + 5 << 12 | /* PWDT_1: 256 cycles */ + 5 << 8 | /* PWDT_0: 256 cycles */ + 1 << 6 | /* BOTH_CS_PD */ + (tcksrx & 0x7) << 3 | + (tcksre & 0x7); + if (!sysinfo->pd_fast_exit) + mmdc0->mdpdc |= (1 << 7); /* SLOW_PD */ + mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ + + /* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ + val = 0xa1390003; + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + mmdc1->mpzqhwctrl = val; + + /* Step 12: Configure and activate periodic refresh */ + mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */ + (7 << 11); /* REFR: Refresh Rate - 8 refreshes */ + + /* Step 13: Deassert config request - init complete */ + mmdc0->mdscr = 0x00000000; + + /* wait for auto-ZQ calibration to complete */ + __udelay(100); +} diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index eceac40fb6..4f2d923aa0 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -21,33 +21,6 @@ #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num) -static inline void imx_uart_setup_ll(void __iomem *uartbase, - unsigned int refclock) -{ - writel(0x00000000, uartbase + UCR1); - - writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST, - uartbase + UCR2); - writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL, - uartbase + UCR3); - writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF), - uartbase + UFCR); - - writel(baudrate_to_ubir(CONFIG_BAUDRATE), - uartbase + UBIR); - writel(refclock_to_ubmr(refclock), - uartbase + UBMR); - - writel(UCR1_UARTEN, uartbase + UCR1); -} - -#define __imx_uart_setup_ll(refclock) \ - do { \ - imx_uart_setup_ll(IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, \ - CONFIG_DEBUG_IMX_UART_PORT)), \ - refclock); \ - } while(0) - #ifdef CONFIG_DEBUG_IMX1_UART #define IMX_DEBUG_SOC MX1 #elif defined CONFIG_DEBUG_IMX21_UART @@ -72,17 +45,23 @@ static inline void imx_uart_setup_ll(void __iomem *uartbase, static inline void imx51_uart_setup_ll(void) { - __imx_uart_setup_ll(54000000); + void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); + + imx51_uart_setup(base); } static inline void imx53_uart_setup_ll(void) { - __imx_uart_setup_ll(66666666); + void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); + + imx53_uart_setup(base); } static inline void imx6_uart_setup_ll(void) { - __imx_uart_setup_ll(80000000); + void *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); + + imx6_uart_setup(base); } static inline void PUTC_LL(int c) @@ -93,20 +72,10 @@ static inline void PUTC_LL(int c) if (!base) return; - if (!(readl(base + UCR1) & UCR1_UARTEN)) - return; - - while (!(readl(base + USR2) & USR2_TXDC)); - - writel(c, base + URTX0); + imx_uart_putc(base, c); } #else -static inline void imx_uart_setup_ll(void __iomem *uartbase, - unsigned int refclock) -{ -} - static inline void imx51_uart_setup_ll(void) {} static inline void imx53_uart_setup_ll(void) {} static inline void imx6_uart_setup_ll(void) {} diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h index 468a9280c7..cf8d89d742 100644 --- a/arch/arm/mach-imx/include/mach/esdctl.h +++ b/arch/arm/mach-imx/include/mach/esdctl.h @@ -135,7 +135,7 @@ void __noreturn imx31_barebox_entry(void *boarddata); void __noreturn imx35_barebox_entry(void *boarddata); void __noreturn imx51_barebox_entry(void *boarddata); void __noreturn imx53_barebox_entry(void *boarddata); -void __noreturn imx6_barebox_entry(void *boarddata); +void __noreturn imx6q_barebox_entry(void *boarddata); void imx_esdctl_disable(void); #endif diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index d4b6a1f7b4..46fe38856f 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -3,6 +3,7 @@ #include <linux/compiler.h> #include <linux/types.h> +#include <bootsource.h> u64 imx_uid(void); @@ -12,6 +13,7 @@ void imx27_boot_save_loc(void __iomem *sysctrl_base); void imx51_boot_save_loc(void __iomem *src_base); void imx53_boot_save_loc(void __iomem *src_base); void imx6_boot_save_loc(void __iomem *src_base); +void imx6_get_boot_source(enum bootsource *src, int *instance); int imx1_init(void); int imx21_init(void); diff --git a/arch/arm/mach-imx/include/mach/imx6-mmdc.h b/arch/arm/mach-imx/include/mach/imx6-mmdc.h index 6ab8049be3..9385b342c2 100644 --- a/arch/arm/mach-imx/include/mach/imx6-mmdc.h +++ b/arch/arm/mach-imx/include/mach/imx6-mmdc.h @@ -54,4 +54,278 @@ int mmdc_do_write_level_calibration(void); int mmdc_do_dqs_calibration(void); void mmdc_print_calibration_results(void); +/* MMDC P0/P1 Registers */ +struct mmdc_p_regs { + u32 mdctl; + u32 mdpdc; + u32 mdotc; + u32 mdcfg0; + u32 mdcfg1; + u32 mdcfg2; + u32 mdmisc; + u32 mdscr; + u32 mdref; + u32 res1[2]; + u32 mdrwd; + u32 mdor; + u32 res2[3]; + u32 mdasp; + u32 res3[240]; + u32 mapsr; + u32 res4[254]; + u32 mpzqhwctrl; + u32 res5[2]; + u32 mpwldectrl0; + u32 mpwldectrl1; + u32 res6; + u32 mpodtctrl; + u32 mprddqby0dl; + u32 mprddqby1dl; + u32 mprddqby2dl; + u32 mprddqby3dl; + u32 res7[4]; + u32 mpdgctrl0; + u32 mpdgctrl1; + u32 res8; + u32 mprddlctl; + u32 res9; + u32 mpwrdlctl; + u32 res10[25]; + u32 mpmur0; +}; + +#define MX6SX_IOM_DDR_BASE 0x020e0200 +struct mx6sx_iomux_ddr_regs { + u32 res1[59]; + u32 dram_dqm0; + u32 dram_dqm1; + u32 dram_dqm2; + u32 dram_dqm3; + u32 dram_ras; + u32 dram_cas; + u32 res2[2]; + u32 dram_sdwe_b; + u32 dram_odt0; + u32 dram_odt1; + u32 dram_sdba0; + u32 dram_sdba1; + u32 dram_sdba2; + u32 dram_sdcke0; + u32 dram_sdcke1; + u32 dram_sdclk_0; + u32 dram_sdqs0; + u32 dram_sdqs1; + u32 dram_sdqs2; + u32 dram_sdqs3; + u32 dram_reset; +}; + +#define MX6SX_IOM_GRP_BASE 0x020e0500 +struct mx6sx_iomux_grp_regs { + u32 res1[61]; + u32 grp_addds; + u32 grp_ddrmode_ctl; + u32 grp_ddrpke; + u32 grp_ddrpk; + u32 grp_ddrhys; + u32 grp_ddrmode; + u32 grp_b0ds; + u32 grp_b1ds; + u32 grp_ctlds; + u32 grp_ddr_type; + u32 grp_b2ds; + u32 grp_b3ds; +}; + +/* + * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL) + */ +#define MX6DQ_IOM_DDR_BASE 0x020e0500 +struct mx6dq_iomux_ddr_regs { + u32 res1[3]; + u32 dram_sdqs5; + u32 dram_dqm5; + u32 dram_dqm4; + u32 dram_sdqs4; + u32 dram_sdqs3; + u32 dram_dqm3; + u32 dram_sdqs2; + u32 dram_dqm2; + u32 res2[16]; + u32 dram_cas; + u32 res3[2]; + u32 dram_ras; + u32 dram_reset; + u32 res4[2]; + u32 dram_sdclk_0; + u32 dram_sdba2; + u32 dram_sdcke0; + u32 dram_sdclk_1; + u32 dram_sdcke1; + u32 dram_sdodt0; + u32 dram_sdodt1; + u32 res5; + u32 dram_sdqs0; + u32 dram_dqm0; + u32 dram_sdqs1; + u32 dram_dqm1; + u32 dram_sdqs6; + u32 dram_dqm6; + u32 dram_sdqs7; + u32 dram_dqm7; +}; + +#define MX6DQ_IOM_GRP_BASE 0x020e0700 +struct mx6dq_iomux_grp_regs { + u32 res1[18]; + u32 grp_b7ds; + u32 grp_addds; + u32 grp_ddrmode_ctl; + u32 res2; + u32 grp_ddrpke; + u32 res3[6]; + u32 grp_ddrmode; + u32 res4[3]; + u32 grp_b0ds; + u32 grp_b1ds; + u32 grp_ctlds; + u32 res5; + u32 grp_b2ds; + u32 grp_ddr_type; + u32 grp_b3ds; + u32 grp_b4ds; + u32 grp_b5ds; + u32 grp_b6ds; +}; + +#define MX6SDL_IOM_DDR_BASE 0x020e0400 +struct mx6sdl_iomux_ddr_regs { + u32 res1[25]; + u32 dram_cas; + u32 res2[2]; + u32 dram_dqm0; + u32 dram_dqm1; + u32 dram_dqm2; + u32 dram_dqm3; + u32 dram_dqm4; + u32 dram_dqm5; + u32 dram_dqm6; + u32 dram_dqm7; + u32 dram_ras; + u32 dram_reset; + u32 res3[2]; + u32 dram_sdba2; + u32 dram_sdcke0; + u32 dram_sdcke1; + u32 dram_sdclk_0; + u32 dram_sdclk_1; + u32 dram_sdodt0; + u32 dram_sdodt1; + u32 dram_sdqs0; + u32 dram_sdqs1; + u32 dram_sdqs2; + u32 dram_sdqs3; + u32 dram_sdqs4; + u32 dram_sdqs5; + u32 dram_sdqs6; + u32 dram_sdqs7; +}; + +#define MX6SDL_IOM_GRP_BASE 0x020e0700 +struct mx6sdl_iomux_grp_regs { + u32 res1[18]; + u32 grp_b7ds; + u32 grp_addds; + u32 grp_ddrmode_ctl; + u32 grp_ddrpke; + u32 res2[2]; + u32 grp_ddrmode; + u32 grp_b0ds; + u32 res3; + u32 grp_ctlds; + u32 grp_b1ds; + u32 grp_ddr_type; + u32 grp_b2ds; + u32 grp_b3ds; + u32 grp_b4ds; + u32 grp_b5ds; + u32 res4; + u32 grp_b6ds; +}; + +/* Device Information: Varies per DDR3 part number and speed grade */ +struct mx6_ddr3_cfg { + u16 mem_speed; /* ie 1600 for DDR3-1600 (800,1066,1333,1600) */ + u8 density; /* chip density (Gb) (1,2,4,8) */ + u8 width; /* bus width (bits) (4,8,16) */ + u8 banks; /* number of banks */ + u8 rowaddr; /* row address bits (11-16)*/ + u8 coladdr; /* col address bits (9-12) */ + u8 pagesz; /* page size (K) (1-2) */ + u16 trcd; /* tRCD=tRP=CL (ns*100) */ + u16 trcmin; /* tRC min (ns*100) */ + u16 trasmin; /* tRAS min (ns*100) */ + u8 SRT; /* self-refresh temperature: 0=normal, 1=extended */ +}; + +/* System Information: Varies per board design, layout, and term choices */ +struct mx6_ddr_sysinfo { + u8 dsize; /* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */ + u8 cs_density; /* density per chip select (Gb) */ + u8 ncs; /* number chip selects used (1|2) */ + char cs1_mirror;/* enable address mirror (0|1) */ + char bi_on; /* Bank interleaving enable */ + u8 rtt_nom; /* Rtt_Nom (DDR3_RTT_*) */ + u8 rtt_wr; /* Rtt_Wr (DDR3_RTT_*) */ + u8 ralat; /* Read Additional Latency (0-7) */ + u8 walat; /* Write Additional Latency (0-3) */ + u8 mif3_mode; /* Command prediction working mode */ + u8 rst_to_cke; /* Time from SDE enable to CKE rise */ + u8 sde_to_rst; /* Time from SDE enable until DDR reset# is high */ + u8 pd_fast_exit;/* enable precharge powerdown fast-exit */ +}; + +/* + * Board specific calibration: + * This includes write leveling calibration values as well as DQS gating + * and read/write delays. These values are board/layout/device specific. + * Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2 + * (DOC-96412) to determine these values over a range of boards and + * temperatures. + */ +struct mx6_mmdc_calibration { + /* write leveling calibration */ + u32 p0_mpwldectrl0; + u32 p0_mpwldectrl1; + u32 p1_mpwldectrl0; + u32 p1_mpwldectrl1; + /* read DQS gating */ + u32 p0_mpdgctrl0; + u32 p0_mpdgctrl1; + u32 p1_mpdgctrl0; + u32 p1_mpdgctrl1; + /* read delay */ + u32 p0_mprddlctl; + u32 p1_mprddlctl; + /* write delay */ + u32 p0_mpwrdlctl; + u32 p1_mpwrdlctl; +}; + +/* configure iomux (pinctl/padctl) */ +void mx6dq_dram_iocfg(unsigned width, + const struct mx6dq_iomux_ddr_regs *, + const struct mx6dq_iomux_grp_regs *); +void mx6sdl_dram_iocfg(unsigned width, + const struct mx6sdl_iomux_ddr_regs *, + const struct mx6sdl_iomux_grp_regs *); +void mx6sx_dram_iocfg(unsigned width, + const struct mx6sx_iomux_ddr_regs *, + const struct mx6sx_iomux_grp_regs *); + +/* configure mx6 mmdc registers */ +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *, + const struct mx6_mmdc_calibration *, + const struct mx6_ddr3_cfg *); + #endif /* __MACH_MMDC_H */ diff --git a/arch/arm/mach-imx/include/mach/imx6.h b/arch/arm/mach-imx/include/mach/imx6.h index 3b7542169e..3ddb6d2d0e 100644 --- a/arch/arm/mach-imx/include/mach/imx6.h +++ b/arch/arm/mach-imx/include/mach/imx6.h @@ -48,29 +48,22 @@ static inline int imx6_cpu_type(void) return __imx6_cpu_type(); } -static inline int cpu_is_mx6s(void) -{ - return imx6_cpu_type() == IMX6_CPUTYPE_IMX6S; -} - -static inline int cpu_is_mx6dl(void) -{ - return imx6_cpu_type() == IMX6_CPUTYPE_IMX6DL; -} - -static inline int cpu_is_mx6d(void) -{ - return imx6_cpu_type() == IMX6_CPUTYPE_IMX6D; -} - -static inline int cpu_is_mx6q(void) -{ - return imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q; -} - -static inline int cpu_is_mx6sx(void) -{ - return imx6_cpu_type() == IMX6_CPUTYPE_IMX6SX; -} +#define DEFINE_MX6_CPU_TYPE(str, type) \ + static inline int cpu_mx6_is_##str(void) \ + { \ + return __imx6_cpu_type() == type; \ + } \ + \ + static inline int cpu_is_##str(void) \ + { \ + if (!cpu_is_mx6()) \ + return 0; \ + return cpu_mx6_is_##str(); \ + } + +DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL); +DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q); +DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D); +DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX); #endif /* __MACH_IMX6_H */ diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h new file mode 100644 index 0000000000..997522e2d5 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/xload.h @@ -0,0 +1,11 @@ +#ifndef __MACH_XLOAD_H +#define __MACH_XLOAD_H + +int imx6_spi_load_image(int instance, unsigned int flash_offset, void *buf, int len); +int imx6_spi_start_image(int instance); +int imx6_esdhc_load_image(int instance, void *buf, int len); +int imx6_esdhc_start_image(int instance); + +int imx_image_size(void); + +#endif /* __MACH_XLOAD_H */ diff --git a/arch/arm/mach-imx/xload-common.c b/arch/arm/mach-imx/xload-common.c new file mode 100644 index 0000000000..2644438f40 --- /dev/null +++ b/arch/arm/mach-imx/xload-common.c @@ -0,0 +1,29 @@ +#include <common.h> +#include <asm/sections.h> +#include <linux/sizes.h> +#include <mach/xload.h> + +int imx_image_size(void) +{ + uint32_t *image_end = (void *)ld_var(__image_end); + uint32_t payload_len, pbl_len, imx_header_len, sizep; + void *pg_start; + + pg_start = image_end + 1; + + /* i.MX header is 4k */ + imx_header_len = SZ_4K; + + /* The length of the PBL image */ + pbl_len = ld_var(__image_end) - ld_var(_text); + + sizep = 4; + + /* The length of the payload is appended directly behind the PBL */ + payload_len = *(image_end); + + pr_debug("%s: payload_len: 0x%08x pbl_len: 0x%08x\n", + __func__, payload_len, pbl_len); + + return imx_header_len + pbl_len + sizep + payload_len; +} diff --git a/arch/arm/mach-imx/xload-esdhc.c b/arch/arm/mach-imx/xload-esdhc.c new file mode 100644 index 0000000000..6479ce0153 --- /dev/null +++ b/arch/arm/mach-imx/xload-esdhc.c @@ -0,0 +1,274 @@ +#define pr_fmt(fmt) "xload-esdhc: " fmt + +#include <common.h> +#include <io.h> +#include <mci.h> +#include <mach/imx6-regs.h> +#include <mach/xload.h> +#include <linux/sizes.h> +#include "../../../drivers/mci/sdhci.h" +#include "../../../drivers/mci/imx-esdhc.h" + +#define SECTOR_SIZE 512 + +#define esdhc_read32(a) readl(a) +#define esdhc_write32(a, v) writel(v,a) +#define IMX_SDHCI_MIXCTRL 0x48 + +struct esdhc { + void __iomem *regs; + int is_mx6; +}; + +static void __udelay(int us) +{ + volatile int i; + + for (i = 0; i < us * 4; i++); +} + +static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data) +{ + u32 xfertyp = 0; + + if (data) + xfertyp |= COMMAND_DPSEL | TRANSFER_MODE_MSBSEL | + TRANSFER_MODE_BCEN |TRANSFER_MODE_DTDSEL; + + if (cmd->resp_type & MMC_RSP_CRC) + xfertyp |= COMMAND_CCCEN; + if (cmd->resp_type & MMC_RSP_OPCODE) + xfertyp |= COMMAND_CICEN; + if (cmd->resp_type & MMC_RSP_136) + xfertyp |= COMMAND_RSPTYP_136; + else if (cmd->resp_type & MMC_RSP_BUSY) + xfertyp |= COMMAND_RSPTYP_48_BUSY; + else if (cmd->resp_type & MMC_RSP_PRESENT) + xfertyp |= COMMAND_RSPTYP_48; + + return COMMAND_CMD(cmd->cmdidx) | xfertyp; +} + +static int esdhc_do_data(struct esdhc *esdhc, struct mci_data *data) +{ + void __iomem *regs = esdhc->regs; + char *buffer; + u32 databuf; + u32 size; + u32 irqstat; + u32 timeout; + u32 present; + + buffer = data->dest; + + timeout = 1000000; + size = data->blocksize * data->blocks; + irqstat = esdhc_read32(regs + SDHCI_INT_STATUS); + + while (size) { + present = esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_BREN; + if (present) { + databuf = esdhc_read32(regs + SDHCI_BUFFER); + *((u32 *)buffer) = databuf; + buffer += 4; + size -= 4; + } + + if (!timeout--) { + pr_err("read time out\n"); + return -ETIMEDOUT; + } + } + + return 0; +} + +static int +esdhc_send_cmd(struct esdhc *esdhc, struct mci_cmd *cmd, struct mci_data *data) +{ + u32 xfertyp, mixctrl; + u32 irqstat; + void __iomem *regs = esdhc->regs; + int ret; + int timeout; + + esdhc_write32(regs + SDHCI_INT_STATUS, -1); + + /* Wait at least 8 SD clock cycles before the next command */ + __udelay(1); + + if (data) { + /* Set up for a data transfer if we have one */ + esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest); + esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | SECTOR_SIZE); + } + + /* Figure out the transfer arguments */ + xfertyp = esdhc_xfertyp(cmd, data); + + /* Send the command */ + esdhc_write32(regs + SDHCI_ARGUMENT, cmd->cmdarg); + + if (esdhc->is_mx6) { + /* write lower-half of xfertyp to mixctrl */ + mixctrl = xfertyp & 0xFFFF; + /* Keep the bits 22-25 of the register as is */ + mixctrl |= (esdhc_read32(regs + IMX_SDHCI_MIXCTRL) & (0xF << 22)); + esdhc_write32(regs + IMX_SDHCI_MIXCTRL, mixctrl); + } + + esdhc_write32(regs + SDHCI_TRANSFER_MODE__COMMAND, xfertyp); + + /* Wait for the command to complete */ + timeout = 10000; + while (!(esdhc_read32(regs + SDHCI_INT_STATUS) & IRQSTAT_CC)) { + __udelay(1); + if (!timeout--) + return -ETIMEDOUT; + } + + irqstat = esdhc_read32(regs + SDHCI_INT_STATUS); + esdhc_write32(regs + SDHCI_INT_STATUS, irqstat); + + if (irqstat & CMD_ERR) + return -EIO; + + if (irqstat & IRQSTAT_CTOE) + return -ETIMEDOUT; + + /* Copy the response to the response buffer */ + cmd->response[0] = esdhc_read32(regs + SDHCI_RESPONSE_0); + + /* Wait until all of the blocks are transferred */ + if (data) { + ret = esdhc_do_data(esdhc, data); + if (ret) + return ret; + } + + esdhc_write32(regs + SDHCI_INT_STATUS, -1); + + /* Wait for the bus to be idle */ + timeout = 10000; + while (esdhc_read32(regs + SDHCI_PRESENT_STATE) & + (PRSSTAT_CICHB | PRSSTAT_CIDHB | PRSSTAT_DLA)) { + __udelay(1); + if (!timeout--) + return -ETIMEDOUT; + } + + return 0; +} + +static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len) +{ + struct mci_cmd cmd; + struct mci_data data; + u32 val; + int ret; + + writel(IRQSTATEN_CC | IRQSTATEN_TC | IRQSTATEN_CINT | IRQSTATEN_CTOE | + IRQSTATEN_CCE | IRQSTATEN_CEBE | IRQSTATEN_CIE | + IRQSTATEN_DTOE | IRQSTATEN_DCE | IRQSTATEN_DEBE | + IRQSTATEN_DINT, esdhc->regs + SDHCI_INT_ENABLE); + + val = readl(esdhc->regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET); + val |= SYSCTL_HCKEN | SYSCTL_IPGEN; + writel(val, esdhc->regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET); + + cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_R1; + + data.dest = dst; + data.blocks = len / SECTOR_SIZE; + data.blocksize = SECTOR_SIZE; + data.flags = MMC_DATA_READ; + + ret = esdhc_send_cmd(esdhc, &cmd, &data); + if (ret) { + pr_debug("send command failed with %d\n", ret); + return ret; + } + + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_R1b; + + esdhc_send_cmd(esdhc, &cmd, NULL); + + return 0; +} + +int imx6_esdhc_load_image(int instance, void *buf, int len) +{ + struct esdhc esdhc; + int ret; + + switch (instance) { + case 0: + esdhc.regs = IOMEM(MX6_USDHC1_BASE_ADDR); + break; + case 1: + esdhc.regs = IOMEM(MX6_USDHC2_BASE_ADDR); + break; + case 2: + esdhc.regs = IOMEM(MX6_USDHC3_BASE_ADDR); + break; + case 3: + esdhc.regs = IOMEM(MX6_USDHC4_BASE_ADDR); + break; + default: + return -EINVAL; + } + + esdhc.is_mx6 = 1; + + ret = esdhc_read_blocks(&esdhc, buf, len); + if (ret) + return ret; + + return 0; +} + +/** + * imx6_esdhc_start_image - Load and start an image from USDHC controller + * @instance: The USDHC controller instance (0..4) + * + * This uses imx6_esdhc_load_image() to load an image from SD/MMC. + * It is assumed that the image is the currently running barebox image + * (This information is used to calculate the length of the image). The + * image is started afterwards. + * + * Return: If successul, this function does not return. A negative error + * code is returned when this function fails. + */ +int imx6_esdhc_start_image(int instance) +{ + void *buf = (void *)0x10000000; + u32 *ivt = buf + SZ_1K; + int ret, len; + void __noreturn (*bb)(void); + + len = imx_image_size(); + len = ALIGN(len, SECTOR_SIZE); + + ret = imx6_esdhc_load_image(instance, buf, 3 * SECTOR_SIZE); + if (ret) + return ret; + if (*(u32 *)(ivt) != 0x402000d1) { + pr_debug("IVT header not found on SD card. Found 0x%08x instead of 0x402000d1\n", + *ivt); + return -EINVAL; + } + + pr_debug("Check ok, loading image\n"); + + ret = imx6_esdhc_load_image(instance, buf, len); + if (ret) + return ret; + + bb = buf; + + bb(); +} diff --git a/arch/arm/mach-imx/xload-spi.c b/arch/arm/mach-imx/xload-spi.c new file mode 100644 index 0000000000..e87af81e41 --- /dev/null +++ b/arch/arm/mach-imx/xload-spi.c @@ -0,0 +1,136 @@ +#include <common.h> +#include <io.h> +#include <spi/imx-spi.h> +#include <mach/imx6-regs.h> +#include <mach/generic.h> +#include <bootsource.h> +#include <asm/sections.h> +#include <linux/sizes.h> +#include <mach/xload.h> + +static int cspi_2_3_read_data(void __iomem *base, u32 *data) +{ + u32 r; + + while (1) { + if (readl(base + CSPI_2_3_STAT) & CSPI_2_3_STAT_RR) + break; + } + + r = swab32(readl(base + CSPI_2_3_RXDATA)); + if (data) + *data = r; + + return 0; +} + +static int cspi_2_3_load(void __iomem *base, unsigned int flash_offset, void *buf, int len) +{ + int transfer_size = 256; + u32 val; + int words, adr = 0; + int ret; + + val = readl(base + CSPI_2_3_CTRL); + val &= ~(0xfff << CSPI_2_3_CTRL_BL_OFFSET); + val |= CSPI_2_3_CTRL_ENABLE; + writel(val, base + CSPI_2_3_CTRL); + + writel(val, base + CSPI_2_3_CTRL); + + for (adr = 0; adr < len; adr += transfer_size) { + + val |= ((transfer_size + 4) * 8 - 1) << CSPI_2_3_CTRL_BL_OFFSET; + writel(val, base + CSPI_2_3_CTRL); + + /* address */ + writel(swab32(0x3) | (adr + flash_offset), base + CSPI_2_3_TXDATA); + writel(val | CSPI_2_3_CTRL_XCH, base + CSPI_2_3_CTRL); + + ret = cspi_2_3_read_data(base, NULL); + if (ret) + return ret; + + words = 0; + + for (words = 0; words < transfer_size >> 2; words++) { + writel(0, base + CSPI_2_3_TXDATA); + cspi_2_3_read_data(base, buf); + buf += 4; + } + } + + return 0; +} + +/** + * imx6_spi_load_image - load an image from SPI NOR + * @instance: The SPI controller instance (0..4) + * @flash_offset: The offset in flash where the image starts + * @buf: The buffer to load the image to + * @len: The size to load + * + * This function loads data from SPI NOR flash on i.MX6. This assumes the + * SPI controller has already been initialized and the pinctrl / clocks are + * configured correctly. This is the case when the ROM has loaded the initial + * portion of the boot loader from exactly this controller. + * + * Return: 0 if successful, negative error code otherwise + */ +int imx6_spi_load_image(int instance, unsigned int flash_offset, void *buf, int len) +{ + void *base; + + switch (instance) { + case 0: + base = IOMEM(MX6_ECSPI1_BASE_ADDR); + break; + case 1: + base = IOMEM(MX6_ECSPI2_BASE_ADDR); + break; + case 2: + base = IOMEM(MX6_ECSPI3_BASE_ADDR); + break; + case 3: + base = IOMEM(MX6_ECSPI4_BASE_ADDR); + break; + case 4: + base = IOMEM(MX6_ECSPI5_BASE_ADDR); + break; + default: + return -EINVAL; + } + + cspi_2_3_load(base, flash_offset, buf, len); + + return 0; +} + +/** + * imx6_spi_start_image - Load and start an image from SPI NOR flash + * @instance: The SPI controller instance (0..4) + * + * This uses imx6_spi_load_image() to load an image from SPI NOR flash. + * It is assumed that the image is the currently running barebox image + * (This information is used to calculate the length of the image). The + * image is started afterwards. + * + * Return: If successul, this function does not return. A negative error + * code is returned when this function fails. + */ +int imx6_spi_start_image(int instance) +{ + void *buf = (void *)0x10000000; + int ret, len; + void __noreturn (*bb)(void); + + len = imx_image_size(); + + ret = imx6_spi_load_image(instance, 0, buf, len); + if (ret) + return ret; + + bb = buf; + + bb(); +} diff --git a/arch/arm/mach-mxs/include/mach/fb.h b/arch/arm/mach-mxs/include/mach/fb.h index 2b6825f7b5..ad28f79d57 100644 --- a/arch/arm/mach-mxs/include/mach/fb.h +++ b/arch/arm/mach-mxs/include/mach/fb.h @@ -15,11 +15,6 @@ #include <fb.h> -#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */ -#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */ -#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ -#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ - /** LC display uses active high data enable signal */ #define FB_SYNC_DE_HIGH_ACT (1 << 27) /** LC display will latch its data at clock's rising edge */ @@ -38,7 +33,7 @@ struct imx_fb_platformdata { unsigned mode_cnt; unsigned dotclk_delay; /**< refer manual HW_LCDIF_VDCTRL4 register */ - unsigned ld_intf_width; /**< refer STMLCDIF_* macros */ + unsigned ld_intf_width; /* interface width in bits */ unsigned bits_per_pixel; void *fixed_screen; /**< if != NULL use this as framebuffer memory */ diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index af359756ba..0b59afc68b 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -43,7 +43,7 @@ config ARCH_AM33XX select CPU_V7 select GENERIC_GPIO select OFTREE - select OMAP_CLOCK_SOURCE_DMTIMER0 + select OMAP_CLOCK_SOURCE_DMTIMER help Say Y here if you are using Texas Instrument's AM33xx based platform @@ -51,7 +51,7 @@ config ARCH_AM33XX config OMAP_CLOCK_SOURCE_S32K bool -config OMAP_CLOCK_SOURCE_DMTIMER0 +config OMAP_CLOCK_SOURCE_DMTIMER bool config OMAP_GPMC @@ -106,6 +106,7 @@ config AM33XX_NET_BOOT bool "enable AM335x network boot" select ENVIRONMENT_VARIABLES select NET_DHCP + select FS_RAMFS select FS_TFTP select DRIVER_NET_CPSW default n diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile index 65072b91e4..db2856dc5e 100644 --- a/arch/arm/mach-omap/Makefile +++ b/arch/arm/mach-omap/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_ARCH_OMAP) += syslib.o omap_devices.o omap_generic.o omap_fb.o pbl-$(CONFIG_ARCH_OMAP) += syslib.o obj-$(CONFIG_OMAP_CLOCK_SOURCE_S32K) += s32k_clksource.o -obj-$(CONFIG_OMAP_CLOCK_SOURCE_DMTIMER0) += dmtimer0.o +obj-$(CONFIG_OMAP_CLOCK_SOURCE_DMTIMER) += dmtimer.o obj-$(CONFIG_ARCH_OMAP3) += omap3_generic.o auxcr.o pbl-$(CONFIG_ARCH_OMAP3) += omap3_generic.o auxcr.o obj-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o diff --git a/arch/arm/mach-omap/am33xx_mux.c b/arch/arm/mach-omap/am33xx_mux.c index 8318713799..cc96ced18e 100644 --- a/arch/arm/mach-omap/am33xx_mux.c +++ b/arch/arm/mach-omap/am33xx_mux.c @@ -27,6 +27,13 @@ static const __maybe_unused struct module_pin_mux uart0_pin_mux[] = { {-1}, }; +static const __maybe_unused struct module_pin_mux uart1_pin_mux[] = { + {OFFSET(uart1_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART1_RXD */ + {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, /* UART1_TXD */ + {-1}, +}; + + static const __maybe_unused struct module_pin_mux uart2_pin_mux[] = { {OFFSET(mii1_txclk), (MODE(1) | PULLUDEN | RXACTIVE)}, /* UART2_RXD */ {OFFSET(mii1_rxclk), (MODE(1) | PULLUDEN)}, /* UART2_TXD */ @@ -302,6 +309,11 @@ void am33xx_enable_uart0_pin_mux(void) configure_module_pin_mux(uart0_pin_mux); } +void am33xx_enable_uart1_pin_mux(void) +{ + configure_module_pin_mux(uart1_pin_mux); +} + void am33xx_enable_uart2_pin_mux(void) { configure_module_pin_mux(uart2_pin_mux); diff --git a/arch/arm/mach-omap/dmtimer0.c b/arch/arm/mach-omap/dmtimer.c index e536f8d222..56adda080a 100644 --- a/arch/arm/mach-omap/dmtimer0.c +++ b/arch/arm/mach-omap/dmtimer.c @@ -1,8 +1,8 @@ /** * @file - * @brief Support DMTimer0 counter + * @brief Support DMTimer counter * - * FileName: arch/arm/mach-omap/dmtimer0.c + * FileName: arch/arm/mach-omap/dmtimer.c */ /* * This File is based on arch/arm/mach-omap/s32k_clksource.c @@ -10,7 +10,10 @@ * Texas Instruments, <www.ti.com> * Nishanth Menon <x0nishan@ti.com> * - * (C) Copyright 2012 Teresa Gámez, Phytec Messtechnik GmbH + * (C) Copyright 2012 Phytec Messtechnik GmbH + * Author: Teresa Gámez <t.gamez@phytec.de> + * (C) Copyright 2015 Phytec Messtechnik GmbH + * Author: Daniel Schultz <d.schultz@phytec.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,6 +32,8 @@ #include <io.h> #include <mach/am33xx-silicon.h> +#include <stdio.h> + #define CLK_RC32K 32768 #define TIDR 0x0 @@ -49,18 +54,20 @@ #define TSICR 0x54 #define TCAR2 0x58 +static void *base = (void *)AM33XX_DMTIMER2_BASE; + /** * @brief Provide a simple counter read * - * @return DMTimer0 counter + * @return DMTimer counter */ -static uint64_t dmtimer0_read(void) +static uint64_t dmtimer_read(void) { - return readl(AM33XX_DMTIMER0_BASE + TCRR); + return readl(base + TCRR); } -static struct clocksource dmtimer0_cs = { - .read = dmtimer0_read, +static struct clocksource dmtimer_cs = { + .read = dmtimer_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, }; @@ -68,18 +75,38 @@ static struct clocksource dmtimer0_cs = { /** * @brief Initialize the Clock * - * Enable dmtimer0. + * Enable dmtimer. * * @return result of @ref init_clock */ -static int dmtimer0_init(void) +static int dmtimer_init(void) { - dmtimer0_cs.mult = clocksource_hz2mult(CLK_RC32K, dmtimer0_cs.shift); + u64 clk_speed; + int sysboot; + + sysboot = (readl(AM33XX_CTRL_STATUS) >> 22) & 3; + switch (sysboot) { + case 0: + clk_speed = 19200000; + break; + case 1: + clk_speed = 24000000; + break; + case 2: + clk_speed = 25000000; + break; + case 3: + clk_speed = 26000000; + break; + } + + dmtimer_cs.mult = clocksource_hz2mult(clk_speed, dmtimer_cs.shift); + /* Enable counter */ - writel(0x3, AM33XX_DMTIMER0_BASE + TCLR); + writel(0x3, base + TCLR); - return init_clock(&dmtimer0_cs); + return init_clock(&dmtimer_cs); } /* Run me at boot time */ -core_initcall(dmtimer0_init); +core_initcall(dmtimer_init); diff --git a/arch/arm/mach-omap/include/mach/am33xx-mux.h b/arch/arm/mach-omap/include/mach/am33xx-mux.h index fe3168b68a..af9f14dd5b 100644 --- a/arch/arm/mach-omap/include/mach/am33xx-mux.h +++ b/arch/arm/mach-omap/include/mach/am33xx-mux.h @@ -254,6 +254,7 @@ extern void am33xx_enable_i2c0_pin_mux(void); extern void am33xx_enable_i2c1_pin_mux(void); extern void am33xx_enable_i2c2_pin_mux(void); extern void am33xx_enable_uart0_pin_mux(void); +extern void am33xx_enable_uart1_pin_mux(void); extern void am33xx_enable_uart2_pin_mux(void); extern void am33xx_enable_mmc0_pin_mux(void); extern void am33xx_enable_spi0_pin_mux(void); diff --git a/arch/arm/mach-omap/include/mach/am33xx-silicon.h b/arch/arm/mach-omap/include/mach/am33xx-silicon.h index 7c209ec5d8..e17e609879 100644 --- a/arch/arm/mach-omap/include/mach/am33xx-silicon.h +++ b/arch/arm/mach-omap/include/mach/am33xx-silicon.h @@ -62,6 +62,9 @@ /* DTMTimer0 */ #define AM33XX_DMTIMER0_BASE (AM33XX_L4_WKUP_BASE + 0x205000) +/* DMTIimer2 */ +#define AM33XX_DMTIMER2_BASE (AM33XX_L4_PER_BASE + 0x40000) +#define AM33XX_CM_DPLL (AM33XX_L4_WKUP_BASE + 0x200500) /* PRM */ #define AM33XX_PRM_BASE (AM33XX_L4_WKUP_BASE + 0x200000) @@ -73,6 +76,7 @@ /* CTRL */ #define AM33XX_CTRL_BASE (AM33XX_L4_WKUP_BASE + 0x210000) #define AM33XX_IDCODE_REG (AM33XX_CTRL_BASE + 0x600) +#define AM33XX_CTRL_STATUS (AM33XX_CTRL_BASE + 0x40) /* Watchdog Timer */ #define AM33XX_WDT_BASE 0x44E35000 diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c index 4a0714ed93..ebcbcbcde1 100644 --- a/arch/arm/mach-omap/xload.c +++ b/arch/arm/mach-omap/xload.c @@ -119,13 +119,14 @@ static void *omap_xload_boot_mmc(void) ret = mount(partname, "fat", "/", NULL); - free(partname); - if (ret) { printf("Unable to mount %s (%d)\n", partname, ret); + free(partname); return NULL; } + free(partname); + buf = read_file("/barebox.bin", &len); if (!buf) { printf("could not read barebox.bin from sd card\n"); @@ -229,13 +230,16 @@ static void *omap_serial_boot(void){ return buf; } +#define TFTP_MOUNT "/.tftp" + static void *am33xx_net_boot(void) { void *buf = NULL; int err; int len; struct dhcp_req_param dhcp_param; - const char *bootfile; + const char *bootfile, *ip; + char *file; am33xx_register_ethaddr(0, 0); @@ -247,7 +251,22 @@ static void *am33xx_net_boot(void) return NULL; } - err = mount(ip_to_string(net_get_serverip()), "tftp", "/", NULL); + /* + * Older tftp server don't send the file size. + * Then tftpfs needs temporary place to store the file. + */ + err = mount("none", "ramfs", "/", NULL); + if (err < 0) { + printf("failed to mount ramfs\n"); + return NULL; + } + + err = make_directory(TFTP_MOUNT); + if (err) + return NULL; + + ip = ip_to_string(net_get_serverip()); + err = mount(ip, "tftp", TFTP_MOUNT, NULL); if (err < 0) { printf("Unable to mount.\n"); return NULL; @@ -259,11 +278,15 @@ static void *am33xx_net_boot(void) return NULL; } - buf = read_file(bootfile, &len); + file = asprintf("%s/%s", TFTP_MOUNT, bootfile); + + buf = read_file(file, &len); if (!buf) printf("could not read %s.\n", bootfile); - umount("/"); + free(file); + + umount(TFTP_MOUNT); return buf; } @@ -293,6 +316,7 @@ static __noreturn int omap_xload(void) func = omap4_xload_boot_usb(); } else { printf("booting from USB not enabled\n"); + func = NULL; } break; case BOOTSOURCE_NAND: diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2b7f631757..54094f4ca0 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -5,6 +5,7 @@ config ARCH_TEXT_BASE default 0xa0000000 if MACH_MIOA701 default 0xa3f00000 if MACH_PCM027 default 0xa3d00000 if MACH_LUBBOCK + default 0xa3d00000 if MACH_MAINSTONE default 0x83f00000 if MACH_ZYLONITE # ---------------------------------------------------------- diff --git a/arch/blackfin/boards/ipe337/barebox.lds.S b/arch/blackfin/boards/ipe337/barebox.lds.S index 9bb7cc4953..51a586af27 100644 --- a/arch/blackfin/boards/ipe337/barebox.lds.S +++ b/arch/blackfin/boards/ipe337/barebox.lds.S @@ -76,6 +76,10 @@ SECTIONS .barebox_initcalls : { INITCALLS } ___barebox_initcalls_end = .; + ___barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + ___barebox_exitcalls_end = .; + ___usymtab_start = .; __usymtab : { BAREBOX_SYMS } ___usymtab_end = .; diff --git a/arch/blackfin/include/asm/common.h b/arch/blackfin/include/asm/common.h index fa58e372bb..443adf7270 100644 --- a/arch/blackfin/include/asm/common.h +++ b/arch/blackfin/include/asm/common.h @@ -1,5 +1 @@ - -/* We have to disable instruction cache before - * executing an external program - */ -#define ARCH_SHUTDOWN +/* nothing special */ diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 88ad61871a..3a04f28caf 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -38,7 +38,11 @@ void __noreturn blackfin_start_barebox(void) start_barebox(); } -void arch_shutdown(void) +/* We have to disable instruction cache before + * executing an external program + */ +static void arch_shutdown(void) { icache_disable(); } +archshutdown_exitcall(arch_shutdown); diff --git a/arch/efi/configs/efi_defconfig b/arch/efi/configs/efi_defconfig index 456f70d32b..3c9a9dcb95 100644 --- a/arch/efi/configs/efi_defconfig +++ b/arch/efi/configs/efi_defconfig @@ -7,6 +7,7 @@ CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y # CONFIG_TIMESTAMP is not set +CONFIG_BLSPEC=y CONFIG_CONSOLE_ACTIVATE_ALL=y CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y diff --git a/arch/efi/efi/efi-block-io.c b/arch/efi/efi/efi-block-io.c index 85603d913d..e02d3b49cc 100644 --- a/arch/efi/efi/efi-block-io.c +++ b/arch/efi/efi/efi-block-io.c @@ -147,7 +147,7 @@ int efi_bio_probe(struct efi_device *efidev) efi_bio_print_info(priv); priv->dev = &efidev->dev; - priv->blk.cdev.name = asprintf("disk%d", cdev_find_free_index("disk")); + priv->blk.cdev.name = xasprintf("disk%d", cdev_find_free_index("disk")); priv->blk.blockbits = ffs(media->block_size) - 1; priv->blk.num_blocks = media->last_block + 1; priv->blk.ops = &efi_bio_ops; diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c index f7bda8dfcb..b6437f4078 100644 --- a/arch/efi/efi/efi-image.c +++ b/arch/efi/efi/efi-image.c @@ -17,6 +17,7 @@ * */ +#include <clock.h> #include <common.h> #include <linux/sizes.h> #include <memory.h> @@ -37,14 +38,62 @@ #include <mach/efi.h> #include <mach/efi-device.h> -static int efi_execute_image(const char *file) +struct linux_kernel_header { + /* first sector of the image */ + uint8_t code1[0x0020]; + uint16_t cl_magic; /**< Magic number 0xA33F */ + uint16_t cl_offset; /**< The offset of command line */ + uint8_t code2[0x01F1 - 0x0020 - 2 - 2]; + uint8_t setup_sects; /**< The size of the setup in sectors */ + uint16_t root_flags; /**< If the root is mounted readonly */ + uint16_t syssize; /**< obsolete */ + uint16_t swap_dev; /**< obsolete */ + uint16_t ram_size; /**< obsolete */ + uint16_t vid_mode; /**< Video mode control */ + uint16_t root_dev; /**< Default root device number */ + uint16_t boot_flag; /**< 0xAA55 magic number */ + + /* second sector of the image */ + uint16_t jump; /**< Jump instruction (this is code!) */ + uint32_t header; /**< Magic signature "HdrS" */ + uint16_t version; /**< Boot protocol version supported */ + uint32_t realmode_swtch; /**< Boot loader hook */ + uint16_t start_sys; /**< The load-low segment (obsolete) */ + uint16_t kernel_version; /**< Points to kernel version string */ + uint8_t type_of_loader; /**< Boot loader identifier */ + uint8_t loadflags; /**< Boot protocol option flags */ + uint16_t setup_move_size; /**< Move to high memory size */ + uint32_t code32_start; /**< Boot loader hook */ + uint32_t ramdisk_image; /**< initrd load address */ + uint32_t ramdisk_size; /**< initrd size */ + uint32_t bootsect_kludge; /**< obsolete */ + uint16_t heap_end_ptr; /**< Free memory after setup end */ + uint8_t ext_loader_ver; /**< boot loader's extension of the version number */ + uint8_t ext_loader_type; /**< boot loader's extension of its type */ + uint32_t cmd_line_ptr; /**< Points to the kernel command line */ + uint32_t initrd_addr_max; /**< Highest address for initrd */ + uint32_t kernel_alignment; /**< Alignment unit required by the kernel */ + uint8_t relocatable_kernel; /** */ + uint8_t min_alignment; /** */ + uint16_t xloadflags; /** */ + uint32_t cmdline_size; /** */ + uint32_t hardware_subarch; /** */ + uint64_t hardware_subarch_data; /** */ + uint32_t payload_offset; /** */ + uint32_t payload_length; /** */ + uint64_t setup_data; /** */ + uint64_t pref_address; /** */ + uint32_t init_size; /** */ + uint32_t handover_offset; /** */ +} __attribute__ ((packed)); + +int efi_load_image(const char *file, efi_loaded_image_t **loaded_image, + efi_handle_t *h) { void *exe; size_t size; efi_handle_t handle; - efi_status_t efiret; - const char *options; - efi_loaded_image_t *loaded_image; + efi_status_t efiret = EFI_SUCCESS; exe = read_file(file, &size); if (!exe) @@ -54,30 +103,153 @@ static int efi_execute_image(const char *file) &handle); if (EFI_ERROR(efiret)) { pr_err("failed to LoadImage: %s\n", efi_strerror(efiret)); - return -efi_errno(efiret);; + goto out; }; efiret = BS->open_protocol(handle, &efi_loaded_image_protocol_guid, - (void **)&loaded_image, + (void **)loaded_image, efi_parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (EFI_ERROR(efiret)) - return -efi_errno(efiret); + if (EFI_ERROR(efiret)) { + pr_err("failed to OpenProtocol: %s\n", efi_strerror(efiret)); + BS->unload_image(handle); + goto out; + } - options = linux_bootargs_get(); - loaded_image->load_options = strdup_char_to_wchar(options); - loaded_image->load_options_size = (strlen(options) + 1) * sizeof(wchar_t); + *h = handle; +out: + memset(exe, 0, size); + free(exe); + return -efi_errno(efiret); +} + +static int efi_execute_image(const char *file) +{ + efi_handle_t handle; + efi_loaded_image_t *loaded_image; + efi_status_t efiret; + struct linux_kernel_header *image_header; + const char *options; + int ret; + + ret = efi_load_image(file, &loaded_image, &handle); + if (ret) + return ret; + + image_header = (struct linux_kernel_header *)loaded_image->image_base; + if (image_header->boot_flag == 0xAA55 && + image_header->header == 0x53726448) { + pr_debug("Linux kernel detected. Adding bootargs."); + options = linux_bootargs_get(); + pr_err("add linux options '%s'\n", options); + loaded_image->load_options = xstrdup_char_to_wchar(options); + loaded_image->load_options_size = + (strlen(options) + 1) * sizeof(wchar_t); + } efiret = BS->start_image(handle, NULL, NULL); + if (EFI_ERROR(efiret)) + pr_err("failed to StartImage: %s\n", efi_strerror(efiret)); + + BS->unload_image(handle); efi_connect_all(); efi_register_devices(); - return 0; + return -efi_errno(efiret); +} + +#ifdef __x86_64__ +typedef void(*handover_fn)(void *image, efi_system_table_t *table, + struct linux_kernel_header *header); + +static inline void linux_efi_handover(efi_handle_t handle, + struct linux_kernel_header *header) +{ + handover_fn handover; + + asm volatile ("cli"); + handover = (handover_fn)((long)header->code32_start + 512 + + header->handover_offset); + handover(handle, efi_sys_table, header); } +#else +typedef void(*handover_fn)(VOID *image, EFI_SYSTEM_TABLE *table, + struct SetupHeader *setup) __attribute__((regparm(0))); + +static inline void linux_efi_handover(efi_handle_t handle, + struct linux_kernel_header *header) +{ + handover_fn handover; + + handover = (handover_fn)((long)header->code32_start + + header->handover_offset); + handover(handle, efi_sys_table, header); +} +#endif static int do_bootm_efi(struct image_data *data) { - return efi_execute_image(data->os_file); + void *tmp; + void *initrd; + size_t size; + efi_handle_t handle; + int ret; + const char *options; + efi_loaded_image_t *loaded_image; + struct linux_kernel_header *image_header, *boot_header; + + ret = efi_load_image(data->os_file, &loaded_image, &handle); + if (ret) + return ret; + + image_header = (struct linux_kernel_header *)loaded_image->image_base; + + if (image_header->boot_flag != 0xAA55 || + image_header->header != 0x53726448 || + image_header->version < 0x20b || + !image_header->relocatable_kernel) { + pr_err("Not a valid kernel image!\n"); + BS->unload_image(handle); + return -EINVAL; + } + + boot_header = xmalloc(0x4000); + memset(boot_header, 0, 0x4000); + memcpy(boot_header, image_header, sizeof(*image_header)); + + boot_header->type_of_loader = 0xff; + + if (data->initrd_file) { + tmp = read_file(data->initrd_file, &size); + initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size)); + memcpy(initrd, tmp, size); + memset(initrd + size, 0, PAGE_ALIGN(size) - size); + free(tmp); + boot_header->ramdisk_image = (uint64_t)initrd; + boot_header->ramdisk_size = PAGE_ALIGN(size); + } + + options = linux_bootargs_get(); + boot_header->cmd_line_ptr = (uint64_t)options; + boot_header->cmdline_size = strlen(options); + + boot_header->code32_start = (uint64_t)loaded_image->image_base + + (image_header->setup_sects+1) * 512; + + if (bootm_verbose(data)) { + printf("\nStarting kernel at 0x%p", loaded_image->image_base); + if (data->initrd_file) + printf(", initrd at 0x%08x", + boot_header->ramdisk_image); + printf("...\n"); + } + + efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid, + get_time_ns()/1000); + + linux_efi_handover(handle, boot_header); + + return 0; } static struct image_handler efi_handle_tr = { diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c index d351775a28..d3f520f60f 100644 --- a/arch/efi/efi/efi.c +++ b/arch/efi/efi/efi.c @@ -52,7 +52,7 @@ void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size) efi_status_t efiret; void *buf; unsigned long size = 0; - s16 *name16 = strdup_char_to_wchar(name); + s16 *name16 = xstrdup_char_to_wchar(name); efiret = RT->get_variable(name16, vendor, NULL, &size, NULL); @@ -83,6 +83,33 @@ out: return buf; } +int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, + void *buf, unsigned long size) +{ + efi_status_t efiret = EFI_SUCCESS; + s16 *name16 = xstrdup_char_to_wchar(name); + + efiret = RT->set_variable(name16, vendor, attributes, size, buf); + + free(name16); + + return -efi_errno(efiret); +} + +int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec) +{ + char buf[20]; + wchar_t buf16[40]; + + snprintf(buf, sizeof(buf), "%lld", usec); + strcpy_char_to_wchar(buf16, buf); + + return efi_set_variable(name, vendor, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, buf16, + (strlen(buf)+1) * sizeof(wchar_t)); +} + struct efi_boot { u32 attributes; u16 file_path_len; @@ -98,7 +125,7 @@ struct efi_boot *efi_get_boot(int num) int size; char *name; - name = asprintf("Boot%04X", num); + name = xasprintf("Boot%04X", num); buf = efi_get_global_var(name, &size); @@ -119,7 +146,7 @@ struct efi_boot *efi_get_boot(int num) ptr += sizeof(u16); - boot->description = strdup_wchar_to_char(ptr); + boot->description = xstrdup_wchar_to_char(ptr); ptr += (strlen(boot->description) + 1) * 2; @@ -299,8 +326,13 @@ static void fixup_tables(void) static int efi_init(void) { + char *env; + defaultenv_append_directory(env_efi); + env = xasprintf("/efivars/barebox-env-%pUl", &efi_barebox_vendor_guid); + default_environment_path_set(env); + return 0; } device_initcall(efi_init); @@ -310,8 +342,10 @@ device_initcall(efi_init); */ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table) { - void *mem; + efi_physical_addr_t mem; + size_t memsize; efi_status_t efiret; + char *uuid; #ifdef DEBUG sys_table->con_out->output_string(sys_table->con_out, L"barebox\n"); @@ -332,10 +366,38 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table) fixup_tables(); - BS->allocate_pool(efi_loaded_image->image_data_type, SZ_16M, &mem); - mem_malloc_init(mem, mem + SZ_16M); + mem = 0x3fffffff; + for (memsize = SZ_256M; memsize >= SZ_8M; memsize /= 2) { + efiret = BS->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, + EFI_LOADER_DATA, + memsize/PAGE_SIZE, &mem); + if (!EFI_ERROR(efiret)) + break; + if (efiret != EFI_OUT_OF_RESOURCES) + panic("failed to allocate malloc pool: %s\n", + efi_strerror(efiret)); + } + if (EFI_ERROR(efiret)) + panic("failed to allocate malloc pool: %s\n", + efi_strerror(efiret)); + mem_malloc_init((void *)mem, (void *)mem + memsize); efi_clocksource_init(); + efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid, + get_time_ns()/1000); + + uuid = device_path_to_partuuid(device_path_from_handle( + efi_loaded_image->device_handle)); + if (uuid) { + wchar_t *uuid16 = xstrdup_char_to_wchar(uuid); + efi_set_variable("LoaderDevicePartUUID", + &efi_systemd_vendor_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + uuid16, (strlen(uuid)+1) * sizeof(wchar_t)); + free(uuid); + free(uuid16); + } start_barebox(); diff --git a/arch/efi/include/mach/efi.h b/arch/efi/include/mach/efi.h index 1e9782a136..2b25cf1868 100644 --- a/arch/efi/include/mach/efi.h +++ b/arch/efi/include/mach/efi.h @@ -21,4 +21,8 @@ static inline void *efi_get_global_var(char *name, int *var_size) return efi_get_variable(name, &efi_global_variable_guid, var_size); } +int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, + void *buf, unsigned long size); +int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec); + #endif /* __MACH_EFI_H */ diff --git a/arch/efi/lib/elf_ia32_efi.lds.S b/arch/efi/lib/elf_ia32_efi.lds.S index a5f6287500..69f43f5547 100644 --- a/arch/efi/lib/elf_ia32_efi.lds.S +++ b/arch/efi/lib/elf_ia32_efi.lds.S @@ -56,6 +56,10 @@ SECTIONS __barebox_initcalls : { INITCALLS } __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + __barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + . = ALIGN(64); __barebox_magicvar_start = .; .barebox_magicvar : { BAREBOX_MAGICVARS } diff --git a/arch/efi/lib/elf_x86_64_efi.lds.S b/arch/efi/lib/elf_x86_64_efi.lds.S index d48432d21b..9aa4e8d829 100644 --- a/arch/efi/lib/elf_x86_64_efi.lds.S +++ b/arch/efi/lib/elf_x86_64_efi.lds.S @@ -58,6 +58,10 @@ SECTIONS __barebox_initcalls : { INITCALLS } __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + __barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + . = ALIGN(64); __barebox_magicvar_start = .; .barebox_magicvar : { BAREBOX_MAGICVARS } diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S index c690e71976..8057634ddb 100644 --- a/arch/mips/lib/barebox.lds.S +++ b/arch/mips/lib/barebox.lds.S @@ -67,6 +67,10 @@ SECTIONS .barebox_initcalls : { INITCALLS } __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + __usymtab_start = .; __usymtab : { BAREBOX_SYMS } __usymtab_end = .; diff --git a/arch/nios2/cpu/barebox.lds.S b/arch/nios2/cpu/barebox.lds.S index 943c507531..a2d7fa8cdf 100644 --- a/arch/nios2/cpu/barebox.lds.S +++ b/arch/nios2/cpu/barebox.lds.S @@ -63,6 +63,10 @@ SECTIONS .barebox_initcalls : { INITCALLS } __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + ___usymtab_start = .; __usymtab : { BAREBOX_SYMS } ___usymtab_end = .; diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c index 7c4dc76e87..537675c5d4 100644 --- a/arch/nios2/lib/board.c +++ b/arch/nios2/lib/board.c @@ -30,7 +30,3 @@ void __noreturn nios_start_barebox(void) start_barebox(); } - -void arch_shutdown(void) -{ -} diff --git a/arch/openrisc/cpu/barebox.lds.S b/arch/openrisc/cpu/barebox.lds.S index 9c353f30f1..b819ca0996 100644 --- a/arch/openrisc/cpu/barebox.lds.S +++ b/arch/openrisc/cpu/barebox.lds.S @@ -65,6 +65,10 @@ SECTIONS .barebox_initcalls : { INITCALLS } > ram __barebox_initcalls_end = .; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } > ram + __barebox_exitcalls_end = .; + ___usymtab_start = .; __usymtab : { BAREBOX_SYMS } > ram ___usymtab_end = .; diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c index 98033b42cf..25bcc0517b 100644 --- a/arch/openrisc/lib/board.c +++ b/arch/openrisc/lib/board.c @@ -29,7 +29,3 @@ void __noreturn openrisc_start_barebox(void) start_barebox(); } - -void arch_shutdown(void) -{ -} diff --git a/arch/ppc/boards/pcm030/Makefile b/arch/ppc/boards/pcm030/Makefile index e7d744bfb4..4e5dc4f57b 100644 --- a/arch/ppc/boards/pcm030/Makefile +++ b/arch/ppc/boards/pcm030/Makefile @@ -1,2 +1,2 @@ -obj-y += pcm030.o +obj-y += pcm030.o eeprom.o extra-y += barebox.lds diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S index 1332ad1cbd..0e08e053f7 100644 --- a/arch/ppc/boards/pcm030/barebox.lds.S +++ b/arch/ppc/boards/pcm030/barebox.lds.S @@ -112,6 +112,11 @@ SECTIONS __barebox_initcalls_end = .; __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start) >> 2; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2; + __usymtab_start = .; __usymtab : { BAREBOX_SYMS } __usymtab_end = .; diff --git a/arch/ppc/boards/pcm030/config.h b/arch/ppc/boards/pcm030/config.h index 6e74964056..3fe1f286d9 100644 --- a/arch/ppc/boards/pcm030/config.h +++ b/arch/ppc/boards/pcm030/config.h @@ -25,18 +25,9 @@ #include <mach/mpc5xxx.h> -#define CFG_MPC5XXX_CLKIN 33333333 /* ... running at 33.333333MHz */ - -#define CFG_GPS_PORT_CONFIG 0x00558c10 /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */ +#define CFG_MPC5XXX_CLKIN 33333000 /* ... running at 33.333MHz */ #define CFG_HID0_INIT HID0_ICE | HID0_ICFI #define CFG_HID0_FINAL HID0_ICE - -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ - -#define OF_CPU "PowerPC,5200@0" -#define OF_TBCLK CFG_MPC5XXX_CLKIN -#define OF_SOC "soc5200@f0000000" - #endif /* __CONFIG_H */ diff --git a/arch/ppc/boards/pcm030/eeprom.c b/arch/ppc/boards/pcm030/eeprom.c new file mode 100644 index 0000000000..aa00f361cd --- /dev/null +++ b/arch/ppc/boards/pcm030/eeprom.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2015 Juergen Borleis <kernel@pengutronix.de> + * + * Based on code from: + * Copyright (C) 2013 Jan Luebbe <j.luebbe@pengutronix.de> + * + * 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 <errno.h> +#include <fcntl.h> +#include <fs.h> +#include <globalvar.h> +#include <xfuncs.h> +#include <init.h> +#include <net.h> + +#define PCM030_EEPROM_DEVICE "/dev/eeprom0" + +/* + * The first 2048 bytes contain the U-Boot environment shipped with the boards. + * After that an area begins where some board specific and partially unique data + * is stored. All of this data is plain test, string delimiter is the semicolon. + * the last string terminates with a '\0'. + * One example found in the 'product' area: PCM-030-02REI;017822;0050C2875974\0 + * The first string seems to be the product type, the second string some kind + * of serial number and the last string the boards unique MAC. + */ +struct pcm030_eeprom { + char env[0x800]; /* u-boot environment */ + char product[0x80]; /* <product>;<serno>;<mac>\0 */ +} __attribute__((packed)); + +static void pcm030_read_factory_data(const struct pcm030_eeprom *buf) +{ + unsigned u, l; + char *board, *serial; + char *full_mac = "xx:xx:xx:xx:xx:xx"; + u8 enetaddr[6]; + + u = 0; + + for (l = 0; (l + u) < sizeof(buf->product); l++) { + if (buf->product[u + l] != ';') + continue; + board = xstrndup(&buf->product[u], l); + u += l + 1; + globalvar_add_simple("model.type", board); + free(board); + } + + for (l = 0; (l + u) < sizeof(buf->product); l++) { + if (buf->product[u + l] != ';') + continue; + serial = xstrndup(&buf->product[u], l); + u += l + 1; + globalvar_add_simple("model.serial", serial); + free(serial); + } + + /* for the MAC do a simple duck test */ + if (buf->product[u] != ';' && buf->product[u + 12] == '\0') { + full_mac[0] = buf->product[u + 0]; + full_mac[1] = buf->product[u + 1]; + full_mac[3] = buf->product[u + 2]; + full_mac[4] = buf->product[u + 3]; + full_mac[6] = buf->product[u + 4]; + full_mac[7] = buf->product[u + 5]; + full_mac[9] = buf->product[u + 6]; + full_mac[10] = buf->product[u + 7]; + full_mac[12] = buf->product[u + 8]; + full_mac[13] = buf->product[u + 9]; + full_mac[15] = buf->product[u + 10]; + full_mac[16] = buf->product[u + 11]; + string_to_ethaddr(full_mac, enetaddr); + eth_register_ethaddr(0, enetaddr); + return; + } + + printf("EEPROM contains no ethernet MAC\n"); +} + +static int pcm030_eeprom_read(void) +{ + int fd, ret; + struct pcm030_eeprom *buf; + + fd = open(PCM030_EEPROM_DEVICE, O_RDONLY); + if (fd < 0) { + perror("failed to open " PCM030_EEPROM_DEVICE); + return fd; + } + + buf = xmalloc(sizeof(struct pcm030_eeprom)); + + ret = pread(fd, buf, sizeof(struct pcm030_eeprom), 0); + if (ret < sizeof(struct pcm030_eeprom)) { + perror("failed to read " PCM030_EEPROM_DEVICE); + goto out; + } + + pcm030_read_factory_data(buf); + ret = 0; +out: + free(buf); + close(fd); + + return ret; +} +late_initcall(pcm030_eeprom_read); diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c index a7fa21d173..11b3beb20f 100644 --- a/arch/ppc/boards/pcm030/pcm030.c +++ b/arch/ppc/boards/pcm030/pcm030.c @@ -32,12 +32,23 @@ #include <memory.h> #include <linux/sizes.h> #include <linux/stat.h> +#include <asm/io.h> #include <fs.h> +#include <i2c/i2c.h> static struct fec_platform_data fec_info = { .xcv_type = PHY_INTERFACE_MODE_MII, }; +static struct i2c_board_info pcm030_i2c_devices[] = { + { I2C_BOARD_INFO("pcf8563", 0x51), }, + { I2C_BOARD_INFO("24c32", 0x52), }, +}; + +struct i2c_platform_data pcm030_i2c_plat = { + .bitrate = 100000, +}; + static int devices_init (void) { struct stat s; @@ -52,6 +63,9 @@ static int devices_init (void) add_generic_device("fec_mpc5xxx", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_FEC, 0x200, IORESOURCE_MEM, &fec_info); + i2c_register_board_info(0, pcm030_i2c_devices, ARRAY_SIZE(pcm030_i2c_devices)); + add_generic_device("i2c-fsl", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_I2C2, 0x100, + IORESOURCE_MEM, &pcm030_i2c_plat); ret = stat("/dev/nor0", &s); if (ret) @@ -141,10 +155,16 @@ void initdram (int board_type) /* Setup pin multiplexing */ /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = 0x00558c10; + *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = 0x00559c10; *(vu_long *)MPC5XXX_CS_BURST = 0x00000000; *(vu_long *)MPC5XXX_CS_DEADCYCLE = 0x33333333; + /* + * Make USB work due to the special base crystal frequency: + * 33,3330MHz * 16 = 533,328MHz main clock, but should be 528 MHz Clock + */ + out_be32((void *)MPC5XXX_CDM_48_FDC, 0x00015555); + mpc5200_setup_bus_clocks(1, 4); if (get_pc() > SZ_128M) { diff --git a/arch/ppc/configs/pcm030_defconfig b/arch/ppc/configs/pcm030_defconfig index 7b84e2f3b6..61380ac294 100644 --- a/arch/ppc/configs/pcm030_defconfig +++ b/arch/ppc/configs/pcm030_defconfig @@ -35,8 +35,11 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_NET=y CONFIG_DRIVER_NET_MPC5200=y +CONFIG_I2C=y +CONFIG_I2C_IMX=y CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y +CONFIG_EEPROM_AT24=y CONFIG_FS_TFTP=y CONFIG_ZLIB=y diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c index c860e709f2..3f826e4994 100644 --- a/arch/ppc/mach-mpc5xxx/cpu.c +++ b/arch/ppc/mach-mpc5xxx/cpu.c @@ -31,7 +31,7 @@ #include <types.h> #include <errno.h> #include <of.h> -#include <mach/clocks.h> +#include <mach/clock.h> int checkcpu (void) { @@ -83,17 +83,21 @@ static int of_mpc5200_fixup(struct device_node *root, void *unused) int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4; - node = of_find_node_by_path("/cpus/PowerPC,5200@0"); - if (!node) + node = of_find_node_by_path_from(root, "/cpus/PowerPC,5200@0"); + if (!node) { + pr_err("Cannot find node '/cpus/PowerPC,5200@0' for proper CPU frequency fixup\n"); return -EINVAL; + } of_property_write_u32(node, "timebase-frequency", get_timebase_clock()); of_property_write_u32(node, "bus-frequency", get_bus_clock()); of_property_write_u32(node, "clock-frequency", get_cpu_clock()); - node = of_find_node_by_path("/soc5200@f0000000"); - if (!node) + node = of_find_node_by_path_from(root, "/soc5200@f0000000"); + if (!node) { + pr_err("Cannot find node '/soc5200@f0000000' for proper SOC frequency fixup\n"); return -EINVAL; + } of_property_write_u32(node, "bus-frequency", get_ipb_clock()); of_property_write_u32(node, "system-frequency", get_bus_clock() * div); diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clock.h index 4e1a903e79..b19686f18c 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/clock.h @@ -6,5 +6,9 @@ unsigned long get_cpu_clock(void); unsigned long get_ipb_clock(void); unsigned long get_pci_clock(void); unsigned long get_timebase_clock(void); +static inline unsigned long fsl_get_i2c_freq(void) +{ + return get_ipb_clock(); +} #endif /* __ASM_ARCH_CLOCKS_H */ diff --git a/arch/ppc/mach-mpc5xxx/time.c b/arch/ppc/mach-mpc5xxx/time.c index 699a66dff4..aaa4573f6f 100644 --- a/arch/ppc/mach-mpc5xxx/time.c +++ b/arch/ppc/mach-mpc5xxx/time.c @@ -20,7 +20,7 @@ #include <common.h> #include <clock.h> #include <init.h> -#include <mach/clocks.h> +#include <mach/clock.h> #include <asm/common.h> uint64_t ppc_clocksource_read(void) diff --git a/arch/ppc/mach-mpc85xx/Kconfig b/arch/ppc/mach-mpc85xx/Kconfig index e29be9c19e..aa518b98fc 100644 --- a/arch/ppc/mach-mpc85xx/Kconfig +++ b/arch/ppc/mach-mpc85xx/Kconfig @@ -81,10 +81,6 @@ config P1022 config MPC8544 bool -config DDR_SPD - bool - select CRC16 - config FSL_DDR2 bool diff --git a/arch/ppc/mach-mpc85xx/Makefile b/arch/ppc/mach-mpc85xx/Makefile index 3e646178b9..de4f5efde2 100644 --- a/arch/ppc/mach-mpc85xx/Makefile +++ b/arch/ppc/mach-mpc85xx/Makefile @@ -9,5 +9,6 @@ obj-y += fsl_i2c.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_OFTREE) += fdt.o obj-$(CONFIG_DRIVER_NET_GIANFAR) += eth-devices.o -obj-$(CONFIG_DDR_SPD) += ../ddr-8xxx/ +obj-$(CONFIG_FSL_DDR2) += ../ddr-8xxx/ +obj-$(CONFIG_FSL_DDR3) += ../ddr-8xxx/ extra-y += barebox.lds diff --git a/arch/ppc/mach-mpc85xx/barebox.lds.S b/arch/ppc/mach-mpc85xx/barebox.lds.S index 87ab7acfe2..1f7f52c39c 100644 --- a/arch/ppc/mach-mpc85xx/barebox.lds.S +++ b/arch/ppc/mach-mpc85xx/barebox.lds.S @@ -109,6 +109,11 @@ SECTIONS __barebox_initcalls_end = .; __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start)>>2; + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2; + __usymtab_start = .; __usymtab : { BAREBOX_SYMS } __usymtab_end = .; diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S index db5b7deb23..0d67ab6607 100644 --- a/arch/sandbox/board/barebox.lds.S +++ b/arch/sandbox/board/barebox.lds.S @@ -8,6 +8,11 @@ SECTIONS __barebox_initcalls_end = .; . = ALIGN(64); + __barebox_exitcalls_start = .; + __barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + + . = ALIGN(64); __barebox_magicvar_start = .; .barebox_magicvar : { BAREBOX_MAGICVARS } __barebox_magicvar_end = .; diff --git a/arch/sandbox/configs/sandbox_defconfig b/arch/sandbox/configs/sandbox_defconfig index ec045f7c0b..d82579b636 100644 --- a/arch/sandbox/configs/sandbox_defconfig +++ b/arch/sandbox/configs/sandbox_defconfig @@ -1,40 +1,103 @@ CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y CONFIG_PARTITION=y +CONFIG_DEFAULT_COMPRESSION_GZIP=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/sandbox/board/env" CONFIG_DEBUG_INFO=y +CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y +CONFIG_CMD_IMD=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_BOOTM is not set CONFIG_CMD_GO=y CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y CONFIG_CMD_PARTITION=y CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_MAGICVAR=y CONFIG_CMD_MAGICVAR_HELP=y CONFIG_CMD_SAVEENV=y +CONFIG_CMD_CMP=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_SHA224SUM=y +CONFIG_CMD_SHA256SUM=y +CONFIG_CMD_SHA384SUM=y +CONFIG_CMD_SHA512SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_LET=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_READF=y CONFIG_CMD_SLEEP=y CONFIG_CMD_DHCP=y +CONFIG_CMD_HOST=y CONFIG_CMD_PING=y CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y CONFIG_CMD_EDIT=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_MENUTREE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_READLINE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MM=y +CONFIG_CMD_DETECT=y CONFIG_CMD_FLASH=y CONFIG_CMD_2048=y CONFIG_CMD_OF_NODE=y CONFIG_CMD_OF_PROPERTY=y CONFIG_CMD_OF_DISPLAY_TIMINGS=y CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_SPD_DECODE=y CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_NET_NETCONSOLE=y CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_NET_TAP=y # CONFIG_SPI is not set +CONFIG_VIDEO=y +CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_PINCTRL is not set CONFIG_FS_CRAMFS=y +CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y +CONFIG_FS_BPKFS=y +CONFIG_FS_UIMAGEFS=y +CONFIG_BZLIB=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DECOMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_BMP=y +CONFIG_PNG=y +CONFIG_FONT_8x16=y +CONFIG_FONT_7x14=y +CONFIG_FONT_MINI_4x6=y +CONFIG_BAREBOX_LOGO=y +CONFIG_BAREBOX_LOGO_64=y +CONFIG_BAREBOX_LOGO_240=y +CONFIG_BAREBOX_LOGO_320=y +CONFIG_BAREBOX_LOGO_400=y +CONFIG_BAREBOX_LOGO_640=y +CONFIG_DIGEST_MD5_GENERIC=y +CONFIG_DIGEST_SHA1_GENERIC=y +CONFIG_DIGEST_SHA224_GENERIC=y +CONFIG_DIGEST_SHA256_GENERIC=y +CONFIG_DIGEST_SHA384_GENERIC=y +CONFIG_DIGEST_SHA512_GENERIC=y +CONFIG_DIGEST_HMAC_GENERIC=y diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S index 6cf6b10d1b..23d7546532 100644 --- a/arch/x86/lib/barebox.lds.S +++ b/arch/x86/lib/barebox.lds.S @@ -185,7 +185,14 @@ SECTIONS . = ALIGN(4); } > barebox - .__usymtab : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) { + .barebox_exitcalls : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) { + __barebox_exitcalls_start = .; + EXITCALLS + __barebox_exitcalls_end = .; + . = ALIGN(4); + } > barebox + + .__usymtab : AT ( LOADADDR(.barebox_exitcalls) + SIZEOF (.barebox_exitcalls) ) { __usymtab_start = .; BAREBOX_SYMS __usymtab_end = .; |