From f91c09acf5c58cde552e4036fe48b8e47e92d69c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 24 Oct 2014 23:39:07 +0200 Subject: ARM: mx6: Add support for Kosagi Novena Add support for the Kosagi Novena board. Currently supported are: - I2C busses - FEC Ethernet - MMC0, MMC1, Booting from MMC - SATA - USB ports - USB Ethernet Signed-off-by: Marek Vasut Cc: Stefano Babic Cc: Sean Cross Cc: Nikolay Dimitrov Reviewed-by: Nikolay Dimitrov --- board/kosagi/novena/Kconfig | 18 ++ board/kosagi/novena/Makefile | 11 + board/kosagi/novena/novena.c | 343 ++++++++++++++++++++++++ board/kosagi/novena/novena_spl.c | 556 +++++++++++++++++++++++++++++++++++++++ board/kosagi/novena/setup.cfg | 47 ++++ 5 files changed, 975 insertions(+) create mode 100644 board/kosagi/novena/Kconfig create mode 100644 board/kosagi/novena/Makefile create mode 100644 board/kosagi/novena/novena.c create mode 100644 board/kosagi/novena/novena_spl.c create mode 100644 board/kosagi/novena/setup.cfg (limited to 'board') diff --git a/board/kosagi/novena/Kconfig b/board/kosagi/novena/Kconfig new file mode 100644 index 0000000..4ba6399 --- /dev/null +++ b/board/kosagi/novena/Kconfig @@ -0,0 +1,18 @@ +if TARGET_KOSAGI_NOVENA + +config SYS_CPU + default "armv7" + +config SYS_BOARD + default "novena" + +config SYS_VENDOR + default "kosagi" + +config SYS_SOC + default "mx6" + +config SYS_CONFIG_NAME + default "novena" + +endif diff --git a/board/kosagi/novena/Makefile b/board/kosagi/novena/Makefile new file mode 100644 index 0000000..6fba177 --- /dev/null +++ b/board/kosagi/novena/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (C) 2014 Marek Vasut +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +obj-y := novena_spl.o +else +obj-y := novena.o +endif diff --git a/board/kosagi/novena/novena.c b/board/kosagi/novena/novena.c new file mode 100644 index 0000000..2361a3c --- /dev/null +++ b/board/kosagi/novena/novena.c @@ -0,0 +1,343 @@ +/* + * Novena board support + * + * Copyright (C) 2014 Marek Vasut + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define NOVENA_BUTTON_GPIO IMX_GPIO_NR(4, 14) +#define NOVENA_SD_WP IMX_GPIO_NR(1, 2) +#define NOVENA_SD_CD IMX_GPIO_NR(1, 4) + +/* + * GPIO button + */ +#ifdef CONFIG_KEYBOARD +static struct input_config button_input; + +static int novena_gpio_button_read_keys(struct input_config *input) +{ + int key = KEY_ENTER; + if (gpio_get_value(NOVENA_BUTTON_GPIO)) + return 0; + input_send_keycodes(&button_input, &key, 1); + return 1; +} + +static int novena_gpio_button_getc(struct stdio_dev *dev) +{ + return input_getc(&button_input); +} + +static int novena_gpio_button_tstc(struct stdio_dev *dev) +{ + return input_tstc(&button_input); +} + +static int novena_gpio_button_init(struct stdio_dev *dev) +{ + gpio_direction_input(NOVENA_BUTTON_GPIO); + input_set_delays(&button_input, 250, 250); + return 0; +} + +int drv_keyboard_init(void) +{ + int error; + struct stdio_dev dev = { + .name = "button", + .flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM, + .start = novena_gpio_button_init, + .getc = novena_gpio_button_getc, + .tstc = novena_gpio_button_tstc, + }; + + error = input_init(&button_input, 0); + if (error) { + debug("%s: Cannot set up input\n", __func__); + return -1; + } + button_input.read_keys = novena_gpio_button_read_keys; + + error = input_stdio_register(&dev); + if (error) + return error; + + return 0; +} +#endif + +/* + * SDHC + */ +#ifdef CONFIG_FSL_ESDHC +static struct fsl_esdhc_cfg usdhc_cfg[] = { + { USDHC3_BASE_ADDR, 0, 4 }, /* Micro SD */ + { USDHC2_BASE_ADDR, 0, 4 }, /* Big SD */ +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + + /* There is no CD for a microSD card, assume always present. */ + if (cfg->esdhc_base == USDHC3_BASE_ADDR) + return 1; + else + return !gpio_get_value(NOVENA_SD_CD); +} + +int board_mmc_getwp(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + + /* There is no WP for a microSD card, assume always read-write. */ + if (cfg->esdhc_base == USDHC3_BASE_ADDR) + return 0; + else + return gpio_get_value(NOVENA_SD_WP); +} + + +int board_mmc_init(bd_t *bis) +{ + s32 status = 0; + int index; + + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + + /* Big SD write-protect and card-detect */ + gpio_direction_input(NOVENA_SD_WP); + gpio_direction_input(NOVENA_SD_CD); + + for (index = 0; index < ARRAY_SIZE(usdhc_cfg); index++) { + status = fsl_esdhc_initialize(bis, &usdhc_cfg[index]); + if (status) + return status; + } + + return status; +} +#endif + +/* + * Video over HDMI + */ +#if defined(CONFIG_VIDEO_IPUV3) +static void enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +struct display_info_t const displays[] = { + { + /* HDMI Output */ + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = enable_hdmi, + .mode = { + .name = "HDMI", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED + } + } +}; + +size_t display_count = ARRAY_SIZE(displays); + +static void setup_display(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + enable_ipu_clock(); + imx_setup_hdmi(); + + /* Turn on LDB0,IPU,IPU DI0 clocks */ + setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK); + + /* set LDB0, LDB1 clk select to 011/011 */ + clrsetbits_le32(&mxc_ccm->cs2cdr, + MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK | + MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK, + (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) | + (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)); + + setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV); + + setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 << + MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); + + writel(IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES | + IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH | + IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW | + IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG | + IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT | + IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG | + IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT | + IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED | + IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0, + &iomux->gpr[2]); + + clrsetbits_le32(&iomux->gpr[3], IOMUXC_GPR3_LVDS0_MUX_CTL_MASK, + IOMUXC_GPR3_MUX_SRC_IPU1_DI0 << + IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); +} +#endif + +int board_early_init_f(void) +{ +#if defined(CONFIG_VIDEO_IPUV3) + setup_display(); +#endif + + /* Bring Ethernet PHY out of reset. */ + gpio_set_value(IMX_GPIO_NR(3, 23), 1); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_CMD_SATA + setup_sata(); +#endif + + return 0; +} + +int checkboard(void) +{ + puts("Board: Novena 4x\n"); + return 0; +} + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + return 0; +} + +/* setup board specific PMIC */ +int power_init_board(void) +{ + struct pmic *p; + u32 reg; + int ret; + + power_pfuze100_init(1); + p = pmic_get("PFUZE100"); + if (!p) + return -EINVAL; + + ret = pmic_probe(p); + if (ret) + return ret; + + pmic_reg_read(p, PFUZE100_DEVICEID, ®); + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); + + /* Set SWBST to 5.0V and enable (for USB) */ + pmic_reg_read(p, PFUZE100_SWBSTCON1, ®); + reg &= ~(SWBST_MODE_MASK | SWBST_VOL_MASK); + reg |= (SWBST_5_00V | SWBST_MODE_AUTO); + pmic_reg_write(p, PFUZE100_SWBSTCON1, reg); + + return 0; +} + +/* EEPROM configuration data */ +struct novena_eeprom_data { + uint8_t signature[6]; + uint8_t version; + uint8_t reserved; + uint32_t serial; + uint8_t mac[6]; + uint16_t features; +}; + +int misc_init_r(void) +{ + struct novena_eeprom_data data; + uchar *datap = (uchar *)&data; + const char *signature = "Novena"; + int ret; + + /* If 'ethaddr' is already set, do nothing. */ + if (getenv("ethaddr")) + return 0; + + /* EEPROM is at bus 2. */ + ret = i2c_set_bus_num(2); + if (ret) { + puts("Cannot select EEPROM I2C bus.\n"); + return 0; + } + + /* EEPROM is at address 0x56. */ + ret = eeprom_read(0x56, 0, datap, sizeof(data)); + if (ret) { + puts("Cannot read I2C EEPROM.\n"); + return 0; + } + + /* Check EEPROM signature. */ + if (memcmp(data.signature, signature, 6)) { + puts("Invalid I2C EEPROM signature.\n"); + return 0; + } + + /* Set ethernet address from EEPROM. */ + eth_setenv_enetaddr("ethaddr", data.mac); + + return ret; +} diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c new file mode 100644 index 0000000..a8389d9 --- /dev/null +++ b/board/kosagi/novena/novena_spl.c @@ -0,0 +1,556 @@ +/* + * Novena SPL + * + * Copyright (C) 2014 Marek Vasut + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DECLARE_GLOBAL_DATA_PTR; + +#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_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define RGMII_PAD_CTRL \ + (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | 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_LOW | \ + PAD_CTL_DSE_240ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE) + +#define BUTTON_PAD_CTRL \ + (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) + +#define NOVENA_AUDIO_PWRON IMX_GPIO_NR(5, 17) +#define NOVENA_FPGA_RESET_N_GPIO IMX_GPIO_NR(5, 7) +#define NOVENA_HDMI_GHOST_HPD IMX_GPIO_NR(5, 4) +#define NOVENA_PCIE_RESET_GPIO IMX_GPIO_NR(3, 29) +#define NOVENA_PCIE_POWER_ON_GPIO IMX_GPIO_NR(7, 12) +#define NOVENA_PCIE_WAKE_UP_GPIO IMX_GPIO_NR(3, 22) +#define NOVENA_PCIE_DISABLE_GPIO IMX_GPIO_NR(2, 16) + +/* + * Audio + */ +static iomux_v3_cfg_t audio_pads[] = { + /* AUD_PWRON */ + MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_audio(void) +{ + imx_iomux_v3_setup_multiple_pads(audio_pads, ARRAY_SIZE(audio_pads)); + gpio_direction_output(NOVENA_AUDIO_PWRON, 1); +} + +/* + * ENET + */ +static iomux_v3_cfg_t enet_pads1[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + /* pin 35 - 1 (PHY_AD2) on reset */ + MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 32 - 1 - (MODE0) all */ + MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 31 - 1 - (MODE1) all */ + MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 28 - 1 - (MODE2) all */ + MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 27 - 1 - (MODE3) all */ + MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */ + MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 42 PHY nRST */ + MX6_PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t enet_pads2[] = { + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(RGMII_PAD_CTRL), + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(RGMII_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_enet(void) +{ + imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1)); + + gpio_direction_output(IMX_GPIO_NR(3, 23), 0); + gpio_direction_output(IMX_GPIO_NR(6, 30), 1); + gpio_direction_output(IMX_GPIO_NR(6, 25), 1); + gpio_direction_output(IMX_GPIO_NR(6, 27), 1); + gpio_direction_output(IMX_GPIO_NR(6, 28), 1); + gpio_direction_output(IMX_GPIO_NR(6, 29), 1); + gpio_direction_output(IMX_GPIO_NR(6, 24), 1); + + imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2)); +} + +/* + * FPGA + */ +static iomux_v3_cfg_t fpga_pads[] = { + /* FPGA_RESET_N */ + MX6_PAD_DISP0_DAT13__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_fpga(void) +{ + imx_iomux_v3_setup_multiple_pads(fpga_pads, ARRAY_SIZE(fpga_pads)); + gpio_direction_output(NOVENA_FPGA_RESET_N_GPIO, 0); +} + +/* + * GPIO Button + */ +static iomux_v3_cfg_t button_pads[] = { + /* Debug */ + MX6_PAD_KEY_COL4__GPIO4_IO14 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_buttons(void) +{ + imx_iomux_v3_setup_multiple_pads(button_pads, ARRAY_SIZE(button_pads)); +} + +/* + * I2C + */ +/* + * I2C1: + * 0x1d ... MMA7455L + * 0x30 ... SO-DIMM temp sensor + * 0x44 ... STMPE610 + * 0x50 ... SO-DIMM ID + */ +struct i2c_pads_info i2c_pad_info0 = { + .scl = { + .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC, + .gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC, + .gp = IMX_GPIO_NR(3, 21) + }, + .sda = { + .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC, + .gp = IMX_GPIO_NR(3, 28) + } +}; + +/* + * I2C2: + * 0x08 ... PMIC + * 0x3a ... HDMI DCC + * 0x50 ... HDMI DCC + */ +static struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = MX6_PAD_EIM_EB2__I2C2_SCL | PC, + .gpio_mode = MX6_PAD_EIM_EB2__GPIO2_IO30 | PC, + .gp = IMX_GPIO_NR(2, 30) + }, + .sda = { + .i2c_mode = MX6_PAD_EIM_D16__I2C2_SDA | PC, + .gpio_mode = MX6_PAD_EIM_D16__GPIO3_IO16 | PC, + .gp = IMX_GPIO_NR(3, 16) + } +}; + +/* + * I2C3: + * 0x11 ... ES8283 + * 0x50 ... LCD EDID + * 0x56 ... EEPROM + */ +static struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX6_PAD_EIM_D17__I2C3_SCL | PC, + .gpio_mode = MX6_PAD_EIM_D17__GPIO3_IO17 | PC, + .gp = IMX_GPIO_NR(3, 17) + }, + .sda = { + .i2c_mode = MX6_PAD_EIM_D18__I2C3_SDA | PC, + .gpio_mode = MX6_PAD_EIM_D18__GPIO3_IO18 | PC, + .gp = IMX_GPIO_NR(3, 18) + } +}; + +static void novena_spl_setup_iomux_i2c(void) +{ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0); + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); +} + +/* + * PCI express + */ +#ifdef CONFIG_CMD_PCI +static iomux_v3_cfg_t pcie_pads[] = { + /* "Reset" pin */ + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* "Power on" pin */ + MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* "Wake up" pin (input) */ + MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* "Disable endpoint" (rfkill) pin */ + MX6_PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_pcie(void) +{ + imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads)); + + /* Ensure PCIe is powered down */ + gpio_direction_output(NOVENA_PCIE_POWER_ON_GPIO, 0); + + /* Put the card into reset */ + gpio_direction_output(NOVENA_PCIE_RESET_GPIO, 0); + + /* Input signal to wake system from mPCIe card */ + gpio_direction_input(NOVENA_PCIE_WAKE_UP_GPIO); + + /* Drive RFKILL high, to ensure the radio is turned on */ + gpio_direction_output(NOVENA_PCIE_DISABLE_GPIO, 1); +} +#else +static inline void novena_spl_setup_iomux_pcie(void) {} +#endif + +/* + * SDHC + */ +static iomux_v3_cfg_t usdhc2_pads[] = { + MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), /* WP */ + MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +static iomux_v3_cfg_t usdhc3_pads[] = { + MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_sdhc(void) +{ + imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + + /* Big SD write-protect and card-detect */ + gpio_direction_input(IMX_GPIO_NR(1, 2)); + gpio_direction_input(IMX_GPIO_NR(1, 4)); +} + +/* + * SPI + */ +#ifdef CONFIG_MXC_SPI +static iomux_v3_cfg_t ecspi3_pads[] = { + /* SS1 */ + MX6_PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT3__GPIO4_IO24 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT4__GPIO4_IO25 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT5__GPIO4_IO26 | MUX_PAD_CTRL(SPI_PAD_CTRL), + MX6_PAD_DISP0_DAT7__ECSPI3_RDY | MUX_PAD_CTRL(SPI_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_spi(void) +{ + imx_iomux_v3_setup_multiple_pads(ecspi3_pads, ARRAY_SIZE(ecspi3_pads)); + /* De-assert the nCS */ + gpio_direction_output(MX6_PAD_DISP0_DAT3__GPIO4_IO24, 1); + gpio_direction_output(MX6_PAD_DISP0_DAT4__GPIO4_IO25, 1); + gpio_direction_output(MX6_PAD_DISP0_DAT5__GPIO4_IO26, 1); +} +#else +static void novena_spl_setup_iomux_spi(void) {} +#endif + +/* + * UART + */ +static iomux_v3_cfg_t const uart2_pads[] = { + MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const uart3_pads[] = { + MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const uart4_pads[] = { + MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT16__UART4_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT17__UART4_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + +}; + +static void novena_spl_setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); + imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads)); + imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); +} + +/* + * Video + */ +#ifdef CONFIG_VIDEO +static iomux_v3_cfg_t hdmi_pads[] = { + /* "Ghost HPD" pin */ + MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void novena_spl_setup_iomux_video(void) +{ + imx_iomux_v3_setup_multiple_pads(hdmi_pads, ARRAY_SIZE(hdmi_pads)); + gpio_direction_input(NOVENA_HDMI_GHOST_HPD); +} +#else +static inline void novena_spl_setup_iomux_video(void) {} +#endif + +/* + * SPL boots from uSDHC card + */ +#ifdef CONFIG_FSL_ESDHC +static struct fsl_esdhc_cfg usdhc_cfg = { + USDHC3_BASE_ADDR, 0, 4 +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + /* There is no CD for a microSD card, assume always present. */ + return 1; +} + +int board_mmc_init(bd_t *bis) +{ + usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + return fsl_esdhc_initialize(bis, &usdhc_cfg); +} +#endif + +/* Configure MX6Q/DUAL mmdc DDR io registers */ +static struct mx6dq_iomux_ddr_regs novena_ddr_ioregs = { + /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ + .dram_sdclk_0 = 0x00020038, + .dram_sdclk_1 = 0x00020038, + .dram_cas = 0x00000038, + .dram_ras = 0x00000038, + .dram_reset = 0x00000038, + /* SDCKE[0:1]: 100k pull-up */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + /* SDBA2: pull-up disabled */ + .dram_sdba2 = 0x00000000, + /* SDODT[0:1]: 100k pull-up, 40 ohm */ + .dram_sdodt0 = 0x00000038, + .dram_sdodt1 = 0x00000038, + /* SDQS[0:7]: Differential input, 40 ohm */ + .dram_sdqs0 = 0x00000038, + .dram_sdqs1 = 0x00000038, + .dram_sdqs2 = 0x00000038, + .dram_sdqs3 = 0x00000038, + .dram_sdqs4 = 0x00000038, + .dram_sdqs5 = 0x00000038, + .dram_sdqs6 = 0x00000038, + .dram_sdqs7 = 0x00000038, + + /* DQM[0:7]: Differential input, 40 ohm */ + .dram_dqm0 = 0x00000038, + .dram_dqm1 = 0x00000038, + .dram_dqm2 = 0x00000038, + .dram_dqm3 = 0x00000038, + .dram_dqm4 = 0x00000038, + .dram_dqm5 = 0x00000038, + .dram_dqm6 = 0x00000038, + .dram_dqm7 = 0x00000038, +}; + +/* Configure MX6Q/DUAL mmdc GRP io registers */ +static struct mx6dq_iomux_grp_regs novena_grp_ioregs = { + /* DDR3 */ + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + /* Disable DDR pullups */ + .grp_ddrpke = 0x00000000, + /* ADDR[00:16], SDBA[0:1]: 40 ohm */ + .grp_addds = 0x00000038, + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ + .grp_ctlds = 0x00000038, + /* DATA[00:63]: Differential input, 40 ohm */ + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000038, + .grp_b1ds = 0x00000038, + .grp_b2ds = 0x00000038, + .grp_b3ds = 0x00000038, + .grp_b4ds = 0x00000038, + .grp_b5ds = 0x00000038, + .grp_b6ds = 0x00000038, + .grp_b7ds = 0x00000038, +}; + +static struct mx6_mmdc_calibration novena_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x00420048, + .p0_mpwldectrl1 = 0x006f0059, + .p1_mpwldectrl0 = 0x005a0104, + .p1_mpwldectrl1 = 0x01070113, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x437c040b, + .p0_mpdgctrl1 = 0x0413040e, + .p1_mpdgctrl0 = 0x444f0446, + .p1_mpdgctrl1 = 0x044d0422, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x4c424249, + .p1_mprddlctl = 0x4e48414f, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x42414641, + .p1_mpwrdlctl = 0x46374b43, +}; + +static struct mx6_ddr_sysinfo novena_ddr_info = { + /* 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, /* RTT_Wr = RZQ/4 */ + .rtt_nom = 2, /* RTT_Nom = RZQ/2 */ + .walat = 3, /* Write additional latency */ + .ralat = 7, /* 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) */ +}; + +static struct mx6_ddr3_cfg elpida_4gib_1600 = { + .mem_speed = 1600, + .density = 4, + .width = 64, + .banks = 8, + .rowaddr = 16, + .coladdr = 10, + .pagesz = 2, + .trcd = 1300, + .trcmin = 4900, + .trasmin = 3590, +}; + +/* + * called from C runtime startup code (arch/arm/lib/crt0.S:_main) + * - we have a stack and a place to store GD, both in SRAM + * - no variable global data is available + */ +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + /* setup GP timer */ + timer_init(); + +#ifdef CONFIG_BOARD_POSTCLK_INIT + board_postclk_init(); +#endif +#ifdef CONFIG_FSL_ESDHC + get_clocks(); +#endif + + /* Setup IOMUX and configure basics. */ + novena_spl_setup_iomux_audio(); + novena_spl_setup_iomux_buttons(); + novena_spl_setup_iomux_enet(); + novena_spl_setup_iomux_fpga(); + novena_spl_setup_iomux_i2c(); + novena_spl_setup_iomux_pcie(); + novena_spl_setup_iomux_sdhc(); + novena_spl_setup_iomux_spi(); + novena_spl_setup_iomux_uart(); + novena_spl_setup_iomux_video(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* Start the DDR DRAM */ + mx6dq_dram_iocfg(64, &novena_ddr_ioregs, &novena_grp_ioregs); + mx6_dram_cfg(&novena_ddr_info, &novena_mmdc_calib, &elpida_4gib_1600); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +void reset_cpu(ulong addr) +{ +} diff --git a/board/kosagi/novena/setup.cfg b/board/kosagi/novena/setup.cfg new file mode 100644 index 0000000..18d139c --- /dev/null +++ b/board/kosagi/novena/setup.cfg @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Marek Vasut + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer docs/README.imxmage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ +IMAGE_VERSION 2 + +/* Boot Device : sd */ +BOOT_FROM sd + +#define __ASSEMBLY__ +#include +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +/* set the default clock gate to save power */ +DATA 4, CCM_CCGR0, 0x00C03F3F +DATA 4, CCM_CCGR1, 0x0030FC03 +DATA 4, CCM_CCGR2, 0x0FFFC000 +DATA 4, CCM_CCGR3, 0x3FF00000 +DATA 4, CCM_CCGR4, 0xFFFFF300 /* enable NAND/GPMI/BCH clocks */ +DATA 4, CCM_CCGR5, 0x0F0000C3 +DATA 4, CCM_CCGR6, 0x000003FF + +/* enable AXI cache for VDOA/VPU/IPU */ +DATA 4, MX6_IOMUXC_GPR4, 0xF00000CF +/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ +DATA 4, MX6_IOMUXC_GPR6, 0x007F007F +DATA 4, MX6_IOMUXC_GPR7, 0x007F007F + +/* + * Setup CCM_CCOSR register as follows: + * + * cko1_en = 1 --> CKO1 enabled + * cko1_div = 111 --> divide by 8 + * cko1_sel = 1011 --> ahb_clk_root + * + * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + */ +DATA 4, CCM_CCOSR, 0x000000fb -- cgit v1.1 From ca9d817ab54077d5b8a814a7af9c8342a0641051 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 21 Oct 2014 21:14:53 -0200 Subject: mx6sabresd: Add Seiko WVGA panel support Add support for the 4.3'' Seiko WVGA parallel display. In order to direct the splash screen to the Seiko display: => setenv panel SEIKO-WVGA => save => reset Signed-off-by: Fabio Estevam Acked-by: Stefano Babic --- board/freescale/mx6sabresd/mx6sabresd.c | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'board') diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index 81dcd6e..3d81fff 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -51,6 +51,8 @@ DECLARE_GLOBAL_DATA_PTR; #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) +#define DISP0_PWR_EN IMX_GPIO_NR(1, 21) + int dram_init(void) { gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); @@ -141,6 +143,45 @@ iomux_v3_cfg_t const ecspi1_pads[] = { MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL), }; +static iomux_v3_cfg_t const rgb_pads[] = { + MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void enable_rgb(struct display_info_t const *dev) +{ + imx_iomux_v3_setup_multiple_pads(rgb_pads, ARRAY_SIZE(rgb_pads)); + gpio_direction_output(DISP0_PWR_EN, 1); +} + static struct i2c_pads_info i2c_pad_info1 = { .scl = { .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | I2C_PAD, @@ -357,6 +398,26 @@ struct display_info_t const displays[] = {{ .vsync_len = 10, .sync = FB_SYNC_EXT, .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = 0, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = NULL, + .enable = enable_rgb, + .mode = { + .name = "SEIKO-WVGA", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = 29850, + .left_margin = 89, + .right_margin = 164, + .upper_margin = 23, + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 10, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED } } }; size_t display_count = ARRAY_SIZE(displays); -- cgit v1.1 From 1719d49c347f2faee387aacbf643d171461820a9 Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Thu, 23 Oct 2014 15:47:05 +0200 Subject: tqma6: fix sf detection Commit 155fa9af95ac5be857a7327e7a968a296e60d4c8 changed the way to define a GPIO line, which can be used to force CS high across multiple transactions. In order to fix sf detection change board code to make use of board_spi_cs_gpio(..). Signed-off-by: Markus Niebel --- board/tqc/tqma6/tqma6.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/tqc/tqma6/tqma6.c b/board/tqc/tqma6/tqma6.c index b552bb8..fd1bd59 100644 --- a/board/tqc/tqma6/tqma6.c +++ b/board/tqc/tqma6/tqma6.c @@ -138,8 +138,10 @@ static iomux_v3_cfg_t const tqma6_ecspi1_pads[] = { NEW_PAD_CTRL(MX6_PAD_EIM_D18__ECSPI1_MOSI, SPI_PAD_CTRL), }; +#define TQMA6_SF_CS_GPIO IMX_GPIO_NR(3, 19) + static unsigned const tqma6_ecspi1_cs[] = { - IMX_GPIO_NR(3, 19), + TQMA6_SF_CS_GPIO, }; static void tqma6_iomuxc_spi(void) @@ -152,6 +154,12 @@ static void tqma6_iomuxc_spi(void) ARRAY_SIZE(tqma6_ecspi1_pads)); } +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + return ((bus == CONFIG_SF_DEFAULT_BUS) && + (cs == CONFIG_SF_DEFAULT_CS)) ? TQMA6_SF_CS_GPIO : -1; +} + static struct i2c_pads_info tqma6_i2c3_pads = { /* I2C3: on board LM75, M24C64, */ .scl = { -- cgit v1.1 From 29fd5c289c6a95a37c26486ad1c02de9a8ec28da Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Thu, 23 Oct 2014 15:47:06 +0200 Subject: tqma6: fix typo in header guard define Signed-off-by: Markus Niebel --- board/tqc/tqma6/tqma6_bb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/tqc/tqma6/tqma6_bb.h b/board/tqc/tqma6/tqma6_bb.h index 9d072d2..fb7b462 100644 --- a/board/tqc/tqma6/tqma6_bb.h +++ b/board/tqc/tqma6/tqma6_bb.h @@ -6,7 +6,7 @@ */ #ifndef __TQMA6_BB__ -#define __TQMA6_BB +#define __TQMA6_BB__ #include -- cgit v1.1 From 1199ddce9c3e5dd25acffe7d7e7999ff779ac832 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 23 Oct 2014 13:46:41 +0200 Subject: ot1200: add feature pads The older 'mr' variant and the generic variant of the OT1200 differ in some places. As the name suggests the generic variant supports more boot devices. In order to be compatible with the 'mr' variant we define some 'feature' GPIOs. On the 'mr' variant this pads are not connected so we define their state with the help of the internal pullups. On the generic variant this GPIOs are connected and represent the state of the hardware. Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/ot1200.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'board') diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index acf95cb..a2fb3cf 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -104,10 +104,25 @@ int board_spi_cs_gpio(unsigned bus, unsigned cs) return (bus == 2 && cs == 0) ? (IMX_GPIO_NR(1, 3)) : -1; } +static iomux_v3_cfg_t const feature_pads[] = { + /* SD card detect */ + MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(PAD_CTL_PUS_100K_DOWN), + + /* eMMC soldered? */ + MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(PAD_CTL_PUS_100K_UP), +}; + +static void setup_iomux_features(void) +{ + imx_iomux_v3_setup_multiple_pads(feature_pads, + ARRAY_SIZE(feature_pads)); +} + int board_early_init_f(void) { setup_iomux_uart(); setup_iomux_spi(); + setup_iomux_features(); return 0; } -- cgit v1.1 From 5a9ca420ce8d90e668c5e0660881f16328984fb0 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 23 Oct 2014 13:46:42 +0200 Subject: ot1200: add support for usdhc4 On the 'mr' variant switching to 'mmc dev 1' will result in "MMC: no card present". Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/ot1200.c | 54 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) (limited to 'board') diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index a2fb3cf..45d761f 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -141,23 +141,67 @@ static iomux_v3_cfg_t const usdhc3_pads[] = { MX6_PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL), }; +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), +}; + int board_mmc_getcd(struct mmc *mmc) { - return 1; + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret; + + if (cfg->esdhc_base == USDHC3_BASE_ADDR) + ret = 1; + else { + gpio_direction_input(IMX_GPIO_NR(1, 4)); + ret = !gpio_get_value(IMX_GPIO_NR(1, 4)); + } + + return ret; } -struct fsl_esdhc_cfg usdhc_cfg[] = { +struct fsl_esdhc_cfg usdhc_cfg[2] = { {USDHC3_BASE_ADDR}, + {USDHC4_BASE_ADDR}, }; int board_mmc_init(bd_t *bis) { + s32 status = 0; + u32 index = 0; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); - usdhc_cfg[0].max_bus_width = 8; + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); - imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[0].max_bus_width = 8; + usdhc_cfg[1].max_bus_width = 4; + + for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { + switch (index) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + break; + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) then supported by the board (%d)\n", + index + 1, CONFIG_SYS_FSL_USDHC_NUM); + return status; + } + + status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]); + } - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); + return status; } #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) -- cgit v1.1 From 56740fa96f338025bf1c75e84a77120423f16680 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 23 Oct 2014 13:46:43 +0200 Subject: ot1200: rework card detect for eMMC Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/ot1200.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'board') diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index 45d761f..2ed8cf7 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -155,9 +155,10 @@ int board_mmc_getcd(struct mmc *mmc) struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; int ret; - if (cfg->esdhc_base == USDHC3_BASE_ADDR) - ret = 1; - else { + if (cfg->esdhc_base == USDHC3_BASE_ADDR) { + gpio_direction_input(IMX_GPIO_NR(4, 5)); + ret = gpio_get_value(IMX_GPIO_NR(4, 5)); + } else { gpio_direction_input(IMX_GPIO_NR(1, 4)); ret = !gpio_get_value(IMX_GPIO_NR(1, 4)); } -- cgit v1.1 From b99ed2766ae7bfc28077b8e2ce90ce2402483195 Mon Sep 17 00:00:00 2001 From: Nikolay Dimitrov Date: Sun, 12 Oct 2014 13:47:51 +0300 Subject: novena: Fix ethernet PHY reset sequence This patch fixes conflict between PHY pins becoming outputs after reset and imx6 still driving the pins. It also fixes the reset timing as recommended by the PHY datasheet. Signed-off-by: Nikolay Dimitrov Cc: Stefano Babic Cc: Sean Cross Cc: Marek Vasut Reviewed-by: Fabio Estevam --- board/kosagi/novena/novena.c | 3 -- board/kosagi/novena/novena_spl.c | 64 +++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 21 deletions(-) (limited to 'board') diff --git a/board/kosagi/novena/novena.c b/board/kosagi/novena/novena.c index 2361a3c..6add9e5 100644 --- a/board/kosagi/novena/novena.c +++ b/board/kosagi/novena/novena.c @@ -237,9 +237,6 @@ int board_early_init_f(void) setup_display(); #endif - /* Bring Ethernet PHY out of reset. */ - gpio_set_value(IMX_GPIO_NR(3, 23), 1); - return 0; } diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c index a8389d9..c4155dd 100644 --- a/board/kosagi/novena/novena_spl.c +++ b/board/kosagi/novena/novena_spl.c @@ -41,6 +41,10 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_HYS) +#define ENET_PHY_CFG_PAD_CTRL \ + (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_HYS) + #define RGMII_PAD_CTRL \ (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) @@ -98,18 +102,20 @@ static iomux_v3_cfg_t enet_pads1[] = { MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(RGMII_PAD_CTRL), MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(RGMII_PAD_CTRL), MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), - /* pin 35 - 1 (PHY_AD2) on reset */ - MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL), - /* pin 32 - 1 - (MODE0) all */ - MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL), - /* pin 31 - 1 - (MODE1) all */ - MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL), - /* pin 28 - 1 - (MODE2) all */ - MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), - /* pin 27 - 1 - (MODE3) all */ - MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), - /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */ - MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* pin 35, PHY_AD2 */ + MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 32, MODE0 */ + MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 31, MODE1 */ + MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 28, MODE2 */ + MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 27, MODE3 */ + MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 33, CLK125_EN */ + MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL), + /* pin 42 PHY nRST */ MX6_PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL), }; @@ -127,15 +133,37 @@ static void novena_spl_setup_iomux_enet(void) { imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1)); + /* Assert Ethernet PHY nRST */ gpio_direction_output(IMX_GPIO_NR(3, 23), 0); - gpio_direction_output(IMX_GPIO_NR(6, 30), 1); - gpio_direction_output(IMX_GPIO_NR(6, 25), 1); - gpio_direction_output(IMX_GPIO_NR(6, 27), 1); - gpio_direction_output(IMX_GPIO_NR(6, 28), 1); - gpio_direction_output(IMX_GPIO_NR(6, 29), 1); - gpio_direction_output(IMX_GPIO_NR(6, 24), 1); + /* + * Use imx6 internal pull-ups to drive PHY mode pins during PHY reset + * de-assertion. The intention is to use weak signal drivers (pull-ups) + * to prevent the conflict between PHY pins becoming outputs after + * reset and imx6 still driving the pins. The issue is described in PHY + * datasheet, p.14 + */ + gpio_direction_input(IMX_GPIO_NR(6, 30)); /* PHY_AD2 = 1 */ + gpio_direction_input(IMX_GPIO_NR(6, 25)); /* MODE0 = 1 */ + gpio_direction_input(IMX_GPIO_NR(6, 27)); /* MODE1 = 1 */ + gpio_direction_input(IMX_GPIO_NR(6, 28)); /* MODE2 = 1 */ + gpio_direction_input(IMX_GPIO_NR(6, 29)); /* MODE3 = 1 */ + gpio_direction_input(IMX_GPIO_NR(6, 24)); /* CLK125_EN = 1 */ + + /* Following reset timing (p.53, fig.8 from the PHY datasheet) */ + mdelay(10); + + /* De-assert Ethernet PHY nRST */ + gpio_set_value(IMX_GPIO_NR(3, 23), 1); + + /* PHY is now configured, connect FEC to the pads */ imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2)); + + /* + * PHY datasheet recommends on p.53 to wait at least 100us after reset + * before using MII, so we enforce the delay here + */ + udelay(100); } /* -- cgit v1.1 From 36255d67790b5a4f086e2c157ecea2455df0b7ce Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Thu, 30 Oct 2014 18:30:54 +0800 Subject: imx: mx6slevk: Add support for USDHC1 and USDHC3 slots There are three SD/MMC sockets on mx6slevk boards. Implements the full support for them. The default boot socket is USDHC2, so the MMC environment is set to that device. Signed-off-by: Ye.Li --- board/freescale/mx6slevk/mx6slevk.c | 105 +++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) (limited to 'board') diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index a500133..e76c343 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -52,6 +52,23 @@ static iomux_v3_cfg_t const uart1_pads[] = { MX6_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL), }; +static iomux_v3_cfg_t const usdhc1_pads[] = { + /* 8 bit SD */ + MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT4__USDHC1_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT5__USDHC1_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT6__USDHC1_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT7__USDHC1_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + /*CD pin*/ + MX6_PAD_KEY_ROW7__GPIO_4_7 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + static iomux_v3_cfg_t const usdhc2_pads[] = { MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), @@ -59,6 +76,21 @@ static iomux_v3_cfg_t const usdhc2_pads[] = { MX6_PAD_SD2_DAT1__USDHC2_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), MX6_PAD_SD2_DAT2__USDHC2_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), MX6_PAD_SD2_DAT3__USDHC2_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + /*CD pin*/ + MX6_PAD_SD2_DAT7__GPIO_5_0 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc3_pads[] = { + MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + /*CD pin*/ + MX6_PAD_REF_CLK_32K__GPIO_3_22 | MUX_PAD_CTRL(NO_PAD_CTRL), }; static iomux_v3_cfg_t const fec_pads[] = { @@ -109,21 +141,82 @@ static void setup_iomux_fec(void) gpio_set_value(ETH_PHY_RESET, 1); } -static struct fsl_esdhc_cfg usdhc_cfg[1] = { - {USDHC2_BASE_ADDR}, +#define USDHC1_CD_GPIO IMX_GPIO_NR(4, 7) +#define USDHC2_CD_GPIO IMX_GPIO_NR(5, 0) +#define USDHC3_CD_GPIO IMX_GPIO_NR(3, 22) + +static struct fsl_esdhc_cfg usdhc_cfg[3] = { + {USDHC1_BASE_ADDR}, + {USDHC2_BASE_ADDR, 0, 4}, + {USDHC3_BASE_ADDR, 0, 4}, }; int board_mmc_getcd(struct mmc *mmc) { - return 1; /* Assume boot SD always present */ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = !gpio_get_value(USDHC1_CD_GPIO); + break; + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + case USDHC3_BASE_ADDR: + ret = !gpio_get_value(USDHC3_CD_GPIO); + break; + } + + return ret; } int board_mmc_init(bd_t *bis) { - imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + int i, ret; + + /* + * According to the board_mmc_init() the following map is done: + * (U-boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc1 USDHC2 + * mmc2 USDHC3 + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_direction_input(USDHC1_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + break; + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_direction_input(USDHC2_CD_GPIO); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + break; + case 2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + gpio_direction_input(USDHC3_CD_GPIO); + usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) than supported by the board\n", i + 1); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) { + printf("Warning: failed to initialize " + "mmc dev %d\n", i); + return ret; + } + } - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); + return 0; } #ifdef CONFIG_FEC_MXC -- cgit v1.1 From 8fe280f330ddfd4a9e395ca15ab4019a1a32aa1f Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Thu, 30 Oct 2014 18:53:49 +0800 Subject: imx: mx6 sabreauto: Add board support for USB EHCI On mx6 sabreauto board, there are two USB ports: 0: OTG 1: HOST The EHCI driver is enabled for this board, but the IOMUX and VBUS power control is not implemented, which cause both USB port failed to work. This patch fix the problem by adding the board support codes. Since the power control uses the GPIO pin from port expander MAX7310, the PCA953X driver is enabled for accessing the MAX7310. The ID pin of OTG Port needs to configure the GPR1 bit 13 for selecting its daisy chain. Add a new function "imx_iomux_set_gpr_register" to handle GPR register setting. Signed-off-by: Ye.Li --- board/freescale/mx6qsabreauto/mx6qsabreauto.c | 93 +++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'board') diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c index 0dc0160..42ae6fa 100644 --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -116,6 +117,44 @@ static iomux_v3_cfg_t const port_exp[] = { MX6_PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), }; +/*Define for building port exp gpio, pin starts from 0*/ +#define PORTEXP_IO_NR(chip, pin) \ + ((chip << 5) + pin) + +/*Get the chip addr from a ioexp gpio*/ +#define PORTEXP_IO_TO_CHIP(gpio_nr) \ + (gpio_nr >> 5) + +/*Get the pin number from a ioexp gpio*/ +#define PORTEXP_IO_TO_PIN(gpio_nr) \ + (gpio_nr & 0x1f) + +static int port_exp_direction_output(unsigned gpio, int value) +{ + int ret; + + i2c_set_bus_num(2); + ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio)); + if (ret) + return ret; + + ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio), + (1 << PORTEXP_IO_TO_PIN(gpio)), + (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio))); + + if (ret) + return ret; + + ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio), + (1 << PORTEXP_IO_TO_PIN(gpio)), + (value << PORTEXP_IO_TO_PIN(gpio))); + + if (ret) + return ret; + + return 0; +} + static void setup_iomux_enet(void) { imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); @@ -361,3 +400,57 @@ int checkboard(void) return 0; } + +#ifdef CONFIG_USB_EHCI_MX6 +#define USB_HOST1_PWR PORTEXP_IO_NR(0x32, 7) +#define USB_OTG_PWR PORTEXP_IO_NR(0x34, 1) + +iomux_v3_cfg_t const usb_otg_pads[] = { + MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_ehci_hcd_init(int port) +{ + switch (port) { + case 0: + imx_iomux_v3_setup_multiple_pads(usb_otg_pads, + ARRAY_SIZE(usb_otg_pads)); + + /* + * Set daisy chain for otg_pin_id on 6q. + * For 6dl, this bit is reserved. + */ + imx_iomux_set_gpr_register(1, 13, 1, 0); + break; + case 1: + break; + default: + printf("MXC USB port %d not yet supported\n", port); + return -EINVAL; + } + return 0; +} + +int board_ehci_power(int port, int on) +{ + switch (port) { + case 0: + if (on) + port_exp_direction_output(USB_OTG_PWR, 1); + else + port_exp_direction_output(USB_OTG_PWR, 0); + break; + case 1: + if (on) + port_exp_direction_output(USB_HOST1_PWR, 1); + else + port_exp_direction_output(USB_HOST1_PWR, 0); + break; + default: + printf("MXC USB port %d not yet supported\n", port); + return -EINVAL; + } + + return 0; +} +#endif -- cgit v1.1 From 2f6bb0a9419ec8016524142cb54fef81038b346e Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Thu, 30 Oct 2014 13:14:03 +0100 Subject: arm, imx, spi: detect spi flash again on aristainetos board 155fa9af95a "spi: mxc: fix sf probe when using mxc_spi" break spi flash detection on the aristainetos board. Fix this. Signed-off-by: Heiko Schocher --- board/aristainetos/aristainetos.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'board') diff --git a/board/aristainetos/aristainetos.c b/board/aristainetos/aristainetos.c index 3bfcf5b..06922c0 100644 --- a/board/aristainetos/aristainetos.c +++ b/board/aristainetos/aristainetos.c @@ -230,6 +230,12 @@ static iomux_v3_cfg_t const backlight_pads[] = { MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), }; +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + return (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS) + ? (IMX_GPIO_NR(3, 20)) : -1; +} + static void setup_spi(void) { int i; -- cgit v1.1 From eb6b9f265c2902ae3864a891f51ed7ea6098097e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 30 Oct 2014 18:46:37 -0200 Subject: novena: Add MAINTAINERS file Commit f91c09acf5c58c ("ARM: mx6: Add support for Kosagi Novena") missed to add a MAINTAINERS file, so add Marek as the maintainer. Signed-off-by: Fabio Estevam --- board/kosagi/novena/MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 board/kosagi/novena/MAINTAINERS (limited to 'board') diff --git a/board/kosagi/novena/MAINTAINERS b/board/kosagi/novena/MAINTAINERS new file mode 100644 index 0000000..d3471c2 --- /dev/null +++ b/board/kosagi/novena/MAINTAINERS @@ -0,0 +1,6 @@ +NOVENA BOARD +M: Marek Vasut +S: Maintained +F: board/kosagi/novena/ +F: include/configs/novena.h +F: configs/novena_defconfig -- cgit v1.1 From b65cbab194307d29cdff2e246e2f97738d9b6a15 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 29 Oct 2014 17:56:21 +0200 Subject: arm: mx6: cm_fx6: change issd gpio order Change the order in which GPIOs are toggled in SATA init sequence to accomodate both SanDisk and Phison SSDs. Signed-off-by: Nikita Kiryanov Cc: Igor Grinberg Cc: Stefano Babic Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index fdb8ebf..090f784 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -29,12 +29,12 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_DWC_AHSATA static int cm_fx6_issd_gpios[] = { /* The order of the GPIOs in the array is important! */ + CM_FX6_SATA_LDO_EN, CM_FX6_SATA_PHY_SLP, CM_FX6_SATA_NRSTDLY, CM_FX6_SATA_PWREN, CM_FX6_SATA_NSTANDBY1, CM_FX6_SATA_NSTANDBY2, - CM_FX6_SATA_LDO_EN, }; static void cm_fx6_sata_power(int on) -- cgit v1.1 From 0b23780ff02bdbec46fac1fe4151e2ebf1eae881 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 29 Oct 2014 17:56:22 +0200 Subject: arm: mx6: cm_fx6: detect 1GB DRAM correctly on solo The 1GB DRAM configuration on mx6 solo uses 2 chip selects, but the code tests 1GB DRAM configuration as if it is all present on one chip select, and thus cannot see the full range of available memory. Refactor the check to detect 1GB DRAM correctly. Signed-off-by: Nikita Kiryanov Cc: Igor Grinberg Cc: Stefano Babic Acked-by: Igor Grinberg --- board/compulab/cm_fx6/spl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'board') diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c index 3948ba2..6fe937b 100644 --- a/board/compulab/cm_fx6/spl.c +++ b/board/compulab/cm_fx6/spl.c @@ -235,10 +235,11 @@ static int cm_fx6_spl_dram_init(void) spl_mx6s_dram_init(DDR_32BIT_1GB, false); bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); - if (bank1_size == 0x40000000) - return 0; - + bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, 0x80000000); if (bank1_size == 0x20000000) { + if (bank2_size == 0x20000000) + return 0; + spl_mx6s_dram_init(DDR_32BIT_512MB, true); return 0; } -- cgit v1.1