uboot/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Freescale Semiconductor, Inc.
   3 *
   4 * Author: Ye Li <ye.li@nxp.com>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <asm/arch/clock.h>
  10#include <asm/arch/crm_regs.h>
  11#include <asm/arch/iomux.h>
  12#include <asm/arch/imx-regs.h>
  13#include <asm/arch/mx6-pins.h>
  14#include <asm/arch/sys_proto.h>
  15#include <asm/gpio.h>
  16#include <asm/imx-common/iomux-v3.h>
  17#include <asm/imx-common/boot_mode.h>
  18#include <asm/io.h>
  19#include <linux/sizes.h>
  20#include <common.h>
  21#include <fsl_esdhc.h>
  22#include <miiphy.h>
  23#include <netdev.h>
  24#include <power/pmic.h>
  25#include <power/pfuze100_pmic.h>
  26#include "../common/pfuze.h"
  27#include <usb.h>
  28#include <usb/ehci-ci.h>
  29#include <pca953x.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
  34        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  35        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  36
  37#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
  38        PAD_CTL_SPEED_HIGH   |                                   \
  39        PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
  40
  41#define ENET_CLK_PAD_CTRL  (PAD_CTL_SPEED_MED | \
  42        PAD_CTL_DSE_120ohm   | PAD_CTL_SRE_FAST)
  43
  44#define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
  45        PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
  46
  47#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
  48#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
  49                        PAD_CTL_SRE_FAST)
  50#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
  51
  52int dram_init(void)
  53{
  54        gd->ram_size = imx_ddr_size();
  55
  56        return 0;
  57}
  58
  59static iomux_v3_cfg_t const uart1_pads[] = {
  60        MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  61        MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  62};
  63
  64static iomux_v3_cfg_t const fec2_pads[] = {
  65        MX6_PAD_ENET1_MDC__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  66        MX6_PAD_ENET1_MDIO__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  67        MX6_PAD_RGMII2_RX_CTL__ENET2_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  68        MX6_PAD_RGMII2_RD0__ENET2_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  69        MX6_PAD_RGMII2_RD1__ENET2_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  70        MX6_PAD_RGMII2_RD2__ENET2_RX_DATA_2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  71        MX6_PAD_RGMII2_RD3__ENET2_RX_DATA_3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  72        MX6_PAD_RGMII2_RXC__ENET2_RX_CLK | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  73        MX6_PAD_RGMII2_TX_CTL__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  74        MX6_PAD_RGMII2_TD0__ENET2_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  75        MX6_PAD_RGMII2_TD1__ENET2_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  76        MX6_PAD_RGMII2_TD2__ENET2_TX_DATA_2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  77        MX6_PAD_RGMII2_TD3__ENET2_TX_DATA_3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  78        MX6_PAD_RGMII2_TXC__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  79};
  80
  81static void setup_iomux_uart(void)
  82{
  83        imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
  84}
  85
  86static int setup_fec(void)
  87{
  88        struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  89
  90        /* Use 125MHz anatop loopback REF_CLK1 for ENET2 */
  91        clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, 0);
  92
  93        return enable_fec_anatop_clock(1, ENET_125MHZ);
  94}
  95
  96int board_eth_init(bd_t *bis)
  97{
  98        int ret;
  99
 100        imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads));
 101        setup_fec();
 102
 103        ret = fecmxc_initialize_multi(bis, 1,
 104                CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
 105        if (ret)
 106                printf("FEC%d MXC: %s:failed\n", 1, __func__);
 107
 108        return ret;
 109}
 110
 111int board_phy_config(struct phy_device *phydev)
 112{
 113        /*
 114         * Enable 1.8V(SEL_1P5_1P8_POS_REG) on
 115         * Phy control debug reg 0
 116         */
 117        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
 118        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
 119
 120        /* rgmii tx clock delay enable */
 121        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
 122        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
 123
 124        if (phydev->drv->config)
 125                phydev->drv->config(phydev);
 126
 127        return 0;
 128}
 129
 130int power_init_board(void)
 131{
 132        struct udevice *dev;
 133        int ret;
 134        u32 dev_id, rev_id, i;
 135        u32 switch_num = 6;
 136        u32 offset = PFUZE100_SW1CMODE;
 137
 138        ret = pmic_get("pfuze100", &dev);
 139        if (ret == -ENODEV)
 140                return 0;
 141
 142        if (ret != 0)
 143                return ret;
 144
 145        dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID);
 146        rev_id = pmic_reg_read(dev, PFUZE100_REVID);
 147        printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id);
 148
 149
 150        /* Init mode to APS_PFM */
 151        pmic_reg_write(dev, PFUZE100_SW1ABMODE, APS_PFM);
 152
 153        for (i = 0; i < switch_num - 1; i++)
 154                pmic_reg_write(dev, offset + i * SWITCH_SIZE, APS_PFM);
 155
 156        /* set SW1AB staby volatage 0.975V */
 157        pmic_clrsetbits(dev, PFUZE100_SW1ABSTBY, 0x3f, 0x1b);
 158
 159        /* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
 160        pmic_clrsetbits(dev, PFUZE100_SW1ABCONF, 0xc0, 0x40);
 161
 162        /* set SW1C staby volatage 1.10V */
 163        pmic_clrsetbits(dev, PFUZE100_SW1CSTBY, 0x3f, 0x20);
 164
 165        /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */
 166        pmic_clrsetbits(dev, PFUZE100_SW1CCONF, 0xc0, 0x40);
 167
 168        return 0;
 169}
 170
 171#ifdef CONFIG_USB_EHCI_MX6
 172#define USB_OTHERREGS_OFFSET    0x800
 173#define UCTRL_PWR_POL           (1 << 9)
 174
 175static iomux_v3_cfg_t const usb_otg_pads[] = {
 176        /* OGT1 */
 177        MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
 178        MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
 179        /* OTG2 */
 180        MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)
 181};
 182
 183static void setup_usb(void)
 184{
 185        imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 186                                         ARRAY_SIZE(usb_otg_pads));
 187}
 188
 189int board_usb_phy_mode(int port)
 190{
 191        if (port == 1)
 192                return USB_INIT_HOST;
 193        else
 194                return usb_phy_mode(port);
 195}
 196
 197int board_ehci_hcd_init(int port)
 198{
 199        u32 *usbnc_usb_ctrl;
 200
 201        if (port > 1)
 202                return -EINVAL;
 203
 204        usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
 205                                 port * 4);
 206
 207        /* Set Power polarity */
 208        setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
 209
 210        return 0;
 211}
 212#endif
 213
 214int board_early_init_f(void)
 215{
 216        setup_iomux_uart();
 217
 218        return 0;
 219}
 220
 221#ifdef CONFIG_FSL_QSPI
 222
 223#define QSPI_PAD_CTRL1  \
 224        (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_HIGH | \
 225         PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_40ohm)
 226
 227static iomux_v3_cfg_t const quadspi_pads[] = {
 228        MX6_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B   | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 229        MX6_PAD_QSPI1A_SCLK__QSPI1_A_SCLK     | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 230        MX6_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 231        MX6_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 232        MX6_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 233        MX6_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 234        MX6_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B   | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 235        MX6_PAD_QSPI1B_SCLK__QSPI1_B_SCLK     | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 236        MX6_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 237        MX6_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 238        MX6_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 239        MX6_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 240};
 241
 242int board_qspi_init(void)
 243{
 244        /* Set the iomux */
 245        imx_iomux_v3_setup_multiple_pads(quadspi_pads,
 246                                         ARRAY_SIZE(quadspi_pads));
 247
 248        /* Set the clock */
 249        enable_qspi_clk(0);
 250
 251        return 0;
 252}
 253#endif
 254
 255#ifdef CONFIG_NAND_MXS
 256iomux_v3_cfg_t gpmi_pads[] = {
 257        MX6_PAD_NAND_CLE__RAWNAND_CLE           | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 258        MX6_PAD_NAND_ALE__RAWNAND_ALE           | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 259        MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 260        MX6_PAD_NAND_READY_B__RAWNAND_READY_B   | MUX_PAD_CTRL(GPMI_PAD_CTRL0),
 261        MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B               | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 262        MX6_PAD_NAND_RE_B__RAWNAND_RE_B         | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 263        MX6_PAD_NAND_WE_B__RAWNAND_WE_B         | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 264        MX6_PAD_NAND_DATA00__RAWNAND_DATA00     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 265        MX6_PAD_NAND_DATA01__RAWNAND_DATA01     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 266        MX6_PAD_NAND_DATA02__RAWNAND_DATA02     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 267        MX6_PAD_NAND_DATA03__RAWNAND_DATA03     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 268        MX6_PAD_NAND_DATA04__RAWNAND_DATA04     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 269        MX6_PAD_NAND_DATA05__RAWNAND_DATA05     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 270        MX6_PAD_NAND_DATA06__RAWNAND_DATA06     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 271        MX6_PAD_NAND_DATA07__RAWNAND_DATA07     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 272};
 273
 274static void setup_gpmi_nand(void)
 275{
 276        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 277
 278        /* config gpmi nand iomux */
 279        imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads));
 280
 281        setup_gpmi_io_clk((MXC_CCM_CS2CDR_QSPI2_CLK_PODF(0) |
 282                        MXC_CCM_CS2CDR_QSPI2_CLK_PRED(3) |
 283                        MXC_CCM_CS2CDR_QSPI2_CLK_SEL(3)));
 284
 285        /* enable apbh clock gating */
 286        setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
 287}
 288#endif
 289
 290int board_init(void)
 291{
 292        struct gpio_desc desc;
 293        int ret;
 294
 295        /* Address of boot parameters */
 296        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 297
 298        ret = dm_gpio_lookup_name("gpio@30_4", &desc);
 299        if (ret)
 300                return ret;
 301
 302        ret = dm_gpio_request(&desc, "cpu_per_rst_b");
 303        if (ret)
 304                return ret;
 305        /* Reset CPU_PER_RST_B signal for enet phy and PCIE */
 306        dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
 307        udelay(500);
 308        dm_gpio_set_value(&desc, 1);
 309
 310        ret = dm_gpio_lookup_name("gpio@32_2", &desc);
 311        if (ret)
 312                return ret;
 313
 314        ret = dm_gpio_request(&desc, "steer_enet");
 315        if (ret)
 316                return ret;
 317
 318        dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
 319        udelay(500);
 320        /* Set steering signal to L for selecting B0 */
 321        dm_gpio_set_value(&desc, 0);
 322
 323#ifdef CONFIG_USB_EHCI_MX6
 324        setup_usb();
 325#endif
 326
 327#ifdef CONFIG_FSL_QSPI
 328        board_qspi_init();
 329#endif
 330
 331#ifdef CONFIG_NAND_MXS
 332        setup_gpmi_nand();
 333#endif
 334
 335        return 0;
 336}
 337
 338#ifdef CONFIG_CMD_BMODE
 339static const struct boot_mode board_boot_modes[] = {
 340        {"sda", MAKE_CFGVAL(0x42, 0x30, 0x00, 0x00)},
 341        {"sdb", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
 342        {"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
 343        {"nand", MAKE_CFGVAL(0x82, 0x00, 0x00, 0x00)},
 344        {NULL,   0},
 345};
 346#endif
 347
 348int board_late_init(void)
 349{
 350#ifdef CONFIG_CMD_BMODE
 351        add_board_boot_modes(board_boot_modes);
 352#endif
 353
 354        return 0;
 355}
 356
 357int checkboard(void)
 358{
 359        puts("Board: MX6SX SABRE AUTO\n");
 360
 361        return 0;
 362}
 363