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