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