uboot/arch/arm/mach-kirkwood/cpu.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Marvell Semiconductor <www.marvell.com>
   4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <netdev.h>
  11#include <asm/cache.h>
  12#include <asm/io.h>
  13#include <asm/arch/cpu.h>
  14#include <asm/arch/soc.h>
  15#include <mvebu_mmc.h>
  16
  17void reset_cpu(unsigned long ignored)
  18{
  19        struct kwcpu_registers *cpureg =
  20            (struct kwcpu_registers *)KW_CPU_REG_BASE;
  21
  22        writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
  23                &cpureg->rstoutn_mask);
  24        writel(readl(&cpureg->sys_soft_rst) | 1,
  25                &cpureg->sys_soft_rst);
  26        while (1) ;
  27}
  28
  29/*
  30 * Window Size
  31 * Used with the Base register to set the address window size and location.
  32 * Must be programmed from LSB to MSB as sequence of ones followed by
  33 * sequence of zeros. The number of ones specifies the size of the window in
  34 * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
  35 * NOTE: A value of 0x0 specifies 64-KByte size.
  36 */
  37unsigned int kw_winctrl_calcsize(unsigned int sizeval)
  38{
  39        int i;
  40        unsigned int j = 0;
  41        u32 val = sizeval >> 1;
  42
  43        for (i = 0; val >= 0x10000; i++) {
  44                j |= (1 << i);
  45                val = val >> 1;
  46        }
  47        return (0x0000ffff & j);
  48}
  49
  50/*
  51 * kw_config_adr_windows - Configure address Windows
  52 *
  53 * There are 8 address windows supported by Kirkwood Soc to addess different
  54 * devices. Each window can be configured for size, BAR and remap addr
  55 * Below configuration is standard for most of the cases
  56 *
  57 * If remap function not used, remap_lo must be set as base
  58 *
  59 * Reference Documentation:
  60 * Mbus-L to Mbus Bridge Registers Configuration.
  61 * (Sec 25.1 and 25.3 of Datasheet)
  62 */
  63int kw_config_adr_windows(void)
  64{
  65        struct kwwin_registers *winregs =
  66                (struct kwwin_registers *)KW_CPU_WIN_BASE;
  67
  68        /* Window 0: PCIE MEM address space */
  69        writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE,
  70                KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl);
  71
  72        writel(KW_DEFADR_PCI_MEM, &winregs[0].base);
  73        writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo);
  74        writel(0x0, &winregs[0].remap_hi);
  75
  76        /* Window 1: PCIE IO address space */
  77        writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE,
  78                KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl);
  79        writel(KW_DEFADR_PCI_IO, &winregs[1].base);
  80        writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo);
  81        writel(0x0, &winregs[1].remap_hi);
  82
  83        /* Window 2: NAND Flash address space */
  84        writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
  85                KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl);
  86        writel(KW_DEFADR_NANDF, &winregs[2].base);
  87        writel(KW_DEFADR_NANDF, &winregs[2].remap_lo);
  88        writel(0x0, &winregs[2].remap_hi);
  89
  90        /* Window 3: SPI Flash address space */
  91        writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
  92                KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl);
  93        writel(KW_DEFADR_SPIF, &winregs[3].base);
  94        writel(KW_DEFADR_SPIF, &winregs[3].remap_lo);
  95        writel(0x0, &winregs[3].remap_hi);
  96
  97        /* Window 4: BOOT Memory address space */
  98        writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
  99                KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl);
 100        writel(KW_DEFADR_BOOTROM, &winregs[4].base);
 101
 102        /* Window 5: Security SRAM address space */
 103        writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM,
 104                KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl);
 105        writel(KW_DEFADR_SASRAM, &winregs[5].base);
 106
 107        /* Window 6-7: Disabled */
 108        writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl);
 109        writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl);
 110
 111        return 0;
 112}
 113
 114/*
 115 * SYSRSTn Duration Counter Support
 116 *
 117 * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
 118 * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
 119 * The SYSRSTn duration counter is useful for implementing a manufacturer
 120 * or factory reset. Upon a long reset assertion that is greater than a
 121 * pre-configured environment variable value for sysrstdelay,
 122 * The counter value is stored in the SYSRSTn Length Counter Register
 123 * The counter is based on the 25-MHz reference clock (40ns)
 124 * It is a 29-bit counter, yielding a maximum counting duration of
 125 * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
 126 * it remains at this value until counter reset is triggered by setting
 127 * bit 31 of KW_REG_SYSRST_CNT
 128 */
 129static void kw_sysrst_action(void)
 130{
 131        int ret;
 132        char *s = env_get("sysrstcmd");
 133
 134        if (!s) {
 135                debug("Error.. %s failed, check sysrstcmd\n",
 136                        __FUNCTION__);
 137                return;
 138        }
 139
 140        debug("Starting %s process...\n", __FUNCTION__);
 141        ret = run_command(s, 0);
 142        if (ret != 0)
 143                debug("Error.. %s failed\n", __FUNCTION__);
 144        else
 145                debug("%s process finished\n", __FUNCTION__);
 146}
 147
 148static void kw_sysrst_check(void)
 149{
 150        u32 sysrst_cnt, sysrst_dly;
 151        char *s;
 152
 153        /*
 154         * no action if sysrstdelay environment variable is not defined
 155         */
 156        s = env_get("sysrstdelay");
 157        if (s == NULL)
 158                return;
 159
 160        /* read sysrstdelay value */
 161        sysrst_dly = (u32) simple_strtoul(s, NULL, 10);
 162
 163        /* read SysRst Length counter register (bits 28:0) */
 164        sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT));
 165        debug("H/w Rst hold time: %d.%d secs\n",
 166                sysrst_cnt / SYSRST_CNT_1SEC_VAL,
 167                sysrst_cnt % SYSRST_CNT_1SEC_VAL);
 168
 169        /* clear the counter for next valid read*/
 170        writel(1 << 31, KW_REG_SYSRST_CNT);
 171
 172        /*
 173         * sysrst_action:
 174         * if H/w Reset key is pressed and hold for time
 175         * more than sysrst_dly in seconds
 176         */
 177        if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly)
 178                kw_sysrst_action();
 179}
 180
 181#if defined(CONFIG_DISPLAY_CPUINFO)
 182int print_cpuinfo(void)
 183{
 184        char *rev = "??";
 185        u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff;
 186        u8 revid = readl(KW_REG_PCIE_REVID) & 0xff;
 187
 188        if ((readl(KW_REG_DEVICE_ID) & 0x03) > 2) {
 189                printf("Error.. %s:Unsupported Kirkwood SoC 88F%04x\n", __FUNCTION__, devid);
 190                return -1;
 191        }
 192
 193        switch (revid) {
 194        case 0:
 195                if (devid == 0x6281)
 196                        rev = "Z0";
 197                else if (devid == 0x6282)
 198                        rev = "A0";
 199                break;
 200        case 1:
 201                rev = "A1";
 202                break;
 203        case 2:
 204                rev = "A0";
 205                break;
 206        case 3:
 207                rev = "A1";
 208                break;
 209        default:
 210                break;
 211        }
 212
 213        printf("SoC:   Kirkwood 88F%04x_%s\n", devid, rev);
 214        return 0;
 215}
 216#endif /* CONFIG_DISPLAY_CPUINFO */
 217
 218#ifdef CONFIG_ARCH_CPU_INIT
 219int arch_cpu_init(void)
 220{
 221        u32 reg;
 222        struct kwcpu_registers *cpureg =
 223                (struct kwcpu_registers *)KW_CPU_REG_BASE;
 224
 225        /* Linux expects` the internal registers to be at 0xf1000000 */
 226        writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
 227
 228        /* Enable and invalidate L2 cache in write through mode */
 229        writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
 230        invalidate_l2_cache();
 231
 232        kw_config_adr_windows();
 233
 234#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
 235        /*
 236         * Configures the I/O voltage of the pads connected to Egigabit
 237         * Ethernet interface to 1.8V
 238         * By default it is set to 3.3V
 239         */
 240        reg = readl(KW_REG_MPP_OUT_DRV_REG);
 241        reg |= (1 << 7);
 242        writel(reg, KW_REG_MPP_OUT_DRV_REG);
 243#endif
 244#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
 245        /*
 246         * Set egiga port0/1 in normal functional mode
 247         * This is required becasue on kirkwood by default ports are in reset mode
 248         * OS egiga driver may not have provision to set them in normal mode
 249         * and if u-boot is build without network support, network may fail at OS level
 250         */
 251        reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0));
 252        reg &= ~(1 << 4);       /* Clear PortReset Bit */
 253        writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0)));
 254        reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1));
 255        reg &= ~(1 << 4);       /* Clear PortReset Bit */
 256        writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1)));
 257#endif
 258#ifdef CONFIG_KIRKWOOD_PCIE_INIT
 259        /*
 260         * Enable PCI Express Port0
 261         */
 262        reg = readl(&cpureg->ctrl_stat);
 263        reg |= (1 << 0);        /* Set PEX0En Bit */
 264        writel(reg, &cpureg->ctrl_stat);
 265#endif
 266        return 0;
 267}
 268#endif /* CONFIG_ARCH_CPU_INIT */
 269
 270/*
 271 * SOC specific misc init
 272 */
 273#if defined(CONFIG_ARCH_MISC_INIT)
 274int arch_misc_init(void)
 275{
 276        volatile u32 temp;
 277
 278        /*CPU streaming & write allocate */
 279        temp = readfr_extra_feature_reg();
 280        temp &= ~(1 << 28);     /* disable wr alloc */
 281        writefr_extra_feature_reg(temp);
 282
 283        temp = readfr_extra_feature_reg();
 284        temp &= ~(1 << 29);     /* streaming disabled */
 285        writefr_extra_feature_reg(temp);
 286
 287        /* L2Cache settings */
 288        temp = readfr_extra_feature_reg();
 289        /* Disable L2C pre fetch - Set bit 24 */
 290        temp |= (1 << 24);
 291        /* enable L2C - Set bit 22 */
 292        temp |= (1 << 22);
 293        writefr_extra_feature_reg(temp);
 294
 295        icache_enable();
 296        /* Change reset vector to address 0x0 */
 297        temp = get_cr();
 298        set_cr(temp & ~CR_V);
 299
 300        /* checks and execute resset to factory event */
 301        kw_sysrst_check();
 302
 303        return 0;
 304}
 305#endif /* CONFIG_ARCH_MISC_INIT */
 306
 307#ifdef CONFIG_MVGBE
 308int cpu_eth_init(bd_t *bis)
 309{
 310        mvgbe_initialize(bis);
 311        return 0;
 312}
 313#endif
 314
 315#ifdef CONFIG_MVEBU_MMC
 316int board_mmc_init(bd_t *bis)
 317{
 318        mvebu_mmc_init(bis);
 319        return 0;
 320}
 321#endif /* CONFIG_MVEBU_MMC */
 322