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/arm1176 | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/arm1176')
17 files changed, 1668 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/arm1176/Makefile b/roms/u-boot/arch/arm/cpu/arm1176/Makefile new file mode 100644 index 00000000..deec4274 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y	= start.o +obj-y	= cpu.o diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/Makefile b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/Makefile new file mode 100644 index 00000000..0ad36906 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -0,0 +1,16 @@ +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# + +obj-y	:= lowlevel_init.o +obj-y	+= init.o reset.o timer.o mbox.o diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/init.c b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/init.c new file mode 100644 index 00000000..e90d3bba --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/init.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <common.h> + +int arch_cpu_init(void) +{ +	icache_enable(); + +	return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/lowlevel_init.S new file mode 100644 index 00000000..c7b08432 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/lowlevel_init.S @@ -0,0 +1,19 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +.globl lowlevel_init +lowlevel_init: +	mov	pc, lr diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/mbox.c b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/mbox.c new file mode 100644 index 00000000..3b17a31e --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/mbox.c @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/mbox.h> + +#define TIMEOUT 1000 /* ms */ + +int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv) +{ +	struct bcm2835_mbox_regs *regs = +		(struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR; +	ulong endtime = get_timer(0) + TIMEOUT; +	u32 val; + +	debug("time: %lu timeout: %lu\n", get_timer(0), endtime); + +	if (send & BCM2835_CHAN_MASK) { +		printf("mbox: Illegal mbox data 0x%08x\n", send); +		return -1; +	} + +	/* Drain any stale responses */ + +	for (;;) { +		val = readl(®s->status); +		if (val & BCM2835_MBOX_STATUS_RD_EMPTY) +			break; +		if (get_timer(0) >= endtime) { +			printf("mbox: Timeout draining stale responses\n"); +			return -1; +		} +		val = readl(®s->read); +	} + +	/* Wait for space to send */ + +	for (;;) { +		val = readl(®s->status); +		if (!(val & BCM2835_MBOX_STATUS_WR_FULL)) +			break; +		if (get_timer(0) >= endtime) { +			printf("mbox: Timeout waiting for send space\n"); +			return -1; +		} +	} + +	/* Send the request */ + +	val = BCM2835_MBOX_PACK(chan, send); +	debug("mbox: TX raw: 0x%08x\n", val); +	writel(val, ®s->write); + +	/* Wait for the response */ + +	for (;;) { +		val = readl(®s->status); +		if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY)) +			break; +		if (get_timer(0) >= endtime) { +			printf("mbox: Timeout waiting for response\n"); +			return -1; +		} +	} + +	/* Read the response */ + +	val = readl(®s->read); +	debug("mbox: RX raw: 0x%08x\n", val); + +	/* Validate the response */ + +	if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) { +		printf("mbox: Response channel mismatch\n"); +		return -1; +	} + +	*recv = BCM2835_MBOX_UNPACK_DATA(val); + +	return 0; +} + +#ifdef DEBUG +void dump_buf(struct bcm2835_mbox_hdr *buffer) +{ +	u32 *p; +	u32 words; +	int i; + +	p = (u32 *)buffer; +	words = buffer->buf_size / 4; +	for (i = 0; i < words; i++) +		printf("    0x%04x: 0x%08x\n", i * 4, p[i]); +} +#endif + +int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer) +{ +	int ret; +	u32 rbuffer; +	struct bcm2835_mbox_tag_hdr *tag; +	int tag_index; + +#ifdef DEBUG +	printf("mbox: TX buffer\n"); +	dump_buf(buffer); +#endif + +	ret = bcm2835_mbox_call_raw(chan, (u32)buffer, &rbuffer); +	if (ret) +		return ret; +	if (rbuffer != (u32)buffer) { +		printf("mbox: Response buffer mismatch\n"); +		return -1; +	} + +#ifdef DEBUG +	printf("mbox: RX buffer\n"); +	dump_buf(buffer); +#endif + +	/* Validate overall response status */ + +	if (buffer->code != BCM2835_MBOX_RESP_CODE_SUCCESS) { +		printf("mbox: Header response code invalid\n"); +		return -1; +	} + +	/* Validate each tag's response status */ + +	tag = (void *)(buffer + 1); +	tag_index = 0; +	while (tag->tag) { +		if (!(tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)) { +			printf("mbox: Tag %d missing val_len response bit\n", +				tag_index); +			return -1; +		} +		/* +		 * Clear the reponse bit so clients can just look right at the +		 * length field without extra processing +		 */ +		tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE; +		tag = (void *)(((u8 *)tag) + sizeof(*tag) + tag->val_buf_size); +		tag_index++; +	} + +	return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/reset.c b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/reset.c new file mode 100644 index 00000000..8c37ad9f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/reset.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/wdog.h> + +#define RESET_TIMEOUT 10 + +void reset_cpu(ulong addr) +{ +	struct bcm2835_wdog_regs *regs = +		(struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; +	uint32_t rstc; + +	rstc = readl(®s->rstc); +	rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; +	rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; + +	writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, ®s->wdog); +	writel(BCM2835_WDOG_PASSWORD | rstc, ®s->rstc); +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/timer.c b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/timer.c new file mode 100644 index 00000000..017907cf --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/bcm2835/timer.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/timer.h> + +ulong get_timer_us(ulong base) +{ +	struct bcm2835_timer_regs *regs = +		(struct bcm2835_timer_regs *)BCM2835_TIMER_PHYSADDR; + +	return readl(®s->clo) - base; +} + +ulong get_timer(ulong base) +{ +	ulong us = get_timer_us(0); +	us /= (1000000 / CONFIG_SYS_HZ); +	us -= base; +	return us; +} + +unsigned long long get_ticks(void) +{ +	return get_timer(0); +} + +ulong get_tbclk(void) +{ +	return CONFIG_SYS_HZ; +} + +void __udelay(unsigned long usec) +{ +	ulong endtime; +	signed long diff; + +	endtime = get_timer_us(0) + usec; + +	do { +		ulong now = get_timer_us(0); +		diff = endtime - now; +	} while (diff >= 0); +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/config.mk b/roms/u-boot/arch/arm/cpu/arm1176/config.mk new file mode 100644 index 00000000..5dc2ebb2 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/config.mk @@ -0,0 +1,9 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t diff --git a/roms/u-boot/arch/arm/cpu/arm1176/cpu.c b/roms/u-boot/arch/arm/cpu/arm1176/cpu.c new file mode 100644 index 00000000..2d816512 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/cpu.c @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush (void); + +int cleanup_before_linux (void) +{ +	/* +	 * this function is called just before we call linux +	 * it prepares the processor for linux +	 * +	 * we turn off caches etc ... +	 */ + +	disable_interrupts (); + +	/* turn off I/D-cache */ +	icache_disable(); +	dcache_disable(); +	/* flush I/D-cache */ +	cache_flush(); + +	return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ +	/* invalidate both caches and flush btb */ +	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0)); +	/* mem barrier to sync things */ +	asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/start.S b/roms/u-boot/arch/arm/cpu/arm1176/start.S new file mode 100644 index 00000000..ce620115 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/start.S @@ -0,0 +1,331 @@ +/* + *  armboot - Startup Code for ARM1176 CPU-core + * + * Copyright (c) 2007	Samsung Electronics + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by + * jsgood (jsgood.yang@samsung.com) + * Base codes by scsuh (sc.suh) + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> + +#ifndef CONFIG_SYS_PHY_UBOOT_BASE +#define CONFIG_SYS_PHY_UBOOT_BASE	CONFIG_SYS_UBOOT_BASE +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + +.globl _start +_start: b	reset +#ifndef CONFIG_SPL_BUILD +	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 */ +#else +	. = _start + 64 +#endif + +.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 + * + ************************************************************************* + */ + +/* 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, #0x3f +	orr	r0, r0, #0xd3 +	msr	cpsr, r0 + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +	/* +	 * we do sys-critical inits only at reboot, +	 * not when booting from ram! +	 */ +cpu_init_crit: +	/* +	 * When booting from NAND - it has definitely been a reset, so, no need +	 * to flush caches and disable the MMU +	 */ +#ifndef CONFIG_SPL_BUILD +	/* +	 * flush v4 I/D caches +	 */ +	mov	r0, #0 +	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */ +	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ + +	/* +	 * disable MMU stuff and caches +	 */ +	mrc	p15, 0, r0, c1, c0, 0 +	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS) +	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM) +	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align +	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache + +	/* Prepare to disable the MMU */ +	adr	r2, mmu_disable_phys +	sub	r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE) +	b	mmu_disable + +	.align 5 +	/* Run in a single cache-line */ +mmu_disable: +	mcr	p15, 0, r0, c1, c0, 0 +	nop +	nop +	mov	pc, r2 +mmu_disable_phys: + +#ifdef CONFIG_DISABLE_TCM +	/* +	 * Disable the TCMs +	 */ +	mrc	p15, 0, r0, c0, c0, 2	/* Return TCM details */ +	cmp	r0, #0 +	beq	skip_tcmdisable +	mov	r1, #0 +	mov	r2, #1 +	tst	r0, r2 +	mcrne	p15, 0, r1, c9, c1, 1	/* Disable Instruction TCM if present*/ +	tst	r0, r2, LSL #16 +	mcrne	p15, 0, r1, c9, c1, 0	/* Disable Data TCM if present*/ +skip_tcmdisable: +#endif +#endif + +#ifdef CONFIG_PERIPORT_REMAP +	/* Peri port setup */ +	ldr	r0, =CONFIG_PERIPORT_BASE +	orr	r0, r0, #CONFIG_PERIPORT_SIZE +	mcr	p15,0,r0,c15,c2,4 +#endif + +	/* +	 * Go setup Memory and board specific bits prior to relocation. +	 */ +	bl	lowlevel_init		/* go setup pll,mux,memory */ + +	bl	_main + +/*------------------------------------------------------------------------------*/ + +	.globl	c_runtime_cpu_setup +c_runtime_cpu_setup: + +	mov	pc, lr + +#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 ... + */ + +	.macro	bad_save_user_regs +	/* carve out a frame on current user stack */ +	sub	sp, sp, #S_FRAME_SIZE +	/* Save user registers (now in svc mode) r0-r12 */ +	stmia	sp, {r0 - r12} + +	ldr	r2, IRQ_STACK_START_IN +	/* get values for "aborted" pc and cpsr (into parm regs) */ +	ldmia	r2, {r2 - r3} +	/* grab pointer to old stack */ +	add	r0, sp, #S_FRAME_SIZE + +	add	r5, sp, #S_SP +	mov	r1, lr +	/* save sp_SVC, lr_SVC, pc, cpsr */ +	stmia	r5, {r0 - r3} +	/* save current stack into r0 (param register) */ +	mov	r0, sp +	.endm + +	.macro get_bad_stack +	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack + +	/* save caller lr in position 0 of saved stack */ +	str	lr, [r13] +	/* get the spsr */ +	mrs	lr, spsr +	/* save spsr in position 1 of saved stack */ +	str	lr, [r13, #4] + +	/* prepare SVC-Mode */ +	mov	r13, #MODE_SVC +	@ msr	spsr_c, r13 +	/* switch modes, make sure moves will execute */ +	msr	spsr, r13 +	/* capture return pc */ +	mov	lr, pc +	/* jump to next instruction & switch modes. */ +	movs	pc, lr +	.endm + +	.macro get_bad_stack_swi +	/* space on current stack for scratch reg. */ +	sub	r13, r13, #4 +	/* save R0's value. */ +	str	r0, [r13] +	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack +	/* save caller lr in position 0 of saved stack */ +	str	lr, [r0] +	/* get the spsr */ +	mrs	lr, spsr +	/* save spsr in position 1 of saved stack */ +	str	lr, [r0, #4] +	/* restore lr */ +	ldr	lr, [r0] +	/* restore r0 */ +	ldr	r0, [r13] +	/* pop stack entry */ +	add	r13, r13, #4 +	.endm + +/* + * exception handlers + */ +	.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 + +	.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 /* CONFIG_SPL_BUILD */ diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/Makefile b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/Makefile new file mode 100644 index 00000000..a4c1edfc --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/Makefile @@ -0,0 +1,6 @@ +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	+= aemif.o clock.o init.o mux.o timer.o +obj-y	+= lowlevel_init.o diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/aemif.c b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/aemif.c new file mode 100644 index 00000000..a0f57289 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/aemif.c @@ -0,0 +1,78 @@ +/* + * TNETV107X: Asynchronous EMIF Configuration + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/mux.h> + +#define ASYNC_EMIF_BASE			TNETV107X_ASYNC_EMIF_CNTRL_BASE +#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4) +#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c) +#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60) +#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4) + +#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0) +#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0) +#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26) +#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20) +#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17) +#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13) +#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7) +#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4) +#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2) +#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0) + +#define NUM_CS				4 + +#define set_config_field(reg, field, val)			\ +	do {							\ +		if (val != -1) {				\ +			reg &= ~CONFIG_##field(0xffffffff);	\ +			reg |=	CONFIG_##field(val);		\ +		}						\ +	} while (0) + +void configure_async_emif(int cs, struct async_emif_config *cfg) +{ +	unsigned long tmp; + +	if (cfg->mode == ASYNC_EMIF_MODE_NAND) { +		tmp = __raw_readl(ASYNC_EMIF_NAND_CONTROL); +		tmp |= (1 << cs); +		__raw_writel(tmp, ASYNC_EMIF_NAND_CONTROL); + +	} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) { +		tmp = __raw_readl(ASYNC_EMIF_ONENAND_CONTROL); +		tmp |= (1 << cs); +		__raw_writel(tmp, ASYNC_EMIF_ONENAND_CONTROL); +	} + +	tmp = __raw_readl(ASYNC_EMIF_CONFIG(cs)); + +	set_config_field(tmp, SELECT_STROBE,	cfg->select_strobe); +	set_config_field(tmp, EXTEND_WAIT,	cfg->extend_wait); +	set_config_field(tmp, WR_SETUP,		cfg->wr_setup); +	set_config_field(tmp, WR_STROBE,	cfg->wr_strobe); +	set_config_field(tmp, WR_HOLD,		cfg->wr_hold); +	set_config_field(tmp, RD_SETUP,		cfg->rd_setup); +	set_config_field(tmp, RD_STROBE,	cfg->rd_strobe); +	set_config_field(tmp, RD_HOLD,		cfg->rd_hold); +	set_config_field(tmp, TURN_AROUND,	cfg->turn_around); +	set_config_field(tmp, WIDTH,		cfg->width); + +	__raw_writel(tmp, ASYNC_EMIF_CONFIG(cs)); +} + +void init_async_emif(int num_cs, struct async_emif_config *config) +{ +	int cs; + +	clk_enable(TNETV107X_LPSC_AEMIF); + +	for (cs = 0; cs < num_cs; cs++) +		configure_async_emif(cs, config + cs); +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/clock.c b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/clock.c new file mode 100644 index 00000000..3708b6f5 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/clock.c @@ -0,0 +1,432 @@ +/* + * TNETV107X: Clock management APIs + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm-generic/errno.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/arch/clock.h> + +#define CLOCK_BASE		TNETV107X_CLOCK_CONTROL_BASE +#define PSC_BASE		TNETV107X_PSC_BASE + +#define BIT(x)			(1 << (x)) + +#define MAX_PREDIV		64 +#define MAX_POSTDIV		8 +#define MAX_MULT		512 +#define MAX_DIV			(MAX_PREDIV * MAX_POSTDIV) + +/* LPSC registers */ +#define PSC_PTCMD		0x120 +#define PSC_PTSTAT		0x128 +#define PSC_MDSTAT(n)		(0x800 + (n) * 4) +#define PSC_MDCTL(n)		(0xA00 + (n) * 4) + +#define PSC_MDCTL_LRSTZ		BIT(8) + +#define psc_reg_read(reg)	__raw_readl((u32 *)(PSC_BASE + (reg))) +#define psc_reg_write(reg, val)	__raw_writel(val, (u32 *)(PSC_BASE + (reg))) + +/* SSPLL registers */ +struct sspll_regs { +	u32	modes; +	u32	postdiv; +	u32	prediv; +	u32	mult_factor; +	u32	divider_range; +	u32	bw_divider; +	u32	spr_amount; +	u32	spr_rate_div; +	u32	diag; +}; + +/* SSPLL base addresses */ +static struct sspll_regs *sspll_regs[] = { +	(struct sspll_regs *)(CLOCK_BASE + 0x040), +	(struct sspll_regs *)(CLOCK_BASE + 0x080), +	(struct sspll_regs *)(CLOCK_BASE + 0x0c0), +}; + +#define sspll_reg(pll, reg)		(&(sspll_regs[pll]->reg)) +#define sspll_reg_read(pll, reg)	__raw_readl(sspll_reg(pll, reg)) +#define sspll_reg_write(pll, reg, val)	__raw_writel(val, sspll_reg(pll, reg)) + + +/* PLL Control Registers */ +struct pllctl_regs { +	u32	ctl;		/* 00 */ +	u32	ocsel;		/* 04 */ +	u32	secctl;		/* 08 */ +	u32	__pad0; +	u32	mult;		/* 10 */ +	u32	prediv;		/* 14 */ +	u32	div1;		/* 18 */ +	u32	div2;		/* 1c */ +	u32	div3;		/* 20 */ +	u32	oscdiv1;	/* 24 */ +	u32	postdiv;	/* 28 */ +	u32	bpdiv;		/* 2c */ +	u32	wakeup;		/* 30 */ +	u32	__pad1; +	u32	cmd;		/* 38 */ +	u32	stat;		/* 3c */ +	u32	alnctl;		/* 40 */ +	u32	dchange;	/* 44 */ +	u32	cken;		/* 48 */ +	u32	ckstat;		/* 4c */ +	u32	systat;		/* 50 */ +	u32	ckctl;		/* 54 */ +	u32	__pad2[2]; +	u32	div4;		/* 60 */ +	u32	div5;		/* 64 */ +	u32	div6;		/* 68 */ +	u32	div7;		/* 6c */ +	u32	div8;		/* 70 */ +}; + +struct lpsc_map { +	int	pll, div; +}; + +static struct pllctl_regs *pllctl_regs[] = { +	(struct pllctl_regs *)(CLOCK_BASE + 0x700), +	(struct pllctl_regs *)(CLOCK_BASE + 0x300), +	(struct pllctl_regs *)(CLOCK_BASE + 0x500), +}; + +#define pllctl_reg(pll, reg)		(&(pllctl_regs[pll]->reg)) +#define pllctl_reg_read(pll, reg)	__raw_readl(pllctl_reg(pll, reg)) +#define pllctl_reg_write(pll, reg, val)	__raw_writel(val, pllctl_reg(pll, reg)) + +#define pllctl_reg_rmw(pll, reg, mask, val)			\ +	pllctl_reg_write(pll, reg,				\ +		(pllctl_reg_read(pll, reg) & ~(mask)) | val) + +#define pllctl_reg_setbits(pll, reg, mask)			\ +	pllctl_reg_rmw(pll, reg, 0, mask) + +#define pllctl_reg_clrbits(pll, reg, mask)			\ +	pllctl_reg_rmw(pll, reg, mask, 0) + +/* PLLCTL Bits */ +#define PLLCTL_CLKMODE		BIT(8) +#define PLLCTL_PLLSELB		BIT(7) +#define PLLCTL_PLLENSRC		BIT(5) +#define PLLCTL_PLLDIS		BIT(4) +#define PLLCTL_PLLRST		BIT(3) +#define PLLCTL_PLLPWRDN		BIT(1) +#define PLLCTL_PLLEN		BIT(0) + +#define PLLDIV_ENABLE		BIT(15) + +static int pll_div_offset[] = { +#define div_offset(reg)	offsetof(struct pllctl_regs, reg) +	div_offset(div1), div_offset(div2), div_offset(div3), +	div_offset(div4), div_offset(div5), div_offset(div6), +	div_offset(div7), div_offset(div8), +}; + +static unsigned long pll_bypass_mask[] = { 1, 4, 2 }; +static unsigned long pll_div_mask[] = { 0x01ff, 0x00ff, 0x00ff }; + +/* Mappings from PLL+DIV to subsystem clocks */ +#define sys_arm1176_clk		{SYS_PLL, 0} +#define sys_dsp_clk		{SYS_PLL, 1} +#define sys_ddr_clk		{SYS_PLL, 2} +#define sys_full_clk		{SYS_PLL, 3} +#define sys_lcd_clk		{SYS_PLL, 4} +#define sys_vlynq_ref_clk	{SYS_PLL, 5} +#define sys_tsc_clk		{SYS_PLL, 6} +#define sys_half_clk		{SYS_PLL, 7} + +#define eth_clk_5		{ETH_PLL, 0} +#define eth_clk_50		{ETH_PLL, 1} +#define eth_clk_125		{ETH_PLL, 2} +#define eth_clk_250		{ETH_PLL, 3} +#define eth_clk_25		{ETH_PLL, 4} + +#define tdm_clk			{TDM_PLL, 0} +#define tdm_extra_clk		{TDM_PLL, 1} +#define tdm1_clk		{TDM_PLL, 2} + +static const struct lpsc_map lpsc_clk_map[] = { +	[TNETV107X_LPSC_ARM]			= sys_arm1176_clk, +	[TNETV107X_LPSC_GEM]			= sys_dsp_clk, +	[TNETV107X_LPSC_DDR2_PHY]		= sys_ddr_clk, +	[TNETV107X_LPSC_TPCC]			= sys_full_clk, +	[TNETV107X_LPSC_TPTC0]			= sys_full_clk, +	[TNETV107X_LPSC_TPTC1]			= sys_full_clk, +	[TNETV107X_LPSC_RAM]			= sys_full_clk, +	[TNETV107X_LPSC_MBX_LITE]		= sys_arm1176_clk, +	[TNETV107X_LPSC_LCD]			= sys_lcd_clk, +	[TNETV107X_LPSC_ETHSS]			= eth_clk_125, +	[TNETV107X_LPSC_AEMIF]			= sys_full_clk, +	[TNETV107X_LPSC_CHIP_CFG]		= sys_half_clk, +	[TNETV107X_LPSC_TSC]			= sys_tsc_clk, +	[TNETV107X_LPSC_ROM]			= sys_half_clk, +	[TNETV107X_LPSC_UART2]			= sys_half_clk, +	[TNETV107X_LPSC_PKTSEC]			= sys_half_clk, +	[TNETV107X_LPSC_SECCTL]			= sys_half_clk, +	[TNETV107X_LPSC_KEYMGR]			= sys_half_clk, +	[TNETV107X_LPSC_KEYPAD]			= sys_half_clk, +	[TNETV107X_LPSC_GPIO]			= sys_half_clk, +	[TNETV107X_LPSC_MDIO]			= sys_half_clk, +	[TNETV107X_LPSC_SDIO0]			= sys_half_clk, +	[TNETV107X_LPSC_UART0]			= sys_half_clk, +	[TNETV107X_LPSC_UART1]			= sys_half_clk, +	[TNETV107X_LPSC_TIMER0]			= sys_half_clk, +	[TNETV107X_LPSC_TIMER1]			= sys_half_clk, +	[TNETV107X_LPSC_WDT_ARM]		= sys_half_clk, +	[TNETV107X_LPSC_WDT_DSP]		= sys_half_clk, +	[TNETV107X_LPSC_SSP]			= sys_half_clk, +	[TNETV107X_LPSC_TDM0]			= tdm_clk, +	[TNETV107X_LPSC_VLYNQ]			= sys_vlynq_ref_clk, +	[TNETV107X_LPSC_MCDMA]			= sys_half_clk, +	[TNETV107X_LPSC_USB0]			= sys_half_clk, +	[TNETV107X_LPSC_TDM1]			= tdm1_clk, +	[TNETV107X_LPSC_DEBUGSS]		= sys_half_clk, +	[TNETV107X_LPSC_ETHSS_RGMII]		= eth_clk_250, +	[TNETV107X_LPSC_SYSTEM]			= sys_half_clk, +	[TNETV107X_LPSC_IMCOP]			= sys_dsp_clk, +	[TNETV107X_LPSC_SPARE]			= sys_half_clk, +	[TNETV107X_LPSC_SDIO1]			= sys_half_clk, +	[TNETV107X_LPSC_USB1]			= sys_half_clk, +	[TNETV107X_LPSC_USBSS]			= sys_half_clk, +	[TNETV107X_LPSC_DDR2_EMIF1_VRST]	= sys_ddr_clk, +	[TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST]	= sys_ddr_clk, +}; + +static const unsigned long pll_ext_freq[] = { +	[SYS_PLL] = CONFIG_PLL_SYS_EXT_FREQ, +	[ETH_PLL] = CONFIG_PLL_ETH_EXT_FREQ, +	[TDM_PLL] = CONFIG_PLL_TDM_EXT_FREQ, +}; + +static unsigned long pll_freq_get(int pll) +{ +	unsigned long mult = 1, prediv = 1, postdiv = 1; +	unsigned long ref = CONFIG_SYS_INT_OSC_FREQ; +	unsigned long ret; +	u32 bypass; + +	bypass = __raw_readl((u32 *)(CLOCK_BASE)); +	if (!(bypass & pll_bypass_mask[pll])) { +		mult	= sspll_reg_read(pll, mult_factor); +		prediv	= sspll_reg_read(pll, prediv) + 1; +		postdiv	= sspll_reg_read(pll, postdiv) + 1; +	} + +	if (pllctl_reg_read(pll, ctl) & PLLCTL_CLKMODE) +		ref = pll_ext_freq[pll]; + +	if (!(pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN)) +		return ref; + +	ret = (unsigned long)(ref + ((unsigned long long)ref * mult) / 256); +	ret /= (prediv * postdiv); + +	return ret; +} + +static unsigned long __pll_div_freq_get(int pll, unsigned int fpll, +					int div) +{ +	int divider = 1; +	unsigned long divreg; + +	divreg = __raw_readl((void *)pllctl_regs[pll] + pll_div_offset[div]); + +	if (divreg & PLLDIV_ENABLE) +		divider = (divreg & pll_div_mask[pll]) + 1; + +	return fpll / divider; +} + +static unsigned long pll_div_freq_get(int pll, int div) +{ +	unsigned int fpll = pll_freq_get(pll); + +	return __pll_div_freq_get(pll, fpll, div); +} + +static void __pll_div_freq_set(int pll, unsigned int fpll, int div, +			       unsigned long hz) +{ +	int divider = (fpll / hz - 1); + +	divider &= pll_div_mask[pll]; +	divider |= PLLDIV_ENABLE; + +	__raw_writel(divider, (void *)pllctl_regs[pll] + pll_div_offset[div]); +	pllctl_reg_setbits(pll, alnctl, (1 << div)); +	pllctl_reg_setbits(pll, dchange, (1 << div)); +} + +static unsigned long pll_div_freq_set(int pll, int div, unsigned long hz) +{ +	unsigned int fpll = pll_freq_get(pll); + +	__pll_div_freq_set(pll, fpll, div, hz); + +	pllctl_reg_write(pll, cmd, 1); + +	/* Wait until new divider takes effect */ +	while (pllctl_reg_read(pll, stat) & 0x01); + +	return __pll_div_freq_get(pll, fpll, div); +} + +unsigned long clk_get_rate(unsigned int clk) +{ +	return pll_div_freq_get(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div); +} + +unsigned long clk_round_rate(unsigned int clk, unsigned long hz) +{ +	unsigned long fpll, divider, pll; + +	pll = lpsc_clk_map[clk].pll; +	fpll = pll_freq_get(pll); +	divider = (fpll / hz - 1); +	divider &= pll_div_mask[pll]; + +	return fpll / (divider + 1); +} + +int clk_set_rate(unsigned int clk, unsigned long _hz) +{ +	unsigned long hz; + +	hz = clk_round_rate(clk, _hz); +	if (hz != _hz) +		return -EINVAL;	/* Cannot set to target freq */ + +	pll_div_freq_set(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div, hz); +	return 0; +} + +void lpsc_control(int mod, unsigned long state, int lrstz) +{ +	u32 mdctl; + +	mdctl = psc_reg_read(PSC_MDCTL(mod)); +	mdctl &= ~0x1f; +	mdctl |= state; + +	if (lrstz == 0) +		mdctl &= ~PSC_MDCTL_LRSTZ; +	else if (lrstz == 1) +		mdctl |= PSC_MDCTL_LRSTZ; + +	psc_reg_write(PSC_MDCTL(mod), mdctl); + +	psc_reg_write(PSC_PTCMD, 1); + +	/* wait for power domain transition to end */ +	while (psc_reg_read(PSC_PTSTAT) & 1); + +	/* Wait for module state change */ +	while ((psc_reg_read(PSC_MDSTAT(mod)) & 0x1f) != state); +} + +int lpsc_status(unsigned int id) +{ +	return psc_reg_read(PSC_MDSTAT(id)) & 0x1f; +} + +static void init_pll(const struct pll_init_data *data) +{ +	unsigned long fpll; +	unsigned long best_pre = 0, best_post = 0, best_mult = 0; +	unsigned long div, prediv, postdiv, mult; +	unsigned long delta, actual; +	long best_delta = -1; +	int i; +	u32 tmp; + +	if (data->pll == SYS_PLL) +		return; /* cannot reconfigure system pll on the fly */ + +	tmp = pllctl_reg_read(data->pll, ctl); +	if (data->internal_osc) { +		tmp &= ~PLLCTL_CLKMODE; +		fpll = CONFIG_SYS_INT_OSC_FREQ; +	} else { +		tmp |= PLLCTL_CLKMODE; +		fpll = pll_ext_freq[data->pll]; +	} +	pllctl_reg_write(data->pll, ctl, tmp); + +	mult = data->pll_freq / fpll; +	for (mult = MAX(mult, 1); mult <= MAX_MULT; mult++) { +		div = (fpll * mult) / data->pll_freq; +		if (div < 1 || div > MAX_DIV) +			continue; + +		for (postdiv = 1; postdiv <= min(div, MAX_POSTDIV); postdiv++) { +			prediv = div / postdiv; +			if (prediv < 1 || prediv > MAX_PREDIV) +				continue; + +			actual = (fpll / prediv) * (mult / postdiv); +			delta = (actual - data->pll_freq); +			if (delta < 0) +				delta = -delta; +			if ((delta < best_delta) || (best_delta == -1)) { +				best_delta = delta; +				best_mult = mult; +				best_pre = prediv; +				best_post = postdiv; +				if (delta == 0) +					goto done; +			} +		} +	} +done: + +	if (best_delta == -1) { +		printf("pll cannot derive %lu from %lu\n", +				data->pll_freq, fpll); +		return; +	} + +	fpll = fpll * best_mult; +	fpll /= best_pre * best_post; + +	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC); +	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN); + +	pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST); + +	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN); +	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLDIS); + +	sspll_reg_write(data->pll, mult_factor,	(best_mult - 1) << 8); +	sspll_reg_write(data->pll, prediv,	best_pre - 1); +	sspll_reg_write(data->pll, postdiv,	best_post - 1); + +	for (i = 0; i < 10; i++) +		if (data->div_freq[i]) +			__pll_div_freq_set(data->pll, fpll, i, +					   data->div_freq[i]); + +	pllctl_reg_write(data->pll, cmd, 1); + +	/* Wait until pll "go" operation completes */ +	while (pllctl_reg_read(data->pll, stat) & 0x01); + +	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST); +	pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN); +} + +void init_plls(int num_pll, struct pll_init_data *config) +{ +	int i; + +	for (i = 0; i < num_pll; i++) +		init_pll(&config[i]); +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/init.c b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/init.c new file mode 100644 index 00000000..d8708267 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/init.c @@ -0,0 +1,22 @@ +/* + * TNETV107X: Architecture initialization + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +void chip_configuration_unlock(void) +{ +       __raw_writel(TNETV107X_KICK0_MAGIC, TNETV107X_KICK0); +       __raw_writel(TNETV107X_KICK1_MAGIC, TNETV107X_KICK1); +} + +int arch_cpu_init(void) +{ +       icache_enable(); +       chip_configuration_unlock(); + +       return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/lowlevel_init.S new file mode 100644 index 00000000..a8bce478 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/lowlevel_init.S @@ -0,0 +1,10 @@ +/* + * TNETV107X: Low-level pre-relocation initialization + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +.globl lowlevel_init +lowlevel_init: +	/* nothing for now, maybe needed for more exotic boot modes */ +	mov	pc, lr diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/mux.c b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/mux.c new file mode 100644 index 00000000..310d84df --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/mux.c @@ -0,0 +1,319 @@ +/* + * TNETV107X: Pinmux configuration + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/mux.h> + +#define MUX_MODE_1		0x00 +#define MUX_MODE_2		0x04 +#define MUX_MODE_3		0x0c +#define MUX_MODE_4		0x1c + +#define MUX_DEBUG		0 + +static const struct pin_config pin_table[] = { +	/*		  reg	shift	mode	*/ +	TNETV107X_MUX_CFG(0,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(0,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(0,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(0,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(0,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(0,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(0,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(1,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(1,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(2,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(2,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(3,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(3,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	10,	MUX_MODE_4), +	TNETV107X_MUX_CFG(3,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(3,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	20,	MUX_MODE_4), +	TNETV107X_MUX_CFG(3,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(3,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(3,	25,	MUX_MODE_4), +	TNETV107X_MUX_CFG(4,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(4,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(4,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(4,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	20,	MUX_MODE_3), +	TNETV107X_MUX_CFG(4,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(4,	25,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	10,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	20,	MUX_MODE_4), +	TNETV107X_MUX_CFG(5,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(5,	25,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	10,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	20,	MUX_MODE_4), +	TNETV107X_MUX_CFG(6,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(6,	25,	MUX_MODE_4), +	TNETV107X_MUX_CFG(7,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(7,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(7,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	10,	MUX_MODE_4), +	TNETV107X_MUX_CFG(7,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(7,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(7,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(7,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(8,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(8,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(8,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(8,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(8,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(8,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(8,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(9,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	0,	MUX_MODE_4), +	TNETV107X_MUX_CFG(9,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(9,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	5,	MUX_MODE_4), +	TNETV107X_MUX_CFG(9,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(9,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	10,	MUX_MODE_4), +	TNETV107X_MUX_CFG(9,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(9,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(9,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(9,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(9,	20,	MUX_MODE_4), +	TNETV107X_MUX_CFG(10,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(10,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(10,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(10,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(10,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(10,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(10,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(11,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(11,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(12,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(13,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(13,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(13,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(13,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(14,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(15,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(15,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(15,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(16,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(16,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(16,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(16,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(16,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(16,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(16,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(17,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(17,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(17,	0,	MUX_MODE_3), +	TNETV107X_MUX_CFG(17,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(17,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(17,	5,	MUX_MODE_3), +	TNETV107X_MUX_CFG(17,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(17,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(17,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(17,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(17,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(17,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(18,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(18,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(18,	0,	MUX_MODE_3), +	TNETV107X_MUX_CFG(18,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(18,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(18,	5,	MUX_MODE_3), +	TNETV107X_MUX_CFG(18,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(18,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(18,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(18,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(18,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(18,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(19,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(19,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(19,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(19,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(19,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(19,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(20,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(20,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(21,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	5,	MUX_MODE_3), +	TNETV107X_MUX_CFG(22,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(22,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(22,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(22,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	20,	MUX_MODE_3), +	TNETV107X_MUX_CFG(22,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(22,	25,	MUX_MODE_3), +	TNETV107X_MUX_CFG(23,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(23,	0,	MUX_MODE_3), +	TNETV107X_MUX_CFG(23,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(23,	5,	MUX_MODE_3), +	TNETV107X_MUX_CFG(23,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(23,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(24,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(24,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(24,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(24,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(24,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(24,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(24,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(24,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(24,	25,	MUX_MODE_2), +	TNETV107X_MUX_CFG(25,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(25,	0,	MUX_MODE_2), +	TNETV107X_MUX_CFG(25,	0,	MUX_MODE_3), +	TNETV107X_MUX_CFG(25,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(25,	5,	MUX_MODE_2), +	TNETV107X_MUX_CFG(25,	5,	MUX_MODE_3), +	TNETV107X_MUX_CFG(25,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(25,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(25,	10,	MUX_MODE_3), +	TNETV107X_MUX_CFG(25,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(25,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(25,	15,	MUX_MODE_3), +	TNETV107X_MUX_CFG(25,	15,	MUX_MODE_4), +	TNETV107X_MUX_CFG(26,	0,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	5,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	10,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	10,	MUX_MODE_2), +	TNETV107X_MUX_CFG(26,	15,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	15,	MUX_MODE_2), +	TNETV107X_MUX_CFG(26,	20,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	20,	MUX_MODE_2), +	TNETV107X_MUX_CFG(26,	25,	MUX_MODE_1), +	TNETV107X_MUX_CFG(26,	25,	MUX_MODE_2), +}; + +const int pin_table_size = sizeof(pin_table) / sizeof(pin_table[0]); + +int mux_select_pin(short index) +{ +	const struct pin_config *cfg; +	unsigned long mask, mode, reg; + +	if (index >= pin_table_size) +		return 0; + +	cfg = &pin_table[index]; + +	mask = 0x1f << cfg->mask_offset; +	mode = cfg->mode << cfg->mask_offset; + +	reg = __raw_readl(TNETV107X_PINMUX(cfg->reg_index)); +	reg = (reg & ~mask) | mode; +	__raw_writel(reg, TNETV107X_PINMUX(cfg->reg_index)); + +	return 1; +} + +int mux_select_pins(const short *pins) +{ +	int i, ret = 1; + +	for (i = 0; pins[i] >= 0; i++) +		ret &= mux_select_pin(pins[i]); + +	return ret; +} diff --git a/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/timer.c b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/timer.c new file mode 100644 index 00000000..6e0dd0d2 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm1176/tnetv107x/timer.c @@ -0,0 +1,93 @@ +/* + * TNETV107X: Timer implementation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> + +struct timer_regs { +	u_int32_t pid12; +	u_int32_t pad[3]; +	u_int32_t tim12; +	u_int32_t tim34; +	u_int32_t prd12; +	u_int32_t prd34; +	u_int32_t tcr; +	u_int32_t tgcr; +	u_int32_t wdtcr; +}; + +#define regs ((struct timer_regs *)CONFIG_SYS_TIMERBASE) + +#define TIMER_LOAD_VAL	(CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) +#define TIM_CLK_DIV	16 + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ +	clk_enable(TNETV107X_LPSC_TIMER0); + +	lastinc = timestamp = 0; + +	/* We are using timer34 in unchained 32-bit mode, full speed */ +	__raw_writel(0x0, ®s->tcr); +	__raw_writel(0x0, ®s->tgcr); +	__raw_writel(0x06 | ((TIM_CLK_DIV - 1) << 8), ®s->tgcr); +	__raw_writel(0x0, ®s->tim34); +	__raw_writel(TIMER_LOAD_VAL, ®s->prd34); +	__raw_writel(2 << 22, ®s->tcr); + +	return 0; +} + +static ulong get_timer_raw(void) +{ +	ulong now = __raw_readl(®s->tim34); + +	if (now >= lastinc) +		timestamp += now - lastinc; +	else +		timestamp += now + TIMER_LOAD_VAL - lastinc; + +	lastinc = now; + +	return timestamp; +} + +ulong get_timer(ulong base) +{ +	return (get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base; +} + +unsigned long long get_ticks(void) +{ +	return get_timer(0); +} + +void __udelay(unsigned long usec) +{ +	ulong tmo; +	ulong endtime; +	signed long diff; + +	tmo = CONFIG_SYS_HZ_CLOCK / 1000; +	tmo *= usec; +	tmo /= (1000 * TIM_CLK_DIV); + +	endtime = get_timer_raw() + tmo; + +	do { +		ulong now = get_timer_raw(); +		diff = endtime - now; +	} while (diff >= 0); +} + +ulong get_tbclk(void) +{ +	return CONFIG_SYS_HZ; +}  | 
