uboot/board/sifive/unmatched/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2020-2021 SiFive, Inc
   4 *
   5 * Authors:
   6 *   Pragnesh Patel <pragnesh.patel@sifive.com>
   7 */
   8
   9#include <init.h>
  10#include <spl.h>
  11#include <misc.h>
  12#include <log.h>
  13#include <linux/delay.h>
  14#include <linux/io.h>
  15#include <asm/gpio.h>
  16#include <asm/arch/gpio.h>
  17#include <asm/arch/spl.h>
  18
  19#define UBRDG_RESET     SIFIVE_GENERIC_GPIO_NR(0, 7)
  20#define ULPI_RESET      SIFIVE_GENERIC_GPIO_NR(0, 9)
  21#define UHUB_RESET      SIFIVE_GENERIC_GPIO_NR(0, 11)
  22#define GEM_PHY_RESET   SIFIVE_GENERIC_GPIO_NR(0, 12)
  23
  24#define MODE_SELECT_REG         0x1000
  25#define MODE_SELECT_SPI         0x6
  26#define MODE_SELECT_SD          0xb
  27#define MODE_SELECT_MASK        GENMASK(3, 0)
  28
  29static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width)
  30{
  31        int ret;
  32
  33        ret = gpio_request(pin, label);
  34        if (ret) {
  35                debug("%s gpio request failed: %d\n", label, ret);
  36                return ret;
  37        }
  38
  39        ret = gpio_direction_output(pin, 1);
  40        if (ret) {
  41                debug("%s gpio direction set failed: %d\n", label, ret);
  42                return ret;
  43        }
  44
  45        udelay(1);
  46
  47        gpio_set_value(pin, 0);
  48        udelay(low_width);
  49        gpio_set_value(pin, 1);
  50
  51        return ret;
  52}
  53
  54static inline int spl_gemgxl_init(void)
  55{
  56        int ret;
  57        /*
  58         * GEMGXL init VSC8541 PHY reset sequence;
  59         * leave pull-down active for 2ms
  60         */
  61        udelay(2000);
  62        ret = spl_reset_device_by_gpio("gem_phy_reset", GEM_PHY_RESET, 1);
  63        mdelay(15);
  64
  65        return ret;
  66}
  67
  68static inline int spl_usb_pcie_bridge_init(void)
  69{
  70        return spl_reset_device_by_gpio("usb_pcie_bridge_reset", UBRDG_RESET, 3000);
  71}
  72
  73static inline int spl_usb_hub_init(void)
  74{
  75        return spl_reset_device_by_gpio("usb_hub_reset", UHUB_RESET, 100);
  76}
  77
  78static inline int spl_ulpi_init(void)
  79{
  80        return spl_reset_device_by_gpio("ulpi_reset", ULPI_RESET, 1);
  81}
  82
  83int spl_board_init_f(void)
  84{
  85        int ret;
  86
  87        ret = spl_soc_init();
  88        if (ret) {
  89                debug("HiFive Unmatched FU740 SPL init failed: %d\n", ret);
  90                goto end;
  91        }
  92
  93        ret = spl_gemgxl_init();
  94        if (ret) {
  95                debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret);
  96                goto end;
  97        }
  98
  99        ret = spl_usb_pcie_bridge_init();
 100        if (ret) {
 101                debug("USB Bridge (ASM1042A) init failed: %d\n", ret);
 102                goto end;
 103        }
 104
 105        ret = spl_usb_hub_init();
 106        if (ret) {
 107                debug("USB Hub (ASM1074) init failed: %d\n", ret);
 108                goto end;
 109        }
 110
 111        ret = spl_ulpi_init();
 112        if (ret) {
 113                debug("USB 2.0 PHY (USB3320C) init failed: %d\n", ret);
 114                goto end;
 115        }
 116
 117end:
 118        return ret;
 119}
 120
 121u32 spl_boot_device(void)
 122{
 123        u32 mode_select = readl((void *)MODE_SELECT_REG);
 124        u32 boot_device = mode_select & MODE_SELECT_MASK;
 125
 126        switch (boot_device) {
 127        case MODE_SELECT_SPI:
 128                return BOOT_DEVICE_SPI;
 129        case MODE_SELECT_SD:
 130                return BOOT_DEVICE_MMC1;
 131        default:
 132                debug("Unsupported boot device 0x%x but trying MMC1\n",
 133                      boot_device);
 134                return BOOT_DEVICE_MMC1;
 135        }
 136}
 137
 138#ifdef CONFIG_SPL_LOAD_FIT
 139int board_fit_config_name_match(const char *name)
 140{
 141        /* boot using first FIT config */
 142        return 0;
 143}
 144#endif
 145