2014-03-06 15:46:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 Gateworks Corporation
|
|
|
|
*
|
|
|
|
* Author: Tim Harvey <tharvey@gateworks.com>
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
|
|
|
#include <asm/arch/clock.h>
|
2015-05-09 01:28:35 +00:00
|
|
|
#include <asm/arch/crm_regs.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <asm/arch/iomux.h>
|
|
|
|
#include <asm/arch/mx6-pins.h>
|
2014-04-25 22:39:07 +00:00
|
|
|
#include <asm/arch/mxc_hdmi.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <asm/arch/sys_proto.h>
|
|
|
|
#include <asm/gpio.h>
|
|
|
|
#include <asm/imx-common/boot_mode.h>
|
|
|
|
#include <asm/imx-common/sata.h>
|
2014-09-30 22:40:03 +00:00
|
|
|
#include <asm/imx-common/spi.h>
|
2014-04-25 22:39:07 +00:00
|
|
|
#include <asm/imx-common/video.h>
|
2015-05-09 01:28:35 +00:00
|
|
|
#include <asm/io.h>
|
|
|
|
#include <dm.h>
|
2015-05-09 01:28:29 +00:00
|
|
|
#include <dm/platform_data/serial_mxc.h>
|
2016-05-24 18:03:55 +00:00
|
|
|
#include <hwconfig.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <i2c.h>
|
|
|
|
#include <fdt_support.h>
|
|
|
|
#include <fsl_esdhc.h>
|
2015-05-09 01:28:35 +00:00
|
|
|
#include <jffs2/load_kernel.h>
|
|
|
|
#include <linux/ctype.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <miiphy.h>
|
|
|
|
#include <mtd_node.h>
|
|
|
|
#include <netdev.h>
|
2014-08-08 05:49:57 +00:00
|
|
|
#include <pci.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <power/pmic.h>
|
2014-05-05 15:22:25 +00:00
|
|
|
#include <power/ltc3676_pmic.h>
|
2014-03-06 15:46:30 +00:00
|
|
|
#include <power/pfuze100_pmic.h>
|
|
|
|
#include <fdt_support.h>
|
|
|
|
#include <jffs2/load_kernel.h>
|
|
|
|
#include <spi_flash.h>
|
|
|
|
|
|
|
|
#include "gsc.h"
|
2015-05-09 01:28:35 +00:00
|
|
|
#include "common.h"
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
2014-08-08 05:35:49 +00:00
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
/*
|
|
|
|
* EEPROM board info struct populated by read_eeprom so that we only have to
|
|
|
|
* read it once.
|
|
|
|
*/
|
2014-08-08 05:35:45 +00:00
|
|
|
struct ventana_board_info ventana_info;
|
2014-03-06 15:46:30 +00:00
|
|
|
|
2015-04-08 19:54:43 +00:00
|
|
|
static int board_type;
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
/* MMC */
|
2015-04-08 19:54:43 +00:00
|
|
|
static iomux_v3_cfg_t const usdhc3_pads[] = {
|
2014-06-02 23:13:26 +00:00
|
|
|
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)),
|
|
|
|
/* CD */
|
2014-08-08 05:35:49 +00:00
|
|
|
IOMUX_PADS(PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(IRQ_PAD_CTRL)),
|
2014-03-06 15:46:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* ENET */
|
2015-04-08 19:54:43 +00:00
|
|
|
static iomux_v3_cfg_t const enet_pads[] = {
|
2014-06-02 23:13:26 +00:00
|
|
|
IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
|
|
|
|
MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
|
|
|
|
MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
|
|
|
|
MUX_PAD_CTRL(ENET_PAD_CTRL)),
|
2014-03-06 15:46:30 +00:00
|
|
|
/* PHY nRST */
|
2014-08-08 05:35:49 +00:00
|
|
|
IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | DIO_PAD_CFG),
|
2014-03-06 15:46:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* NAND */
|
2015-04-08 19:54:43 +00:00
|
|
|
static iomux_v3_cfg_t const nfc_pads[] = {
|
2014-06-02 23:13:26 +00:00
|
|
|
IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
|
2014-03-06 15:46:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef CONFIG_CMD_NAND
|
|
|
|
static void setup_gpmi_nand(void)
|
|
|
|
{
|
|
|
|
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
|
|
|
|
|
|
|
|
/* config gpmi nand iomux */
|
2014-06-02 23:13:26 +00:00
|
|
|
SETUP_IOMUX_PADS(nfc_pads);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
/* config gpmi and bch clock to 100 MHz */
|
|
|
|
clrsetbits_le32(&mxc_ccm->cs2cdr,
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
|
|
|
|
MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
|
|
|
|
|
|
|
|
/* enable gpmi and bch clock gating */
|
|
|
|
setbits_le32(&mxc_ccm->CCGR4,
|
|
|
|
MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
|
|
|
|
MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
|
|
|
|
MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
|
|
|
|
MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
|
|
|
|
MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
|
|
|
|
|
|
|
|
/* enable apbh clock gating */
|
|
|
|
setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-05-09 01:28:28 +00:00
|
|
|
static void setup_iomux_enet(int gpio)
|
2014-03-06 15:46:30 +00:00
|
|
|
{
|
2014-06-02 23:13:26 +00:00
|
|
|
SETUP_IOMUX_PADS(enet_pads);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
/* toggle PHY_RST# */
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_request(gpio, "phy_rst#");
|
|
|
|
gpio_direction_output(gpio, 0);
|
2014-03-06 15:46:30 +00:00
|
|
|
mdelay(2);
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_set_value(gpio, 1);
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_USB_EHCI_MX6
|
2015-04-08 19:54:43 +00:00
|
|
|
static iomux_v3_cfg_t const usb_pads[] = {
|
2014-08-08 05:35:49 +00:00
|
|
|
IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | DIO_PAD_CFG),
|
|
|
|
IOMUX_PADS(PAD_KEY_COL4__USB_OTG_OC | DIO_PAD_CFG),
|
2014-06-02 23:13:26 +00:00
|
|
|
/* OTG PWR */
|
2014-08-08 05:35:49 +00:00
|
|
|
IOMUX_PADS(PAD_EIM_D22__GPIO3_IO22 | DIO_PAD_CFG),
|
2014-03-06 15:46:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int board_ehci_hcd_init(int port)
|
|
|
|
{
|
2015-05-09 01:28:28 +00:00
|
|
|
int gpio;
|
2014-03-06 15:46:30 +00:00
|
|
|
|
2014-06-02 23:13:26 +00:00
|
|
|
SETUP_IOMUX_PADS(usb_pads);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
2015-05-26 18:04:54 +00:00
|
|
|
/* Reset USB HUB */
|
|
|
|
switch (board_type) {
|
|
|
|
case GW53xx:
|
|
|
|
case GW552x:
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio = (IMX_GPIO_NR(1, 9));
|
2014-03-06 15:46:30 +00:00
|
|
|
break;
|
2015-05-26 18:04:54 +00:00
|
|
|
case GW54proto:
|
|
|
|
case GW54xx:
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio = (IMX_GPIO_NR(1, 16));
|
2014-03-06 15:46:30 +00:00
|
|
|
break;
|
2015-05-09 01:28:28 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
|
2015-05-09 01:28:28 +00:00
|
|
|
/* request and toggle hub rst */
|
|
|
|
gpio_request(gpio, "usb_hub_rst#");
|
|
|
|
gpio_direction_output(gpio, 0);
|
|
|
|
mdelay(2);
|
|
|
|
gpio_set_value(gpio, 1);
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_ehci_power(int port, int on)
|
|
|
|
{
|
|
|
|
if (port)
|
|
|
|
return 0;
|
|
|
|
gpio_set_value(GP_USB_OTG_PWR, on);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_USB_EHCI_MX6 */
|
|
|
|
|
|
|
|
#ifdef CONFIG_FSL_ESDHC
|
2015-04-08 19:54:43 +00:00
|
|
|
static struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR };
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
int board_mmc_getcd(struct mmc *mmc)
|
|
|
|
{
|
|
|
|
/* Card Detect */
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_request(GP_SD3_CD, "sd_cd");
|
2014-03-06 15:46:30 +00:00
|
|
|
gpio_direction_input(GP_SD3_CD);
|
|
|
|
return !gpio_get_value(GP_SD3_CD);
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_mmc_init(bd_t *bis)
|
|
|
|
{
|
|
|
|
/* Only one USDHC controller on Ventana */
|
2014-06-02 23:13:26 +00:00
|
|
|
SETUP_IOMUX_PADS(usdhc3_pads);
|
2014-03-06 15:46:30 +00:00
|
|
|
usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
|
|
|
usdhc_cfg.max_bus_width = 4;
|
|
|
|
|
|
|
|
return fsl_esdhc_initialize(bis, &usdhc_cfg);
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_FSL_ESDHC */
|
|
|
|
|
|
|
|
#ifdef CONFIG_MXC_SPI
|
|
|
|
iomux_v3_cfg_t const ecspi1_pads[] = {
|
|
|
|
/* SS1 */
|
2014-06-02 23:13:26 +00:00
|
|
|
IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(SPI_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
|
|
|
|
IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
|
2014-03-06 15:46:30 +00:00
|
|
|
};
|
|
|
|
|
spi: mxc: fix sf probe when using mxc_spi
MXC SPI driver has a feature whereas a GPIO line can be used to force CS high
across multiple transactions. This is set up by embedding the GPIO information
in the CS value:
cs = (cs | gpio << 8)
This merge of cs and gpio data into one value breaks the sf probe command:
if the use of gpio is required, invoking "sf probe <cs>" will not work, because
the CS argument doesn't have the GPIO information in it. Instead, the user must
use "sf probe <cs | gpio << 8>". For example, if bank 2 gpio 30 is used to force
cs high on cs 0, bus 0, then instead of typing "sf probe 0" the user now must
type "sf probe 15872".
This is inconsistent with the description of the sf probe command, and forces
the user to be aware of implementaiton details.
Fix this by introducing a new board function: board_spi_cs_gpio(), which will
accept a naked CS value, and provide the driver with the relevant GPIO, if one
is necessary.
Cc: Eric Nelson <eric.nelson@boundarydevices.com>
Cc: Eric Benard <eric@eukrea.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Tim Harvey <tharvey@gateworks.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Tom Rini <trini@ti.com>
Cc: Marek Vasut <marex@denx.de>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
2014-08-20 12:08:50 +00:00
|
|
|
int board_spi_cs_gpio(unsigned bus, unsigned cs)
|
|
|
|
{
|
|
|
|
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
static void setup_spi(void)
|
|
|
|
{
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_request(IMX_GPIO_NR(3, 19), "spi_cs");
|
spi: mxc: fix sf probe when using mxc_spi
MXC SPI driver has a feature whereas a GPIO line can be used to force CS high
across multiple transactions. This is set up by embedding the GPIO information
in the CS value:
cs = (cs | gpio << 8)
This merge of cs and gpio data into one value breaks the sf probe command:
if the use of gpio is required, invoking "sf probe <cs>" will not work, because
the CS argument doesn't have the GPIO information in it. Instead, the user must
use "sf probe <cs | gpio << 8>". For example, if bank 2 gpio 30 is used to force
cs high on cs 0, bus 0, then instead of typing "sf probe 0" the user now must
type "sf probe 15872".
This is inconsistent with the description of the sf probe command, and forces
the user to be aware of implementaiton details.
Fix this by introducing a new board function: board_spi_cs_gpio(), which will
accept a naked CS value, and provide the driver with the relevant GPIO, if one
is necessary.
Cc: Eric Nelson <eric.nelson@boundarydevices.com>
Cc: Eric Benard <eric@eukrea.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Tim Harvey <tharvey@gateworks.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Tom Rini <trini@ti.com>
Cc: Marek Vasut <marex@denx.de>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
2014-08-20 12:08:50 +00:00
|
|
|
gpio_direction_output(IMX_GPIO_NR(3, 19), 1);
|
2014-06-02 23:13:26 +00:00
|
|
|
SETUP_IOMUX_PADS(ecspi1_pads);
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* configure eth0 PHY board-specific LED behavior */
|
|
|
|
int board_phy_config(struct phy_device *phydev)
|
|
|
|
{
|
|
|
|
unsigned short val;
|
|
|
|
|
|
|
|
/* Marvel 88E1510 */
|
|
|
|
if (phydev->phy_id == 0x1410dd1) {
|
|
|
|
/*
|
|
|
|
* Page 3, Register 16: LED[2:0] Function Control Register
|
|
|
|
* LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link
|
|
|
|
* LED[1] (LNK:Green) R16_3.7:4 to 0001: on-link, blink-activity
|
|
|
|
*/
|
|
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
|
|
|
|
val = phy_read(phydev, MDIO_DEVAD_NONE, 16);
|
|
|
|
val &= 0xff00;
|
|
|
|
val |= 0x0017;
|
|
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 16, val);
|
|
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (phydev->drv->config)
|
|
|
|
phydev->drv->config(phydev);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_eth_init(bd_t *bis)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_FEC_MXC
|
2016-05-24 18:03:58 +00:00
|
|
|
struct ventana_board_info *info = &ventana_info;
|
|
|
|
|
|
|
|
if (test_bit(EECONFIG_ETH0, info->config)) {
|
2015-05-09 01:28:28 +00:00
|
|
|
setup_iomux_enet(GP_PHY_RST);
|
2014-08-21 06:35:14 +00:00
|
|
|
cpu_eth_init(bis);
|
2015-04-08 19:54:48 +00:00
|
|
|
}
|
2014-03-06 15:46:30 +00:00
|
|
|
#endif
|
|
|
|
|
2015-04-08 19:54:32 +00:00
|
|
|
#ifdef CONFIG_E1000
|
|
|
|
e1000_initialize(bis);
|
|
|
|
#endif
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
#ifdef CONFIG_CI_UDC
|
|
|
|
/* For otg ethernet*/
|
|
|
|
usb_eth_initialize(bis);
|
|
|
|
#endif
|
|
|
|
|
2015-04-08 19:54:33 +00:00
|
|
|
/* default to the first detected enet dev */
|
|
|
|
if (!getenv("ethprime")) {
|
|
|
|
struct eth_device *dev = eth_get_dev_by_index(0);
|
|
|
|
if (dev) {
|
|
|
|
setenv("ethprime", dev->name);
|
|
|
|
printf("set ethprime to %s\n", getenv("ethprime"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-25 22:39:07 +00:00
|
|
|
#if defined(CONFIG_VIDEO_IPUV3)
|
|
|
|
|
|
|
|
static void enable_hdmi(struct display_info_t const *dev)
|
|
|
|
{
|
|
|
|
imx_enable_hdmi_phy();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int detect_i2c(struct display_info_t const *dev)
|
|
|
|
{
|
|
|
|
return i2c_set_bus_num(dev->bus) == 0 &&
|
|
|
|
i2c_probe(dev->addr) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void enable_lvds(struct display_info_t const *dev)
|
|
|
|
{
|
|
|
|
struct iomuxc *iomux = (struct iomuxc *)
|
|
|
|
IOMUXC_BASE_ADDR;
|
|
|
|
|
|
|
|
/* set CH0 data width to 24bit (IOMUXC_GPR2:5 0=18bit, 1=24bit) */
|
|
|
|
u32 reg = readl(&iomux->gpr[2]);
|
|
|
|
reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
|
|
|
|
writel(reg, &iomux->gpr[2]);
|
|
|
|
|
|
|
|
/* Enable Backlight */
|
2016-05-24 18:03:53 +00:00
|
|
|
gpio_request(IMX_GPIO_NR(1, 10), "bklt_gpio");
|
|
|
|
gpio_direction_output(IMX_GPIO_NR(1, 10), 0);
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_request(IMX_GPIO_NR(1, 18), "bklt_en");
|
2014-08-08 05:35:49 +00:00
|
|
|
SETUP_IOMUX_PAD(PAD_SD1_CMD__GPIO1_IO18 | DIO_PAD_CFG);
|
2014-04-25 22:39:07 +00:00
|
|
|
gpio_direction_output(IMX_GPIO_NR(1, 18), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
} }, {
|
|
|
|
/* Freescale MXC-LVDS1: HannStar HSD100PXN1-A00 w/ egalx_ts cont */
|
|
|
|
.bus = 2,
|
|
|
|
.addr = 0x4,
|
|
|
|
.pixfmt = IPU_PIX_FMT_LVDS666,
|
|
|
|
.detect = detect_i2c,
|
|
|
|
.enable = enable_lvds,
|
|
|
|
.mode = {
|
|
|
|
.name = "Hannstar-XGA",
|
|
|
|
.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
|
2015-04-08 19:54:57 +00:00
|
|
|
} }, {
|
|
|
|
/* DLC700JMG-T-4 */
|
|
|
|
.bus = 0,
|
|
|
|
.addr = 0,
|
|
|
|
.detect = NULL,
|
|
|
|
.enable = enable_lvds,
|
|
|
|
.pixfmt = IPU_PIX_FMT_LVDS666,
|
|
|
|
.mode = {
|
|
|
|
.name = "DLC700JMGT4",
|
|
|
|
.refresh = 60,
|
|
|
|
.xres = 1024, /* 1024x600active pixels */
|
|
|
|
.yres = 600,
|
|
|
|
.pixclock = 15385, /* 64MHz */
|
|
|
|
.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
|
|
|
|
} }, {
|
|
|
|
/* DLC800FIG-T-3 */
|
|
|
|
.bus = 0,
|
|
|
|
.addr = 0,
|
|
|
|
.detect = NULL,
|
|
|
|
.enable = enable_lvds,
|
|
|
|
.pixfmt = IPU_PIX_FMT_LVDS666,
|
|
|
|
.mode = {
|
|
|
|
.name = "DLC800FIGT3",
|
|
|
|
.refresh = 60,
|
|
|
|
.xres = 1024, /* 1024x768 active pixels */
|
|
|
|
.yres = 768,
|
|
|
|
.pixclock = 15385, /* 64MHz */
|
|
|
|
.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
|
2014-04-25 22:39:07 +00:00
|
|
|
} } };
|
|
|
|
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;
|
|
|
|
int reg;
|
|
|
|
|
|
|
|
enable_ipu_clock();
|
|
|
|
imx_setup_hdmi();
|
|
|
|
/* Turn on LDB0,IPU,IPU DI0 clocks */
|
|
|
|
reg = __raw_readl(&mxc_ccm->CCGR3);
|
|
|
|
reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
|
|
|
|
writel(reg, &mxc_ccm->CCGR3);
|
|
|
|
|
|
|
|
/* set LDB0, LDB1 clk select to 011/011 */
|
|
|
|
reg = readl(&mxc_ccm->cs2cdr);
|
|
|
|
reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
|
|
|
|
|MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
|
|
|
|
reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
|
|
|
|
|(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
|
|
|
|
writel(reg, &mxc_ccm->cs2cdr);
|
|
|
|
|
|
|
|
reg = readl(&mxc_ccm->cscmr2);
|
|
|
|
reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
|
|
|
|
writel(reg, &mxc_ccm->cscmr2);
|
|
|
|
|
|
|
|
reg = readl(&mxc_ccm->chsccdr);
|
|
|
|
reg |= (CHSCCDR_CLK_SEL_LDB_DI0
|
|
|
|
<<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
|
|
|
|
writel(reg, &mxc_ccm->chsccdr);
|
|
|
|
|
|
|
|
reg = 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;
|
|
|
|
writel(reg, &iomux->gpr[2]);
|
|
|
|
|
|
|
|
reg = readl(&iomux->gpr[3]);
|
|
|
|
reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
|
|
|
|
| (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
|
|
|
|
<<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
|
|
|
|
writel(reg, &iomux->gpr[3]);
|
|
|
|
|
2016-05-24 18:03:53 +00:00
|
|
|
/* LVDS Backlight GPIO on LVDS connector - output low */
|
2014-08-08 05:35:49 +00:00
|
|
|
SETUP_IOMUX_PAD(PAD_SD2_CLK__GPIO1_IO10 | DIO_PAD_CFG);
|
2014-04-25 22:39:07 +00:00
|
|
|
gpio_direction_output(IMX_GPIO_NR(1, 10), 0);
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_VIDEO_IPUV3 */
|
|
|
|
|
2014-05-05 15:22:25 +00:00
|
|
|
/* setup board specific PMIC */
|
|
|
|
int power_init_board(void)
|
|
|
|
{
|
2015-05-09 01:28:37 +00:00
|
|
|
setup_pmic();
|
2014-05-05 15:22:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
#if defined(CONFIG_CMD_PCI)
|
|
|
|
int imx6_pcie_toggle_reset(void)
|
|
|
|
{
|
|
|
|
if (board_type < GW_UNKNOWN) {
|
2014-06-02 23:13:26 +00:00
|
|
|
uint pin = gpio_cfg[board_type].pcie_rst;
|
2015-05-09 01:28:28 +00:00
|
|
|
gpio_request(pin, "pci_rst#");
|
2014-06-02 23:13:26 +00:00
|
|
|
gpio_direction_output(pin, 0);
|
2014-03-06 15:46:30 +00:00
|
|
|
mdelay(50);
|
2014-06-02 23:13:26 +00:00
|
|
|
gpio_direction_output(pin, 1);
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2014-08-08 05:49:57 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Most Ventana boards have a PLX PEX860x PCIe switch onboard and use its
|
|
|
|
* GPIO's as PERST# signals for its downstream ports - configure the GPIO's
|
|
|
|
* properly and assert reset for 100ms.
|
|
|
|
*/
|
|
|
|
void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
|
|
|
|
unsigned short vendor, unsigned short device,
|
|
|
|
unsigned short class)
|
|
|
|
{
|
|
|
|
u32 dw;
|
|
|
|
|
|
|
|
debug("%s: %02d:%02d.%02d: %04x:%04x\n", __func__,
|
|
|
|
PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), vendor, device);
|
|
|
|
if (vendor == PCI_VENDOR_ID_PLX &&
|
|
|
|
(device & 0xfff0) == 0x8600 &&
|
|
|
|
PCI_DEV(dev) == 0 && PCI_FUNC(dev) == 0) {
|
|
|
|
debug("configuring PLX 860X downstream PERST#\n");
|
|
|
|
pci_hose_read_config_dword(hose, dev, 0x62c, &dw);
|
|
|
|
dw |= 0xaaa8; /* GPIO1-7 outputs */
|
|
|
|
pci_hose_write_config_dword(hose, dev, 0x62c, dw);
|
|
|
|
|
|
|
|
pci_hose_read_config_dword(hose, dev, 0x644, &dw);
|
|
|
|
dw |= 0xfe; /* GPIO1-7 output high */
|
|
|
|
pci_hose_write_config_dword(hose, dev, 0x644, dw);
|
|
|
|
|
|
|
|
mdelay(100);
|
|
|
|
}
|
|
|
|
}
|
2014-03-06 15:46:30 +00:00
|
|
|
#endif /* CONFIG_CMD_PCI */
|
|
|
|
|
|
|
|
#ifdef CONFIG_SERIAL_TAG
|
|
|
|
/*
|
|
|
|
* called when setting up ATAGS before booting kernel
|
|
|
|
* populate serialnum from the following (in order of priority):
|
|
|
|
* serial# env var
|
|
|
|
* eeprom
|
|
|
|
*/
|
|
|
|
void get_board_serial(struct tag_serialnr *serialnr)
|
|
|
|
{
|
|
|
|
char *serial = getenv("serial#");
|
|
|
|
|
|
|
|
if (serial) {
|
|
|
|
serialnr->high = 0;
|
|
|
|
serialnr->low = simple_strtoul(serial, NULL, 10);
|
|
|
|
} else if (ventana_info.model[0]) {
|
|
|
|
serialnr->high = 0;
|
|
|
|
serialnr->low = ventana_info.serial;
|
|
|
|
} else {
|
|
|
|
serialnr->high = 0;
|
|
|
|
serialnr->low = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Board Support
|
|
|
|
*/
|
|
|
|
|
|
|
|
int board_early_init_f(void)
|
|
|
|
{
|
|
|
|
setup_iomux_uart();
|
2015-05-09 01:28:28 +00:00
|
|
|
|
2014-04-25 22:39:07 +00:00
|
|
|
#if defined(CONFIG_VIDEO_IPUV3)
|
|
|
|
setup_display();
|
|
|
|
#endif
|
2014-03-06 15:46:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int dram_init(void)
|
|
|
|
{
|
2014-06-02 23:13:27 +00:00
|
|
|
gd->ram_size = imx_ddr_size();
|
2014-03-06 15:46:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_init(void)
|
|
|
|
{
|
2014-07-09 20:59:54 +00:00
|
|
|
struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
clrsetbits_le32(&iomuxc_regs->gpr[1],
|
|
|
|
IOMUXC_GPR1_OTG_ID_MASK,
|
|
|
|
IOMUXC_GPR1_OTG_ID_GPIO1);
|
|
|
|
|
|
|
|
/* address of linux boot parameters */
|
|
|
|
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
|
|
|
|
|
|
|
|
#ifdef CONFIG_CMD_NAND
|
|
|
|
setup_gpmi_nand();
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_MXC_SPI
|
|
|
|
setup_spi();
|
|
|
|
#endif
|
2015-05-09 01:28:35 +00:00
|
|
|
setup_ventana_i2c();
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_CMD_SATA
|
|
|
|
setup_sata();
|
|
|
|
#endif
|
|
|
|
/* read Gateworks EEPROM into global struct (used later) */
|
2014-08-08 05:35:45 +00:00
|
|
|
board_type = read_eeprom(CONFIG_I2C_GSC, &ventana_info);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
2015-05-09 01:28:35 +00:00
|
|
|
setup_iomux_gpio(board_type, &ventana_info);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
|
|
|
|
/*
|
|
|
|
* called during late init (after relocation and after board_init())
|
|
|
|
* by virtue of CONFIG_DISPLAY_BOARDINFO_LATE as we needed i2c initialized and
|
|
|
|
* EEPROM read.
|
|
|
|
*/
|
|
|
|
int checkboard(void)
|
|
|
|
{
|
|
|
|
struct ventana_board_info *info = &ventana_info;
|
|
|
|
unsigned char buf[4];
|
|
|
|
const char *p;
|
|
|
|
int quiet; /* Quiet or minimal output mode */
|
|
|
|
|
|
|
|
quiet = 0;
|
|
|
|
p = getenv("quiet");
|
|
|
|
if (p)
|
|
|
|
quiet = simple_strtol(p, NULL, 10);
|
|
|
|
else
|
|
|
|
setenv("quiet", "0");
|
|
|
|
|
|
|
|
puts("\nGateworks Corporation Copyright 2014\n");
|
|
|
|
if (info->model[0]) {
|
|
|
|
printf("Model: %s\n", info->model);
|
|
|
|
printf("MFGDate: %02x-%02x-%02x%02x\n",
|
|
|
|
info->mfgdate[0], info->mfgdate[1],
|
|
|
|
info->mfgdate[2], info->mfgdate[3]);
|
|
|
|
printf("Serial:%d\n", info->serial);
|
|
|
|
} else {
|
|
|
|
puts("Invalid EEPROM - board will not function fully\n");
|
|
|
|
}
|
|
|
|
if (quiet)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Display GSC firmware revision/CRC/status */
|
2015-04-08 19:54:59 +00:00
|
|
|
gsc_info(0);
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
/* Display RTC */
|
|
|
|
if (!gsc_i2c_read(GSC_RTC_ADDR, 0x00, 1, buf, 4)) {
|
|
|
|
printf("RTC: %d\n",
|
|
|
|
buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_CMD_BMODE
|
|
|
|
/*
|
|
|
|
* BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4
|
|
|
|
* see Table 8-11 and Table 5-9
|
|
|
|
* BOOT_CFG1[7] = 1 (boot from NAND)
|
|
|
|
* BOOT_CFG1[5] = 0 - raw NAND
|
|
|
|
* BOOT_CFG1[4] = 0 - default pad settings
|
|
|
|
* BOOT_CFG1[3:2] = 00 - devices = 1
|
|
|
|
* BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3
|
|
|
|
* BOOT_CFG2[4:3] = 00 - Boot Search Count = 2
|
|
|
|
* BOOT_CFG2[2:1] = 01 - Pages In Block = 64
|
|
|
|
* BOOT_CFG2[0] = 0 - Reset time 12ms
|
|
|
|
*/
|
|
|
|
static const struct boot_mode board_boot_modes[] = {
|
|
|
|
/* NAND: 64pages per block, 3 row addr cycles, 2 copies of FCB/DBBT */
|
|
|
|
{ "nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00) },
|
|
|
|
{ NULL, 0 },
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* late init */
|
|
|
|
int misc_init_r(void)
|
|
|
|
{
|
|
|
|
struct ventana_board_info *info = &ventana_info;
|
|
|
|
|
|
|
|
/* set env vars based on EEPROM data */
|
|
|
|
if (ventana_info.model[0]) {
|
|
|
|
char str[16], fdt[36];
|
|
|
|
char *p;
|
|
|
|
const char *cputype = "";
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FDT name will be prefixed with CPU type. Three versions
|
|
|
|
* will be created each increasingly generic and bootloader
|
|
|
|
* env scripts will try loading each from most specific to
|
|
|
|
* least.
|
|
|
|
*/
|
2014-06-02 23:13:27 +00:00
|
|
|
if (is_cpu_type(MXC_CPU_MX6Q) ||
|
|
|
|
is_cpu_type(MXC_CPU_MX6D))
|
2014-03-06 15:46:30 +00:00
|
|
|
cputype = "imx6q";
|
2014-06-02 23:13:27 +00:00
|
|
|
else if (is_cpu_type(MXC_CPU_MX6DL) ||
|
|
|
|
is_cpu_type(MXC_CPU_MX6SOLO))
|
2014-03-06 15:46:30 +00:00
|
|
|
cputype = "imx6dl";
|
2014-08-08 05:35:42 +00:00
|
|
|
setenv("soctype", cputype);
|
2014-08-08 05:35:41 +00:00
|
|
|
if (8 << (ventana_info.nand_flash_size-1) >= 2048)
|
|
|
|
setenv("flash_layout", "large");
|
|
|
|
else
|
|
|
|
setenv("flash_layout", "normal");
|
2014-03-06 15:46:30 +00:00
|
|
|
memset(str, 0, sizeof(str));
|
|
|
|
for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)
|
|
|
|
str[i] = tolower(info->model[i]);
|
2015-05-26 18:04:55 +00:00
|
|
|
setenv("model", str);
|
2014-03-06 15:46:30 +00:00
|
|
|
if (!getenv("fdt_file")) {
|
|
|
|
sprintf(fdt, "%s-%s.dtb", cputype, str);
|
|
|
|
setenv("fdt_file", fdt);
|
|
|
|
}
|
|
|
|
p = strchr(str, '-');
|
|
|
|
if (p) {
|
|
|
|
*p++ = 0;
|
|
|
|
|
|
|
|
setenv("model_base", str);
|
2015-05-26 18:04:56 +00:00
|
|
|
sprintf(fdt, "%s-%s.dtb", cputype, str);
|
|
|
|
setenv("fdt_file1", fdt);
|
2016-05-24 18:03:58 +00:00
|
|
|
if (board_type != GW551x &&
|
|
|
|
board_type != GW552x &&
|
|
|
|
board_type != GW553x)
|
2014-08-21 06:35:14 +00:00
|
|
|
str[4] = 'x';
|
2014-03-06 15:46:30 +00:00
|
|
|
str[5] = 'x';
|
|
|
|
str[6] = 0;
|
2015-05-26 18:04:56 +00:00
|
|
|
sprintf(fdt, "%s-%s.dtb", cputype, str);
|
|
|
|
setenv("fdt_file2", fdt);
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize env from EEPROM */
|
|
|
|
if (test_bit(EECONFIG_ETH0, info->config) &&
|
|
|
|
!getenv("ethaddr")) {
|
|
|
|
eth_setenv_enetaddr("ethaddr", info->mac0);
|
|
|
|
}
|
|
|
|
if (test_bit(EECONFIG_ETH1, info->config) &&
|
|
|
|
!getenv("eth1addr")) {
|
|
|
|
eth_setenv_enetaddr("eth1addr", info->mac1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* board serial-number */
|
|
|
|
sprintf(str, "%6d", info->serial);
|
|
|
|
setenv("serial#", str);
|
2015-04-08 19:54:51 +00:00
|
|
|
|
|
|
|
/* memory MB */
|
|
|
|
sprintf(str, "%d", (int) (gd->ram_size >> 20));
|
|
|
|
setenv("mem_mb", str);
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-09 01:28:35 +00:00
|
|
|
/* setup baseboard specific GPIO based on board and env */
|
|
|
|
setup_board_gpio(board_type, info);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_CMD_BMODE
|
|
|
|
add_board_boot_modes(board_boot_modes);
|
|
|
|
#endif
|
|
|
|
|
2015-05-09 01:28:36 +00:00
|
|
|
/* disable boot watchdog */
|
|
|
|
gsc_boot_wd_disable();
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
|
|
|
|
|
2015-04-08 19:55:01 +00:00
|
|
|
static int ft_sethdmiinfmt(void *blob, char *mode)
|
|
|
|
{
|
|
|
|
int off;
|
|
|
|
|
|
|
|
if (!mode)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_compatible(blob, -1, "nxp,tda1997x");
|
|
|
|
if (off < 0)
|
|
|
|
return off;
|
|
|
|
|
|
|
|
if (0 == strcasecmp(mode, "yuv422bt656")) {
|
|
|
|
u8 cfg[] = { 0x00, 0x00, 0x00, 0x82, 0x81, 0x00,
|
|
|
|
0x00, 0x00, 0x00 };
|
|
|
|
mode = "422_ccir";
|
|
|
|
fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1);
|
|
|
|
fdt_setprop_u32(blob, off, "vidout_trc", 1);
|
|
|
|
fdt_setprop_u32(blob, off, "vidout_blc", 1);
|
|
|
|
fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg));
|
|
|
|
printf(" set HDMI input mode to %s\n", mode);
|
|
|
|
} else if (0 == strcasecmp(mode, "yuv422smp")) {
|
|
|
|
u8 cfg[] = { 0x00, 0x00, 0x00, 0x88, 0x87, 0x00,
|
|
|
|
0x82, 0x81, 0x00 };
|
|
|
|
mode = "422_smp";
|
|
|
|
fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1);
|
|
|
|
fdt_setprop_u32(blob, off, "vidout_trc", 0);
|
|
|
|
fdt_setprop_u32(blob, off, "vidout_blc", 0);
|
|
|
|
fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg));
|
|
|
|
printf(" set HDMI input mode to %s\n", mode);
|
|
|
|
} else {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-05-24 18:03:55 +00:00
|
|
|
/* enable a property of a node if the node is found */
|
|
|
|
static inline void ft_enable_path(void *blob, const char *path)
|
|
|
|
{
|
|
|
|
int i = fdt_path_offset(blob, path);
|
|
|
|
if (i >= 0) {
|
|
|
|
debug("enabling %s\n", path);
|
|
|
|
fdt_status_okay(blob, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
/*
|
|
|
|
* called prior to booting kernel or by 'fdt boardsetup' command
|
|
|
|
*
|
|
|
|
* unless 'fdt_noauto' env var is set we will update the following in the DTB:
|
|
|
|
* - mtd partitions based on mtdparts/mtdids env
|
|
|
|
* - system-serial (board serial num from EEPROM)
|
|
|
|
* - board (full model from EEPROM)
|
|
|
|
* - peripherals removed from DTB if not loaded on board (per EEPROM config)
|
|
|
|
*/
|
2014-10-24 00:58:47 +00:00
|
|
|
int ft_board_setup(void *blob, bd_t *bd)
|
2014-03-06 15:46:30 +00:00
|
|
|
{
|
|
|
|
struct ventana_board_info *info = &ventana_info;
|
2014-08-08 05:35:45 +00:00
|
|
|
struct ventana_eeprom_config *cfg;
|
2014-03-06 15:46:30 +00:00
|
|
|
struct node_info nodes[] = {
|
|
|
|
{ "sst,w25q256", MTD_DEV_TYPE_NOR, }, /* SPI flash */
|
|
|
|
{ "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */
|
|
|
|
};
|
|
|
|
const char *model = getenv("model");
|
2015-04-08 19:54:58 +00:00
|
|
|
const char *display = getenv("display");
|
2015-04-08 19:54:44 +00:00
|
|
|
int i;
|
|
|
|
char rev = 0;
|
|
|
|
|
|
|
|
/* determine board revision */
|
|
|
|
for (i = sizeof(ventana_info.model) - 1; i > 0; i--) {
|
|
|
|
if (ventana_info.model[i] >= 'A') {
|
|
|
|
rev = ventana_info.model[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
if (getenv("fdt_noauto")) {
|
|
|
|
puts(" Skiping ft_board_setup (fdt_noauto defined)\n");
|
2014-10-24 00:58:47 +00:00
|
|
|
return 0;
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 18:04:58 +00:00
|
|
|
if (test_bit(EECONFIG_NAND, info->config)) {
|
|
|
|
/* Update partition nodes using info from mtdparts env var */
|
|
|
|
puts(" Updating MTD partitions...\n");
|
|
|
|
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
|
|
|
}
|
2014-03-06 15:46:30 +00:00
|
|
|
|
2015-04-08 19:54:58 +00:00
|
|
|
/* Update display timings from display env var */
|
|
|
|
if (display) {
|
|
|
|
if (fdt_fixup_display(blob, fdt_get_alias(blob, "lvds0"),
|
|
|
|
display) >= 0)
|
|
|
|
printf(" Set display timings for %s...\n", display);
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
printf(" Adjusting FDT per EEPROM for %s...\n", model);
|
|
|
|
|
|
|
|
/* board serial number */
|
|
|
|
fdt_setprop(blob, 0, "system-serial", getenv("serial#"),
|
2014-04-25 16:18:33 +00:00
|
|
|
strlen(getenv("serial#")) + 1);
|
2014-03-06 15:46:30 +00:00
|
|
|
|
|
|
|
/* board (model contains model from device-tree) */
|
|
|
|
fdt_setprop(blob, 0, "board", info->model,
|
|
|
|
strlen((const char *)info->model) + 1);
|
|
|
|
|
2015-04-08 19:55:01 +00:00
|
|
|
/* set desired digital video capture format */
|
|
|
|
ft_sethdmiinfmt(blob, getenv("hdmiinfmt"));
|
|
|
|
|
2015-04-08 19:54:56 +00:00
|
|
|
/*
|
|
|
|
* disable serial2 node for GW54xx for compatibility with older
|
|
|
|
* 3.10.x kernel that improperly had this node enabled in the DT
|
|
|
|
*/
|
|
|
|
if (board_type == GW54xx) {
|
|
|
|
i = fdt_path_offset(blob,
|
|
|
|
"/soc/aips-bus@02100000/serial@021ec000");
|
|
|
|
if (i)
|
|
|
|
fdt_del_node(blob, i);
|
|
|
|
}
|
|
|
|
|
2015-04-08 19:54:44 +00:00
|
|
|
/*
|
|
|
|
* disable wdog1/wdog2 nodes for GW51xx below revC to work around
|
|
|
|
* errata causing wdog timer to be unreliable.
|
|
|
|
*/
|
|
|
|
if (board_type == GW51xx && rev >= 'A' && rev < 'C') {
|
|
|
|
i = fdt_path_offset(blob,
|
|
|
|
"/soc/aips-bus@02000000/wdog@020bc000");
|
|
|
|
if (i)
|
|
|
|
fdt_status_disabled(blob, i);
|
|
|
|
}
|
|
|
|
|
2015-04-08 19:55:00 +00:00
|
|
|
/* GW522x Uses GPIO3_IO23 instead of GPIO1_IO29 */
|
|
|
|
else if (board_type == GW52xx && info->model[4] == '2') {
|
|
|
|
u32 handle = 0;
|
|
|
|
u32 *range = NULL;
|
|
|
|
|
|
|
|
i = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-pcie");
|
|
|
|
if (i)
|
|
|
|
range = (u32 *)fdt_getprop(blob, i, "reset-gpio",
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (range) {
|
|
|
|
i = fdt_path_offset(blob,
|
|
|
|
"/soc/aips-bus@02000000/gpio@020a4000");
|
|
|
|
if (i)
|
|
|
|
handle = fdt_get_phandle(blob, i);
|
|
|
|
if (handle) {
|
|
|
|
range[0] = cpu_to_fdt32(handle);
|
|
|
|
range[1] = cpu_to_fdt32(23);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-08 19:54:53 +00:00
|
|
|
/*
|
|
|
|
* isolate CSI0_DATA_EN for GW551x below revB to work around
|
|
|
|
* errata causing non functional digital video in (it is not hooked up)
|
|
|
|
*/
|
|
|
|
else if (board_type == GW551x && rev == 'A') {
|
|
|
|
u32 *range = NULL;
|
|
|
|
int len;
|
|
|
|
const u32 *handle = NULL;
|
|
|
|
|
|
|
|
i = fdt_node_offset_by_compatible(blob, -1,
|
|
|
|
"fsl,imx-tda1997x-video");
|
|
|
|
if (i)
|
|
|
|
handle = fdt_getprop(blob, i, "pinctrl-0", NULL);
|
|
|
|
if (handle)
|
|
|
|
i = fdt_node_offset_by_phandle(blob,
|
|
|
|
fdt32_to_cpu(*handle));
|
|
|
|
if (i)
|
|
|
|
range = (u32 *)fdt_getprop(blob, i, "fsl,pins", &len);
|
|
|
|
if (range) {
|
|
|
|
len /= sizeof(u32);
|
|
|
|
for (i = 0; i < len; i += 6) {
|
|
|
|
u32 mux_reg = fdt32_to_cpu(range[i+0]);
|
|
|
|
u32 conf_reg = fdt32_to_cpu(range[i+1]);
|
|
|
|
/* mux PAD_CSI0_DATA_EN to GPIO */
|
|
|
|
if (is_cpu_type(MXC_CPU_MX6Q) &&
|
|
|
|
mux_reg == 0x260 && conf_reg == 0x630)
|
|
|
|
range[i+3] = cpu_to_fdt32(0x5);
|
|
|
|
else if (!is_cpu_type(MXC_CPU_MX6Q) &&
|
|
|
|
mux_reg == 0x08c && conf_reg == 0x3a0)
|
|
|
|
range[i+3] = cpu_to_fdt32(0x5);
|
|
|
|
}
|
|
|
|
fdt_setprop_inplace(blob, i, "fsl,pins", range, len);
|
|
|
|
}
|
2015-04-08 19:55:02 +00:00
|
|
|
|
|
|
|
/* set BT656 video format */
|
|
|
|
ft_sethdmiinfmt(blob, "yuv422bt656");
|
2015-04-08 19:54:53 +00:00
|
|
|
}
|
|
|
|
|
2016-05-24 18:03:55 +00:00
|
|
|
/* Configure DIO */
|
|
|
|
for (i = 0; i < gpio_cfg[board_type].num_gpios; i++) {
|
|
|
|
struct dio_cfg *cfg = &gpio_cfg[board_type].dio_cfg[i];
|
|
|
|
char arg[10];
|
|
|
|
|
|
|
|
sprintf(arg, "dio%d", i);
|
|
|
|
if (!hwconfig(arg))
|
|
|
|
continue;
|
|
|
|
if (hwconfig_subarg_cmp(arg, "mode", "pwm") && cfg->pwm_param)
|
|
|
|
{
|
|
|
|
char path[48];
|
|
|
|
sprintf(path, "/soc/aips-bus@02000000/pwm@%08x",
|
|
|
|
0x02080000 + (0x4000 * (cfg->pwm_param - 1)));
|
|
|
|
printf(" Enabling pwm%d for DIO%d\n",
|
|
|
|
cfg->pwm_param, i);
|
|
|
|
ft_enable_path(blob, path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 15:46:30 +00:00
|
|
|
/*
|
|
|
|
* Peripheral Config:
|
|
|
|
* remove nodes by alias path if EEPROM config tells us the
|
|
|
|
* peripheral is not loaded on the board.
|
|
|
|
*/
|
2014-08-08 05:35:45 +00:00
|
|
|
if (getenv("fdt_noconfig")) {
|
|
|
|
puts(" Skiping periperhal config (fdt_noconfig defined)\n");
|
2014-10-24 00:58:47 +00:00
|
|
|
return 0;
|
2014-08-08 05:35:45 +00:00
|
|
|
}
|
|
|
|
cfg = econfig;
|
|
|
|
while (cfg->name) {
|
|
|
|
if (!test_bit(cfg->bit, info->config)) {
|
|
|
|
fdt_del_node_and_alias(blob, cfg->dtalias ?
|
|
|
|
cfg->dtalias : cfg->name);
|
|
|
|
}
|
|
|
|
cfg++;
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
2014-10-24 00:58:47 +00:00
|
|
|
|
|
|
|
return 0;
|
2014-03-06 15:46:30 +00:00
|
|
|
}
|
|
|
|
#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */
|
|
|
|
|
2015-05-09 01:28:29 +00:00
|
|
|
static struct mxc_serial_platdata ventana_mxc_serial_plat = {
|
|
|
|
.reg = (struct mxc_uart *)UART2_BASE,
|
|
|
|
};
|
|
|
|
|
|
|
|
U_BOOT_DEVICE(ventana_serial) = {
|
|
|
|
.name = "serial_mxc",
|
|
|
|
.platdata = &ventana_mxc_serial_plat,
|
|
|
|
};
|