diff options
Diffstat (limited to 'roms/u-boot/board/liebherr')
19 files changed, 2006 insertions, 0 deletions
diff --git a/roms/u-boot/board/liebherr/display5/Kconfig b/roms/u-boot/board/liebherr/display5/Kconfig new file mode 100644 index 000000000..b096c8917 --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/Kconfig @@ -0,0 +1,18 @@ +if TARGET_DISPLAY5 + +config SYS_CPU + default "armv7" + +config SYS_BOARD + default "display5" + +config SYS_VENDOR + default "liebherr" + +config SYS_SOC + default "mx6" + +config SYS_CONFIG_NAME + default "display5" + +endif diff --git a/roms/u-boot/board/liebherr/display5/MAINTAINERS b/roms/u-boot/board/liebherr/display5/MAINTAINERS new file mode 100644 index 000000000..52178318b --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/MAINTAINERS @@ -0,0 +1,7 @@ +DISPLAY5 BOARD +M: Lukasz Majewski <lukma@denx.de> +S: Maintained +F: board/liebherr/display5/ +F: include/configs/display5.h +F: configs/display5_defconfig +F: configs/display5_factory_defconfig diff --git a/roms/u-boot/board/liebherr/display5/Makefile b/roms/u-boot/board/liebherr/display5/Makefile new file mode 100644 index 000000000..ee503add7 --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (C) 2017, DENX Software Engineering +# Lukasz Majewski <lukma@denx.de> +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +obj-y = spl.o +else +obj-y := display5.o +endif diff --git a/roms/u-boot/board/liebherr/display5/common.h b/roms/u-boot/board/liebherr/display5/common.h new file mode 100644 index 000000000..44c747007 --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/common.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#ifndef __DISPL5_COMMON_H_ +#define __DISPL5_COMMON_H_ + +#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define SPI_PAD_CTRL (PAD_CTL_HYS | \ + PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + +#define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \ + PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#endif /* __DISPL5_COMMON_H_ */ diff --git a/roms/u-boot/board/liebherr/display5/display5.c b/roms/u-boot/board/liebherr/display5/display5.c new file mode 100644 index 000000000..e3a59dbec --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/display5.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include <common.h> +#include <dm.h> +#include <fdt_support.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <asm/arch/mx6-ddr.h> +#include <asm/arch/sys_proto.h> +#include <env.h> +#include <errno.h> +#include <asm/gpio.h> +#include <malloc.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/boot_mode.h> +#include <miiphy.h> +#include <netdev.h> +#include <i2c.h> +#include <linux/delay.h> + +#include <dm/platform_data/serial_mxc.h> +#include <dm/platdata.h> + +#include "common.h" + +DECLARE_GLOBAL_DATA_PTR; + +static bool hw_ids_valid; +static bool sw_ids_valid; +static u32 cpu_id; +static u32 unit_id; + +const char *gpio_table_sw_names[] = { + "GPIO2_4", "GPIO2_5", "GPIO2_6", "GPIO2_7" +}; + +const char *gpio_table_sw_ids_names[] = { + "sw0", "sw1", "sw2", "sw3" +}; + +const char *gpio_table_hw_names[] = { + "GPIO6_7", "GPIO6_9", "GPIO6_10", "GPIO6_11", + "GPIO4_7", "GPIO4_11", "GPIO4_13", "GPIO4_15" +}; + +const char *gpio_table_hw_ids_names[] = { + "hw0", "hw1", "hw2", "hw3", "hw4", "hw5", "hw6", "hw7" +}; + +static int get_board_id(const char **pin_names, const char **ids_names, + int size, bool *valid, u32 *id) +{ + struct gpio_desc desc; + int i, ret, val; + + *valid = false; + + for (i = 0; i < size; i++) { + memset(&desc, 0, sizeof(desc)); + + ret = dm_gpio_lookup_name(pin_names[i], &desc); + if (ret) { + printf("Can't lookup request SWx gpios\n"); + return ret; + } + + ret = dm_gpio_request(&desc, ids_names[i]); + if (ret) { + printf("Can't lookup request SWx gpios\n"); + return ret; + } + + dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN); + + val = dm_gpio_get_value(&desc); + if (val < 0) { + printf("Can't get SW%d ID\n", i); + *id = 0; + return val; + } + *id |= val << i; + } + *valid = true; + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +iomux_v3_cfg_t const misc_pads[] = { + /* Prod ID GPIO pins */ + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D7__GPIO2_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* HW revision GPIO pins */ + MX6_PAD_NANDF_CLE__GPIO6_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_WP_B__GPIO6_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_RB0__GPIO6_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_CS0__GPIO6_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_KEY_ROW2__GPIO4_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* XTALOSC */ + MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* Emergency recovery pin */ + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +/* + * Do not overwrite the console + * Always use serial for U-Boot console + */ +int overwrite_console(void) +{ + return 1; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + fdt_fixup_ethernet(blob); + return 0; +} +#endif + +int board_phy_config(struct phy_device *phydev) +{ + /* display5 due to PCB routing can only work with 100 Mbps */ + phydev->advertising &= ~(ADVERTISED_1000baseX_Half | + ADVERTISED_1000baseX_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); + + if (phydev->drv->config) + return phydev->drv->config(phydev); + + return 0; +} + +int board_init(void) +{ + struct gpio_desc phy_int_gbe, spi2_wp; + int ret; + + debug("board init\n"); + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + /* Setup misc (application specific) stuff */ + SETUP_IOMUX_PADS(misc_pads); + + get_board_id(gpio_table_sw_names, &gpio_table_sw_ids_names[0], + ARRAY_SIZE(gpio_table_sw_names), &sw_ids_valid, &unit_id); + debug("SWx unit_id 0x%x\n", unit_id); + + get_board_id(gpio_table_hw_names, &gpio_table_hw_ids_names[0], + ARRAY_SIZE(gpio_table_hw_names), &hw_ids_valid, &cpu_id); + debug("HWx cpu_id 0x%x\n", cpu_id); + + if (hw_ids_valid && sw_ids_valid) + printf("ID: unit type 0x%x rev 0x%x\n", unit_id, cpu_id); + + udelay(25); + + /* Setup low level FEC (ETH) */ + ret = dm_gpio_lookup_name("GPIO1_28", &phy_int_gbe); + if (ret) { + printf("Cannot get GPIO1_28\n"); + } else { + ret = dm_gpio_request(&phy_int_gbe, "INT_GBE"); + if (!ret) + dm_gpio_set_dir_flags(&phy_int_gbe, GPIOD_IS_IN); + } + + iomuxc_set_rgmii_io_voltage(DDR_SEL_1P5V_IO); + enable_fec_anatop_clock(0, ENET_125MHZ); + + /* Setup #WP for SPI-NOR memory */ + ret = dm_gpio_lookup_name("GPIO7_0", &spi2_wp); + if (ret) { + printf("Cannot get GPIO7_0\n"); + } else { + ret = dm_gpio_request(&spi2_wp, "spi2_#wp"); + if (!ret) + dm_gpio_set_dir_flags(&spi2_wp, GPIOD_IS_OUT | + GPIOD_IS_OUT_ACTIVE); + } + + return 0; +} + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + /* eMMC, USDHC-4, 8-bit bus width */ + /* SPI-NOR, ECSPI-2 SS0, 3-bytes addressing */ + {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)}, + {"spinor", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x09)}, + {NULL, 0}, +}; + +static void setup_boot_modes(void) +{ + add_board_boot_modes(board_boot_modes); +} +#else +static inline void setup_boot_modes(void) {} +#endif + +int misc_init_r(void) +{ + struct gpio_desc em_pad; + int ret; + + setup_boot_modes(); + + ret = dm_gpio_lookup_name("GPIO3_29", &em_pad); + if (ret) { + printf("Can't find emergency PAD gpio\n"); + return ret; + } + + ret = dm_gpio_request(&em_pad, "Emergency_PAD"); + if (ret) { + printf("Can't request emergency PAD gpio\n"); + return ret; + } + + dm_gpio_set_dir_flags(&em_pad, GPIOD_IS_IN); + + return 0; +} diff --git a/roms/u-boot/board/liebherr/display5/spl.c b/roms/u-boot/board/liebherr/display5/spl.c new file mode 100644 index 000000000..39f70f578 --- /dev/null +++ b/roms/u-boot/board/liebherr/display5/spl.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include <common.h> +#include <cpu_func.h> +#include <env.h> +#include <image.h> +#include <init.h> +#include <log.h> +#include <serial.h> +#include <spl.h> +#include <asm/global_data.h> +#include <linux/delay.h> +#include <linux/libfdt.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/mx6-ddr.h> +#include <asm/arch/mx6-pins.h> +#include "asm/arch/crm_regs.h" +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h> +#include "asm/arch/iomux.h" +#include <asm/mach-imx/iomux-v3.h> +#include <asm/gpio.h> +#include <fsl_esdhc_imx.h> +#include <netdev.h> +#include <bootcount.h> +#include <watchdog.h> +#include "common.h" + +DECLARE_GLOBAL_DATA_PTR; + +static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { + .dram_sdclk_0 = 0x00000030, + .dram_sdclk_1 = 0x00000030, + .dram_cas = 0x00000030, + .dram_ras = 0x00000030, + .dram_reset = 0x00000030, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = 0x00000030, + .dram_sdodt1 = 0x00000030, + + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + + .dram_dqm0 = 0x00000030, + .dram_dqm1 = 0x00000030, + .dram_dqm2 = 0x00000030, + .dram_dqm3 = 0x00000030, + .dram_dqm4 = 0x00000030, + .dram_dqm5 = 0x00000030, + .dram_dqm6 = 0x00000030, + .dram_dqm7 = 0x00000030, +}; + +static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = 0x00000030, + .grp_ctlds = 0x00000030, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +/* 4x128Mx16.cfg */ +static const struct mx6_mmdc_calibration mx6_4x256mx16_mmdc_calib = { + .p0_mpwldectrl0 = 0x002D0028, + .p0_mpwldectrl1 = 0x0032002D, + .p1_mpwldectrl0 = 0x00210036, + .p1_mpwldectrl1 = 0x0019002E, + .p0_mpdgctrl0 = 0x4349035C, + .p0_mpdgctrl1 = 0x0348033D, + .p1_mpdgctrl0 = 0x43550362, + .p1_mpdgctrl1 = 0x03520316, + .p0_mprddlctl = 0x41393940, + .p1_mprddlctl = 0x3F3A3C47, + .p0_mpwrdlctl = 0x413A423A, + .p1_mpwrdlctl = 0x4042483E, +}; + +/* MT41K128M16JT-125 (2Gb density) */ +static const struct mx6_ddr3_cfg mt41k128m16jt_125 = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +iomux_v3_cfg_t const uart_console_pads[] = { + /* UART5 */ + MX6_PAD_CSI0_DAT14__UART5_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT15__UART5_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT18__UART5_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT19__UART5_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +void displ5_set_iomux_uart_spl(void) +{ + SETUP_IOMUX_PADS(uart_console_pads); +} + +iomux_v3_cfg_t const misc_pads_spl[] = { + /* Emergency recovery pin */ + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +void displ5_set_iomux_misc_spl(void) +{ + SETUP_IOMUX_PADS(misc_pads_spl); +} + +#ifdef CONFIG_MXC_SPI +iomux_v3_cfg_t const ecspi2_pads[] = { + /* SPI2, NOR Flash nWP, CS0 */ + MX6_PAD_CSI0_DAT10__ECSPI2_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_CSI0_DAT9__ECSPI2_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_CSI0_DAT8__ECSPI2_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_CSI0_DAT11__GPIO5_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_spi_cs_gpio(unsigned int bus, unsigned int cs) +{ + if (bus != 1 || cs != 0) + return -EINVAL; + + return IMX_GPIO_NR(5, 29); +} + +void displ5_set_iomux_ecspi_spl(void) +{ + SETUP_IOMUX_PADS(ecspi2_pads); +} + +#else +void displ5_set_iomux_ecspi_spl(void) {} +#endif + +#ifdef CONFIG_FSL_ESDHC_IMX +iomux_v3_cfg_t const usdhc4_pads[] = { + MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_ALE__SD4_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +void displ5_set_iomux_usdhc_spl(void) +{ + SETUP_IOMUX_PADS(usdhc4_pads); +} + +#else +void displ5_set_iomux_usdhc_spl(void) {} +#endif + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC3F, &ccm->CCGR1); + writel(0x0FFFCFC0, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +#ifdef CONFIG_MX6_DDRCAL +static void spl_dram_print_cal(struct mx6_ddr_sysinfo const *sysinfo) +{ + struct mx6_mmdc_calibration calibration = {0}; + + mmdc_read_calibration(sysinfo, &calibration); + + debug(".p0_mpdgctrl0\t= 0x%08X\n", calibration.p0_mpdgctrl0); + debug(".p0_mpdgctrl1\t= 0x%08X\n", calibration.p0_mpdgctrl1); + debug(".p0_mprddlctl\t= 0x%08X\n", calibration.p0_mprddlctl); + debug(".p0_mpwrdlctl\t= 0x%08X\n", calibration.p0_mpwrdlctl); + debug(".p0_mpwldectrl0\t= 0x%08X\n", calibration.p0_mpwldectrl0); + debug(".p0_mpwldectrl1\t= 0x%08X\n", calibration.p0_mpwldectrl1); + debug(".p1_mpdgctrl0\t= 0x%08X\n", calibration.p1_mpdgctrl0); + debug(".p1_mpdgctrl1\t= 0x%08X\n", calibration.p1_mpdgctrl1); + debug(".p1_mprddlctl\t= 0x%08X\n", calibration.p1_mprddlctl); + debug(".p1_mpwrdlctl\t= 0x%08X\n", calibration.p1_mpwrdlctl); + debug(".p1_mpwldectrl0\t= 0x%08X\n", calibration.p1_mpwldectrl0); + debug(".p1_mpwldectrl1\t= 0x%08X\n", calibration.p1_mpwldectrl1); +} + +static void spl_dram_perform_cal(struct mx6_ddr_sysinfo const *sysinfo) +{ + int ret; + + /* Perform DDR DRAM calibration */ + udelay(100); + ret = mmdc_do_write_level_calibration(sysinfo); + if (ret) { + printf("DDR: Write level calibration error [%d]\n", ret); + return; + } + + ret = mmdc_do_dqs_calibration(sysinfo); + if (ret) { + printf("DDR: DQS calibration error [%d]\n", ret); + return; + } + + spl_dram_print_cal(sysinfo); +} +#endif /* CONFIG_MX6_DDRCAL */ + +static void spl_dram_init(void) +{ + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = 2, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* single chip select */ + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ + .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .pd_fast_exit = 1, /* enable precharge power-down fast exit */ + .ddr_type = DDR_TYPE_DDR3, + .refsel = 1, /* Refresh cycles at 32KHz */ + .refr = 7, /* 8 refresh commands per refresh cycle */ + }; + + mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125); + +#ifdef CONFIG_MX6_DDRCAL + spl_dram_perform_cal(&sysinfo); +#endif +} + +#ifdef CONFIG_SPL_SPI_SUPPORT +static void displ5_init_ecspi(void) +{ + displ5_set_iomux_ecspi_spl(); + enable_spi_clk(1, 1); +} +#else +static inline void displ5_init_ecspi(void) { } +#endif + +#ifdef CONFIG_SPL_MMC_SUPPORT +static struct fsl_esdhc_cfg usdhc_cfg = { + .esdhc_base = USDHC4_BASE_ADDR, + .max_bus_width = 8, +}; + +int board_mmc_init(struct bd_info *bd) +{ + displ5_set_iomux_usdhc_spl(); + + usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + gd->arch.sdhc_clk = usdhc_cfg.sdhc_clk; + + return fsl_esdhc_initialize(bd, &usdhc_cfg); +} +#endif + +void board_init_f(ulong dummy) +{ + ccgr_init(); + + arch_cpu_init(); + + gpr_init(); + + /* setup GP timer */ + timer_init(); + + displ5_set_iomux_uart_spl(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + displ5_init_ecspi(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + displ5_set_iomux_misc_spl(); + + /* Initialize and reset WDT in SPL */ + hw_watchdog_init(); + WATCHDOG_RESET(); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +#define EM_PAD IMX_GPIO_NR(3, 29) +int board_check_emergency_pad(void) +{ + int ret; + + ret = gpio_direction_input(EM_PAD); + if (ret) + return ret; + + return !gpio_get_value(EM_PAD); +} + +void board_boot_order(u32 *spl_boot_list) +{ + /* Default boot sequence SPI -> MMC */ + spl_boot_list[0] = spl_boot_device(); + spl_boot_list[1] = BOOT_DEVICE_MMC1; + spl_boot_list[2] = BOOT_DEVICE_UART; + spl_boot_list[3] = BOOT_DEVICE_NONE; + + /* + * In case of emergency PAD pressed, we always boot + * to proper u-boot and perform recovery tasks there. + */ + if (board_check_emergency_pad()) + return; + +#ifdef CONFIG_SPL_ENV_SUPPORT + /* 'fastboot' */ + const char *s; + + if (env_init() || env_load()) + return; + + s = env_get("BOOT_FROM"); + if (s && !bootcount_error() && strcmp(s, "ACTIVE") == 0) { + spl_boot_list[0] = BOOT_DEVICE_MMC1; + spl_boot_list[1] = spl_boot_device(); + } +#endif +} + +void reset_cpu(void) {} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + return 0; +} +#endif + +#ifdef CONFIG_SPL_OS_BOOT +/* Return: 1 - boot to U-Boot. 0 - boot OS (falcon mode) */ +int spl_start_uboot(void) +{ + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + +#ifdef CONFIG_SPL_ENV_SUPPORT + if (env_get_yesno("boot_os") != 1) + return 1; +#endif + return 0; +} +#endif diff --git a/roms/u-boot/board/liebherr/mccmon6/Kconfig b/roms/u-boot/board/liebherr/mccmon6/Kconfig new file mode 100644 index 000000000..4cc7fc2ba --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/Kconfig @@ -0,0 +1,12 @@ +if TARGET_MCCMON6 + +config SYS_BOARD + default "mccmon6" + +config SYS_VENDOR + default "liebherr" + +config SYS_CONFIG_NAME + default "mccmon6" + +endif diff --git a/roms/u-boot/board/liebherr/mccmon6/MAINTAINERS b/roms/u-boot/board/liebherr/mccmon6/MAINTAINERS new file mode 100644 index 000000000..c9c718305 --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/MAINTAINERS @@ -0,0 +1,7 @@ +MCCMON6 BOARD +M: Lukasz Majewski <lukma@denx.de> +S: Maintained +F: board/liebherr/mccmon6/ +F: include/configs/mccmon6.h +F: configs/mccmon6_nor_defconfig +F: configs/mccmon6_sd_defconfig diff --git a/roms/u-boot/board/liebherr/mccmon6/Makefile b/roms/u-boot/board/liebherr/mccmon6/Makefile new file mode 100644 index 000000000..3c9786c6b --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2016-2017 +# Lukasz Majewski, DENX Software Engineering, lukma@denx.de +ifdef CONFIG_SPL_BUILD +obj-y := spl.o +else +obj-y := mccmon6.o +endif diff --git a/roms/u-boot/board/liebherr/mccmon6/mccmon6.c b/roms/u-boot/board/liebherr/mccmon6/mccmon6.c new file mode 100644 index 000000000..1b49526fb --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/mccmon6.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2017 + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include <common.h> +#include <env.h> +#include <init.h> +#include <serial.h> +#include <asm/arch/clock.h> +#include <asm/arch/iomux.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + return 0; +} + +int board_late_init(void) +{ + env_set("board_name", "mccmon6"); + + return 0; +} + +int checkboard(void) +{ + puts("Board: MCCMON6\n"); + + return 0; +} diff --git a/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_nor.cfg b/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_nor.cfg new file mode 100644 index 000000000..6f966a7dd --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_nor.cfg @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016-2017 + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +IMAGE_VERSION 2 +BOOT_FROM nor diff --git a/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_sd.cfg b/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_sd.cfg new file mode 100644 index 000000000..5a65e0f54 --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/mon6_imximage_sd.cfg @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016-2017 + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +IMAGE_VERSION 2 +BOOT_FROM sd diff --git a/roms/u-boot/board/liebherr/mccmon6/spl.c b/roms/u-boot/board/liebherr/mccmon6/spl.c new file mode 100644 index 000000000..56eae3b4e --- /dev/null +++ b/roms/u-boot/board/liebherr/mccmon6/spl.c @@ -0,0 +1,577 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014 Wandboard + * Author: Tungyi Lin <tungyilin1127@gmail.com> + * Richard Hu <hakahu@gmail.com> + */ + +#include <image.h> +#include <init.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <errno.h> +#include <asm/gpio.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/video.h> +#include <mmc.h> +#include <fsl_esdhc_imx.h> +#include <asm/arch/crm_regs.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <serial.h> +#include <spl.h> +#include <linux/delay.h> + +#include <asm/arch/mx6-ddr.h> +/* + * Driving strength: + * 0x30 == 40 Ohm + * 0x28 == 48 Ohm + */ + +#define IMX6DQ_DRIVE_STRENGTH 0x30 +#define IMX6SDL_DRIVE_STRENGTH 0x28 + +/* configure MX6Q/DUAL mmdc DDR io registers */ +static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = { + .dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH, + .dram_cas = IMX6DQ_DRIVE_STRENGTH, + .dram_ras = IMX6DQ_DRIVE_STRENGTH, + .dram_reset = IMX6DQ_DRIVE_STRENGTH, + .dram_sdcke0 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdcke1 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH, + .dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm0 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm1 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm2 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm3 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm4 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm5 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm6 = IMX6DQ_DRIVE_STRENGTH, + .dram_dqm7 = IMX6DQ_DRIVE_STRENGTH, +}; + +/* configure MX6Q/DUAL mmdc GRP io registers */ +static struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = { + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = IMX6DQ_DRIVE_STRENGTH, + .grp_ctlds = IMX6DQ_DRIVE_STRENGTH, + .grp_ddrmode = 0x00020000, + .grp_b0ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b1ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b2ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b3ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b4ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b5ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b6ds = IMX6DQ_DRIVE_STRENGTH, + .grp_b7ds = IMX6DQ_DRIVE_STRENGTH, +}; + +/* configure MX6SOLO/DUALLITE mmdc DDR io registers */ +struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = { + .dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH, + .dram_cas = IMX6SDL_DRIVE_STRENGTH, + .dram_ras = IMX6SDL_DRIVE_STRENGTH, + .dram_reset = IMX6SDL_DRIVE_STRENGTH, + .dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm0 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm1 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm2 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm3 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm4 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm5 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm6 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm7 = IMX6SDL_DRIVE_STRENGTH, +}; + +/* configure MX6SOLO/DUALLITE mmdc GRP io registers */ +struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = IMX6SDL_DRIVE_STRENGTH, + .grp_ctlds = IMX6SDL_DRIVE_STRENGTH, + .grp_ddrmode = 0x00020000, + .grp_b0ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b1ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b2ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b3ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b4ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b5ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b6ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b7ds = IMX6SDL_DRIVE_STRENGTH, +}; + +/* H5T04G63AFR-PB */ +static struct mx6_ddr3_cfg h5t04g63afr = { + .mem_speed = 1600, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* H5TQ2G63DFR-H9 */ +static struct mx6_ddr3_cfg h5tq2g63dfr = { + .mem_speed = 1333, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1350, + .trcmin = 4950, + .trasmin = 3600, +}; + +static struct mx6_mmdc_calibration mx6q_2g_mmdc_calib = { + .p0_mpwldectrl0 = 0x001f001f, + .p0_mpwldectrl1 = 0x001f001f, + .p1_mpwldectrl0 = 0x001f001f, + .p1_mpwldectrl1 = 0x001f001f, + .p0_mpdgctrl0 = 0x4301030d, + .p0_mpdgctrl1 = 0x03020277, + .p1_mpdgctrl0 = 0x4300030a, + .p1_mpdgctrl1 = 0x02780248, + .p0_mprddlctl = 0x4536393b, + .p1_mprddlctl = 0x36353441, + .p0_mpwrdlctl = 0x41414743, + .p1_mpwrdlctl = 0x462f453f, +}; + +/* DDR 64bit 2GB */ +static struct mx6_ddr_sysinfo mem_q = { + .dsize = 2, + .cs1_mirror = 0, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, + .ncs = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 0, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static struct mx6_mmdc_calibration mx6dl_1g_mmdc_calib = { + .p0_mpwldectrl0 = 0x001f001f, + .p0_mpwldectrl1 = 0x001f001f, + .p1_mpwldectrl0 = 0x001f001f, + .p1_mpwldectrl1 = 0x001f001f, + .p0_mpdgctrl0 = 0x420e020e, + .p0_mpdgctrl1 = 0x02000200, + .p1_mpdgctrl0 = 0x42020202, + .p1_mpdgctrl1 = 0x01720172, + .p0_mprddlctl = 0x494c4f4c, + .p1_mprddlctl = 0x4a4c4c49, + .p0_mpwrdlctl = 0x3f3f3133, + .p1_mpwrdlctl = 0x39373f2e, +}; + +static struct mx6_mmdc_calibration mx6s_512m_mmdc_calib = { + .p0_mpwldectrl0 = 0x0040003c, + .p0_mpwldectrl1 = 0x0032003e, + .p0_mpdgctrl0 = 0x42350231, + .p0_mpdgctrl1 = 0x021a0218, + .p0_mprddlctl = 0x4b4b4e49, + .p0_mpwrdlctl = 0x3f3f3035, +}; + +/* DDR 64bit 1GB */ +static struct mx6_ddr_sysinfo mem_dl = { + .dsize = 2, + .cs1_mirror = 0, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, + .ncs = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 0, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +/* DDR 32bit 512MB */ +static struct mx6_ddr_sysinfo mem_s = { + .dsize = 1, + .cs1_mirror = 0, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, + .ncs = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 0, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void spl_dram_init(void) +{ + if (is_cpu_type(MXC_CPU_MX6SOLO)) { + mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); + mx6_dram_cfg(&mem_s, &mx6s_512m_mmdc_calib, &h5tq2g63dfr); + } else if (is_cpu_type(MXC_CPU_MX6DL)) { + mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); + mx6_dram_cfg(&mem_dl, &mx6dl_1g_mmdc_calib, &h5tq2g63dfr); + } else if (is_cpu_type(MXC_CPU_MX6Q)) { + mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs); + mx6_dram_cfg(&mem_q, &mx6q_2g_mmdc_calib, &h5t04g63afr); + } + + udelay(100); +} + +static void setup_spi(void) +{ + enable_spi_clk(true, 2); +} + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +static iomux_v3_cfg_t const uart1_pads[] = { + IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static void setup_iomux_uart(void) +{ + SETUP_IOMUX_PADS(uart1_pads); +} + +void board_init_f(ulong dummy) +{ + ccgr_init(); + + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + gpr_init(); + + /* iomux */ + setup_iomux_uart(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* enable ECSPI clocks */ + setup_spi(); + + /* DDR initialization */ + spl_dram_init(); +} + +void board_boot_order(u32 *spl_boot_list) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC1: + spl_boot_list[0] = BOOT_DEVICE_MMC2; + spl_boot_list[1] = BOOT_DEVICE_MMC1; + break; + + case BOOT_DEVICE_NOR: + spl_boot_list[0] = BOOT_DEVICE_NOR; + break; + } +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + return 0; +} +#endif + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + char s[16]; + int ret; + /* + * We use BOOT_DEVICE_MMC1, but SD card is connected + * to MMC2 + * + * Correct "mapping" is delivered in board defined + * board_boot_order() function. + * + * SD card boot is regarded as a "development" one, + * hence we _always_ go through the u-boot. + * + */ + if (spl_boot_device() == BOOT_DEVICE_MMC1) + return 1; + + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + + env_init(); + ret = env_get_f("boot_os", s, sizeof(s)); + if ((ret != -1) && (strcmp(s, "no") == 0)) + return 1; + + /* + * Check if SWUpdate recovery needs to be started + * + * recovery_status = NULL (not set - ret == -1) -> normal operation + * + * recovery_status = progress or + * recovery_status = failed or + * recovery_status = <any value> -> start SWUpdate + * + */ + ret = env_get_f("recovery_status", s, sizeof(s)); + if (ret != -1) + return 1; + + return 0; +} +#endif /* CONFIG_SPL_OS_BOOT */ + +#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define NOR_WP IMX_GPIO_NR(1, 1) + +static iomux_v3_cfg_t const eimnor_pads[] = { + IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A24__EIM_ADDR24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A25__EIM_ADDR25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static void eimnor_cs_setup(void) +{ + struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR; + + /* NOR configuration */ + writel(0x00620181, &weim_regs->cs0gcr1); + writel(0x00000001, &weim_regs->cs0gcr2); + writel(0x0b020000, &weim_regs->cs0rcr1); + writel(0x0000b000, &weim_regs->cs0rcr2); + writel(0x0804a240, &weim_regs->cs0wcr1); + writel(0x00000000, &weim_regs->cs0wcr2); + + writel(0x00000120, &weim_regs->wcr); + writel(0x00000010, &weim_regs->wiar); + writel(0x00000000, &weim_regs->ear); + + set_chipselect_size(CS0_128); +} + +static void setup_eimnor(void) +{ + SETUP_IOMUX_PADS(eimnor_pads); + gpio_direction_output(NOR_WP, 1); + + enable_eim_clk(1); + eimnor_cs_setup(); +} + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC2_CD_GPIO IMX_GPIO_NR(1, 4) + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + /* Carrier MicroSD Card Detect */ + IOMUX_PADS(PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const usdhc3_pads[] = { + IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL)), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC3_BASE_ADDR}, + {USDHC2_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + case USDHC3_BASE_ADDR: + /* + * eMMC don't have card detect pin - since it is soldered to the + * PCB board + */ + ret = 1; + break; + } + return ret; +} + +int board_mmc_init(struct bd_info *bis) +{ + int ret; + u32 index = 0; + + /* + * MMC MAP + * (U-Boot device node) (Physical Port) + * mmc0 Soldered on board eMMC device + * mmc1 MicroSD card + */ + for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { + switch (index) { + case 0: + SETUP_IOMUX_PADS(usdhc3_pads); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[0].max_bus_width = 8; + break; + case 1: + SETUP_IOMUX_PADS(usdhc2_pads); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + usdhc_cfg[1].max_bus_width = 4; + gpio_direction_input(USDHC2_CD_GPIO); + break; + default: + printf("Warning: More USDHC controllers (%d) than supported (%d)\n", + index + 1, CONFIG_SYS_FSL_USDHC_NUM); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]); + if (ret) + return ret; + } + + return 0; +} + +#ifdef CONFIG_SPL_BOARD_INIT +#define DISPLAY_EN IMX_GPIO_NR(1, 2) +void spl_board_init(void) +{ + setup_eimnor(); + + gpio_direction_output(DISPLAY_EN, 1); +} +#endif /* CONFIG_SPL_BOARD_INIT */ diff --git a/roms/u-boot/board/liebherr/xea/Kconfig b/roms/u-boot/board/liebherr/xea/Kconfig new file mode 100644 index 000000000..5428de464 --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/Kconfig @@ -0,0 +1,24 @@ +if TARGET_XEA + +config SYS_BOARD + default "xea" + +config SYS_VENDOR + default "liebherr" + +config SYS_SOC + default "mxs" + +config SYS_CONFIG_NAME + default "xea" + +config ENV_SIZE + default 0x2000 + +config ENV_SECT_SIZE + default 0x10000 if ENV_IS_IN_SPI_FLASH + +config ENV_OFFSET + default 0x80000 if ENV_IS_IN_SPI_FLASH + +endif diff --git a/roms/u-boot/board/liebherr/xea/MAINTAINERS b/roms/u-boot/board/liebherr/xea/MAINTAINERS new file mode 100644 index 000000000..623184d0f --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/MAINTAINERS @@ -0,0 +1,6 @@ +XEA BOARD +M: Lukasz Majewski <lukma@denx.de> +S: Maintained +F: board/liebherr/xea/ +F: include/configs/xea.h +F: configs/imx28_xea_defconfig diff --git a/roms/u-boot/board/liebherr/xea/Makefile b/roms/u-boot/board/liebherr/xea/Makefile new file mode 100644 index 000000000..abf500857 --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2019 +# Lukasz Majewski, DENX Software Engineering, lukma@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := xea.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl_xea.o +endif diff --git a/roms/u-boot/board/liebherr/xea/README b/roms/u-boot/board/liebherr/xea/README new file mode 100644 index 000000000..3e55d3ea4 --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/README @@ -0,0 +1,63 @@ +Building SPL/U-Boot for xea board +================================= + +Setup environment, configure and build, e.g. by: + + $ make imx28_xea_defconfig + $ make -j4 u-boot.sb u-boot.img + +Now you should see u-boot.sb and u-boot.img files in the build directory. + + +Booting +======= + +The boot ROM loads SPL from SPI NOR flash into SRAM. SPL configures +DRAM and loads either a Linux kernel (falcon mode) or, if the rescue +pin is asserted, the main U-Boot. Both kernel and U-Boot reside in +eMMC boot partition 0. For redundancy, a copy of U-Boot is also +stored in SPI flash. If a valid kernel image is not found, U-Boot is +loaded from eMMC or, if this fails, SPI flash. + +Boot area layout +---------------- + +SPI NOR +Offset Function File +------------------------------------------ +0x00000000 SPL u-boot.sb +0x00010000 U-Boot u-boot.img +0x00080000 Environment + +eMMC +Offset Function File +------------------------------------------ +0x00000000 U-Boot u-boot.img +0x00080000 Devicetree imx28-bttc.dtb +0x00100000 Kernel uImage + + +Falcon mode +=========== + +In falcon mode, the default, SPL loads the kernel and devicetree +directly. For this to work, the stored devicetree must include +correct "memory" and "chosen" nodes as these are not updated by SPL +before booting the kernel. + + +Updating from U-Boot +==================== + +The default U-Boot environment includes command sequences to update +SPL, U-Boot, and kernel over TFTP. These are as follows: + +- update_spl: writes u-boot.sb to SPI NOR +- update_uboot: writes u-boot.img to eMMC and SPI NOR +- update_kernel: writes kernel and devicetree to eMMC + +They can be invoked at the U-Boot prompt using the "run" command, +e.g. "run update_spl" to update the SPL. + +These update commands download the above-named files from the +${hostname} directory on the server provided by DHCP. diff --git a/roms/u-boot/board/liebherr/xea/spl_xea.c b/roms/u-boot/board/liebherr/xea/spl_xea.c new file mode 100644 index 000000000..192f68fca --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/spl_xea.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DENX M28 Boot setup + * + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2018 DENX Software Engineering + * Måns Rullgård, DENX Software Engineering, mans@mansr.com + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/iomux-mx28.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> + +#define MUX_CONFIG_LCD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_BOOT (MXS_PAD_3V3) +#define MUX_CONFIG_TSC (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_SSP2 (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP) +#define MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_NOPULL) +#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL) + +const iomux_cfg_t iomux_setup[] = { + /* AUART0 IRDA */ + MX28_PAD_AUART0_RX__AUART0_RX, + MX28_PAD_AUART0_TX__AUART0_TX, + + /* AUART 4 RS422 */ + MX28_PAD_AUART0_CTS__AUART4_RX, + MX28_PAD_AUART0_RTS__AUART4_TX, + + /* USB0 */ + MX28_PAD_AUART1_CTS__USB0_OVERCURRENT, + MX28_PAD_AUART1_RTS__USB0_ID, + MX28_PAD_LCD_VSYNC__GPIO_1_28, /* PRW_On */ + + /* USB1 */ + MX28_PAD_PWM2__USB1_OVERCURRENT, + + /* eMMC */ + MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA4__SSP0_D4 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA5__SSP0_D5 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA6__SSP0_D6 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DATA7__SSP0_D7 | MUX_CONFIG_SSP0, + MX28_PAD_SSP0_DETECT__GPIO_2_9, /* Reset for eMMC */ + MX28_PAD_SSP0_SCK__SSP0_SCK | MUX_CONFIG_SSP0, + + /* DIG Keys */ + MX28_PAD_GPMI_D00__GPIO_0_0, + MX28_PAD_GPMI_D01__GPIO_0_1, + MX28_PAD_GPMI_D02__GPIO_0_2, + MX28_PAD_GPMI_D03__GPIO_0_3, + MX28_PAD_GPMI_D04__GPIO_0_4, + MX28_PAD_GPMI_D05__GPIO_0_5, + MX28_PAD_GPMI_D06__GPIO_0_6, + MX28_PAD_GPMI_D07__GPIO_0_7, + + /* ADR_0-2 */ + MX28_PAD_GPMI_CE1N__GPIO_0_17, + MX28_PAD_GPMI_CE2N__GPIO_0_18, + MX28_PAD_GPMI_CE3N__GPIO_0_19, + + /* Read Keys */ + MX28_PAD_GPMI_RDY0__GPIO_0_20, + + /* LATCH_EN */ + MX28_PAD_GPMI_RDY1__GPIO_0_21, + + /* Power off */ + MX28_PAD_GPMI_RDN__GPIO_0_24, + + /* I2C1 Touch */ + MX28_PAD_AUART2_CTS__GPIO_3_10, + MX28_PAD_AUART2_RTS__GPIO_3_11, + MX28_PAD_GPMI_RDY2__GPIO_0_22, /* Touch Reset */ + + /* TIVA */ + MX28_PAD_AUART1_RX__SSP2_CARD_DETECT, + MX28_PAD_SSP2_MISO__SSP2_D0, + MX28_PAD_SSP2_MOSI__SSP2_CMD, + MX28_PAD_SSP2_SCK__SSP2_SCK, + MX28_PAD_SSP2_SS0__SSP2_D3, + MX28_PAD_SSP2_SS1__GPIO_2_20, + MX28_PAD_SSP2_SS2__GPIO_2_21, + + /* SPI3 NOR-Flash */ + MX28_PAD_AUART1_TX__SSP3_CARD_DETECT, + MX28_PAD_AUART2_RX__SSP3_D1, + MX28_PAD_AUART2_TX__SSP3_D2, + MX28_PAD_SSP3_MISO__SSP3_D0, + MX28_PAD_SSP3_MOSI__SSP3_CMD, + MX28_PAD_SSP3_SCK__SSP3_SCK, + MX28_PAD_SSP3_SS0__SSP3_D3, + + /* NOR-Flash CMD */ + MX28_PAD_LCD_RS__GPIO_1_26, /* Hold */ + MX28_PAD_LCD_WR_RWN__GPIO_1_25, /* write protect */ + + /* I2C0 Codec */ + MX28_PAD_I2C0_SCL__I2C0_SCL, + MX28_PAD_I2C0_SDA__I2C0_SDA, + + /* I2S Codec */ + MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK, + MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK, + MX28_PAD_SAIF0_MCLK__SAIF0_MCLK, + MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0, + MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0, + + /* PWR-Hold */ + MX28_PAD_SPDIF__GPIO_3_27, + + /* EMI */ + MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI, + MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_ODT1__EMI_ODT1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI, + MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI, + + MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI, + MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI, + MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI, + MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI, + MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI, + MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI, + MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI, + MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI, + + /* Uart3 Bluetooth-Interface */ + MX28_PAD_AUART3_CTS__AUART3_CTS, + MX28_PAD_AUART3_RTS__AUART3_RTS, + MX28_PAD_AUART3_RX__AUART3_RX, + MX28_PAD_AUART3_TX__AUART3_TX, + + /* framebuffer */ + MX28_PAD_LCD_CS__LCD_CS | MUX_CONFIG_LCD, + MX28_PAD_LCD_D00__LCD_D0 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D01__LCD_D1 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D02__LCD_D2 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D03__LCD_D3 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D04__LCD_D4 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D05__LCD_D5 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D06__LCD_D6 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D07__LCD_D7 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D08__LCD_D8 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D09__LCD_D9 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D10__LCD_D10 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D11__LCD_D11 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D12__LCD_D12 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D13__LCD_D13 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D14__LCD_D14 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D15__LCD_D15 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D16__LCD_D16 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D17__LCD_D17 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D18__LCD_D18 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D19__LCD_D19 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D20__LCD_D20 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D21__LCD_D21 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D22__LCD_D22 | MUX_CONFIG_LCD, + MX28_PAD_LCD_D23__LCD_D23 | MUX_CONFIG_LCD, + MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | MUX_CONFIG_LCD, + MX28_PAD_LCD_ENABLE__LCD_ENABLE | MUX_CONFIG_LCD, + MX28_PAD_LCD_HSYNC__LCD_HSYNC | MUX_CONFIG_LCD, + MX28_PAD_LCD_RD_E__LCD_VSYNC | MUX_CONFIG_LCD, + MX28_PAD_LCD_RESET__LCD_RESET | MUX_CONFIG_LCD, + + /* DUART RS232 */ + MX28_PAD_PWM0__DUART_RX, + MX28_PAD_PWM1__DUART_TX, + + /* FEC Ethernet */ + MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET, + MX28_PAD_ENET0_COL__ENET1_TX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_CRS__ENET1_RX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET, + MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RX_CLK__GPIO_4_13, /* Phy Interrupt */ + MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_RXD3__ENET1_RXD1 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TX_CLK__GPIO_4_5, /* n.c. */ + MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET, + MX28_PAD_ENET0_TXD3__ENET1_TXD1 | MUX_CONFIG_ENET, + MX28_PAD_SSP1_CMD__GPIO_2_13, /* PHY reset */ + + /* TIVA boot control */ + MX28_PAD_GPMI_RDY3__GPIO_0_23 | MUX_CONFIG_BOOT, /* TIVA0 */ + MX28_PAD_GPMI_WRN__GPIO_0_25 | MUX_CONFIG_BOOT, /* TIVA1 */ +}; + +u32 mxs_dram_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00010101, 0x01010101, + 0x000f0f01, 0x0f02010a, 0x00000000, 0x00010101, + 0x00000100, 0x00000100, 0x00000000, 0x00000002, + 0x01010000, 0x07080403, 0x07005303, 0x0b0000c8, + 0x0200a0c1, 0x0002040c, 0x0038430a, 0x04290322, + 0x02040203, 0x00c8002b, 0x00000000, 0x00000000, + 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, + 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000612, 0x01000102, + 0x06120612, 0x00000200, 0x00020007, 0xf4004a27, + 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07400300, + 0x07400300, 0x07400300, 0x07400300, 0x00000005, + 0x00000000, 0x00000000, 0x01000000, 0x00000000, + 0x00000001, 0x000f1133, 0x00000000, 0x00001f04, + 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, + 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00010000, 0x00030404, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x01010000, + 0x01000000, 0x03030000, 0x00010303, 0x01020202, + 0x00000000, 0x02040101, 0x21002103, 0x00061200, + 0x06120612, 0x00000642, 0x00000000, 0x00000004, + 0x00000000, 0x00000080, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff +}; + +void lowlevel_init(void) +{ + struct mxs_pinctrl_regs *pinctrl_regs = + (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE; + + /* Set EMI drive strength */ + writel(0x00003fff, &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_clr); + writel(0x00002aaa, &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set); + + mxs_common_spl_init(0, NULL, iomux_setup, ARRAY_SIZE(iomux_setup)); +} diff --git a/roms/u-boot/board/liebherr/xea/xea.c b/roms/u-boot/board/liebherr/xea/xea.c new file mode 100644 index 000000000..cd11b0ada --- /dev/null +++ b/roms/u-boot/board/liebherr/xea/xea.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * XEA iMX28 board + * + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2018 DENX Software Engineering + * Måns Rullgård, DENX Software Engineering, mans@mansr.com + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + */ + +#include <common.h> +#include <fdt_support.h> +#include <init.h> +#include <log.h> +#include <net.h> +#include <asm/global_data.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux-mx28.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <linux/delay.h> +#include <linux/mii.h> +#include <miiphy.h> +#include <netdev.h> +#include <errno.h> +#include <usb.h> +#include <serial.h> + +#ifdef CONFIG_SPL_BUILD +#include <spl.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Functions + */ + +static void init_clocks(void) +{ + /* IO0 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK0, 480000); + /* IO1 clock at 480MHz */ + mxs_set_ioclk(MXC_IOCLK1, 480000); + + /* SSP0 clock at 96MHz */ + mxs_set_sspclk(MXC_SSPCLK0, 96000, 0); + /* SSP2 clock at 160MHz */ + mxs_set_sspclk(MXC_SSPCLK2, 160000, 0); + /* SSP3 clock at 96MHz */ + mxs_set_sspclk(MXC_SSPCLK3, 96000, 0); +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong arg) +{ + init_clocks(); + preloader_console_init(); +} + +static int boot_tiva0, boot_tiva1; + +/* Check if TIVAs request booting via U-Boot proper */ +void spl_board_init(void) +{ + struct gpio_desc btiva0, btiva1, en_3_3v; + int ret; + + /* + * Setup GPIO0_0 (TIVA power enable pin) to be output high + * to allow TIVA startup. + */ + ret = dm_gpio_lookup_name("GPIO0_0", &en_3_3v); + if (ret) + printf("Cannot get GPIO0_0\n"); + + ret = dm_gpio_request(&en_3_3v, "pwr_3_3v"); + if (ret) + printf("Cannot request GPIO0_0\n"); + + /* Set GPIO0_0 to HIGH */ + dm_gpio_set_dir_flags(&en_3_3v, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + + ret = dm_gpio_lookup_name("GPIO0_23", &btiva0); + if (ret) + printf("Cannot get GPIO0_23\n"); + + ret = dm_gpio_lookup_name("GPIO0_25", &btiva1); + if (ret) + printf("Cannot get GPIO0_25\n"); + + ret = dm_gpio_request(&btiva0, "boot-tiva0"); + if (ret) + printf("Cannot request GPIO0_23\n"); + + ret = dm_gpio_request(&btiva1, "boot-tiva1"); + if (ret) + printf("Cannot request GPIO0_25\n"); + + dm_gpio_set_dir_flags(&btiva0, GPIOD_IS_IN); + dm_gpio_set_dir_flags(&btiva1, GPIOD_IS_IN); + + udelay(1000); + + boot_tiva0 = dm_gpio_get_value(&btiva0); + boot_tiva1 = dm_gpio_get_value(&btiva1); +} + +void board_boot_order(u32 *spl_boot_list) +{ + spl_boot_list[0] = BOOT_DEVICE_MMC1; + spl_boot_list[1] = BOOT_DEVICE_SPI; + spl_boot_list[2] = BOOT_DEVICE_UART; +} + +int spl_start_uboot(void) +{ + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + + debug("%s: btiva0: %d btiva1: %d\n", __func__, boot_tiva0, boot_tiva1); + return !boot_tiva0 || !boot_tiva1; +} +#else + +int board_early_init_f(void) +{ + init_clocks(); + + return 0; +} + +int board_init(void) +{ + struct gpio_desc phy_rst; + int ret; + + /* Address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + cpu_eth_init(NULL); + + /* PHY INT#/PWDN# */ + ret = dm_gpio_lookup_name("GPIO4_13", &phy_rst); + if (ret) { + printf("Cannot get GPIO4_13\n"); + return ret; + } + + ret = dm_gpio_request(&phy_rst, "phy-rst"); + if (ret) { + printf("Cannot request GPIO4_13\n"); + return ret; + } + + dm_gpio_set_dir_flags(&phy_rst, GPIOD_IS_IN); + udelay(1000); + + return 0; +} + +int dram_init(void) +{ + return mxs_dram_init(); +} + +#ifdef CONFIG_OF_BOARD_SETUP +static int fdt_fixup_l2switch(void *blob) +{ + u8 ethaddr[6]; + int ret; + + if (eth_env_get_enetaddr("ethaddr", ethaddr)) { + ret = fdt_find_and_setprop(blob, + "/ahb@80080000/switch@800f0000", + "local-mac-address", ethaddr, 6, 1); + if (ret < 0) + printf("%s: can't find usbether@1 node: %d\n", + __func__, ret); + } + + return 0; +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + /* + * i.MX28 L2 switch needs manual update (fixup) of eth MAC address + * (in 'local-mac-address' property) as it uses "switch@800f0000" + * node, not set by default FIT image handling code in + * "ethernet@800f0000" + */ + fdt_fixup_l2switch(blob); + + return 0; +} +#endif + +#endif /* CONFIG_SPL_BUILD */ |