mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-10 14:53:26 +09:00
![Benoît Thébaudeau](/assets/img/avatar_default.png)
PUE requires PKE to mean something, as do pull values with PUE, so do not compell users to explicitly use PKE and PUE everywhere. This is also what is done on Linux and what has already been done for i.MX51. By the way, remove some unused pad control definitions. There is no change of behavior. Note that SPI_PAD_CTRL was defined by several boards with a pull value, but without PKE or PUE, which means that no pull was actually enabled in the pad. This might be a bug in those boards, but this patch does not change the behavior, so it just removes the meaningless pull value from those definitions. Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
298 lines
8.5 KiB
C
298 lines
8.5 KiB
C
/*
|
|
* Copyright (C) 2012 Freescale Semiconductor, Inc.
|
|
*
|
|
* Author: Fabio Estevam <fabio.estevam@freescale.com>
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/clock.h>
|
|
#include <asm/arch/imx-regs.h>
|
|
#include <asm/arch/iomux.h>
|
|
#include <asm/arch/mx6q_pins.h>
|
|
#include <asm/errno.h>
|
|
#include <asm/gpio.h>
|
|
#include <asm/imx-common/iomux-v3.h>
|
|
#include <asm/imx-common/boot_mode.h>
|
|
#include <mmc.h>
|
|
#include <fsl_esdhc.h>
|
|
#include <miiphy.h>
|
|
#include <netdev.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
#define UART_PAD_CTRL (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_PUS_47K_UP | \
|
|
PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
|
|
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
|
|
|
|
#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
|
|
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
|
|
|
|
int dram_init(void)
|
|
{
|
|
gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
iomux_v3_cfg_t const uart1_pads[] = {
|
|
MX6_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
|
|
MX6_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
|
|
};
|
|
|
|
iomux_v3_cfg_t const enet_pads[] = {
|
|
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__ENET_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
|
|
/* AR8031 PHY Reset */
|
|
MX6_PAD_ENET_CRS_DV__GPIO_1_25 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
|
};
|
|
|
|
static void setup_iomux_enet(void)
|
|
{
|
|
imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
|
|
|
|
/* Reset AR8031 PHY */
|
|
gpio_direction_output(IMX_GPIO_NR(1, 25) , 0);
|
|
udelay(500);
|
|
gpio_set_value(IMX_GPIO_NR(1, 25), 1);
|
|
}
|
|
|
|
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),
|
|
MX6_PAD_SD2_DAT0__USDHC2_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
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),
|
|
MX6_PAD_NANDF_D4__USDHC2_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_NANDF_D5__USDHC2_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_NANDF_D6__USDHC2_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_NANDF_D7__USDHC2_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_NANDF_D2__GPIO_2_2 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
|
|
};
|
|
|
|
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),
|
|
MX6_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_NANDF_D0__GPIO_2_0 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
|
|
};
|
|
|
|
iomux_v3_cfg_t const usdhc4_pads[] = {
|
|
MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
|
};
|
|
|
|
static void setup_iomux_uart(void)
|
|
{
|
|
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
|
|
}
|
|
|
|
#ifdef CONFIG_FSL_ESDHC
|
|
struct fsl_esdhc_cfg usdhc_cfg[3] = {
|
|
{USDHC2_BASE_ADDR},
|
|
{USDHC3_BASE_ADDR},
|
|
{USDHC4_BASE_ADDR},
|
|
};
|
|
|
|
#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 2)
|
|
#define USDHC3_CD_GPIO IMX_GPIO_NR(2, 0)
|
|
|
|
int board_mmc_getcd(struct mmc *mmc)
|
|
{
|
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
|
int ret = 0;
|
|
|
|
switch (cfg->esdhc_base) {
|
|
case USDHC2_BASE_ADDR:
|
|
ret = !gpio_get_value(USDHC2_CD_GPIO);
|
|
break;
|
|
case USDHC3_BASE_ADDR:
|
|
ret = !gpio_get_value(USDHC3_CD_GPIO);
|
|
break;
|
|
case USDHC4_BASE_ADDR:
|
|
ret = 1; /* eMMC/uSDHC4 is always present */
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int board_mmc_init(bd_t *bis)
|
|
{
|
|
s32 status = 0;
|
|
int i;
|
|
|
|
/*
|
|
* According to the board_mmc_init() the following map is done:
|
|
* (U-boot device node) (Physical Port)
|
|
* mmc0 SD2
|
|
* mmc1 SD3
|
|
* mmc2 eMMC
|
|
*/
|
|
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
|
|
switch (i) {
|
|
case 0:
|
|
imx_iomux_v3_setup_multiple_pads(
|
|
usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
|
|
gpio_direction_input(USDHC2_CD_GPIO);
|
|
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
|
break;
|
|
case 1:
|
|
imx_iomux_v3_setup_multiple_pads(
|
|
usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
|
|
gpio_direction_input(USDHC3_CD_GPIO);
|
|
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
|
break;
|
|
case 2:
|
|
imx_iomux_v3_setup_multiple_pads(
|
|
usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
|
|
usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
|
|
break;
|
|
default:
|
|
printf("Warning: you configured more USDHC controllers"
|
|
"(%d) then supported by the board (%d)\n",
|
|
i + 1, CONFIG_SYS_FSL_USDHC_NUM);
|
|
return status;
|
|
}
|
|
|
|
status |= fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
#endif
|
|
|
|
int mx6_rgmii_rework(struct phy_device *phydev)
|
|
{
|
|
unsigned short val;
|
|
|
|
/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
|
|
|
|
val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
|
|
val &= 0xffe3;
|
|
val |= 0x18;
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
|
|
|
|
/* introduce tx clock delay */
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
|
|
val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
|
|
val |= 0x0100;
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_phy_config(struct phy_device *phydev)
|
|
{
|
|
mx6_rgmii_rework(phydev);
|
|
|
|
if (phydev->drv->config)
|
|
phydev->drv->config(phydev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_eth_init(bd_t *bis)
|
|
{
|
|
int ret;
|
|
|
|
setup_iomux_enet();
|
|
|
|
ret = cpu_eth_init(bis);
|
|
if (ret)
|
|
printf("FEC MXC: %s:failed\n", __func__);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_early_init_f(void)
|
|
{
|
|
setup_iomux_uart();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_init(void)
|
|
{
|
|
/* address of boot parameters */
|
|
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_CMD_BMODE
|
|
static const struct boot_mode board_boot_modes[] = {
|
|
/* 4 bit bus width */
|
|
{"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
|
|
{"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
|
|
/* 8 bit bus width */
|
|
{"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
|
|
{NULL, 0},
|
|
};
|
|
#endif
|
|
|
|
int board_late_init(void)
|
|
{
|
|
#ifdef CONFIG_CMD_BMODE
|
|
add_board_boot_modes(board_boot_modes);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int checkboard(void)
|
|
{
|
|
puts("Board: MX6Q-SabreSD\n");
|
|
|
|
return 0;
|
|
}
|