uboot/board/mscc/ocelot/ocelot.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
   2/*
   3 * Copyright (c) 2018 Microsemi Corporation
   4 */
   5
   6#include <common.h>
   7#include <image.h>
   8#include <init.h>
   9#include <log.h>
  10#include <asm/global_data.h>
  11#include <asm/io.h>
  12#include <asm/addrspace.h>
  13#include <asm/types.h>
  14#include <spi.h>
  15#include <led.h>
  16#include <wait_bit.h>
  17#include <miiphy.h>
  18#include <linux/bitops.h>
  19
  20DECLARE_GLOBAL_DATA_PTR;
  21
  22enum {
  23        BOARD_TYPE_PCB120 = 0xAABBCC00,
  24        BOARD_TYPE_PCB123,
  25};
  26
  27void mscc_switch_reset(bool enter)
  28{
  29        /* Nasty workaround to avoid GPIO19 (DDR!) being reset */
  30        mscc_gpio_set_alternate(19, 2);
  31
  32        debug("applying SwC reset\n");
  33
  34        writel(ICPU_RESET_CORE_RST_PROTECT, BASE_CFG + ICPU_RESET);
  35        writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_DEVCPU_GCB + PERF_SOFT_RST);
  36
  37        if (wait_for_bit_le32(BASE_DEVCPU_GCB + PERF_SOFT_RST,
  38                              PERF_SOFT_RST_SOFT_CHIP_RST, false, 5000, false))
  39                pr_err("Tiemout while waiting for switch reset\n");
  40
  41        /*
  42         * Reset GPIO19 mode back as regular GPIO, output, high (DDR
  43         * not reset) (Order is important)
  44         */
  45        setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
  46        writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_SET);
  47        mscc_gpio_set_alternate(19, 0);
  48}
  49
  50int board_phy_config(struct phy_device *phydev)
  51{
  52        if (gd->board_type == BOARD_TYPE_PCB123)
  53                return 0;
  54
  55        phy_write(phydev, 0, 31, 0x10);
  56        phy_write(phydev, 0, 18, 0x80F0);
  57        while (phy_read(phydev, 0, 18) & 0x8000)
  58                ;
  59        phy_write(phydev, 0, 31, 0);
  60
  61        return 0;
  62}
  63
  64void board_debug_uart_init(void)
  65{
  66        /* too early for the pinctrl driver, so configure the UART pins here */
  67        mscc_gpio_set_alternate(6, 1);
  68        mscc_gpio_set_alternate(7, 1);
  69}
  70
  71int board_early_init_r(void)
  72{
  73        /* Prepare SPI controller to be used in master mode */
  74        writel(0, BASE_CFG + ICPU_SW_MODE);
  75        clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
  76                        ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
  77                        ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
  78
  79        /* Address of boot parameters */
  80        gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE;
  81
  82        return 0;
  83}
  84
  85static void do_board_detect(void)
  86{
  87        u16 dummy = 0;
  88
  89        /* Enable MIIM */
  90        mscc_gpio_set_alternate(14, 1);
  91        mscc_gpio_set_alternate(15, 1);
  92        if (mscc_phy_rd(1, 0, 0, &dummy) == 0)
  93                gd->board_type = BOARD_TYPE_PCB120;
  94        else
  95                gd->board_type = BOARD_TYPE_PCB123;
  96}
  97
  98#if defined(CONFIG_MULTI_DTB_FIT)
  99int board_fit_config_name_match(const char *name)
 100{
 101        if (gd->board_type == BOARD_TYPE_PCB120 &&
 102            strcmp(name, "ocelot_pcb120") == 0)
 103                return 0;
 104
 105        if (gd->board_type == BOARD_TYPE_PCB123 &&
 106            strcmp(name, "ocelot_pcb123") == 0)
 107                return 0;
 108
 109        return -1;
 110}
 111#endif
 112
 113#if defined(CONFIG_DTB_RESELECT)
 114int embedded_dtb_select(void)
 115{
 116        do_board_detect();
 117        fdtdec_setup();
 118
 119        return 0;
 120}
 121#endif
 122