uboot/board/Arcturus/ucp1020/ucp1020.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2013-2019 Arcturus Networks, Inc.
   4 *           https://www.arcturusnetworks.com/products/ucp1020/
   5 *           by Oleksandr G Zhadan et al.
   6 * based on board/freescale/p1_p2_rdb_pc/spl.c
   7 * original copyright follows:
   8 * Copyright 2013 Freescale Semiconductor, Inc.
   9 */
  10
  11#include <common.h>
  12#include <command.h>
  13#include <env.h>
  14#include <hwconfig.h>
  15#include <init.h>
  16#include <pci.h>
  17#include <i2c.h>
  18#include <miiphy.h>
  19#include <linux/libfdt.h>
  20#include <fdt_support.h>
  21#include <fsl_mdio.h>
  22#include <tsec.h>
  23#include <ioports.h>
  24#include <netdev.h>
  25#include <micrel.h>
  26#include <spi_flash.h>
  27#include <mmc.h>
  28#include <linux/ctype.h>
  29#include <asm/fsl_serdes.h>
  30#include <asm/gpio.h>
  31#include <asm/processor.h>
  32#include <asm/mmu.h>
  33#include <asm/cache.h>
  34#include <asm/immap_85xx.h>
  35#include <asm/fsl_pci.h>
  36#include <fsl_ddr_sdram.h>
  37#include <asm/io.h>
  38#include <asm/fsl_law.h>
  39#include <asm/fsl_lbc.h>
  40#include <asm/mp.h>
  41#include "ucp1020.h"
  42
  43void spi_set_speed(struct spi_slave *slave, uint hz)
  44{
  45        /* TO DO: It's actially have to be in spi/ */
  46}
  47
  48/*
  49 * To be compatible with cmd_gpio
  50 */
  51int name_to_gpio(const char *name)
  52{
  53        int gpio = 31 - simple_strtoul(name, NULL, 10);
  54
  55        if (gpio < 16)
  56                gpio = -1;
  57
  58        return gpio;
  59}
  60
  61void board_gpio_init(void)
  62{
  63        int i;
  64        char envname[8], *val;
  65
  66        for (i = 0; i < GPIO_MAX_NUM; i++) {
  67                sprintf(envname, "GPIO%d", i);
  68                val = env_get(envname);
  69                if (val) {
  70                        char direction = toupper(val[0]);
  71                        char level = toupper(val[1]);
  72
  73                        if (direction == 'I') {
  74                                gpio_direction_input(i);
  75                        } else {
  76                                if (direction == 'O') {
  77                                        if (level == '1')
  78                                                gpio_direction_output(i, 1);
  79                                        else
  80                                                gpio_direction_output(i, 0);
  81                                }
  82                        }
  83                }
  84        }
  85
  86        val = env_get("PCIE_OFF");
  87        if (val) {
  88                gpio_direction_input(GPIO_PCIE1_EN);
  89                gpio_direction_input(GPIO_PCIE2_EN);
  90        } else {
  91                gpio_direction_output(GPIO_PCIE1_EN, 1);
  92                gpio_direction_output(GPIO_PCIE2_EN, 1);
  93        }
  94
  95        val = env_get("SDHC_CDWP_OFF");
  96        if (!val) {
  97                ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  98
  99                setbits_be32(&gur->pmuxcr,
 100                             (MPC85xx_PMUXCR_SDHC_CD | MPC85xx_PMUXCR_SDHC_WP));
 101        }
 102}
 103
 104int board_early_init_f(void)
 105{
 106        return 0;       /* Just in case. Could be disable in config file */
 107}
 108
 109int checkboard(void)
 110{
 111        printf("Board: %s\n", CONFIG_BOARDNAME_LOCAL);
 112        board_gpio_init();
 113#ifdef CONFIG_MMC
 114        printf("SD/MMC: 4-bit Mode\n");
 115#endif
 116
 117        return 0;
 118}
 119
 120#ifdef CONFIG_PCI
 121void pci_init_board(void)
 122{
 123        fsl_pcie_init_board(0);
 124}
 125#endif
 126
 127int board_early_init_r(void)
 128{
 129        const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
 130        const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
 131
 132        /*
 133         * Remap Boot flash region to caching-inhibited
 134         * so that flash can be erased properly.
 135         */
 136
 137        /* Flush d-cache and invalidate i-cache of any FLASH data */
 138        flush_dcache();
 139        invalidate_icache();
 140
 141        /* invalidate existing TLB entry for flash */
 142        disable_tlb(flash_esel);
 143
 144        set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, /* tlb, epn, rpn */
 145                MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, /* perms, wimge */
 146                0, flash_esel, BOOKE_PAGESZ_64M, 1);/* ts, esel, tsize, iprot */
 147
 148        return 0;
 149}
 150
 151int board_phy_config(struct phy_device *phydev)
 152{
 153#if defined(CONFIG_PHY_MICREL_KSZ9021)
 154        int regval;
 155        static int cnt;
 156
 157        if (cnt++ == 0)
 158                printf("PHYs address [");
 159
 160        if (phydev->addr == TSEC1_PHY_ADDR || phydev->addr == TSEC3_PHY_ADDR) {
 161                regval =
 162                    ksz9021_phy_extended_read(phydev,
 163                                              MII_KSZ9021_EXT_STRAP_STATUS);
 164                /*
 165                 * min rx data delay
 166                 */
 167                ksz9021_phy_extended_write(phydev,
 168                                           MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW,
 169                                           0x6666);
 170                /*
 171                 * max rx/tx clock delay, min rx/tx control
 172                 */
 173                ksz9021_phy_extended_write(phydev,
 174                                           MII_KSZ9021_EXT_RGMII_CLOCK_SKEW,
 175                                           0xf6f6);
 176                printf("0x%x", (regval & 0x1f));
 177        } else {
 178                printf("0x%x", (TSEC2_PHY_ADDR & 0x1f));
 179        }
 180        if (cnt == 3)
 181                printf("] ");
 182        else
 183                printf(",");
 184#endif
 185
 186#if defined(CONFIG_PHY_MICREL_KSZ9031_DEBUG)
 187        regval = ksz9031_phy_extended_read(phydev, 2, 0x01, 0x4000);
 188        if (regval >= 0)
 189                printf(" (ADDR 0x%x) ", regval & 0x1f);
 190#endif
 191
 192        return 0;
 193}
 194
 195int last_stage_init(void)
 196{
 197        static char newkernelargs[256];
 198        static u8 id1[16];
 199        static u8 id2;
 200#ifdef CONFIG_MMC
 201        struct mmc *mmc;
 202#endif
 203        char *sval, *kval;
 204
 205        if (i2c_read(CONFIG_SYS_I2C_IDT6V49205B, 7, 1, &id1[0], 2) < 0) {
 206                printf("Error reading i2c IDT6V49205B information!\n");
 207        } else {
 208                printf("IDT6V49205B(0x%02x): ready\n", id1[1]);
 209                i2c_read(CONFIG_SYS_I2C_IDT6V49205B, 4, 1, &id1[0], 2);
 210                if (!(id1[1] & 0x02)) {
 211                        id1[1] |= 0x02;
 212                        i2c_write(CONFIG_SYS_I2C_IDT6V49205B, 4, 1, &id1[0], 2);
 213                        asm("nop; nop");
 214                }
 215        }
 216
 217        if (i2c_read(CONFIG_SYS_I2C_NCT72_ADDR, 0xFE, 1, &id2, 1) < 0)
 218                printf("Error reading i2c NCT72 information!\n");
 219        else
 220                printf("NCT72(0x%x): ready\n", id2);
 221
 222        kval = env_get("kernelargs");
 223
 224#ifdef CONFIG_MMC
 225        mmc = find_mmc_device(0);
 226        if (mmc)
 227                if (!mmc_init(mmc)) {
 228                        printf("MMC/SD card detected\n");
 229                        if (kval) {
 230                                int n = strlen(defkargs);
 231                                char *tmp = strstr(kval, defkargs);
 232
 233                                *tmp = 0;
 234                                strcpy(newkernelargs, kval);
 235                                strcat(newkernelargs, " ");
 236                                strcat(newkernelargs, mmckargs);
 237                                strcat(newkernelargs, " ");
 238                                strcat(newkernelargs, &tmp[n]);
 239                                env_set("kernelargs", newkernelargs);
 240                        } else {
 241                                env_set("kernelargs", mmckargs);
 242                        }
 243                }
 244#endif
 245        get_arc_info();
 246
 247        if (kval) {
 248                sval = env_get("SERIAL");
 249                if (sval) {
 250                        strcpy(newkernelargs, "SN=");
 251                        strcat(newkernelargs, sval);
 252                        strcat(newkernelargs, " ");
 253                        strcat(newkernelargs, kval);
 254                        env_set("kernelargs", newkernelargs);
 255                }
 256        } else {
 257                printf("Error reading kernelargs env variable!\n");
 258        }
 259
 260        return 0;
 261}
 262
 263int board_eth_init(bd_t *bis)
 264{
 265        struct fsl_pq_mdio_info mdio_info;
 266        struct tsec_info_struct tsec_info[4];
 267#ifdef CONFIG_TSEC2
 268        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 269#endif
 270        int num = 0;
 271
 272#ifdef CONFIG_TSEC1
 273        SET_STD_TSEC_INFO(tsec_info[num], 1);
 274        num++;
 275#endif
 276#ifdef CONFIG_TSEC2
 277        SET_STD_TSEC_INFO(tsec_info[num], 2);
 278        if (is_serdes_configured(SGMII_TSEC2)) {
 279                if (!(in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_SGMII2_DIS)) {
 280                        puts("eTSEC2 is in sgmii mode.\n");
 281                        tsec_info[num].flags |= TSEC_SGMII;
 282                        tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII;
 283                }
 284        }
 285        num++;
 286#endif
 287#ifdef CONFIG_TSEC3
 288        SET_STD_TSEC_INFO(tsec_info[num], 3);
 289        num++;
 290#endif
 291
 292        if (!num) {
 293                printf("No TSECs initialized\n");
 294                return 0;
 295        }
 296
 297        mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
 298        mdio_info.name = DEFAULT_MII_NAME;
 299
 300        fsl_pq_mdio_init(bis, &mdio_info);
 301
 302        tsec_eth_init(bis, tsec_info, num);
 303
 304        return pci_eth_init(bis);
 305}
 306
 307#ifdef CONFIG_OF_BOARD_SETUP
 308int ft_board_setup(void *blob, bd_t *bd)
 309{
 310        phys_addr_t base;
 311        phys_size_t size;
 312        const char *soc_usb_compat = "fsl-usb2-dr";
 313        int err, usb1_off, usb2_off;
 314
 315        ft_cpu_setup(blob, bd);
 316
 317        base = env_get_bootm_low();
 318        size = env_get_bootm_size();
 319
 320        fdt_fixup_memory(blob, (u64)base, (u64)size);
 321
 322        FT_FSL_PCI_SETUP;
 323
 324#if defined(CONFIG_HAS_FSL_DR_USB)
 325        fsl_fdt_fixup_dr_usb(blob, bd);
 326#endif
 327
 328#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH)
 329        /* Delete eLBC node as it is muxed with USB2 controller */
 330        if (hwconfig("usb2")) {
 331                const char *soc_elbc_compat = "fsl,p1020-elbc";
 332                int off = fdt_node_offset_by_compatible(blob, -1,
 333                                                        soc_elbc_compat);
 334                if (off < 0) {
 335                        printf
 336                            ("WARNING: could not find compatible node %s: %s\n",
 337                             soc_elbc_compat, fdt_strerror(off));
 338                        return off;
 339                }
 340                err = fdt_del_node(blob, off);
 341                if (err < 0) {
 342                        printf("WARNING: could not remove %s: %s\n",
 343                               soc_elbc_compat, fdt_strerror(err));
 344                }
 345                return err;
 346        }
 347#endif
 348
 349/* Delete USB2 node as it is muxed with eLBC */
 350        usb1_off = fdt_node_offset_by_compatible(blob, -1, soc_usb_compat);
 351        if (usb1_off < 0) {
 352                printf("WARNING: could not find compatible node %s: %s.\n",
 353                       soc_usb_compat, fdt_strerror(usb1_off));
 354                return usb1_off;
 355        }
 356        usb2_off =
 357            fdt_node_offset_by_compatible(blob, usb1_off, soc_usb_compat);
 358        if (usb2_off < 0) {
 359                printf("WARNING: could not find compatible node %s: %s.\n",
 360                       soc_usb_compat, fdt_strerror(usb2_off));
 361                return usb2_off;
 362        }
 363        err = fdt_del_node(blob, usb2_off);
 364        if (err < 0) {
 365                printf("WARNING: could not remove %s: %s.\n",
 366                       soc_usb_compat, fdt_strerror(err));
 367        }
 368        return 0;
 369}
 370#endif
 371