diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/arch/arm/cpu/arm926ejs/orion5x | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/arm926ejs/orion5x')
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/Makefile | 18 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/cpu.c | 295 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/dram.c | 55 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S | 277 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/timer.c | 171 | 
5 files changed, 816 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/Makefile new file mode 100644 index 00000000..546ebcb5 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> +# +# Based on original Kirkwood support which is +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	= cpu.o +obj-y	+= dram.o +obj-y	+= timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y	+= lowlevel_init.o +endif diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/cpu.c new file mode 100644 index 00000000..b55c5f09 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/cpu.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * Based on original Kirkwood support which is + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <u-boot/md5.h> +#include <asm/arch/cpu.h> +#include <hush.h> + +#define BUFLEN	16 + +void reset_cpu(unsigned long ignored) +{ +	struct orion5x_cpu_registers *cpureg = +	    (struct orion5x_cpu_registers *)ORION5X_CPU_REG_BASE; + +	writel(readl(&cpureg->rstoutn_mask) | (1 << 2), +		&cpureg->rstoutn_mask); +	writel(readl(&cpureg->sys_soft_rst) | 1, +		&cpureg->sys_soft_rst); +	while (1) +		; +} + +/* + * Compute Window Size field value from size expressed in bytes + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of ones followed by + * sequence of zeros. The number of ones specifies the size of the window in + * 64 KiB granularity (e.g., a value of 0x00FF specifies 256 = 16 MiB). + * NOTES: + * 1) A sizeval equal to 0x0 specifies 4 GiB. + * 2) A return value of 0x0 specifies 64 KiB. + */ +unsigned int orion5x_winctrl_calcsize(unsigned int sizeval) +{ +	/* +	 * Calculate the number of 64 KiB blocks needed minus one (rounding up). +	 * For sizeval > 0 this is equivalent to: +	 * sizeval = (u32) ceil((double) sizeval / 65536.0) - 1 +	 */ +	sizeval = (sizeval - 1) >> 16; + +	/* +	 * Propagate 'one' bits to the right by 'oring' them. +	 * We need only treat bits 15-0. +	 */ +	sizeval |= sizeval >> 1;  /* 'Or' bit 15 onto bit 14 */ +	sizeval |= sizeval >> 2;  /* 'Or' bits 15-14 onto bits 13-12 */ +	sizeval |= sizeval >> 4;  /* 'Or' bits 15-12 onto bits 11-8 */ +	sizeval |= sizeval >> 8;  /* 'Or' bits 15-8 onto bits 7-0*/ + +	return sizeval; +} + +/* + * orion5x_config_adr_windows - Configure address Windows + * + * There are 8 address windows supported by Orion5x Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * If remap function not used, remap_lo must be set as base + * + * NOTES: + * + * 1) in order to avoid windows with inconsistent control and base values + *    (which could prevent access to BOOTCS and hence execution from FLASH) + *    always disable window before writing the base value then reenable it + *    by writing the control value. + * + * 2) in order to avoid losing access to BOOTCS when disabling window 7, + *    first configure window 6 for BOOTCS, then configure window 7 for BOOTCS, + *    then configure windows 6 for its own target. + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int orion5x_config_adr_windows(void) +{ +	struct orion5x_win_registers *winregs = +		(struct orion5x_win_registers *)ORION5X_CPU_WIN_BASE; + +/* Disable window 0, configure it for its intended target, enable it. */ +	writel(0, &winregs[0].ctrl); +	writel(ORION5X_ADR_PCIE_MEM, &winregs[0].base); +	writel(ORION5X_ADR_PCIE_MEM_REMAP_LO, &winregs[0].remap_lo); +	writel(ORION5X_ADR_PCIE_MEM_REMAP_HI, &winregs[0].remap_hi); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_MEM, +		ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_MEM, +		ORION5X_WIN_ENABLE), &winregs[0].ctrl); +/* Disable window 1, configure it for its intended target, enable it. */ +	writel(0, &winregs[1].ctrl); +	writel(ORION5X_ADR_PCIE_IO, &winregs[1].base); +	writel(ORION5X_ADR_PCIE_IO_REMAP_LO, &winregs[1].remap_lo); +	writel(ORION5X_ADR_PCIE_IO_REMAP_HI, &winregs[1].remap_hi); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_IO, +		ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_IO, +		ORION5X_WIN_ENABLE), &winregs[1].ctrl); +/* Disable window 2, configure it for its intended target, enable it. */ +	writel(0, &winregs[2].ctrl); +	writel(ORION5X_ADR_PCI_MEM, &winregs[2].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_MEM, +		ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_MEM, +		ORION5X_WIN_ENABLE), &winregs[2].ctrl); +/* Disable window 3, configure it for its intended target, enable it. */ +	writel(0, &winregs[3].ctrl); +	writel(ORION5X_ADR_PCI_IO, &winregs[3].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_IO, +		ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_IO, +		ORION5X_WIN_ENABLE), &winregs[3].ctrl); +/* Disable window 4, configure it for its intended target, enable it. */ +	writel(0, &winregs[4].ctrl); +	writel(ORION5X_ADR_DEV_CS0, &winregs[4].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS0, +		ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS0, +		ORION5X_WIN_ENABLE), &winregs[4].ctrl); +/* Disable window 5, configure it for its intended target, enable it. */ +	writel(0, &winregs[5].ctrl); +	writel(ORION5X_ADR_DEV_CS1, &winregs[5].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS1, +		ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS1, +		ORION5X_WIN_ENABLE), &winregs[5].ctrl); +/* Disable window 6, configure it for FLASH, enable it. */ +	writel(0, &winregs[6].ctrl); +	writel(ORION5X_ADR_BOOTROM, &winregs[6].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, +		ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, +		ORION5X_WIN_ENABLE), &winregs[6].ctrl); +/* Disable window 7, configure it for FLASH, enable it. */ +	writel(0, &winregs[7].ctrl); +	writel(ORION5X_ADR_BOOTROM, &winregs[7].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, +		ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, +		ORION5X_WIN_ENABLE), &winregs[7].ctrl); +/* Disable window 6, configure it for its intended target, enable it. */ +	writel(0, &winregs[6].ctrl); +	writel(ORION5X_ADR_DEV_CS2, &winregs[6].base); +	writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS2, +		ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS2, +		ORION5X_WIN_ENABLE), &winregs[6].ctrl); + +	return 0; +} + +/* + * Orion5x identification is done through PCIE space. + */ + +u32 orion5x_device_id(void) +{ +	return readl(PCIE_DEV_ID_OFF) >> 16; +} + +u32 orion5x_device_rev(void) +{ +	return readl(PCIE_DEV_REV_OFF) & 0xff; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) + +/* Display device and revision IDs. + * This function must cover all known device/revision + * combinations, not only the one for which u-boot is + * compiled; this way, one can identify actual HW in + * case of a mismatch. + */ +int print_cpuinfo(void) +{ +	char dev_str[7]; /* room enough for 0x0000 plus null byte */ +	char rev_str[5]; /* room enough for 0x00 plus null byte */ +	char *dev_name = NULL; +	char *rev_name = NULL; + +	u32 dev = orion5x_device_id(); +	u32 rev = orion5x_device_rev(); + +	if (dev == MV88F5181_DEV_ID) { +		dev_name = "MV88F5181"; +		if (rev == MV88F5181_REV_B1) +			rev_name = "B1"; +		else if (rev == MV88F5181L_REV_A1) { +			dev_name = "MV88F5181L"; +			rev_name = "A1"; +		} else if (rev == MV88F5181L_REV_A0) { +			dev_name = "MV88F5181L"; +			rev_name = "A0"; +		} +	} else if (dev == MV88F5182_DEV_ID) { +		dev_name = "MV88F5182"; +		if (rev == MV88F5182_REV_A2) +			rev_name = "A2"; +	} else if (dev == MV88F5281_DEV_ID) { +		dev_name = "MV88F5281"; +		if (rev == MV88F5281_REV_D2) +			rev_name = "D2"; +		else if (rev == MV88F5281_REV_D1) +			rev_name = "D1"; +		else if (rev == MV88F5281_REV_D0) +			rev_name = "D0"; +	} else if (dev == MV88F6183_DEV_ID) { +		dev_name = "MV88F6183"; +		if (rev == MV88F6183_REV_B0) +			rev_name = "B0"; +	} +	if (dev_name == NULL) { +		sprintf(dev_str, "0x%04x", dev); +		dev_name = dev_str; +	} +	if (rev_name == NULL) { +		sprintf(rev_str, "0x%02x", rev); +		rev_name = rev_str; +	} + +	printf("SoC:   Orion5x %s-%s\n", dev_name, rev_name); + +	return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ +	/* Enable and invalidate L2 cache in write through mode */ +	invalidate_l2_cache(); + +	orion5x_config_adr_windows(); + +	return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ +	u32 temp; + +	/*CPU streaming & write allocate */ +	temp = readfr_extra_feature_reg(); +	temp &= ~(1 << 28);	/* disable wr alloc */ +	writefr_extra_feature_reg(temp); + +	temp = readfr_extra_feature_reg(); +	temp &= ~(1 << 29);	/* streaming disabled */ +	writefr_extra_feature_reg(temp); + +	/* L2Cache settings */ +	temp = readfr_extra_feature_reg(); +	/* Disable L2C pre fetch - Set bit 24 */ +	temp |= (1 << 24); +	/* enable L2C - Set bit 22 */ +	temp |= (1 << 22); +	writefr_extra_feature_reg(temp); + +	icache_enable(); +	/* Change reset vector to address 0x0 */ +	temp = get_cr(); +	set_cr(temp & ~CR_V); + +	/* Set CPIOs and MPPs - values provided by board +	   include file */ +	writel(ORION5X_MPP0_7, ORION5X_MPP_BASE+0x00); +	writel(ORION5X_MPP8_15, ORION5X_MPP_BASE+0x04); +	writel(ORION5X_MPP16_23, ORION5X_MPP_BASE+0x50); +	writel(ORION5X_GPIO_OUT_VALUE, ORION5X_GPIO_BASE+0x00); +	writel(ORION5X_GPIO_OUT_ENABLE, ORION5X_GPIO_BASE+0x04); +	writel(ORION5X_GPIO_IN_POLARITY, ORION5X_GPIO_BASE+0x0c); + +	/* initialize timer */ +	timer_init_r(); +	return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_MVGBE +int cpu_eth_init(bd_t *bis) +{ +	mvgbe_initialize(bis); +	return 0; +} +#endif diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/dram.c b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/dram.c new file mode 100644 index 00000000..9ed93d25 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/dram.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * Based on original Kirkwood support which is + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/arch/cpu.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * orion5x_sdram_bar - reads SDRAM Base Address Register + */ +u32 orion5x_sdram_bar(enum memory_bank bank) +{ +	struct orion5x_ddr_addr_decode_registers *winregs = +		(struct orion5x_ddr_addr_decode_registers *) +		ORION5X_DRAM_BASE; + +	u32 result = 0; +	u32 enable = 0x01 & winregs[bank].size; + +	if ((!enable) || (bank > BANK3)) +		return 0; + +	result = winregs[bank].base; +	return result; +} +int dram_init (void) +{ +	/* dram_init must store complete ramsize in gd->ram_size */ +	gd->ram_size = get_ram_size( +			(long *) orion5x_sdram_bar(0), +			CONFIG_MAX_RAM_BANK_SIZE); +	return 0; +} + +void dram_init_banksize (void) +{ +	int i; + +	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { +		gd->bd->bi_dram[i].start = orion5x_sdram_bar(i); +		gd->bd->bi_dram[i].size = get_ram_size( +			(long *) (gd->bd->bi_dram[i].start), +			CONFIG_MAX_RAM_BANK_SIZE); +	} +} diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S new file mode 100644 index 00000000..4dacc296 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include "asm/arch/orion5x.h" + +/* + * Configuration values for SDRAM access setup + */ + +#define SDRAM_CONFIG			0x3148400 +#define SDRAM_MODE			0x62 +#define SDRAM_CONTROL			0x4041000 +#define SDRAM_TIME_CTRL_LOW		0x11602220 +#define SDRAM_TIME_CTRL_HI		0x40c +#define SDRAM_OPEN_PAGE_EN		0x0 +/* DDR 1 2x 32M NANYA NT5DS16M16CS-6K ==> 64MB */ +#define SDRAM_BANK0_SIZE		0x3ff0001 +#define SDRAM_ADDR_CTRL			0x10 + +#define SDRAM_OP_NOP			0x05 +#define SDRAM_OP_SETMODE		0x03 + +#define SDRAM_PAD_CTRL_WR_EN		0x80000000 +#define SDRAM_PAD_CTRL_TUNE_EN		0x00010000 +#define SDRAM_PAD_CTRL_DRVN_MASK	0x0000003f +#define SDRAM_PAD_CTRL_DRVP_MASK	0x00000fc0 + +/* + * For Guideline MEM-3 - Drive Strength value + */ + +#define DDR1_PAD_STRENGTH_DEFAULT	0x00001000 +#define SDRAM_PAD_CTRL_DRV_STR_MASK	0x00003000 + +/* + * For Guideline MEM-4 - DQS Reference Delay Tuning + */ + +#define MSAR_ARMDDRCLCK_MASK		0x000000f0 +#define MSAR_ARMDDRCLCK_H_MASK		0x00000100 + +#define MSAR_ARMDDRCLCK_333_167		0x00000000 +#define MSAR_ARMDDRCLCK_500_167		0x00000030 +#define MSAR_ARMDDRCLCK_667_167		0x00000060 +#define MSAR_ARMDDRCLCK_400_200_1	0x000001E0 +#define MSAR_ARMDDRCLCK_400_200		0x00000010 +#define MSAR_ARMDDRCLCK_600_200		0x00000050 +#define MSAR_ARMDDRCLCK_800_200		0x00000070 + +#define FTDLL_DDR1_166MHZ		0x0047F001 + +#define FTDLL_DDR1_200MHZ		0x0044D001 + +/* + * Low-level init happens right after start.S has switched to SVC32, + * flushed and disabled caches and disabled MMU. We're still running + * from the boot chip select, so the first thing we should do is set + * up RAM for us to relocate into. + */ + +.globl lowlevel_init + +lowlevel_init: + +	/* Use 'r4 as the base for internal register accesses */ +	ldr	r4, =ORION5X_REGS_PHY_BASE + +	/* move internal registers from the default 0xD0000000 +	 * to their intended location, defined by SoC */ +	ldr	r3, =0xD0000000 +	add	r3, r3, #0x20000 +	str	r4, [r3, #0x80] + +	/* Use R3 as the base for DRAM registers */ +	add	r3, r4, #0x01000 + +	/*DDR SDRAM Initialization Control */ +	ldr	r6, =0x00000001 +	str	r6, [r3, #0x480] + +	/* Use R3 as the base for PCI registers */ +	add	r3, r4, #0x31000 + +	/* Disable arbiter */ +	ldr	r6, =0x00000030 +	str	r6, [r3, #0xd00] + +	/* Use R3 as the base for DRAM registers */ +	add	r3, r4, #0x01000 + +	/* set all dram windows to 0 */ +	mov	r6, #0 +	str	r6, [r3, #0x504] +	str	r6, [r3, #0x50C] +	str	r6, [r3, #0x514] +	str	r6, [r3, #0x51C] + +	/* 1) Configure SDRAM  */ +	ldr	r6, =SDRAM_CONFIG +	str	r6, [r3, #0x400] + +	/* 2) Set SDRAM Control reg */ +	ldr	r6, =SDRAM_CONTROL +	str	r6, [r3, #0x404] + +	/* 3) Write SDRAM address control register */ +	ldr	r6, =SDRAM_ADDR_CTRL +	str	r6, [r3, #0x410] + +	/* 4) Write SDRAM bank 0 size register */ +	ldr	r6, =SDRAM_BANK0_SIZE +	str	r6, [r3, #0x504] +	/* keep other banks disabled */ + +	/* 5) Write SDRAM open pages control register */ +	ldr	r6, =SDRAM_OPEN_PAGE_EN +	str	r6, [r3, #0x414] + +	/* 6) Write SDRAM timing Low register */ +	ldr	r6, =SDRAM_TIME_CTRL_LOW +	str	r6, [r3, #0x408] + +	/* 7) Write SDRAM timing High register */ +	ldr	r6, =SDRAM_TIME_CTRL_HI +	str	r6, [r3, #0x40C] + +	/* 8) Write SDRAM mode register */ +	/* The CPU must not attempt to change the SDRAM Mode register setting */ +	/* prior to DRAM controller completion of the DRAM initialization     */ +	/* sequence. To guarantee this restriction, it is recommended that    */ +	/* the CPU sets the SDRAM Operation register to NOP command, performs */ +	/* read polling until the register is back in Normal operation value, */ +	/* and then sets SDRAM Mode register to its new value.		      */ + +	/* 8.1 write 'nop' to SDRAM operation */ +	ldr	r6, =SDRAM_OP_NOP +	str	r6, [r3, #0x418] + +	/* 8.2 poll SDRAM operation until back in 'normal' mode.  */ +1: +	ldr	r6, [r3, #0x418] +	cmp	r6, #0 +	bne	1b + +	/* 8.3 Now its safe to write new value to SDRAM Mode register	      */ +	ldr	r6, =SDRAM_MODE +	str	r6, [r3, #0x41C] + +	/* 8.4 Set new mode */ +	ldr	r6, =SDRAM_OP_SETMODE +	str	r6, [r3, #0x418] + +	/* 8.5 poll SDRAM operation until back in 'normal' mode.  */ +2: +	ldr	r6, [r3, #0x418] +	cmp	r6, #0 +	bne	2b + +	/* DDR SDRAM Address/Control Pads Calibration */ +	ldr	r6, [r3, #0x4C0] + +	/* Set Bit [31] to make the register writable			*/ +	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	str	r6, [r3, #0x4C0] + +	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN +	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK +	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK + +	/* Get the final N locked value of driving strength [22:17]	*/ +	mov	r1, r6 +	mov	r1, r1, LSL #9 +	mov	r1, r1, LSR #26	 /* r1[5:0]<DrvN>  = r3[22:17]<LockN>	*/ +	orr	r1, r1, r1, LSL #6 /* r1[11:6]<DrvP> = r1[5:0]<DrvN>	*/ + +	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/ +	orr	r6, r6, r1 +	str	r6, [r3, #0x4C0] + +	/* DDR SDRAM Data Pads Calibration				*/ +	ldr	r6, [r3, #0x4C4] + +	/* Set Bit [31] to make the register writable			*/ +	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	str	r6, [r3, #0x4C4] + +	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN +	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK +	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK + +	/* Get the final N locked value of driving strength [22:17]	*/ +	mov	r1, r6 +	mov	r1, r1, LSL #9 +	mov	r1, r1, LSR #26 +	orr	r1, r1, r1, LSL #6 /* r1[5:0] = r3[22:17]<LockN>	*/ + +	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/ +	orr	r6, r6, r1 + +	str	r6, [r3, #0x4C4] + +	/* Implement Guideline (GL# MEM-3) Drive Strength Value		*/ +	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/ + +	ldr	r1, =DDR1_PAD_STRENGTH_DEFAULT + +	/* Enable writes to DDR SDRAM Addr/Ctrl Pads Calibration register */ +	ldr	r6, [r3, #0x4C0] +	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	str	r6, [r3, #0x4C0] + +	/* Correct strength and disable writes again */ +	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK +	orr	r6, r6, r1 +	str	r6, [r3, #0x4C0] + +	/* Enable writes to DDR SDRAM Data Pads Calibration register */ +	ldr	r6, [r3, #0x4C4] +	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	str	r6, [r3, #0x4C4] + +	/* Correct strength and disable writes again */ +	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK +	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN +	orr	r6, r6, r1 +	str	r6, [r3, #0x4C4] + +	/* Implement Guideline (GL# MEM-4) DQS Reference Delay Tuning	*/ +	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/ + +	/* Get the "sample on reset" register for the DDR frequancy	*/ +	ldr	r3, =0x10000 +	ldr	r6, [r3, #0x010] +	ldr	r1, =MSAR_ARMDDRCLCK_MASK +	and	r1, r6, r1 + +	ldr	r6, =FTDLL_DDR1_166MHZ +	cmp	r1, #MSAR_ARMDDRCLCK_333_167 +	beq	3f +	cmp	r1, #MSAR_ARMDDRCLCK_500_167 +	beq	3f +	cmp	r1, #MSAR_ARMDDRCLCK_667_167 +	beq	3f + +	ldr	r6, =FTDLL_DDR1_200MHZ +	cmp	r1, #MSAR_ARMDDRCLCK_400_200_1 +	beq	3f +	cmp	r1, #MSAR_ARMDDRCLCK_400_200 +	beq	3f +	cmp	r1, #MSAR_ARMDDRCLCK_600_200 +	beq	3f +	cmp	r1, #MSAR_ARMDDRCLCK_800_200 +	beq	3f + +	ldr	r6, =0 + +3: +	/* Use R3 as the base for DRAM registers */ +	add	r3, r4, #0x01000 + +	ldr	r2, [r3, #0x484] +	orr	r2, r2, r6 +	str	r2, [r3, #0x484] + +	/* Return to U-boot via saved link register */ +	mov	pc, lr diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/timer.c new file mode 100644 index 00000000..ec4f6bee --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/timer.c @@ -0,0 +1,171 @@ +/* +  * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * Based on original Kirkwood support which is + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#define UBOOT_CNTR	0	/* counter to use for uboot timer */ + +/* Timer reload and current value registers */ +struct orion5x_tmr_val { +	u32 reload;	/* Timer reload reg */ +	u32 val;	/* Timer value reg */ +}; + +/* Timer registers */ +struct orion5x_tmr_registers { +	u32 ctrl;	/* Timer control reg */ +	u32 pad[3]; +	struct orion5x_tmr_val tmr[2]; +	u32 wdt_reload; +	u32 wdt_val; +}; + +struct orion5x_tmr_registers *orion5x_tmr_regs = +	(struct orion5x_tmr_registers *)ORION5X_TIMER_BASE; + +/* + * ARM Timers Registers Map + */ +#define CNTMR_CTRL_REG			(&orion5x_tmr_regs->ctrl) +#define CNTMR_RELOAD_REG(tmrnum)	(&orion5x_tmr_regs->tmr[tmrnum].reload) +#define CNTMR_VAL_REG(tmrnum)		(&orion5x_tmr_regs->tmr[tmrnum].val) + +/* + * ARM Timers Control Register + * CPU_TIMERS_CTRL_REG (CTCR) + */ +#define CTCR_ARM_TIMER_EN_OFFS(cntr)	(cntr * 2) +#define CTCR_ARM_TIMER_EN_MASK(cntr)	(1 << CTCR_ARM_TIMER_EN_OFFS) +#define CTCR_ARM_TIMER_EN(cntr)		(1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) +#define CTCR_ARM_TIMER_DIS(cntr)	(0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) + +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr)	((cntr * 2) + 1) +#define CTCR_ARM_TIMER_AUTO_MASK(cntr)	(1 << 1) +#define CTCR_ARM_TIMER_AUTO_EN(cntr)	(1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) +#define CTCR_ARM_TIMER_AUTO_DIS(cntr)	(0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) + +/* + * ARM Timer\Watchdog Reload Register + * CNTMR_RELOAD_REG (TRR) + */ +#define TRG_ARM_TIMER_REL_OFFS		0 +#define TRG_ARM_TIMER_REL_MASK		0xffffffff + +/* + * ARM Timer\Watchdog Register + * CNTMR_VAL_REG (TVRG) + */ +#define TVR_ARM_TIMER_OFFS		0 +#define TVR_ARM_TIMER_MASK		0xffffffff +#define TVR_ARM_TIMER_MAX		0xffffffff +#define TIMER_LOAD_VAL 			0xffffffff + +static inline ulong read_timer(void) +{ +	return readl(CNTMR_VAL_REG(UBOOT_CNTR)) +	      / (CONFIG_SYS_TCLK / 1000); +} + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +ulong get_timer_masked(void) +{ +	ulong now = read_timer(); + +	if (lastdec >= now) { +		/* normal mode */ +		timestamp += lastdec - now; +	} else { +		/* we have an overflow ... */ +		timestamp += lastdec + +			(TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; +	} +	lastdec = now; + +	return timestamp; +} + +ulong get_timer(ulong base) +{ +	return get_timer_masked() - base; +} + +static inline ulong uboot_cntr_val(void) +{ +	return readl(CNTMR_VAL_REG(UBOOT_CNTR)); +} + +void __udelay(unsigned long usec) +{ +	uint current; +	ulong delayticks; + +	current = uboot_cntr_val(); +	delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + +	if (current < delayticks) { +		delayticks -= current; +		while (uboot_cntr_val() < current) +			; +		while ((TIMER_LOAD_VAL - delayticks) < uboot_cntr_val()) +			; +	} else { +		while (uboot_cntr_val() > (current - delayticks)) +			; +	} +} + +/* + * init the counter + */ +int timer_init(void) +{ +	unsigned int cntmrctrl; + +	/* load value into timer */ +	writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); +	writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + +	/* enable timer in auto reload mode */ +	cntmrctrl = readl(CNTMR_CTRL_REG); +	cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); +	cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); +	writel(cntmrctrl, CNTMR_CTRL_REG); +	return 0; +} + +void timer_init_r(void) +{ +	/* init the timestamp and lastdec value */ +	lastdec = read_timer(); +	timestamp = 0; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ +	return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ +	return (ulong)CONFIG_SYS_HZ; +}  | 
