uboot/board/xilinx/zynqmp/zynqmp.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2014 - 2015 Xilinx, Inc.
   3 * Michal Simek <michal.simek@xilinx.com>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <sata.h>
  10#include <ahci.h>
  11#include <scsi.h>
  12#include <malloc.h>
  13#include <asm/arch/clk.h>
  14#include <asm/arch/hardware.h>
  15#include <asm/arch/sys_proto.h>
  16#include <asm/io.h>
  17#include <usb.h>
  18#include <dwc3-uboot.h>
  19#include <zynqmppl.h>
  20#include <i2c.h>
  21#include <g_dnl.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
  26    !defined(CONFIG_SPL_BUILD)
  27static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
  28
  29static const struct {
  30        uint32_t id;
  31        char *name;
  32} zynqmp_devices[] = {
  33        {
  34                .id = 0x10,
  35                .name = "3eg",
  36        },
  37        {
  38                .id = 0x11,
  39                .name = "2eg",
  40        },
  41        {
  42                .id = 0x20,
  43                .name = "5ev",
  44        },
  45        {
  46                .id = 0x21,
  47                .name = "4ev",
  48        },
  49        {
  50                .id = 0x30,
  51                .name = "7ev",
  52        },
  53        {
  54                .id = 0x38,
  55                .name = "9eg",
  56        },
  57        {
  58                .id = 0x39,
  59                .name = "6eg",
  60        },
  61        {
  62                .id = 0x40,
  63                .name = "11eg",
  64        },
  65        {
  66                .id = 0x50,
  67                .name = "15eg",
  68        },
  69        {
  70                .id = 0x58,
  71                .name = "19eg",
  72        },
  73        {
  74                .id = 0x59,
  75                .name = "17eg",
  76        },
  77};
  78
  79static int chip_id(void)
  80{
  81        struct pt_regs regs;
  82        regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
  83        regs.regs[1] = 0;
  84        regs.regs[2] = 0;
  85        regs.regs[3] = 0;
  86
  87        smc_call(&regs);
  88
  89        /*
  90         * SMC returns:
  91         * regs[0][31:0]  = status of the operation
  92         * regs[0][63:32] = CSU.IDCODE register
  93         * regs[1][31:0]  = CSU.version register
  94         */
  95        regs.regs[0] = upper_32_bits(regs.regs[0]);
  96        regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
  97                        ZYNQMP_CSU_IDCODE_SVD_MASK;
  98        regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
  99
 100        return regs.regs[0];
 101}
 102
 103static char *zynqmp_get_silicon_idcode_name(void)
 104{
 105        uint32_t i, id;
 106
 107        id = chip_id();
 108        for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
 109                if (zynqmp_devices[i].id == id)
 110                        return zynqmp_devices[i].name;
 111        }
 112        return "unknown";
 113}
 114#endif
 115
 116#define ZYNQMP_VERSION_SIZE     9
 117
 118int board_init(void)
 119{
 120        printf("EL Level:\tEL%d\n", current_el());
 121
 122#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
 123    !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
 124    defined(CONFIG_SPL_BUILD))
 125        if (current_el() != 3) {
 126                static char version[ZYNQMP_VERSION_SIZE];
 127
 128                strncat(version, "xczu", ZYNQMP_VERSION_SIZE);
 129                zynqmppl.name = strncat(version,
 130                                        zynqmp_get_silicon_idcode_name(),
 131                                        ZYNQMP_VERSION_SIZE);
 132                printf("Chip ID:\t%s\n", zynqmppl.name);
 133                fpga_init();
 134                fpga_add(fpga_xilinx, &zynqmppl);
 135        }
 136#endif
 137
 138        return 0;
 139}
 140
 141int board_early_init_r(void)
 142{
 143        u32 val;
 144
 145        if (current_el() == 3) {
 146                val = readl(&crlapb_base->timestamp_ref_ctrl);
 147                val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
 148                writel(val, &crlapb_base->timestamp_ref_ctrl);
 149
 150                /* Program freq register in System counter */
 151                writel(zynqmp_get_system_timer_freq(),
 152                       &iou_scntr_secure->base_frequency_id_register);
 153                /* And enable system counter */
 154                writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
 155                       &iou_scntr_secure->counter_control_register);
 156        }
 157        /* Program freq register in System counter and enable system counter */
 158        writel(gd->cpu_clk, &iou_scntr->base_frequency_id_register);
 159        writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG |
 160               ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
 161               &iou_scntr->counter_control_register);
 162
 163        return 0;
 164}
 165
 166int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 167{
 168#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
 169    defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
 170    defined(CONFIG_ZYNQ_EEPROM_BUS)
 171        i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
 172
 173        if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
 174                        CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
 175                        ethaddr, 6))
 176                printf("I2C EEPROM MAC address read failed\n");
 177#endif
 178
 179        return 0;
 180}
 181
 182#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
 183void dram_init_banksize(void)
 184{
 185        fdtdec_setup_memory_banksize();
 186}
 187
 188int dram_init(void)
 189{
 190        if (fdtdec_setup_memory_size() != 0)
 191                return -EINVAL;
 192
 193        return 0;
 194}
 195#else
 196int dram_init(void)
 197{
 198        gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
 199
 200        return 0;
 201}
 202#endif
 203
 204void reset_cpu(ulong addr)
 205{
 206}
 207
 208int board_late_init(void)
 209{
 210        u32 reg = 0;
 211        u8 bootmode;
 212        const char *mode;
 213        char *new_targets;
 214
 215        if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
 216                debug("Saved variables - Skipping\n");
 217                return 0;
 218        }
 219
 220        reg = readl(&crlapb_base->boot_mode);
 221        if (reg >> BOOT_MODE_ALT_SHIFT)
 222                reg >>= BOOT_MODE_ALT_SHIFT;
 223
 224        bootmode = reg & BOOT_MODES_MASK;
 225
 226        puts("Bootmode: ");
 227        switch (bootmode) {
 228        case USB_MODE:
 229                puts("USB_MODE\n");
 230                mode = "usb";
 231                break;
 232        case JTAG_MODE:
 233                puts("JTAG_MODE\n");
 234                mode = "pxe dhcp";
 235                break;
 236        case QSPI_MODE_24BIT:
 237        case QSPI_MODE_32BIT:
 238                mode = "qspi0";
 239                puts("QSPI_MODE\n");
 240                break;
 241        case EMMC_MODE:
 242                puts("EMMC_MODE\n");
 243                mode = "mmc0";
 244                break;
 245        case SD_MODE:
 246                puts("SD_MODE\n");
 247                mode = "mmc0";
 248                break;
 249        case SD1_LSHFT_MODE:
 250                puts("LVL_SHFT_");
 251                /* fall through */
 252        case SD_MODE1:
 253                puts("SD_MODE1\n");
 254#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
 255                mode = "mmc1";
 256#else
 257                mode = "mmc0";
 258#endif
 259                break;
 260        case NAND_MODE:
 261                puts("NAND_MODE\n");
 262                mode = "nand0";
 263                break;
 264        default:
 265                mode = "";
 266                printf("Invalid Boot Mode:0x%x\n", bootmode);
 267                break;
 268        }
 269
 270        /*
 271         * One terminating char + one byte for space between mode
 272         * and default boot_targets
 273         */
 274        new_targets = calloc(1, strlen(mode) +
 275                                strlen(getenv("boot_targets")) + 2);
 276
 277        sprintf(new_targets, "%s %s", mode, getenv("boot_targets"));
 278        setenv("boot_targets", new_targets);
 279
 280        return 0;
 281}
 282
 283int checkboard(void)
 284{
 285        puts("Board: Xilinx ZynqMP\n");
 286        return 0;
 287}
 288
 289#ifdef CONFIG_USB_DWC3
 290static struct dwc3_device dwc3_device_data0 = {
 291        .maximum_speed = USB_SPEED_HIGH,
 292        .base = ZYNQMP_USB0_XHCI_BASEADDR,
 293        .dr_mode = USB_DR_MODE_PERIPHERAL,
 294        .index = 0,
 295};
 296
 297static struct dwc3_device dwc3_device_data1 = {
 298        .maximum_speed = USB_SPEED_HIGH,
 299        .base = ZYNQMP_USB1_XHCI_BASEADDR,
 300        .dr_mode = USB_DR_MODE_PERIPHERAL,
 301        .index = 1,
 302};
 303
 304int usb_gadget_handle_interrupts(int index)
 305{
 306        dwc3_uboot_handle_interrupt(index);
 307        return 0;
 308}
 309
 310int board_usb_init(int index, enum usb_init_type init)
 311{
 312        debug("%s: index %x\n", __func__, index);
 313
 314#if defined(CONFIG_USB_GADGET_DOWNLOAD)
 315        g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME);
 316#endif
 317
 318        switch (index) {
 319        case 0:
 320                return dwc3_uboot_init(&dwc3_device_data0);
 321        case 1:
 322                return dwc3_uboot_init(&dwc3_device_data1);
 323        };
 324
 325        return -1;
 326}
 327
 328int board_usb_cleanup(int index, enum usb_init_type init)
 329{
 330        dwc3_uboot_exit(index);
 331        return 0;
 332}
 333#endif
 334