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