uboot/board/technologic/ts4800/ts4800.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2015 Savoir-faire Linux Inc.
   3 *
   4 * Derived from MX51EVK code by
   5 *   Freescale Semiconductor, Inc.
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <asm/io.h>
  12#include <asm/gpio.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/arch/iomux-mx51.h>
  15#include <asm/errno.h>
  16#include <asm/arch/sys_proto.h>
  17#include <asm/arch/crm_regs.h>
  18#include <asm/arch/clock.h>
  19#include <asm/imx-common/mx5_video.h>
  20#include <mmc.h>
  21#include <fsl_esdhc.h>
  22#include <mc13892.h>
  23
  24#include <malloc.h>
  25#include <netdev.h>
  26#include <phy.h>
  27#include "ts4800.h"
  28
  29DECLARE_GLOBAL_DATA_PTR;
  30
  31#ifdef CONFIG_FSL_ESDHC
  32struct fsl_esdhc_cfg esdhc_cfg[2] = {
  33        {MMC_SDHC1_BASE_ADDR},
  34        {MMC_SDHC2_BASE_ADDR},
  35};
  36#endif
  37
  38int dram_init(void)
  39{
  40        /* dram_init must store complete ramsize in gd->ram_size */
  41        gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
  42                                PHYS_SDRAM_1_SIZE);
  43        return 0;
  44}
  45
  46u32 get_board_rev(void)
  47{
  48        u32 rev = get_cpu_rev();
  49        if (!gpio_get_value(IMX_GPIO_NR(1, 22)))
  50                rev |= BOARD_REV_2_0 << BOARD_VER_OFFSET;
  51        return rev;
  52}
  53
  54#define UART_PAD_CTRL   (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH)
  55
  56static void setup_iomux_uart(void)
  57{
  58        static const iomux_v3_cfg_t uart_pads[] = {
  59                MX51_PAD_UART1_RXD__UART1_RXD,
  60                MX51_PAD_UART1_TXD__UART1_TXD,
  61                NEW_PAD_CTRL(MX51_PAD_UART1_RTS__UART1_RTS, UART_PAD_CTRL),
  62                NEW_PAD_CTRL(MX51_PAD_UART1_CTS__UART1_CTS, UART_PAD_CTRL),
  63        };
  64
  65        imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
  66}
  67
  68static void setup_iomux_fec(void)
  69{
  70        static const iomux_v3_cfg_t fec_pads[] = {
  71                NEW_PAD_CTRL(MX51_PAD_EIM_EB2__FEC_MDIO,
  72                                PAD_CTL_HYS |
  73                                PAD_CTL_PUS_22K_UP |
  74                                PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST),
  75                MX51_PAD_EIM_EB3__FEC_RDATA1,
  76                NEW_PAD_CTRL(MX51_PAD_EIM_CS2__FEC_RDATA2, PAD_CTL_HYS),
  77                MX51_PAD_EIM_CS3__FEC_RDATA3,
  78                MX51_PAD_NANDF_CS2__FEC_TX_ER,
  79                MX51_PAD_EIM_CS5__FEC_CRS,
  80                MX51_PAD_EIM_CS4__FEC_RX_ER,
  81                /* PAD used on TS4800 */
  82                MX51_PAD_DI2_PIN2__FEC_MDC,
  83                MX51_PAD_DISP2_DAT14__FEC_RDAT0,
  84                MX51_PAD_DISP2_DAT10__FEC_COL,
  85                MX51_PAD_DISP2_DAT11__FEC_RXCLK,
  86                MX51_PAD_DISP2_DAT15__FEC_TDAT0,
  87                MX51_PAD_DISP2_DAT6__FEC_TDAT1,
  88                MX51_PAD_DISP2_DAT7__FEC_TDAT2,
  89                MX51_PAD_DISP2_DAT8__FEC_TDAT3,
  90                MX51_PAD_DISP2_DAT9__FEC_TX_EN,
  91                MX51_PAD_DISP2_DAT13__FEC_TX_CLK,
  92                MX51_PAD_DISP2_DAT12__FEC_RX_DV,
  93        };
  94
  95        imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
  96}
  97
  98#ifdef CONFIG_FSL_ESDHC
  99int board_mmc_getcd(struct mmc *mmc)
 100{
 101        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 102        int ret;
 103
 104        imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_0__GPIO1_0,
 105                                                NO_PAD_CTRL));
 106        gpio_direction_input(IMX_GPIO_NR(1, 0));
 107        imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_6__GPIO1_6,
 108                                                NO_PAD_CTRL));
 109        gpio_direction_input(IMX_GPIO_NR(1, 6));
 110
 111        if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
 112                ret = !gpio_get_value(IMX_GPIO_NR(1, 0));
 113        else
 114                ret = !gpio_get_value(IMX_GPIO_NR(1, 6));
 115
 116        return ret;
 117}
 118
 119int board_mmc_init(bd_t *bis)
 120{
 121        static const iomux_v3_cfg_t sd1_pads[] = {
 122                NEW_PAD_CTRL(MX51_PAD_SD1_CMD__SD1_CMD, PAD_CTL_DSE_MAX |
 123                        PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
 124                NEW_PAD_CTRL(MX51_PAD_SD1_CLK__SD1_CLK, PAD_CTL_DSE_MAX |
 125                        PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
 126                NEW_PAD_CTRL(MX51_PAD_SD1_DATA0__SD1_DATA0, PAD_CTL_DSE_MAX |
 127                        PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
 128                NEW_PAD_CTRL(MX51_PAD_SD1_DATA1__SD1_DATA1, PAD_CTL_DSE_MAX |
 129                        PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
 130                NEW_PAD_CTRL(MX51_PAD_SD1_DATA2__SD1_DATA2, PAD_CTL_DSE_MAX |
 131                        PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
 132                NEW_PAD_CTRL(MX51_PAD_SD1_DATA3__SD1_DATA3, PAD_CTL_DSE_MAX |
 133                        PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SRE_FAST),
 134                NEW_PAD_CTRL(MX51_PAD_GPIO1_0__SD1_CD, PAD_CTL_HYS),
 135                NEW_PAD_CTRL(MX51_PAD_GPIO1_1__SD1_WP, PAD_CTL_HYS),
 136        };
 137
 138        esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 139
 140        imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads));
 141
 142        return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
 143}
 144#endif
 145
 146int board_early_init_f(void)
 147{
 148        setup_iomux_uart();
 149        setup_iomux_fec();
 150
 151        return 0;
 152}
 153
 154int board_init(void)
 155{
 156        /* address of boot parameters */
 157        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 158
 159        return 0;
 160}
 161
 162/*
 163 * Read the MAC address from FEC's registers PALR PAUR.
 164 * User is supposed to configure these registers when MAC address is known
 165 * from another source (fuse), but on TS4800, MAC address is not fused and
 166 * the bootrom configure these registers on startup.
 167 */
 168static int fec_get_mac_from_register(uint32_t base_addr)
 169{
 170        unsigned char ethaddr[6];
 171        u32 reg_mac[2];
 172        int i;
 173
 174        reg_mac[0] = in_be32(base_addr + 0xE4);
 175        reg_mac[1] = in_be32(base_addr + 0xE8);
 176
 177        for(i = 0; i < 6; i++)
 178                ethaddr[i] = (reg_mac[i / 4] >> ((i % 4) * 8)) & 0xFF;
 179
 180        if (is_valid_ethaddr(ethaddr)) {
 181                eth_setenv_enetaddr("ethaddr", ethaddr);
 182                return 0;
 183        }
 184
 185        return -1;
 186}
 187
 188#define TS4800_GPIO_FEC_PHY_RES         IMX_GPIO_NR(2, 14)
 189int board_eth_init(bd_t *bd)
 190{
 191        int dev_id = -1;
 192        int phy_id = 0xFF;
 193        uint32_t addr = IMX_FEC_BASE;
 194
 195        uint32_t base_mii;
 196        struct mii_dev *bus = NULL;
 197        struct phy_device *phydev = NULL;
 198        int ret;
 199
 200        /* reset FEC phy */
 201        imx_iomux_v3_setup_pad(MX51_PAD_EIM_A20__GPIO2_14);
 202        gpio_direction_output(TS4800_GPIO_FEC_PHY_RES, 0);
 203        mdelay(1);
 204        gpio_set_value(TS4800_GPIO_FEC_PHY_RES, 1);
 205        mdelay(1);
 206
 207        base_mii = addr;
 208        debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
 209        bus = fec_get_miibus(base_mii, dev_id);
 210        if (!bus)
 211                return -ENOMEM;
 212
 213        phydev = phy_find_by_mask(bus, phy_id, PHY_INTERFACE_MODE_MII);
 214        if (!phydev) {
 215                free(bus);
 216                return -ENOMEM;
 217        }
 218
 219        if (fec_get_mac_from_register(addr))
 220                printf("eth_init: failed to get MAC address\n");
 221
 222        ret = fec_probe(bd, dev_id, addr, bus, phydev);
 223        if (ret) {
 224                free(phydev);
 225                free(bus);
 226        }
 227
 228        return ret;
 229}
 230
 231/*
 232 * Do not overwrite the console
 233 * Use always serial for U-Boot console
 234 */
 235int overwrite_console(void)
 236{
 237        return 1;
 238}
 239
 240int checkboard(void)
 241{
 242        puts("Board: TS4800\n");
 243
 244        return 0;
 245}
 246
 247void hw_watchdog_reset(void)
 248{
 249        struct ts4800_wtd_regs *wtd = (struct ts4800_wtd_regs *) (TS4800_SYSCON_BASE + 0xE);
 250        /* feed the watchdog for another 10s */
 251        writew(0x2, &wtd->feed);
 252}
 253
 254void hw_watchdog_init(void)
 255{
 256        return;
 257}
 258