uboot/arch/arm/cpu/armv7/ls102xa/cpu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2014 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <cpu_func.h>
   8#include <init.h>
   9#include <net.h>
  10#include <vsprintf.h>
  11#include <asm/arch/clock.h>
  12#include <asm/global_data.h>
  13#include <asm/io.h>
  14#include <asm/arch/immap_ls102xa.h>
  15#include <asm/cache.h>
  16#include <asm/system.h>
  17#include <tsec.h>
  18#include <netdev.h>
  19#include <fsl_esdhc.h>
  20#include <config.h>
  21#include <fsl_wdog.h>
  22#include <linux/delay.h>
  23
  24#include "fsl_epu.h"
  25
  26#define DCSR_RCPM2_BLOCK_OFFSET 0x223000
  27#define DCSR_RCPM2_CPMFSMCR0    0x400
  28#define DCSR_RCPM2_CPMFSMSR0    0x404
  29#define DCSR_RCPM2_CPMFSMCR1    0x414
  30#define DCSR_RCPM2_CPMFSMSR1    0x418
  31#define CPMFSMSR_FSM_STATE_MASK 0x7f
  32
  33DECLARE_GLOBAL_DATA_PTR;
  34
  35#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  36
  37/*
  38 * Bit[1] of the descriptor indicates the descriptor type,
  39 * and bit[0] indicates whether the descriptor is valid.
  40 */
  41#define PMD_TYPE_TABLE          0x3
  42#define PMD_TYPE_SECT           0x1
  43
  44/* AttrIndx[2:0] */
  45#define PMD_ATTRINDX(t)         ((t) << 2)
  46
  47/* Section */
  48#define PMD_SECT_AF             (1 << 10)
  49
  50#define BLOCK_SIZE_L1           (1UL << 30)
  51#define BLOCK_SIZE_L2           (1UL << 21)
  52
  53/* TTBCR flags */
  54#define TTBCR_EAE               (1 << 31)
  55#define TTBCR_T0SZ(x)           ((x) << 0)
  56#define TTBCR_T1SZ(x)           ((x) << 16)
  57#define TTBCR_USING_TTBR0       (TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
  58#define TTBCR_IRGN0_NC          (0 << 8)
  59#define TTBCR_IRGN0_WBWA        (1 << 8)
  60#define TTBCR_IRGN0_WT          (2 << 8)
  61#define TTBCR_IRGN0_WBNWA       (3 << 8)
  62#define TTBCR_IRGN0_MASK        (3 << 8)
  63#define TTBCR_ORGN0_NC          (0 << 10)
  64#define TTBCR_ORGN0_WBWA        (1 << 10)
  65#define TTBCR_ORGN0_WT          (2 << 10)
  66#define TTBCR_ORGN0_WBNWA       (3 << 10)
  67#define TTBCR_ORGN0_MASK        (3 << 10)
  68#define TTBCR_SHARED_NON        (0 << 12)
  69#define TTBCR_SHARED_OUTER      (2 << 12)
  70#define TTBCR_SHARED_INNER      (3 << 12)
  71#define TTBCR_EPD0              (0 << 7)
  72#define TTBCR                   (TTBCR_SHARED_NON | \
  73                                 TTBCR_ORGN0_NC | \
  74                                 TTBCR_IRGN0_NC | \
  75                                 TTBCR_USING_TTBR0 | \
  76                                 TTBCR_EAE)
  77
  78/*
  79 * Memory region attributes for LPAE (defined in pgtable):
  80 *
  81 * n = AttrIndx[2:0]
  82 *
  83 *                            n       MAIR
  84 *      UNCACHED              000     00000000
  85 *      BUFFERABLE            001     01000100
  86 *      DEV_WC                001     01000100
  87 *      WRITETHROUGH          010     10101010
  88 *      WRITEBACK             011     11101110
  89 *      DEV_CACHED            011     11101110
  90 *      DEV_SHARED            100     00000100
  91 *      DEV_NONSHARED         100     00000100
  92 *      unused                101
  93 *      unused                110
  94 *      WRITEALLOC            111     11111111
  95 */
  96#define MT_MAIR0                0xeeaa4400
  97#define MT_MAIR1                0xff000004
  98#define MT_STRONLY_ORDER        0
  99#define MT_NORMAL_NC            1
 100#define MT_DEVICE_MEM           4
 101#define MT_NORMAL               7
 102
 103/* The phy_addr must be aligned to 4KB */
 104static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr)
 105{
 106        u32 value = phy_addr | PMD_TYPE_TABLE;
 107
 108        page_table[2 * index] = value;
 109        page_table[2 * index + 1] = 0;
 110}
 111
 112/* The phy_addr must be aligned to 4KB */
 113static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr,
 114                                 u32 memory_type)
 115{
 116        u64 value;
 117
 118        value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF;
 119        value |= PMD_ATTRINDX(memory_type);
 120        page_table[2 * index] = value & 0xFFFFFFFF;
 121        page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF;
 122}
 123
 124/*
 125 * Start MMU after DDR is available, we create MMU table in DRAM.
 126 * The base address of TTLB is gd->arch.tlb_addr. We use two
 127 * levels of translation tables here to cover 40-bit address space.
 128 *
 129 * The TTLBs are located at PHY 2G~4G.
 130 *
 131 * VA mapping:
 132 *
 133 *  -------  <---- 0GB
 134 * |       |
 135 * |       |
 136 * |-------| <---- 0x24000000
 137 * |///////|  ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000
 138 * |-------| <---- 0x300000000
 139 * |       |
 140 * |-------| <---- 0x34000000
 141 * |///////|  ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000
 142 * |-------| <---- 0x40000000
 143 * |       |
 144 * |-------| <---- 0x80000000 DDR0 space start
 145 * |\\\\\\\|
 146 *.|\\\\\\\|  ===> 2GB VA map for 2GB DDR0 Memory space
 147 * |\\\\\\\|
 148 *  -------  <---- 4GB DDR0 space end
 149 */
 150static void mmu_setup(void)
 151{
 152        u32 *level0_table = (u32 *)gd->arch.tlb_addr;
 153        u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000);
 154        u64 va_start = 0;
 155        u32 reg;
 156        int i;
 157
 158        /* Level 0 Table 2-3 are used to map DDR */
 159        set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL);
 160        set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL);
 161        /* Level 0 Table 1 is used to map device */
 162        set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM);
 163        /* Level 0 Table 0 is used to map device including PCIe MEM */
 164        set_pgtable(level0_table, 0, (u32)level1_table);
 165
 166        /* Level 1 has 512 entries */
 167        for (i = 0; i < 512; i++) {
 168                /* Mapping for PCIe 1 */
 169                if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR &&
 170                    va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR +
 171                                 CONFIG_SYS_PCIE_MMAP_SIZE))
 172                        set_pgsection(level1_table, i,
 173                                      CONFIG_SYS_PCIE1_PHYS_BASE + va_start,
 174                                      MT_DEVICE_MEM);
 175                /* Mapping for PCIe 2 */
 176                else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR &&
 177                         va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR +
 178                                     CONFIG_SYS_PCIE_MMAP_SIZE))
 179                        set_pgsection(level1_table, i,
 180                                      CONFIG_SYS_PCIE2_PHYS_BASE + va_start,
 181                                      MT_DEVICE_MEM);
 182                else
 183                        set_pgsection(level1_table, i,
 184                                      va_start,
 185                                      MT_DEVICE_MEM);
 186                va_start += BLOCK_SIZE_L2;
 187        }
 188
 189        asm volatile("dsb sy;isb");
 190        asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */
 191                        : : "r" (TTBCR) : "memory");
 192        asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */
 193                        : : "r" ((u32)level0_table), "r" (0) : "memory");
 194        asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */
 195                        : : "r" (MT_MAIR0) : "memory");
 196        asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */
 197                        : : "r" (MT_MAIR1) : "memory");
 198
 199        /* Set the access control to all-supervisor */
 200        asm volatile("mcr p15, 0, %0, c3, c0, 0"
 201                     : : "r" (~0));
 202
 203        /* Enable the mmu */
 204        reg = get_cr();
 205        set_cr(reg | CR_M);
 206}
 207
 208/*
 209 * This function is called from lib/board.c. It recreates MMU
 210 * table in main memory. MMU and i/d-cache are enabled here.
 211 */
 212void enable_caches(void)
 213{
 214        /* Invalidate all TLB */
 215        mmu_page_table_flush(gd->arch.tlb_addr,
 216                             gd->arch.tlb_addr +  gd->arch.tlb_size);
 217        /* Set up and enable mmu */
 218        mmu_setup();
 219
 220        /* Invalidate & Enable d-cache */
 221        invalidate_dcache_all();
 222        set_cr(get_cr() | CR_C);
 223}
 224#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
 225
 226
 227uint get_svr(void)
 228{
 229        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 230
 231        return in_be32(&gur->svr);
 232}
 233
 234#if defined(CONFIG_DISPLAY_CPUINFO)
 235int print_cpuinfo(void)
 236{
 237        char buf1[32], buf2[32];
 238        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 239        unsigned int svr, major, minor, ver, i;
 240
 241        svr = in_be32(&gur->svr);
 242        major = SVR_MAJ(svr);
 243        minor = SVR_MIN(svr);
 244
 245        puts("CPU:   Freescale LayerScape ");
 246
 247        ver = SVR_SOC_VER(svr);
 248        switch (ver) {
 249        case SOC_VER_SLS1020:
 250                puts("SLS1020");
 251                break;
 252        case SOC_VER_LS1020:
 253                puts("LS1020");
 254                break;
 255        case SOC_VER_LS1021:
 256                puts("LS1021");
 257                break;
 258        case SOC_VER_LS1022:
 259                puts("LS1022");
 260                break;
 261        default:
 262                puts("Unknown");
 263                break;
 264        }
 265
 266        if (IS_E_PROCESSOR(svr) && (ver != SOC_VER_SLS1020))
 267                puts("E");
 268
 269        printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
 270
 271        puts("Clock Configuration:");
 272
 273        printf("\n       CPU0(ARMV7):%-4s MHz, ", strmhz(buf1, gd->cpu_clk));
 274        printf("\n       Bus:%-4s MHz, ", strmhz(buf1, gd->bus_clk));
 275        printf("DDR:%-4s MHz (%s MT/s data rate), ",
 276               strmhz(buf1, gd->mem_clk/2), strmhz(buf2, gd->mem_clk));
 277        puts("\n");
 278
 279        /* Display the RCW, so that no one gets confused as to what RCW
 280         * we're actually using for this boot.
 281         */
 282        puts("Reset Configuration Word (RCW):");
 283        for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
 284                u32 rcw = in_be32(&gur->rcwsr[i]);
 285
 286                if ((i % 4) == 0)
 287                        printf("\n       %08x:", i * 4);
 288                printf(" %08x", rcw);
 289        }
 290        puts("\n");
 291
 292        return 0;
 293}
 294#endif
 295
 296#ifdef CONFIG_FSL_ESDHC
 297int cpu_mmc_init(struct bd_info *bis)
 298{
 299        return fsl_esdhc_mmc_init(bis);
 300}
 301#endif
 302
 303int cpu_eth_init(struct bd_info *bis)
 304{
 305#if defined(CONFIG_TSEC_ENET) && !defined(CONFIG_DM_ETH)
 306        tsec_standard_init(bis);
 307#endif
 308
 309        return 0;
 310}
 311
 312int arch_cpu_init(void)
 313{
 314        void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
 315        void *rcpm2_base =
 316                (void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET);
 317        struct ccsr_scfg *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
 318        u32 state;
 319
 320        icache_enable();
 321
 322        /*
 323         * The RCPM FSM state may not be reset after power-on.
 324         * So, reset them.
 325         */
 326        state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) &
 327                CPMFSMSR_FSM_STATE_MASK;
 328        if (state != 0) {
 329                out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80);
 330                out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0);
 331        }
 332
 333        state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) &
 334                CPMFSMSR_FSM_STATE_MASK;
 335        if (state != 0) {
 336                out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80);
 337                out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0);
 338        }
 339
 340        /*
 341         * After wakeup from deep sleep, Clear EPU registers
 342         * as early as possible to prevent from possible issue.
 343         * It's also safe to clear at normal boot.
 344         */
 345        fsl_epu_clean(epu_base);
 346
 347        setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR);
 348
 349        return 0;
 350}
 351
 352#ifdef CONFIG_ARMV7_NONSEC
 353/* Set the address at which the secondary core starts from.*/
 354void smp_set_core_boot_addr(unsigned long addr, int corenr)
 355{
 356        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 357
 358        out_be32(&gur->scratchrw[0], addr);
 359}
 360
 361/* Release the secondary core from holdoff state and kick it */
 362void smp_kick_all_cpus(void)
 363{
 364        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 365
 366        out_be32(&gur->brrl, 0x2);
 367
 368        /*
 369         * LS1 STANDBYWFE is not captured outside the ARM module in the soc.
 370         * So add a delay to wait bootrom execute WFE.
 371         */
 372        udelay(1);
 373
 374        asm volatile("sev");
 375}
 376#endif
 377
 378void reset_cpu(void)
 379{
 380        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 381
 382        clrbits_be16(&wdog->wcr, WCR_SRS);
 383
 384        while (1) {
 385                /*
 386                 * Let the watchdog trigger
 387                 */
 388        }
 389}
 390
 391void arch_preboot_os(void)
 392{
 393        unsigned long ctrl;
 394
 395        /* Disable PL1 Physical Timer */
 396        asm("mrc p15, 0, %0, c14, c2, 1" : "=r" (ctrl));
 397        ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
 398        asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl));
 399}
 400