uboot/arch/arm/mach-socfpga/misc_gen5.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  Copyright (C) 2012-2017 Altera Corporation <www.altera.com>
   4 */
   5
   6#include <common.h>
   7#include <cpu_func.h>
   8#include <init.h>
   9#include <asm/global_data.h>
  10#include <asm/io.h>
  11#include <env.h>
  12#include <errno.h>
  13#include <fdtdec.h>
  14#include <linux/bitops.h>
  15#include <linux/libfdt.h>
  16#include <altera.h>
  17#include <miiphy.h>
  18#include <netdev.h>
  19#include <watchdog.h>
  20#include <asm/arch/misc.h>
  21#include <asm/arch/reset_manager.h>
  22#include <asm/arch/scan_manager.h>
  23#include <asm/arch/sdram.h>
  24#include <asm/arch/system_manager.h>
  25#include <asm/arch/nic301.h>
  26#include <asm/arch/scu.h>
  27#include <asm/pl310.h>
  28
  29#include <dt-bindings/reset/altr,rst-mgr.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33static struct pl310_regs *const pl310 =
  34        (struct pl310_regs *)CFG_SYS_PL310_BASE;
  35static struct nic301_registers *nic301_regs =
  36        (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS;
  37static struct scu_registers *scu_regs =
  38        (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS;
  39
  40/*
  41 * FPGA programming support for SoC FPGA Cyclone V
  42 */
  43static Altera_desc altera_fpga[] = {
  44        {
  45                /* Family */
  46                Altera_SoCFPGA,
  47                /* Interface type */
  48                fast_passive_parallel,
  49                /* No limitation as additional data will be ignored */
  50                -1,
  51                /* No device function table */
  52                NULL,
  53                /* Base interface address specified in driver */
  54                NULL,
  55                /* No cookie implementation */
  56                0
  57        },
  58};
  59
  60static const struct {
  61        const u16       pn;
  62        const char      *name;
  63        const char      *var;
  64} socfpga_fpga_model[] = {
  65        /* Cyclone V E */
  66        { 0x2b15, "Cyclone V, E/A2", "cv_e_a2" },
  67        { 0x2b05, "Cyclone V, E/A4", "cv_e_a4" },
  68        { 0x2b22, "Cyclone V, E/A5", "cv_e_a5" },
  69        { 0x2b13, "Cyclone V, E/A7", "cv_e_a7" },
  70        { 0x2b14, "Cyclone V, E/A9", "cv_e_a9" },
  71        /* Cyclone V GX/GT */
  72        { 0x2b01, "Cyclone V, GX/C3", "cv_gx_c3" },
  73        { 0x2b12, "Cyclone V, GX/C4", "cv_gx_c4" },
  74        { 0x2b02, "Cyclone V, GX/C5 or GT/D5", "cv_gx_c5" },
  75        { 0x2b03, "Cyclone V, GX/C7 or GT/D7", "cv_gx_c7" },
  76        { 0x2b04, "Cyclone V, GX/C9 or GT/D9", "cv_gx_c9" },
  77        /* Cyclone V SE/SX/ST */
  78        { 0x2d11, "Cyclone V, SE/A2 or SX/C2", "cv_se_a2" },
  79        { 0x2d01, "Cyclone V, SE/A4 or SX/C4", "cv_se_a4" },
  80        { 0x2d12, "Cyclone V, SE/A5 or SX/C5 or ST/D5", "cv_se_a5" },
  81        { 0x2d02, "Cyclone V, SE/A6 or SX/C6 or ST/D6", "cv_se_a6" },
  82        /* Arria V */
  83        { 0x2d03, "Arria V, D5", "av_d5" },
  84        /* Arria V ST/SX */
  85        { 0x2d13, "Arria V, ST/D3 or SX/B3", "av_st_d3" },
  86};
  87
  88static int socfpga_fpga_id(const bool print_id)
  89{
  90        const u32 altera_mi = 0x6e;
  91        const u32 id = scan_mgr_get_fpga_id();
  92
  93        const u32 lsb = id & 0x00000001;
  94        const u32 mi = (id >> 1) & 0x000007ff;
  95        const u32 pn = (id >> 12) & 0x0000ffff;
  96        const u32 version = (id >> 28) & 0x0000000f;
  97        int i;
  98
  99        if ((mi != altera_mi) || (lsb != 1)) {
 100                printf("FPGA:  Not Altera chip ID\n");
 101                return -EINVAL;
 102        }
 103
 104        for (i = 0; i < ARRAY_SIZE(socfpga_fpga_model); i++)
 105                if (pn == socfpga_fpga_model[i].pn)
 106                        break;
 107
 108        if (i == ARRAY_SIZE(socfpga_fpga_model)) {
 109                printf("FPGA:  Unknown Altera chip, ID 0x%08x\n", id);
 110                return -EINVAL;
 111        }
 112
 113        if (print_id)
 114                printf("FPGA:  Altera %s, version 0x%01x\n",
 115                       socfpga_fpga_model[i].name, version);
 116        return i;
 117}
 118
 119/*
 120 * Print CPU information
 121 */
 122#if defined(CONFIG_DISPLAY_CPUINFO)
 123int print_cpuinfo(void)
 124{
 125        const u32 bootinfo = readl(socfpga_get_sysmgr_addr() +
 126                                   SYSMGR_GEN5_BOOTINFO);
 127        const u32 bsel = SYSMGR_GET_BOOTINFO_BSEL(bootinfo);
 128
 129        puts("CPU:   Altera SoCFPGA Platform\n");
 130        socfpga_fpga_id(1);
 131
 132        printf("BOOT:  %s\n", bsel_str[bsel].name);
 133        return 0;
 134}
 135#endif
 136
 137#ifdef CONFIG_ARCH_MISC_INIT
 138int arch_misc_init(void)
 139{
 140        const u32 bsel = readl(socfpga_get_sysmgr_addr() +
 141                               SYSMGR_GEN5_BOOTINFO) & 0x7;
 142        const int fpga_id = socfpga_fpga_id(0);
 143        env_set("bootmode", bsel_str[bsel].mode);
 144        if (fpga_id >= 0)
 145                env_set("fpgatype", socfpga_fpga_model[fpga_id].var);
 146        return 0;
 147}
 148#endif
 149
 150/*
 151 * Convert all NIC-301 AMBA slaves from secure to non-secure
 152 */
 153static void socfpga_nic301_slave_ns(void)
 154{
 155        writel(0x1, &nic301_regs->lwhps2fpgaregs);
 156        writel(0x1, &nic301_regs->hps2fpgaregs);
 157        writel(0x1, &nic301_regs->acp);
 158        writel(0x1, &nic301_regs->rom);
 159        writel(0x1, &nic301_regs->ocram);
 160        writel(0x1, &nic301_regs->sdrdata);
 161}
 162
 163void socfpga_sdram_remap_zero(void)
 164{
 165        u32 remap;
 166
 167        socfpga_nic301_slave_ns();
 168
 169        /*
 170         * Private components security:
 171         * U-Boot : configure private timer, global timer and cpu component
 172         * access as non secure for kernel stage (as required by Linux)
 173         */
 174        setbits_le32(&scu_regs->sacr, 0xfff);
 175
 176        /* Configure the L2 controller to make SDRAM start at 0 */
 177        remap = 0x1; /* remap.mpuzero */
 178        /* Keep fpga bridge enabled when running from FPGA onchip RAM */
 179        if (socfpga_is_booting_from_fpga())
 180                remap |= 0x8; /* remap.hps2fpga */
 181        writel(remap, &nic301_regs->remap);
 182
 183        writel(0x1, &pl310->pl310_addr_filter_start);
 184}
 185
 186static u32 iswgrp_handoff[8];
 187
 188int arch_early_init_r(void)
 189{
 190        int i;
 191
 192        /*
 193         * Write magic value into magic register to unlock support for
 194         * issuing warm reset. The ancient kernel code expects this
 195         * value to be written into the register by the bootloader, so
 196         * to support that old code, we write it here instead of in the
 197         * reset_cpu() function just before resetting the CPU.
 198         */
 199        writel(0xae9efebc,
 200               socfpga_get_sysmgr_addr() + SYSMGR_GEN5_WARMRAMGRP_EN);
 201
 202        for (i = 0; i < 8; i++) /* Cache initial SW setting regs */
 203                iswgrp_handoff[i] = readl(socfpga_get_sysmgr_addr() +
 204                                          SYSMGR_ISWGRP_HANDOFF_OFFSET(i));
 205
 206        socfpga_bridges_reset(1);
 207
 208        socfpga_sdram_remap_zero();
 209
 210        /* Add device descriptor to FPGA device table */
 211        socfpga_fpga_add(&altera_fpga[0]);
 212
 213        return 0;
 214}
 215
 216#ifndef CONFIG_SPL_BUILD
 217static struct socfpga_sdr_ctrl *sdr_ctrl =
 218        (struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
 219
 220void do_bridge_reset(int enable, unsigned int mask)
 221{
 222        int i;
 223
 224        if (enable) {
 225                socfpga_bridges_set_handoff_regs(!(mask & BIT(0)),
 226                                                 !(mask & BIT(1)),
 227                                                 !(mask & BIT(2)));
 228                for (i = 0; i < 2; i++) {       /* Reload SW setting cache */
 229                        iswgrp_handoff[i] =
 230                                readl(socfpga_get_sysmgr_addr() +
 231                                      SYSMGR_ISWGRP_HANDOFF_OFFSET(i));
 232                }
 233
 234                writel(iswgrp_handoff[2],
 235                       socfpga_get_sysmgr_addr() +
 236                       SYSMGR_GEN5_FPGAINFGRP_MODULE);
 237                writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
 238                writel(iswgrp_handoff[0],
 239                       socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
 240                writel(iswgrp_handoff[1], &nic301_regs->remap);
 241
 242                writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
 243                writel(iswgrp_handoff[0],
 244                       socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
 245        } else {
 246                writel(0, socfpga_get_sysmgr_addr() +
 247                       SYSMGR_GEN5_FPGAINFGRP_MODULE);
 248                writel(0, &sdr_ctrl->fpgaport_rst);
 249                writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
 250                writel(1, &nic301_regs->remap);
 251        }
 252}
 253#endif
 254