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/pxa | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/pxa')
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/Makefile | 15 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/config.mk | 22 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c | 126 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c | 286 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/start.S | 450 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/timer.c | 85 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/pxa/usb.c | 89 | 
7 files changed, 1073 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/pxa/Makefile b/roms/u-boot/arch/arm/cpu/pxa/Makefile new file mode 100644 index 00000000..8cd475e3 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/Makefile @@ -0,0 +1,15 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y	= start.o + +obj-$(CONFIG_CPU_PXA25X)	+= pxa2xx.o +obj-$(CONFIG_CPU_PXA27X)	+= pxa2xx.o + +obj-y	+= cpuinfo.o +obj-y	+= timer.o +obj-y	+= usb.o diff --git a/roms/u-boot/arch/arm/cpu/pxa/config.mk b/roms/u-boot/arch/arm/cpu/pxa/config.mk new file mode 100644 index 00000000..525f5d33 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/config.mk @@ -0,0 +1,22 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -mcpu=xscale + +# +# !WARNING! +# The PXA's OneNAND SPL uses .text.0 and .text.1 segments to allow booting from +# really small OneNAND memories where the mmap'd window is only 1KiB big. The +# .text.0 contains only the bare minimum needed to load the real SPL into SRAM. +# Add .text.0 and .text.1 into OBJFLAGS, so when the SPL is being objcopy'd, +# they are not discarded. +# + +#ifdef CONFIG_SPL_BUILD +OBJCOPYFLAGS += -j .text.0 -j .text.1 +#endif diff --git a/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c b/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c new file mode 100644 index 00000000..9d160799 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c @@ -0,0 +1,126 @@ +/* + * PXA CPU information display + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <linux/compiler.h> + +#define	CPU_MASK_PXA_PRODID	0x000003f0 +#define	CPU_MASK_PXA_REVID	0x0000000f + +#define	CPU_MASK_PRODREV	(CPU_MASK_PXA_PRODID | CPU_MASK_PXA_REVID) + +#define	CPU_VALUE_PXA25X	0x100 +#define	CPU_VALUE_PXA27X	0x110 + +static uint32_t pxa_get_cpuid(void) +{ +	uint32_t cpuid; +	asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid)); +	return cpuid; +} + +int cpu_is_pxa25x(void) +{ +	uint32_t id = pxa_get_cpuid(); +	id &= CPU_MASK_PXA_PRODID; +	return id == CPU_VALUE_PXA25X; +} + +int cpu_is_pxa27x(void) +{ +	uint32_t id = pxa_get_cpuid(); +	id &= CPU_MASK_PXA_PRODID; +	return id == CPU_VALUE_PXA27X; +} + +uint32_t pxa_get_cpu_revision(void) +{ +	return pxa_get_cpuid() & CPU_MASK_PRODREV; +} + +#ifdef	CONFIG_DISPLAY_CPUINFO +static const char *pxa25x_get_revision(void) +{ +	static __maybe_unused const char * const revs_25x[] = { "A0" }; +	static __maybe_unused const char * const revs_26x[] = { +								"A0", "B0", "B1" +								}; +	static const char *unknown = "Unknown"; +	uint32_t id; + +	if (!cpu_is_pxa25x()) +		return unknown; + +	id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; + +/* PXA26x is a sick special case as it can't be told apart from PXA25x :-( */ +#ifdef	CONFIG_CPU_PXA26X +	switch (id) { +	case 3: return revs_26x[0]; +	case 5: return revs_26x[1]; +	case 6: return revs_26x[2]; +	} +#else +	if (id == 6) +		return revs_25x[0]; +#endif +	return unknown; +} + +static const char *pxa27x_get_revision(void) +{ +	static const char *const rev[] = { "A0", "A1", "B0", "B1", "C0", "C5" }; +	static const char *unknown = "Unknown"; +	uint32_t id; + +	if (!cpu_is_pxa27x()) +		return unknown; + +	id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; + +	if ((id == 5) || (id == 6) || (id > 7)) +		return unknown; + +	/* Cap the special PXA270 C5 case. */ +	if (id == 7) +		id = 5; + +	return rev[id]; +} + +static int print_cpuinfo_pxa2xx(void) +{ +	if (cpu_is_pxa25x()) { +		puts("Marvell PXA25x rev. "); +		puts(pxa25x_get_revision()); +	} else if (cpu_is_pxa27x()) { +		puts("Marvell PXA27x rev. "); +		puts(pxa27x_get_revision()); +	} else +		return -EINVAL; + +	puts("\n"); + +	return 0; +} + +int print_cpuinfo(void) +{ +	int ret; + +	puts("CPU: "); + +	ret = print_cpuinfo_pxa2xx(); +	if (!ret) +		return ret; + +	return ret; +} +#endif diff --git a/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c b/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c new file mode 100644 index 00000000..7e861e26 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c @@ -0,0 +1,286 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/system.h> +#include <command.h> +#include <common.h> +#include <asm/arch/pxa-regs.h> + +/* Flush I/D-cache */ +static void cache_flush(void) +{ +	unsigned long i = 0; + +	asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i)); +} + +int cleanup_before_linux(void) +{ +	/* +	 * This function is called just before we call Linux. It prepares +	 * the processor for Linux by just disabling everything that can +	 * disturb booting Linux. +	 */ + +	disable_interrupts(); +	icache_disable(); +	dcache_disable(); +	cache_flush(); + +	return 0; +} + +void pxa_wait_ticks(int ticks) +{ +	writel(0, OSCR); +	while (readl(OSCR) < ticks) +		asm volatile("" : : : "memory"); +} + +inline void writelrb(uint32_t val, uint32_t addr) +{ +	writel(val, addr); +	asm volatile("" : : : "memory"); +	readl(addr); +	asm volatile("" : : : "memory"); +} + +void pxa2xx_dram_init(void) +{ +	uint32_t tmp; +	int i; +	/* +	 * 1) Initialize Asynchronous static memory controller +	 */ + +	writelrb(CONFIG_SYS_MSC0_VAL, MSC0); +	writelrb(CONFIG_SYS_MSC1_VAL, MSC1); +	writelrb(CONFIG_SYS_MSC2_VAL, MSC2); +	/* +	 * 2) Initialize Card Interface +	 */ + +	/* MECR: Memory Expansion Card Register */ +	writelrb(CONFIG_SYS_MECR_VAL, MECR); +	/* MCMEM0: Card Interface slot 0 timing */ +	writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0); +	/* MCMEM1: Card Interface slot 1 timing */ +	writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1); +	/* MCATT0: Card Interface Attribute Space Timing, slot 0 */ +	writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0); +	/* MCATT1: Card Interface Attribute Space Timing, slot 1 */ +	writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1); +	/* MCIO0: Card Interface I/O Space Timing, slot 0 */ +	writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0); +	/* MCIO1: Card Interface I/O Space Timing, slot 1 */ +	writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1); + +	/* +	 * 3) Configure Fly-By DMA register +	 */ + +	writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG); + +	/* +	 * 4) Initialize Timing for Sync Memory (SDCLK0) +	 */ + +	/* +	 * Before accessing MDREFR we need a valid DRI field, so we set +	 * this to power on defaults + DRI field. +	 */ + +	/* Read current MDREFR config and zero out DRI */ +	tmp = readl(MDREFR) & ~0xfff; +	/* Add user-specified DRI */ +	tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff; +	/* Configure important bits */ +	tmp |= MDREFR_K0RUN | MDREFR_SLFRSH; +	tmp &= ~(MDREFR_APD | MDREFR_E1PIN); + +	/* Write MDREFR back */ +	writelrb(tmp, MDREFR); + +	/* +	 * 5) Initialize Synchronous Static Memory (Flash/Peripherals) +	 */ + +	/* Initialize SXCNFG register. Assert the enable bits. +	 * +	 * Write SXMRS to cause an MRS command to all enabled banks of +	 * synchronous static memory. Note that SXLCR need not be written +	 * at this time. +	 */ +	writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG); + +	/* +	 * 6) Initialize SDRAM +	 */ + +	writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR); +	writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR); + +	/* +	 * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure +	 *    but not enable each SDRAM partition pair. +	 */ + +	writelrb(CONFIG_SYS_MDCNFG_VAL & +		~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG); +	/* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */ +	pxa_wait_ticks(0x300); + +	/* +	 * 8) Trigger a number (usually 8) refresh cycles by attempting +	 *    non-burst read or write accesses to disabled SDRAM, as commonly +	 *    specified in the power up sequence documented in SDRAM data +	 *    sheets. The address(es) used for this purpose must not be +	 *    cacheable. +	 */ +	for (i = 9; i >= 0; i--) { +		writel(i, 0xa0000000); +		asm volatile("" : : : "memory"); +	} +	/* +	 * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1). +	 */ + +	tmp = CONFIG_SYS_MDCNFG_VAL & +		(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3); +	tmp |= readl(MDCNFG); +	writelrb(tmp, MDCNFG); + +	/* +	 * 10) Write MDMRS. +	 */ + +	writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS); + +	/* +	 * 11) Enable APD +	 */ + +	if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) { +		tmp = readl(MDREFR); +		tmp |= MDREFR_APD; +		writelrb(tmp, MDREFR); +	} +} + +void pxa_gpio_setup(void) +{ +	writel(CONFIG_SYS_GPSR0_VAL, GPSR0); +	writel(CONFIG_SYS_GPSR1_VAL, GPSR1); +	writel(CONFIG_SYS_GPSR2_VAL, GPSR2); +#if defined(CONFIG_CPU_PXA27X) +	writel(CONFIG_SYS_GPSR3_VAL, GPSR3); +#endif + +	writel(CONFIG_SYS_GPCR0_VAL, GPCR0); +	writel(CONFIG_SYS_GPCR1_VAL, GPCR1); +	writel(CONFIG_SYS_GPCR2_VAL, GPCR2); +#if defined(CONFIG_CPU_PXA27X) +	writel(CONFIG_SYS_GPCR3_VAL, GPCR3); +#endif + +	writel(CONFIG_SYS_GPDR0_VAL, GPDR0); +	writel(CONFIG_SYS_GPDR1_VAL, GPDR1); +	writel(CONFIG_SYS_GPDR2_VAL, GPDR2); +#if defined(CONFIG_CPU_PXA27X) +	writel(CONFIG_SYS_GPDR3_VAL, GPDR3); +#endif + +	writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L); +	writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U); +	writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L); +	writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U); +	writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L); +	writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U); +#if defined(CONFIG_CPU_PXA27X) +	writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L); +	writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U); +#endif + +	writel(CONFIG_SYS_PSSR_VAL, PSSR); +} + +void pxa_interrupt_setup(void) +{ +	writel(0, ICLR); +	writel(0, ICMR); +#if defined(CONFIG_CPU_PXA27X) +	writel(0, ICLR2); +	writel(0, ICMR2); +#endif +} + +void pxa_clock_setup(void) +{ +	writel(CONFIG_SYS_CKEN, CKEN); +	writel(CONFIG_SYS_CCCR, CCCR); +	asm volatile("mcr	p14, 0, %0, c6, c0, 0" : : "r"(0x0b)); + +	/* enable the 32Khz oscillator for RTC and PowerManager */ +	writel(OSCC_OON, OSCC); +	while (!(readl(OSCC) & OSCC_OOK)) +		asm volatile("" : : : "memory"); +} + +void pxa_wakeup(void) +{ +	uint32_t rcsr; + +	rcsr = readl(RCSR); +	writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR); + +	/* Wakeup */ +	if (rcsr & RCSR_SMR) { +		writel(PSSR_PH, PSSR); +		pxa2xx_dram_init(); +		icache_disable(); +		dcache_disable(); +		asm volatile("mov	pc, %0" : : "r"(readl(PSPR))); +	} +} + +int arch_cpu_init(void) +{ +	pxa_gpio_setup(); +	pxa_wakeup(); +	pxa_interrupt_setup(); +	pxa_clock_setup(); +	return 0; +} + +void i2c_clk_enable(void) +{ +	/* Set the global I2C clock on */ +	writel(readl(CKEN) | CKEN14_I2C, CKEN); +} + +void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn)); + +void reset_cpu(ulong ignored) +{ +	uint32_t tmp; + +	setbits_le32(OWER, OWER_WME); + +	tmp = readl(OSCR); +	tmp += 0x1000; +	writel(tmp, OSMR3); +	writel(MDREFR_SLFRSH, MDREFR); + +	for (;;) +		; +} diff --git a/roms/u-boot/arch/arm/cpu/pxa/start.S b/roms/u-boot/arch/arm/cpu/pxa/start.S new file mode 100644 index 00000000..ae0d13ce --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/start.S @@ -0,0 +1,450 @@ +/* + *  armboot - Startup Code for XScale CPU-core + * + *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net> + *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + *  Copyright (C) 2000	Wolfgang Denk <wd@denx.de> + *  Copyright (C) 2001	Alex Zuepke <azu@sysgo.de> + *  Copyright (C) 2001	Marius Groger <mag@sysgo.de> + *  Copyright (C) 2002	Alex Zupke <azu@sysgo.de> + *  Copyright (C) 2002	Gary Jennejohn <garyj@denx.de> + *  Copyright (C) 2002	Kyle Harris <kharris@nexus-tech.net> + *  Copyright (C) 2003	Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de> + *  Copyright (C) 2003	Kshitij <kshitij@ti.com> + *  Copyright (C) 2003	Richard Woodruff <r-woodruff2@ti.com> + *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de> + *  Copyright (C) 2004	Texas Instruments <r-woodruff2@ti.com> + *  Copyright (C) 2010	Marek Vasut <marek.vasut@gmail.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> + +#ifdef CONFIG_CPU_PXA25X +#if ((CONFIG_SYS_INIT_SP_ADDR) != 0xfffff800) +#error "Init SP address must be set to 0xfffff800 for PXA250" +#endif +#endif + +.globl _start +_start: b	reset +#ifdef CONFIG_SPL_BUILD +	ldr	pc, _hang +	ldr	pc, _hang +	ldr	pc, _hang +	ldr	pc, _hang +	ldr	pc, _hang +	ldr	pc, _hang +	ldr	pc, _hang + +_hang: +	.word	do_hang +	.word	0x12345678 +	.word	0x12345678 +	.word	0x12345678 +	.word	0x12345678 +	.word	0x12345678 +	.word	0x12345678 +	.word	0x12345678	/* now 16*4=64 */ +#else +	ldr	pc, _undefined_instruction +	ldr	pc, _software_interrupt +	ldr	pc, _prefetch_abort +	ldr	pc, _data_abort +	ldr	pc, _not_used +	ldr	pc, _irq +	ldr	pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt:	.word software_interrupt +_prefetch_abort:	.word prefetch_abort +_data_abort:		.word data_abort +_not_used:		.word not_used +_irq:			.word irq +_fiq:			.word fiq +_pad:			.word 0x12345678 /* now 16*4=64 */ +#endif	/* CONFIG_SPL_BUILD */ +.global _end_vect +_end_vect: + +	.balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: +	.word	0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: +	.word 0x0badc0de +#endif + +/* IRQ stack memory (calculated at run-time) + 8 bytes */ +.globl IRQ_STACK_START_IN +IRQ_STACK_START_IN: +	.word	0x0badc0de + +/* + * the actual reset code + */ + +reset: +	/* +	 * set the cpu to SVC32 mode +	 */ +	mrs	r0,cpsr +	bic	r0,r0,#0x1f +	orr	r0,r0,#0xd3 +	msr	cpsr,r0 + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +	bl  cpu_init_crit +#endif + +#ifdef	CONFIG_CPU_PXA25X +	bl	lock_cache_for_stack +#endif + +	bl	_main + +/*------------------------------------------------------------------------------*/ + +	.globl	c_runtime_cpu_setup +c_runtime_cpu_setup: + +#ifdef CONFIG_CPU_PXA25X +	/* +	 * Unlock (actually, disable) the cache now that board_init_f +	 * is done. We could do this earlier but we would need to add +	 * a new C runtime hook, whereas c_runtime_cpu_setup already +	 * exists. +	 * As this routine is just a call to cpu_init_crit, let us +	 * tail-optimize and do a simple branch here. +	 */ +	b	cpu_init_crit +#else +	bx	lr +#endif + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_CPU_PXA25X) +cpu_init_crit: +	/* +	 * flush v4 I/D caches +	 */ +	mov	r0, #0 +	mcr	p15, 0, r0, c7, c7, 0	/* Invalidate I+D+BTB caches */ +	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate Unified TLB */ + +	/* +	 * disable MMU stuff and caches +	 */ +	mrc	p15, 0, r0, c1, c0, 0 +	bic	r0, r0, #0x00003300	@ clear bits 13:12, 9:8 (--VI --RS) +	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM) +	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align +	mcr	p15, 0, r0, c1, c0, 0 + +	mov	pc, lr		/* back to my caller */ +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */ + +#ifndef CONFIG_SPL_BUILD +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE	72 + +#define S_OLD_R0	68 +#define S_PSR		64 +#define S_PC		60 +#define S_LR		56 +#define S_SP		52 + +#define S_IP		48 +#define S_FP		44 +#define S_R10		40 +#define S_R9		36 +#define S_R8		32 +#define S_R7		28 +#define S_R6		24 +#define S_R5		20 +#define S_R4		16 +#define S_R3		12 +#define S_R2		8 +#define S_R1		4 +#define S_R0		0 + +#define MODE_SVC 0x13 +#define I_BIT	 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + +	.macro	bad_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current user stack +	stmia	sp, {r0 - r12}			@ Save user registers (now in svc mode) r0-r12 + +	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort stack +	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc and cpsr (into parm regs) +	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack + +	add	r5, sp, #S_SP +	mov	r1, lr +	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr +	mov	r0, sp				@ save current stack into r0 (param register) +	.endm + +	.macro	irq_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE +	stmia	sp, {r0 - r12}			@ Calling r0-r12 +	add	r8, sp, #S_PC			@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. +	stmdb	r8, {sp, lr}^			@ Calling SP, LR +	str	lr, [r8, #0]			@ Save calling PC +	mrs	r6, spsr +	str	r6, [r8, #4]			@ Save CPSR +	str	r0, [r8, #8]			@ Save OLD_R0 +	mov	r0, sp +	.endm + +	.macro	irq_restore_user_regs +	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr +	mov	r0, r0 +	ldr	lr, [sp, #S_PC]			@ Get PC +	add	sp, sp, #S_FRAME_SIZE +	subs	pc, lr, #4			@ return & move spsr_svc into cpsr +	.endm + +	.macro get_bad_stack +	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode) + +	str	lr, [r13]			@ save caller lr in position 0 of saved stack +	mrs	lr, spsr			@ get the spsr +	str	lr, [r13, #4]			@ save spsr in position 1 of saved stack + +	mov	r13, #MODE_SVC			@ prepare SVC-Mode +	@ msr	spsr_c, r13 +	msr	spsr, r13			@ switch modes, make sure moves will execute +	mov	lr, pc				@ capture return pc +	movs	pc, lr				@ jump to next instruction & switch modes. +	.endm + +	.macro get_bad_stack_swi +	sub	r13, r13, #4			@ space on current stack for scratch reg. +	str	r0, [r13]			@ save R0's value. +	ldr	r0, IRQ_STACK_START_IN		@ get data regions start +	str	lr, [r0]			@ save caller lr in position 0 of saved stack +	mrs	lr, spsr			@ get the spsr +	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack +	ldr	lr, [r0]			@ restore lr +	ldr	r0, [r13]			@ restore r0 +	add	r13, r13, #4			@ pop stack entry +	.endm + +	.macro get_irq_stack			@ setup IRQ stack +	ldr	sp, IRQ_STACK_START +	.endm + +	.macro get_fiq_stack			@ setup FIQ stack +	ldr	sp, FIQ_STACK_START +	.endm +#endif	/* CONFIG_SPL_BUILD */ + +/* + * exception handlers + */ +#ifdef CONFIG_SPL_BUILD +	.align	5 +do_hang: +	bl	hang				/* hang and never return */ +#else	/* !CONFIG_SPL_BUILD */ +	.align	5 +undefined_instruction: +	get_bad_stack +	bad_save_user_regs +	bl	do_undefined_instruction + +	.align	5 +software_interrupt: +	get_bad_stack_swi +	bad_save_user_regs +	bl	do_software_interrupt + +	.align	5 +prefetch_abort: +	get_bad_stack +	bad_save_user_regs +	bl	do_prefetch_abort + +	.align	5 +data_abort: +	get_bad_stack +	bad_save_user_regs +	bl	do_data_abort + +	.align	5 +not_used: +	get_bad_stack +	bad_save_user_regs +	bl	do_not_used + +#ifdef CONFIG_USE_IRQ + +	.align	5 +irq: +	get_irq_stack +	irq_save_user_regs +	bl	do_irq +	irq_restore_user_regs + +	.align	5 +fiq: +	get_fiq_stack +	/* someone ought to write a more effiction fiq_save_user_regs */ +	irq_save_user_regs +	bl	do_fiq +	irq_restore_user_regs + +#else + +	.align	5 +irq: +	get_bad_stack +	bad_save_user_regs +	bl	do_irq + +	.align	5 +fiq: +	get_bad_stack +	bad_save_user_regs +	bl	do_fiq + +#endif +	.align 5 +#endif	/* CONFIG_SPL_BUILD */ + + +/* + * Enable MMU to use DCache as DRAM. + * + * This is useful on PXA25x and PXA26x in early bootstages, where there is no + * other possible memory available to hold stack. + */ +#ifdef CONFIG_CPU_PXA25X +.macro CPWAIT reg +	mrc	p15, 0, \reg, c2, c0, 0 +	mov	\reg, \reg +	sub	pc, pc, #4 +.endm +lock_cache_for_stack: +	/* Domain access -- enable for all CPs */ +	ldr	r0, =0x0000ffff +	mcr	p15, 0, r0, c3, c0, 0 + +	/* Point TTBR to MMU table */ +	ldr	r0, =mmutable +	mcr	p15, 0, r0, c2, c0, 0 + +	/* Kick in MMU, ICache, DCache, BTB */ +	mrc	p15, 0, r0, c1, c0, 0 +	bic	r0, #0x1b00 +	bic	r0, #0x0087 +	orr	r0, #0x1800 +	orr	r0, #0x0005 +	mcr	p15, 0, r0, c1, c0, 0 +	CPWAIT	r0 + +	/* Unlock Icache, Dcache */ +	mcr	p15, 0, r0, c9, c1, 1 +	mcr	p15, 0, r0, c9, c2, 1 + +	/* Flush Icache, Dcache, BTB */ +	mcr	p15, 0, r0, c7, c7, 0 + +	/* Unlock I-TLB, D-TLB */ +	mcr	p15, 0, r0, c10, c4, 1 +	mcr	p15, 0, r0, c10, c8, 1 + +	/* Flush TLB */ +	mcr	p15, 0, r0, c8, c7, 0 + +	/* Allocate 4096 bytes of Dcache as RAM */ + +	/* Drain pending loads and stores */ +	mcr	p15, 0, r0, c7, c10, 4 + +	mov	r4, #0x00 +	mov	r5, #0x00 +	mov	r2, #0x01 +	mcr	p15, 0, r0, c9, c2, 0 +	CPWAIT	r0 + +	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */ +	mov	r0, #128 +	ldr	r1, =0xfffff000 + +alloc: +	mcr	p15, 0, r1, c7, c2, 5 +	/* Drain pending loads and stores */ +	mcr	p15, 0, r0, c7, c10, 4 +	strd	r4, [r1], #8 +	strd	r4, [r1], #8 +	strd	r4, [r1], #8 +	strd	r4, [r1], #8 +	subs	r0, #0x01 +	bne	alloc +	/* Drain pending loads and stores */ +	mcr	p15, 0, r0, c7, c10, 4 +	mov	r2, #0x00 +	mcr	p15, 0, r2, c9, c2, 0 +	CPWAIT	r0 + +	mov	pc, lr + +.section .mmutable, "a" +mmutable: +	.align	14 +	/* 0x00000000 - 0xffe00000 : 1:1, uncached mapping */ +	.set	__base, 0 +	.rept	0xfff +	.word	(__base << 20) | 0xc12 +	.set	__base, __base + 1 +	.endr + +	/* 0xfff00000 : 1:1, cached mapping */ +	.word	(0xfff << 20) | 0x1c1e +#endif	/* CONFIG_CPU_PXA25X */ diff --git a/roms/u-boot/arch/arm/cpu/pxa/timer.c b/roms/u-boot/arch/arm/cpu/pxa/timer.c new file mode 100644 index 00000000..c4717de6 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/timer.c @@ -0,0 +1,85 @@ +/* + * Marvell PXA2xx/3xx timer driver + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/arch/pxa-regs.h> +#include <asm/io.h> +#include <common.h> +#include <div64.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define	TIMER_LOAD_VAL	0xffffffff + +#define	timestamp	(gd->arch.tbl) +#define	lastinc		(gd->arch.lastinc) + +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#define	TIMER_FREQ_HZ	3250000 +#elif defined(CONFIG_CPU_PXA25X) +#define	TIMER_FREQ_HZ	3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +static unsigned long long tick_to_time(unsigned long long tick) +{ +	return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); +} + +static unsigned long long us_to_tick(unsigned long long us) +{ +	return lldiv(us * TIMER_FREQ_HZ, 1000000); +} + +int timer_init(void) +{ +	writel(0, OSCR); +	return 0; +} + +unsigned long long get_ticks(void) +{ +	/* Current tick value */ +	uint32_t now = readl(OSCR); + +	if (now >= lastinc) { +		/* +		 * Normal mode (non roll) +		 * Move stamp forward with absolute diff ticks +		 */ +		timestamp += (now - lastinc); +	} else { +		/* We have rollover of incrementer */ +		timestamp += (TIMER_LOAD_VAL - lastinc) + now; +	} + +	lastinc = now; +	return timestamp; +} + +ulong get_timer(ulong base) +{ +	return tick_to_time(get_ticks()) - base; +} + +void __udelay(unsigned long usec) +{ +	unsigned long long tmp; +	ulong tmo; + +	tmo = us_to_tick(usec); +	tmp = get_ticks() + tmo;	/* get current timestamp */ + +	while (get_ticks() < tmp)	/* loop till event */ +		 /*NOP*/; +} + +ulong get_tbclk(void) +{ +	return TIMER_FREQ_HZ; +} diff --git a/roms/u-boot/arch/arm/cpu/pxa/usb.c b/roms/u-boot/arch/arm/cpu/pxa/usb.c new file mode 100644 index 00000000..c31c2d73 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/pxa/usb.c @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2006 + * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) +# if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_CPU_PXA27X) + +#include <asm/arch/pxa-regs.h> +#include <asm/io.h> +#include <usb.h> + +int usb_cpu_init(void) +{ +#if defined(CONFIG_CPU_MONAHANS) +	/* Enable USB host clock. */ +	writel(readl(CKENA) | CKENA_2_USBHOST | CKENA_20_UDC, CKENA); +	udelay(100); +#endif +#if defined(CONFIG_CPU_PXA27X) +	/* Enable USB host clock. */ +	writel(readl(CKEN) | CKEN10_USBHOST, CKEN); +#endif + +#if defined(CONFIG_CPU_MONAHANS) +	/* Configure Port 2 for Host (USB Client Registers) */ +	writel(0x3000c, UP2OCR); +#endif + +	writel(readl(UHCHR) | UHCHR_FHR, UHCHR); +	mdelay(11); +	writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR); + +	writel(readl(UHCHR) | UHCHR_FSBIR, UHCHR); +	while (readl(UHCHR) & UHCHR_FSBIR) +		udelay(1); + +#if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) +	writel(readl(UHCHR) & ~UHCHR_SSEP0, UHCHR); +#endif +#if defined(CONFIG_CPU_PXA27X) +	writel(readl(UHCHR) & ~UHCHR_SSEP2, UHCHR); +#endif +	writel(readl(UHCHR) & ~(UHCHR_SSEP1 | UHCHR_SSE), UHCHR); + +	return 0; +} + +int usb_cpu_stop(void) +{ +	writel(readl(UHCHR) | UHCHR_FHR, UHCHR); +	udelay(11); +	writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR); + +	writel(readl(UHCCOMS) | UHCCOMS_HCR, UHCCOMS); +	udelay(10); + +#if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X) +	writel(readl(UHCHR) | UHCHR_SSEP0, UHCHR); +#endif +#if defined(CONFIG_CPU_PXA27X) +	writel(readl(UHCHR) | UHCHR_SSEP2, UHCHR); +#endif +	writel(readl(UHCHR) | UHCHR_SSEP1 | UHCHR_SSE, UHCHR); + +#if defined(CONFIG_CPU_MONAHANS) +	/* Disable USB host clock. */ +	writel(readl(CKENA) & ~(CKENA_2_USBHOST | CKENA_20_UDC), CKENA); +	udelay(100); +#endif +#if defined(CONFIG_CPU_PXA27X) +	/* Disable USB host clock. */ +	writel(readl(CKEN) & ~CKEN10_USBHOST, CKEN); +#endif + +	return 0; +} + +int usb_cpu_init_fail(void) +{ +	return usb_cpu_stop(); +} + +# endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_CPU_PXA27X) */ +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */  | 
