diff options
Diffstat (limited to 'arch')
60 files changed, 2623 insertions, 481 deletions
| diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile index 4f467be91..def3980b6 100644 --- a/arch/arm/cpu/arm926ejs/at91/Makefile +++ b/arch/arm/cpu/arm926ejs/at91/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_AT91SAM9263)	+= at91sam9263_devices.o  COBJS-$(CONFIG_AT91SAM9RL)	+= at91sam9rl_devices.o  COBJS-$(CONFIG_AT91SAM9M10G45)	+= at91sam9m10g45_devices.o  COBJS-$(CONFIG_AT91SAM9G45)	+= at91sam9m10g45_devices.o +COBJS-$(CONFIG_AT91_EFLASH)	+= eflash.o  COBJS-$(CONFIG_AT91_LED)	+= led.o  COBJS-y += clock.o  COBJS-y += cpu.o diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c index 77d49ab1c..87b04426b 100644 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c +++ b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c @@ -28,12 +28,27 @@  #include <asm/arch/gpio.h>  #include <asm/arch/io.h> +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif +  void at91_serial0_hw_init(void)  {  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;  	at91_set_a_periph(AT91_PIO_PORTB, 4, 1);		/* TXD0 */ -	at91_set_a_periph(AT91_PIO_PORTB, 5, 0);		/* RXD0 */ +	at91_set_a_periph(AT91_PIO_PORTB, 5, PUP);		/* RXD0 */  	writel(1 << AT91SAM9260_ID_US0, &pmc->pcer);  } @@ -42,7 +57,7 @@ void at91_serial1_hw_init(void)  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;  	at91_set_a_periph(AT91_PIO_PORTB, 6, 1);		/* TXD1 */ -	at91_set_a_periph(AT91_PIO_PORTB, 7, 0);		/* RXD1 */ +	at91_set_a_periph(AT91_PIO_PORTB, 7, PUP);		/* RXD1 */  	writel(1 << AT91SAM9260_ID_US1, &pmc->pcer);  } @@ -51,7 +66,7 @@ void at91_serial2_hw_init(void)  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;  	at91_set_a_periph(AT91_PIO_PORTB, 8, 1);		/* TXD2 */ -	at91_set_a_periph(AT91_PIO_PORTB, 9, 0);		/* RXD2 */ +	at91_set_a_periph(AT91_PIO_PORTB, 9, PUP);		/* RXD2 */  	writel(1 << AT91SAM9260_ID_US2, &pmc->pcer);  } @@ -59,7 +74,7 @@ void at91_serial3_hw_init(void)  {  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE; -	at91_set_a_periph(AT91_PIO_PORTB, 14, 0);		/* DRXD */ +	at91_set_a_periph(AT91_PIO_PORTB, 14, PUP);		/* DRXD */  	at91_set_a_periph(AT91_PIO_PORTB, 15, 1);		/* DTXD */  	writel(1 << AT91_ID_SYS, &pmc->pcer);  } @@ -88,9 +103,9 @@ void at91_spi0_hw_init(unsigned long cs_mask)  {  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE; -	at91_set_a_periph(AT91_PIO_PORTA, 0, 0);	/* SPI0_MISO */ -	at91_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* SPI0_MOSI */ -	at91_set_a_periph(AT91_PIO_PORTA, 2, 0);	/* SPI0_SPCK */ +	at91_set_a_periph(AT91_PIO_PORTA, 0, PUP);	/* SPI0_MISO */ +	at91_set_a_periph(AT91_PIO_PORTA, 1, PUP);	/* SPI0_MOSI */ +	at91_set_a_periph(AT91_PIO_PORTA, 2, PUP);	/* SPI0_SPCK */  	/* Enable clock */  	writel(1 << AT91SAM9260_ID_SPI0, &pmc->pcer); @@ -125,9 +140,9 @@ void at91_spi1_hw_init(unsigned long cs_mask)  {  	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE; -	at91_set_a_periph(AT91_PIO_PORTB, 0, 0);	/* SPI1_MISO */ -	at91_set_a_periph(AT91_PIO_PORTB, 1, 0);	/* SPI1_MOSI */ -	at91_set_a_periph(AT91_PIO_PORTB, 2, 0);	/* SPI1_SPCK */ +	at91_set_a_periph(AT91_PIO_PORTB, 0, PUP);	/* SPI1_MISO */ +	at91_set_a_periph(AT91_PIO_PORTB, 1, PUP);	/* SPI1_MOSI */ +	at91_set_a_periph(AT91_PIO_PORTB, 2, PUP);	/* SPI1_SPCK */  	/* Enable clock */  	writel(1 << AT91SAM9260_ID_SPI1, &pmc->pcer); @@ -194,3 +209,24 @@ void at91_macb_hw_init(void)  #endif  }  #endif + +#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI) +void at91_mci_hw_init(void) +{ +	at91_set_a_periph(AT91_PIO_PORTA, 8, 1);	/* MCCK */ +#if defined(CONFIG_ATMEL_MCI_PORTB) +	at91_set_b_periph(AT91_PIO_PORTA, 1, 1);	/* MCCDB */ +	at91_set_b_periph(AT91_PIO_PORTA, 0, 1);	/* MCDB0 */ +	at91_set_b_periph(AT91_PIO_PORTA, 5, 1);	/* MCDB1 */ +	at91_set_b_periph(AT91_PIO_PORTA, 4, 1);	/* MCDB2 */ +	at91_set_b_periph(AT91_PIO_PORTA, 3, 1);	/* MCDB3 */ +#else +	at91_set_a_periph(AT91_PIO_PORTA, 7, 1);	/* MCCDA */ +	at91_set_a_periph(AT91_PIO_PORTA, 6, 1);	/* MCDA0 */ +	at91_set_a_periph(AT91_PIO_PORTA, 9, 1);	/* MCDA1 */ +	at91_set_a_periph(AT91_PIO_PORTA, 10, 1);	/* MCDA2 */ +	at91_set_a_periph(AT91_PIO_PORTA, 11, 1);	/* MCDA3 */ +#endif +} +#endif + diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c new file mode 100644 index 000000000..2e851dbd2 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/at91/eflash.c @@ -0,0 +1,271 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * this driver supports the enhanced embedded flash in the Atmel + * AT91SAM9XE devices with the following geometry: + * + * AT91SAM9XE128: 1 plane of  8 regions of 32 pages (total  256 pages) + * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total  512 pages) + * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages) + * (the exact geometry is read from the flash at runtime, so any + *  future devices should already be covered) + * + * Regions can be write/erase protected. + * Whole (!) pages can be individually written with erase on the fly. + * Writing partial pages will corrupt the rest of the page. + * + * The flash is presented to u-boot with each region being a sector, + * having the following effects: + * Each sector can be hardware protected (protect on/off). + * Each page in a sector can be rewritten anytime. + * Since pages are erased when written, the "erase" does nothing. + * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected + * by u-Boot commands. + * + * Note: Redundant environment will not work in this flash since + * it does use partial page writes. Make sure the environent spans + * whole pages! + */ + +/* + * optional TODOs (nice to have features): + * + * make the driver coexist with other NOR flash drivers + *	(use an index into flash_info[], requires work + *	in those other drivers, too) + * Make the erase command fill the sectors with 0xff + *	(if the flashes grow larger in the future and + *	someone puts a jffs2 into them) + * do a read-modify-write for partially programmed pages + */ +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/at91_eefc.h> +#include <asm/arch/at91_dbu.h> + +/* checks to detect configuration errors */ +#if CONFIG_SYS_MAX_FLASH_BANKS!=1 +#error eflash: this driver can only handle 1 bank +#endif + +/* global structure */ +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; +static u32 pagesize; + +unsigned long flash_init (void) +{ +	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00; +	at91_dbu_t *dbu = (at91_dbu_t *) 0xfffff200; +	u32 id, size, nplanes, planesize, nlocks; +	u32 addr, i, tmp=0; + +	debug("eflash: init\n"); + +	flash_info[0].flash_id = FLASH_UNKNOWN; + +	/* check if its an AT91ARM9XE SoC */ +	if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) { +		puts("eflash: not an AT91SAM9XE\n"); +		return 0; +	} + +	/* now query the eflash for its structure */ +	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr); +	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) +		; +	id = readl(&eefc->frr);		/* word 0 */ +	size = readl(&eefc->frr);	/* word 1 */ +	pagesize = readl(&eefc->frr);	/* word 2 */ +	nplanes = readl(&eefc->frr);	/* word 3 */ +	planesize = readl(&eefc->frr);	/* word 4 */ +	debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n", +		id, size, pagesize, nplanes, planesize); +	for (i=1; i<nplanes; i++) { +		tmp = readl(&eefc->frr);	/* words 5..4+nplanes-1 */ +	}; +	nlocks = readl(&eefc->frr);	/* word 4+nplanes */ +	debug("nlocks=%u\n", nlocks); +	/* since we are going to use the lock regions as sectors, check count */ +	if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) { +		printf("eflash: number of lock regions(%u) "\ +			"> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n", +			nlocks); +		nlocks = CONFIG_SYS_MAX_FLASH_SECT; +	} +	flash_info[0].size = size; +	flash_info[0].sector_count = nlocks; +	flash_info[0].flash_id = id; + +	addr = AT91SAM9XE_FLASH_BASE; +	for (i=0; i<nlocks; i++) { +		tmp = readl(&eefc->frr);	/* words 4+nplanes+1.. */ +		flash_info[0].start[i] = addr; +		flash_info[0].protect[i] = 0; +		addr += tmp; +	}; + +	/* now read the protection information for all regions */ +	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); +	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) +		; +	for (i=0; i<flash_info[0].sector_count; i++) { +		if (i%32 == 0) +			tmp = readl(&eefc->frr); +		flash_info[0].protect[i] = (tmp >> (i%32)) & 1; +#if defined(CONFIG_EFLASH_PROTSECTORS) +		if (i < CONFIG_EFLASH_PROTSECTORS) +			flash_info[0].protect[i] = 1; +#endif +	} + +	return size; +} + +void flash_print_info (flash_info_t *info) +{ +	int i; + +	puts("AT91SAM9XE embedded flash\n  Size: "); +	print_size(info->size, " in "); +	printf("%d Sectors\n", info->sector_count); + +	printf("  Sector Start Addresses:"); +	for (i=0; i<info->sector_count; ++i) { +		if ((i % 5) == 0) +			printf("\n   "); +		printf(" %08lX%s", +			info->start[i], +			info->protect[i] ? " (RO)" : "     " +		); +	} +	printf ("\n"); +	return; +} + +int flash_real_protect (flash_info_t *info, long sector, int prot) +{ +	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00; +	u32 pagenum = (info->start[sector]-AT91SAM9XE_FLASH_BASE)/pagesize; +	u32 i, tmp=0; + +	debug("protect sector=%ld prot=%d\n", sector, prot); + +#if defined(CONFIG_EFLASH_PROTSECTORS) +	if (sector < CONFIG_EFLASH_PROTSECTORS) { +		if (!prot) { +			printf("eflash: sector %lu cannot be unprotected\n", +				sector); +		} +		return 1; /* return anyway, caller does not care for result */ +	} +#endif +	if (prot) { +		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB | +			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); +	} else { +		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB | +			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); +	} +	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) +		; +	/* now re-read the protection information for all regions */ +	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); +	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) +		; +	for (i=0; i<info->sector_count; i++) { +		if (i%32 == 0) +			tmp = readl(&eefc->frr); +		info->protect[i] = (tmp >> (i%32)) & 1; +	} +	return 0; +} + +static u32 erase_write_page (u32 pagenum) +{ +	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00; + +	debug("erase+write page=%u\n", pagenum); + +	/* give erase and write page command */ +	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP | +		(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); +	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) +		; +	/* return status */ +	return readl(&eefc->fsr) +		& (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE); +} + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ +	debug("erase first=%d last=%d\n", s_first, s_last); +	puts("this flash does not need and support erasing!\n"); +	return 0; +} + +/* + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ +	u32 pagenum; +	u32 *src32, *dst32; +	u32 i; + +	debug("write src=%08lx addr=%08lx cnt=%lx\n", +		(ulong)src, addr, cnt); + +	/* REQUIRE addr to be on a page start, abort if not */ +	if (addr % pagesize) { +		printf ("eflash: start %08lx is not on page start\n"\ +			"        write aborted\n", addr); +		return 1; +	} + +	/* now start copying data */ +	pagenum = (addr-AT91SAM9XE_FLASH_BASE)/pagesize; +	src32 = (u32 *) src; +	dst32 = (u32 *) addr; +	while (cnt > 0) { +		i = pagesize / 4; +		/* fill page buffer */ +		while (i--) +			*dst32++ = *src32++; +		/* write page */ +		if (erase_write_page(pagenum)) +			return 1; +		pagenum++; +		if (cnt > pagesize) +			cnt -= pagesize; +		else +			cnt = 0; +	} +	return 0; +} + diff --git a/arch/arm/cpu/arm926ejs/at91/reset.c b/arch/arm/cpu/arm926ejs/at91/reset.c index 1b67e7788..d2569d8ba 100644 --- a/arch/arm/cpu/arm926ejs/at91/reset.c +++ b/arch/arm/cpu/arm926ejs/at91/reset.c @@ -27,18 +27,19 @@  #include <asm/arch/at91_rstc.h>  #include <asm/arch/io.h> -/* - * Reset the cpu by setting up the watchdog timer and let him time out. - */ +/* Reset the cpu by telling the reset controller to do so */  void reset_cpu(ulong ignored)  {  	at91_rstc_t *rstc = (at91_rstc_t *) AT91_RSTC_BASE; -	/* this is the way Linux does it */ - -	writel(AT91_RSTC_KEY | AT91_RSTC_CR_PROCRST | AT91_RSTC_CR_PERRST, -		&rstc->cr); - -	while (1); -	/* Never reached */ +	writel(AT91_RSTC_KEY +		| AT91_RSTC_CR_PROCRST	/* Processor Reset */ +		| AT91_RSTC_CR_PERRST	/* Peripheral Reset */ +#ifdef CONFIG_AT91RESET_EXTRST +		| AT91_RSTC_CR_EXTRST	/* External Reset (assert nRST pin) */ +#endif +		, &rstc->cr); +	/* never reached */ +	while (1) +		;  } diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c index d21eebfb4..8efc34bcf 100644 --- a/arch/arm/cpu/arm926ejs/at91/timer.c +++ b/arch/arm/cpu/arm926ejs/at91/timer.c @@ -138,8 +138,5 @@ ulong get_timer(ulong base)   */  ulong get_tbclk(void)  { -	ulong tbclk; - -	tbclk = CONFIG_SYS_HZ; -	return tbclk; +	return timer_freq;  } diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c index c63e8641f..82c978bd9 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c @@ -81,7 +81,7 @@ unsigned int kw_winctrl_calcsize(unsigned int sizeval)  	unsigned int j = 0;  	u32 val = sizeval >> 1; -	for (i = 0; val > 0x10000; i++) { +	for (i = 0; val >= 0x10000; i++) {  		j |= (1 << i);  		val = val >> 1;  	} diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/Makefile b/arch/arm/cpu/arm926ejs/mb86r0x/Makefile new file mode 100644 index 000000000..ce3e5a5a5 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mb86r0x/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)lib$(SOC).a + +COBJS	= clock.o reset.o timer.o +SOBJS	= + +SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS)) +START	:= $(addprefix $(obj),$(START)) + +all:	$(obj).depend $(LIB) + +$(LIB):	$(OBJS) +	$(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/clock.c b/arch/arm/cpu/arm926ejs/mb86r0x/clock.c new file mode 100644 index 000000000..70c8c8b04 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mb86r0x/clock.c @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2010 + * Matthias Weisser <weisserm@arcor.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +/* + * Get the peripheral bus frequency depending on pll pin settings + */ +ulong get_bus_freq(ulong dummy) +{ +	struct mb86r0x_crg * crg = (struct mb86r0x_crg *) +					MB86R0x_CRG_BASE; +	uint32_t pllmode; + +	pllmode = readl(&crg->crpr) & MB86R0x_CRG_CRPR_PLLMODE; + +	if (pllmode == MB86R0x_CRG_CRPR_PLLMODE_X20) +		return 40000000; + +	return 41164767; +} diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/reset.c b/arch/arm/cpu/arm926ejs/mb86r0x/reset.c new file mode 100644 index 000000000..e7f0f6788 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mb86r0x/reset.c @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2010 + * Matthias Weisser <weisserm@arcor.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +/* + * Reset the cpu by setting software reset request bit + */ +void reset_cpu(ulong ignored) +{ +	struct mb86r0x_crg * crg = (struct mb86r0x_crg *) +					MB86R0x_CRG_BASE; + +	writel(MB86R0x_CRSR_SWRSTREQ, &crg->crsr); +	while (1) +		/* NOP */; +	/* Never reached */ +} diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/timer.c b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c new file mode 100644 index 000000000..9175b71d1 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian.pop@leadtechdesign.com> + * Lead Tech Design <www.leadtechdesign.com> + * + * (C) Copyright 2010 + * Matthias Weisser, Graf-Syteco <weisserm@arcor.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <div64.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +#define TIMER_LOAD_VAL	0xffffffff +#define TIMER_FREQ	(CONFIG_MB86R0x_IOCLK  / 256) + +static unsigned long long timestamp; +static ulong lastdec; + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ +	tick *= CONFIG_SYS_HZ; +	do_div(tick, TIMER_FREQ); + +	return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ +	usec *= TIMER_FREQ; +	do_div(usec, 1000000); + +	return usec; +} + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init(void) +{ +	struct mb86r0x_timer * timer = (struct mb86r0x_timer *) +					MB86R0x_TIMER_BASE; +	ulong ctrl = readl(&timer->control); + +	writel(TIMER_LOAD_VAL, &timer->load); + +	ctrl |= MB86R0x_TIMER_ENABLE | MB86R0x_TIMER_PRS_8S | +		MB86R0x_TIMER_SIZE_32; + +	writel(ctrl, &timer->control); + +	reset_timer_masked(); + +	return 0; +} + +/* + * timer without interrupts + */ +unsigned long long get_ticks(void) +{ +	struct mb86r0x_timer * timer = (struct mb86r0x_timer *) +					MB86R0x_TIMER_BASE; +	ulong now = readl(&timer->value); + +	if (now <= lastdec) { +		/* normal mode (non roll) */ +		/* move stamp forward with absolut diff ticks */ +		timestamp += lastdec - now; +	} else { +		/* we have rollover of incrementer */ +		timestamp += lastdec + TIMER_LOAD_VAL - now; +	} +	lastdec = now; +	return timestamp; +} + +void reset_timer_masked(void) +{ +	struct mb86r0x_timer * timer = (struct mb86r0x_timer *) +					MB86R0x_TIMER_BASE; + +	/* capture current value time */ +	lastdec = readl(&timer->value); +	timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked(void) +{ +	return tick_to_time(get_ticks()); +} + +void __udelay(unsigned long usec) +{ +	unsigned long long tmp; +	ulong tmo; + +	tmo = usec_to_tick(usec); +	tmp = get_ticks();			/* get current timestamp */ + +	while ((get_ticks() - tmp) < tmo)	/* loop till event */ +		 /*NOP*/; +} + +void reset_timer(void) +{ +	reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ +	return get_timer_masked() - base; +} + +/* + * 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) +{ +	ulong tbclk; + +	tbclk = TIMER_FREQ; +	return tbclk; +} diff --git a/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/arch/arm/cpu/arm926ejs/orion5x/cpu.c index 3740e33e9..260f88b46 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/cpu.c +++ b/arch/arm/cpu/arm926ejs/orion5x/cpu.c @@ -61,7 +61,7 @@ unsigned int orion5x_winctrl_calcsize(unsigned int sizeval)  	unsigned int j = 0;  	u32 val = sizeval >> 1; -	for (i = 0; val > 0x10000; i++) { +	for (i = 0; val >= 0x10000; i++) {  		j |= (1 << i);  		val = val >> 1;  	} diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 3a4a304e4..caee7263b 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)libomap-common.a  SOBJS	:= reset.o +  COBJS	:= timer.o +COBJS	+= syslib.o  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/armv7/omap-common/reset.S b/arch/arm/cpu/armv7/omap-common/reset.S index a53c40819..838b1221e 100644 --- a/arch/arm/cpu/armv7/omap-common/reset.S +++ b/arch/arm/cpu/armv7/omap-common/reset.S @@ -27,10 +27,12 @@  reset_cpu:  	ldr	r1, rstctl			@ get addr for global reset  						@ reg -	mov	r3, #0x2			@ full reset pll + mpu +	ldr	r3, rstbit			@ sw reset bit  	str	r3, [r1]			@ force reset  	mov	r0, r0  _loop_forever:  	b	_loop_forever  rstctl:  	.word	PRM_RSTCTRL +rstbit: +	.word	PRM_RSTCTRL_RESET diff --git a/arch/arm/cpu/armv7/omap3/syslib.c b/arch/arm/cpu/armv7/omap-common/syslib.c index 9ced495c8..f9ed9a307 100644 --- a/arch/arm/cpu/armv7/omap3/syslib.c +++ b/arch/arm/cpu/armv7/omap-common/syslib.c @@ -23,8 +23,6 @@  #include <common.h>  #include <asm/io.h> -#include <asm/arch/mem.h> -#include <asm/arch/clocks.h>  #include <asm/arch/sys_proto.h>  /************************************************************ diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile index 79ae26706..95526d689 100644 --- a/arch/arm/cpu/armv7/omap3/Makefile +++ b/arch/arm/cpu/armv7/omap3/Makefile @@ -32,7 +32,6 @@ COBJS	+= board.o  COBJS	+= clock.o  COBJS	+= gpio.o  COBJS	+= mem.o -COBJS	+= syslib.o  COBJS	+= sys_info.o  COBJS-$(CONFIG_EMIF4)	+= emif4.o diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 69e56f55c..6c2a132b6 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -120,41 +120,6 @@ void secureworld_exit()  }  /****************************************************************************** - * Routine: setup_auxcr() - * Description: Write to AuxCR desired value using SMI. - *              general use. - *****************************************************************************/ -void setup_auxcr() -{ -	unsigned long i; -	volatile unsigned int j; -	/* Save r0, r12 and restore them after usage */ -	__asm__ __volatile__("mov %0, r12":"=r"(j)); -	__asm__ __volatile__("mov %0, r0":"=r"(i)); - -	/* -	 * GP Device ROM code API usage here -	 * r12 = AUXCR Write function and r0 value -	 */ -	__asm__ __volatile__("mov r12, #0x3"); -	__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1"); -	/* Enabling ASA */ -	__asm__ __volatile__("orr r0, r0, #0x10"); -	/* Enable L1NEON */ -	__asm__ __volatile__("orr r0, r0, #1 << 5"); -	/* SMI instruction to call ROM Code API */ -	__asm__ __volatile__(".word 0xE1600070"); -	/* Set PLD_FWD bit in L2AUXCR (Cortex-A8 erratum 725233 workaround) */ -	__asm__ __volatile__("mov r12, #0x2"); -	__asm__ __volatile__("mrc p15, 1, r0, c9, c0, 2"); -	__asm__ __volatile__("orr r0, r0, #1 << 27"); -	/* SMI instruction to call ROM Code API */ -	__asm__ __volatile__(".word 0xE1600070"); -	__asm__ __volatile__("mov r0, %0":"=r"(i)); -	__asm__ __volatile__("mov r12, %0":"=r"(j)); -} - -/******************************************************************************   * Routine: try_unlock_sram()   * Description: If chip is GP/EMU(special) type, unlock the SRAM for   *              general use. diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S index 4b65ac58a..24e950f38 100644 --- a/arch/arm/cpu/armv7/omap3/cache.S +++ b/arch/arm/cpu/armv7/omap3/cache.S @@ -43,6 +43,7 @@  .global invalidate_dcache  .global l2_cache_enable  .global l2_cache_disable +.global setup_auxcr  /*   *	invalidate_dcache() @@ -128,64 +129,56 @@ finished_inval:  	ldmfd	r13!, {r0 - r5, r7, r9 - r12, pc} - -l2_cache_enable: -	stmfd	r13!, {r0, r1, r2, lr} -	@ ES2 onwards we can disable/enable L2 ourselves +l2_cache_set: +	stmfd	r13!, {r4 - r6, lr} +	mov	r5,  r0  	bl	get_cpu_rev -	cmp	r0, #CPU_3XX_ES20 -	blt	l2_cache_disable_EARLIER_THAN_ES2 -	mrc	15, 0, r3, cr1, cr0, 1 -	orr	r3, r3, #2 -	mcr	15, 0, r3, cr1, cr0, 1 -	b	l2_cache_enable_END -l2_cache_enable_EARLIER_THAN_ES2: -	@ Save r0, r12 and restore them after usage -	mov	r3, ip -	str	r3, [sp, #4] -	mov	r3, r0 -	@ +	mov	r4,  r0 +	bl	get_cpu_family +	@ ES2 onwards we can disable/enable L2 ourselves +	cmp	r0,  #CPU_OMAP34XX +	cmpeq	r4,  #CPU_3XX_ES10 +	mrc	15, 0, r0, cr1, cr0, 1 +	bic	r0, r0, #2 +	orr	r0, r0, r5, lsl #1 +	mcreq	15, 0, r0, cr1, cr0, 1  	@ GP Device ROM code API usage here  	@ r12 = AUXCR Write function and r0 value -	@  	mov	ip, #3 -	mrc	15, 0, r0, cr1, cr0, 1 -	orr	r0, r0, #2 -	@ SMI instruction to call ROM Code API -	.word	0xe1600070 -	mov	r0, r3 -	mov	ip, r3 -	str	r3, [sp, #4] -l2_cache_enable_END: -	ldmfd	r13!, {r1, r2, r3, pc} +	@ SMCNE instruction to call ROM Code API +	.word	0x11600070 +	ldmfd	r13!, {r4 - r6, pc} +l2_cache_enable: +	mov	r0, #1 +	b	l2_cache_set  l2_cache_disable: -	stmfd	r13!, {r0, r1, r2, lr} -	@ ES2 onwards we can disable/enable L2 ourselves -	bl	get_cpu_rev -	cmp	r0, #CPU_3XX_ES20 -	blt	l2_cache_disable_EARLIER_THAN_ES2 -	mrc	15, 0, r3, cr1, cr0, 1 -	bic	r3, r3, #2 -	mcr	15, 0, r3, cr1, cr0, 1 -	b	l2_cache_disable_END -l2_cache_disable_EARLIER_THAN_ES2: -	@ Save r0, r12 and restore them after usage -	mov	r3, ip -	str	r3, [sp, #4] -	mov	r3, r0 -	@ -	@ GP Device ROM code API usage here -	@ r12 = AUXCR Write function and r0 value -	@ -	mov	ip, #3 -	mrc	15, 0, r0, cr1, cr0, 1 -	bic	r0, r0, #2 -	@ SMI instruction to call ROM Code API -	.word	0xe1600070 -	mov	r0, r3 -	mov	ip, r3 -	str	r3, [sp, #4] -l2_cache_disable_END: -	ldmfd	r13!, {r1, r2, r3, pc} +	mov	r0, #0 +	b	l2_cache_set + +/****************************************************************************** + * Routine: setup_auxcr() + * Description: Write to AuxCR desired value using SMI. + *              general use. + *****************************************************************************/ +setup_auxcr: +	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register +	and	r2, r0, #0x00f00000		@ variant +	and	r3, r0, #0x0000000f		@ revision +	orr	r1, r3, r2, lsr #20-4		@ combine variant and revision +	mov	r12, #0x3 +	mrc	p15, 0, r0, c1, c0, 1 +	orr	r0, r0, #0x10			@ Enable ASA +	@ Enable L1NEON on pre-r2p1 (erratum 621766 workaround) +	cmp	r1, #0x21 +	orrlt	r0, r0, #1 << 5 +	.word 0xE1600070			@ SMC +	mov	r12, #0x2 +	mrc	p15, 1, r0, c9, c0, 2 +	@ Set PLD_FWD bit in L2AUXCR on pre-r2p1 (erratum 725233 workaround) +	cmp	r1, #0x21 +	orrlt	r0, r0, #1 << 27 +	.word 0xE1600070			@ SMC +	bx	lr + diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c index 6330c9e5d..2238c52e3 100644 --- a/arch/arm/cpu/armv7/omap3/clock.c +++ b/arch/arm/cpu/armv7/omap3/clock.c @@ -50,12 +50,7 @@ u32 get_osc_clk_speed(void)  	if (val & SYSCLKDIV_2)  		cdiv = 2; -	else if (val & SYSCLKDIV_1) -		cdiv = 1;  	else -		/* -		 * Should never reach here! (Assume divider as 1) -		 */  		cdiv = 1;  	/* enable timer2 */ @@ -89,11 +84,7 @@ u32 get_osc_clk_speed(void)  	while (readl(&s32k_base->s32k_cr) < (start + 20)) ;  	cend = readl(&gpt1_base->tcrr);		/* get end sys_clk count */  	cdiff = cend - cstart;			/* get elapsed ticks */ - -	if (cdiv == 2) -	{ -		cdiff *= 2; -	} +	cdiff *= cdiv;  	/* based on number of ticks assign speed */  	if (cdiff > 19000) @@ -135,65 +126,22 @@ void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)  	}  } -/****************************************************************************** - * prcm_init() - inits clocks for PRCM as defined in clocks.h - *               called from SRAM, or Flash (using temp SRAM stack). - *****************************************************************************/ -void prcm_init(void) +/* + * OMAP34XX/35XX specific functions + */ + +static void dpll3_init_34xx(u32 sil_index, u32 clk_index)  { +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_core_dpll_param();  	void (*f_lock_pll) (u32, u32, u32, u32);  	int xip_safe, p0, p1, p2, p3; -	u32 osc_clk = 0, sys_clkin_sel; -	u32 clk_index, sil_index = 0; -	struct prm *prm_base = (struct prm *)PRM_BASE; -	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; -	dpll_param *dpll_param_p; - -	f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + -				SRAM_VECT_CODE);  	xip_safe = is_running_in_sram(); -	/* -	 * Gauge the input clock speed and find out the sys_clkin_sel -	 * value corresponding to the input clock. -	 */ -	osc_clk = get_osc_clk_speed(); -	get_sys_clkin_sel(osc_clk, &sys_clkin_sel); - -	/* set input crystal speed */ -	sr32(&prm_base->clksel, 0, 3, sys_clkin_sel); - -	/* If the input clock is greater than 19.2M always divide/2 */ -	if (sys_clkin_sel > 2) { -		/* input clock divider */ -		sr32(&prm_base->clksrc_ctrl, 6, 2, 2); -		clk_index = sys_clkin_sel / 2; -	} else { -		/* input clock divider */ -		sr32(&prm_base->clksrc_ctrl, 6, 2, 1); -		clk_index = sys_clkin_sel; -	} - -	/* -	 * The DPLL tables are defined according to sysclk value and -	 * silicon revision. The clk_index value will be used to get -	 * the values for that input sysclk from the DPLL param table -	 * and sil_index will get the values for that SysClk for the -	 * appropriate silicon rev. -	 */ -	if (get_cpu_rev()) -		sil_index = 1; - -	/* Unlock MPU DPLL (slows things down, and needed later) */ -	sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); -	wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); +	/* Moving to the right sysclk and ES rev base */ +	ptr = ptr + (3 * clk_index) + sil_index; -	/* Getting the base address of Core DPLL param table */ -	dpll_param_p = (dpll_param *) get_core_dpll_param(); - -	/* Moving it to the right sysclk and ES rev base */ -	dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;  	if (xip_safe) {  		/*  		 * CORE DPLL @@ -208,34 +156,38 @@ void prcm_init(void)  		 * work. write another value and then default value.  		 */ -		/* m3x2 */ -		sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1); -		/* m3x2 */ +		/* CM_CLKSEL1_EMU[DIV_DPLL3] */ +		sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;  		sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2); -		/* Set M2 */ -		sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2); -		/* Set M */ -		sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m); -		/* Set N */ -		sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n); -		/* 96M Src */ + +		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ +		sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2); + +		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ +		sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m); + +		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ +		sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n); + +		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */  		sr32(&prcm_base->clksel1_pll, 6, 1, 0); -		/* ssi */ + +		/* SSI */  		sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV); -		/* fsusb */ +		/* FSUSB */  		sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV); -		/* l4 */ +		/* L4 */  		sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV); -		/* l3 */ +		/* L3 */  		sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV); -		/* gfx */ -		sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV); -		/* reset mgr */ +		/* GFX */ +		sr32(&prcm_base->clksel_gfx,  0, 3, GFX_DIV); +		/* RESET MGR */  		sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM); -		/* FREQSEL */ -		sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel); -		/* lock mode */ -		sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK); +		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ +		sr32(&prcm_base->clken_pll,   4, 4, ptr->fsel); +		/* LOCK MODE */ +		sr32(&prcm_base->clken_pll,   0, 3, PLL_LOCK);  		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,  				LDELAY); @@ -244,102 +196,405 @@ void prcm_init(void)  		 * if running from flash, jump to small relocated code  		 * area in SRAM.  		 */ +		f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + +				SRAM_VECT_CODE); +  		p0 = readl(&prcm_base->clken_pll);  		sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS); -		sr32(&p0, 4, 4, dpll_param_p->fsel);	/* FREQSEL */ +		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ +		sr32(&p0, 4, 4, ptr->fsel);  		p1 = readl(&prcm_base->clksel1_pll); -		sr32(&p1, 27, 2, dpll_param_p->m2);	/* Set M2 */ -		sr32(&p1, 16, 11, dpll_param_p->m);	/* Set M */ -		sr32(&p1, 8, 7, dpll_param_p->n);		/* Set N */ -		sr32(&p1, 6, 1, 0);	/* set source for 96M */ +		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ +		sr32(&p1, 27, 5, ptr->m2); +		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ +		sr32(&p1, 16, 11, ptr->m); +		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ +		sr32(&p1, 8, 7, ptr->n); +		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ +		sr32(&p1, 6, 1, 0);  		p2 = readl(&prcm_base->clksel_core); -		sr32(&p2, 8, 4, CORE_SSI_DIV);	/* ssi */ -		sr32(&p2, 4, 2, CORE_FUSB_DIV);	/* fsusb */ -		sr32(&p2, 2, 2, CORE_L4_DIV);	/* l4 */ -		sr32(&p2, 0, 2, CORE_L3_DIV);	/* l3 */ +		/* SSI */ +		sr32(&p2, 8, 4, CORE_SSI_DIV); +		/* FSUSB */ +		sr32(&p2, 4, 2, CORE_FUSB_DIV); +		/* L4 */ +		sr32(&p2, 2, 2, CORE_L4_DIV); +		/* L3 */ +		sr32(&p2, 0, 2, CORE_L3_DIV);  		p3 = (u32)&prcm_base->idlest_ckgen;  		(*f_lock_pll) (p0, p1, p2, p3);  	} +} -	/* PER DPLL */ -	sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP); -	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); - -	/* Getting the base address to PER DPLL param table */ - -	/* Set N */ -	dpll_param_p = (dpll_param *) get_per_dpll_param(); +static void dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_per_dpll_param();  	/* Moving it to the right sysclk base */ -	dpll_param_p = dpll_param_p + clk_index; +	ptr = ptr + clk_index; + +	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ +	sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP); +	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);  	/*  	 * Errata 1.50 Workaround for OMAP3 ES1.0 only  	 * If using default divisors, write default divisor + 1  	 * and then the actual divisor value  	 */ -	sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1);	/* set M6 */ -	sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);		/* set M6 */ -	sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1);	/* set M5 */ -	sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);		/* set M5 */ -	sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1);	/* set M4 */ -	sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);		/* set M4 */ -	sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1);	/* set M3 */ -	sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);		/* set M3 */ -	sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */ -	sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2);	/* set M2 */ +	/* M6 */ +	sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1)); +	sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); +	/* M5 */ +	sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1)); +	sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); +	/* M4 */ +	sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1)); +	sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); +	/* M3 */ +	sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1)); +	sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); +	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ +	sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1)); +	sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);  	/* Workaround end */ -	sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m);	/* set m */ -	sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n);	/* set n */ -	sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel);	/* FREQSEL */ -	sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);		/* lock mode */ +	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ +	sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m); + +	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ +	sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n); + +	/* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ +	sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel); + +	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ +	sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);  	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); +} -	/* Getting the base address to MPU DPLL param table */ -	dpll_param_p = (dpll_param *) get_mpu_dpll_param(); +static void mpu_init_34xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_mpu_dpll_param(); -	/* Moving it to the right sysclk and ES rev base */ -	dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; +	/* Moving to the right sysclk and ES rev base */ +	ptr = ptr + (3 * clk_index) + sil_index;  	/* MPU DPLL (unlocked already) */ -	/* Set M2 */ -	sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2); -	/* Set M */ -	sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m); -	/* Set N */ -	sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n); -	/* FREQSEL */ -	sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel); -	/* lock mode */ -	sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); -	wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); +	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ +	sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2); + +	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ +	sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m); + +	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ +	sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n); + +	/* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ +	sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel); +} + +static void iva_init_34xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_iva_dpll_param(); + +	/* Moving to the right sysclk and ES rev base */ +	ptr = ptr + (3 * clk_index) + sil_index; + +	/* IVA DPLL */ +	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ +	sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP); +	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); + +	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ +	sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2); + +	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ +	sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m); + +	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ +	sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n); + +	/* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ +	sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel); + +	/* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ +	sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK); + +	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ + +static void dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param(); +	void (*f_lock_pll) (u32, u32, u32, u32); +	int xip_safe, p0, p1, p2, p3; + +	xip_safe = is_running_in_sram(); + +	/* Moving it to the right sysclk base */ +	ptr += clk_index; + +	if (xip_safe) { +		/* CORE DPLL */ + +		/* Select relock bypass: CM_CLKEN_PLL[0:2] */ +		sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS); +		wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen, +				LDELAY); + +		/* CM_CLKSEL1_EMU[DIV_DPLL3] */ +		sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2); + +		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ +		sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2); + +		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ +		sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m); + +		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ +		sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n); + +		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ +		sr32(&prcm_base->clksel1_pll, 6, 1, 0); + +		/* SSI */ +		sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV); +		/* FSUSB */ +		sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV); +		/* L4 */ +		sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV); +		/* L3 */ +		sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV); +		/* GFX */ +		sr32(&prcm_base->clksel_gfx,  0, 3, GFX_DIV); +		/* RESET MGR */ +		sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM); +		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ +		sr32(&prcm_base->clken_pll,   4, 4, ptr->fsel); +		/* LOCK MODE */ +		sr32(&prcm_base->clken_pll,   0, 3, PLL_LOCK); + +		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen, +				LDELAY); +	} else if (is_running_in_flash()) { +		/* +		 * if running from flash, jump to small relocated code +		 * area in SRAM. +		 */ +		f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start + +				SRAM_VECT_CODE); + +		p0 = readl(&prcm_base->clken_pll); +		sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS); +		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ +		sr32(&p0, 4, 4, ptr->fsel); + +		p1 = readl(&prcm_base->clksel1_pll); +		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ +		sr32(&p1, 27, 5, ptr->m2); +		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ +		sr32(&p1, 16, 11, ptr->m); +		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ +		sr32(&p1, 8, 7, ptr->n); +		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ +		sr32(&p1, 6, 1, 0); + +		p2 = readl(&prcm_base->clksel_core); +		/* SSI */ +		sr32(&p2, 8, 4, CORE_SSI_DIV); +		/* FSUSB */ +		sr32(&p2, 4, 2, CORE_FUSB_DIV); +		/* L4 */ +		sr32(&p2, 2, 2, CORE_L4_DIV); +		/* L3 */ +		sr32(&p2, 0, 2, CORE_L3_DIV); + +		p3 = (u32)&prcm_base->idlest_ckgen; + +		(*f_lock_pll) (p0, p1, p2, p3); +	} +} + +static void dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	struct dpll_per_36x_param *ptr; + +	ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + +	/* Moving it to the right sysclk base */ +	ptr += clk_index; + +	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ +	sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP); +	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); + +	/* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ +	sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6); + +	/* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ +	sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5); + +	/* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ +	sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4); + +	/* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ +	sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3); + +	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ +	sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2); + +	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ +	sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m); + +	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ +	sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n); + +	/* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ +	sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div); + +	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ +	sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); +	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); +} + +static void mpu_init_36xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param(); + +	/* Moving to the right sysclk */ +	ptr += clk_index; + +	/* MPU DPLL (unlocked already */ + +	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ +	sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2); + +	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ +	sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m); -	/* Getting the base address to IVA DPLL param table */ -	dpll_param_p = (dpll_param *) get_iva_dpll_param(); +	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ +	sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n); +} + +static void iva_init_36xx(u32 sil_index, u32 clk_index) +{ +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; +	dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param(); -	/* Moving it to the right sysclk and ES rev base */ -	dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; +	/* Moving to the right sysclk */ +	ptr += clk_index; -	/* IVA DPLL (set to 12*20=240MHz) */ +	/* IVA DPLL */ +	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */  	sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);  	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); -	/* set M2 */ -	sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2); -	/* set M */ -	sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m); -	/* set N */ -	sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n); -	/* FREQSEL */ -	sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel); -	/* lock mode */ + +	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ +	sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2); + +	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ +	sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m); + +	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ +	sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n); + +	/* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */  	sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK); +  	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY); +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + *               called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ +	u32 osc_clk = 0, sys_clkin_sel; +	u32 clk_index, sil_index = 0; +	struct prm *prm_base = (struct prm *)PRM_BASE; +	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + +	/* +	 * Gauge the input clock speed and find out the sys_clkin_sel +	 * value corresponding to the input clock. +	 */ +	osc_clk = get_osc_clk_speed(); +	get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + +	/* set input crystal speed */ +	sr32(&prm_base->clksel, 0, 3, sys_clkin_sel); + +	/* If the input clock is greater than 19.2M always divide/2 */ +	if (sys_clkin_sel > 2) { +		/* input clock divider */ +		sr32(&prm_base->clksrc_ctrl, 6, 2, 2); +		clk_index = sys_clkin_sel / 2; +	} else { +		/* input clock divider */ +		sr32(&prm_base->clksrc_ctrl, 6, 2, 1); +		clk_index = sys_clkin_sel; +	} + +	if (get_cpu_family() == CPU_OMAP36XX) { +		/* Unlock MPU DPLL (slows things down, and needed later) */ +		sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); +		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, +				LDELAY); + +		dpll3_init_36xx(0, clk_index); +		dpll4_init_36xx(0, clk_index); +		iva_init_36xx(0, clk_index); +		mpu_init_36xx(0, clk_index); + +		/* Lock MPU DPLL to set frequency */ +		sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); +		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, +				LDELAY); +	} else { +		/* +		 * The DPLL tables are defined according to sysclk value and +		 * silicon revision. The clk_index value will be used to get +		 * the values for that input sysclk from the DPLL param table +		 * and sil_index will get the values for that SysClk for the +		 * appropriate silicon rev. +		 */ +		if (((get_cpu_family() == CPU_OMAP34XX) +				&& (get_cpu_rev() >= CPU_3XX_ES20)) || +			(get_cpu_family() == CPU_AM35XX)) +			sil_index = 1; + +		/* Unlock MPU DPLL (slows things down, and needed later) */ +		sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); +		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, +				LDELAY); + +		dpll3_init_34xx(sil_index, clk_index); +		dpll4_init_34xx(sil_index, clk_index); +		iva_init_34xx(sil_index, clk_index); +		mpu_init_34xx(sil_index, clk_index); + +		/* Lock MPU DPLL to set frequency */ +		sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); +		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, +				LDELAY); +	}  	/* Set up GPTimers to sys_clk source only */  	sr32(&prcm_base->clksel_per, 0, 8, 0xff); diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S index 73063ec8e..91c6dbcc0 100644 --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S @@ -359,3 +359,72 @@ per_dpll_param:  get_per_dpll_param:  	adr	r0, per_dpll_param  	mov	pc, lr + +/* + * Tables for 36XX/37XX devices + * + */ +mpu_36x_dpll_param: +/* 12MHz */ +.word 50, 0, 0, 1 +/* 13MHz */ +.word 600, 12, 0, 1 +/* 19.2MHz */ +.word 125, 3, 0, 1 +/* 26MHz */ +.word 300, 12, 0, 1 +/* 38.4MHz */ +.word 125, 7, 0, 1 + +iva_36x_dpll_param: +/* 12MHz */ +.word 130, 2, 0, 1 +/* 13MHz */ +.word 20, 0, 0, 1 +/* 19.2MHz */ +.word 325, 11, 0, 1 +/* 26MHz */ +.word 10, 0, 0, 1 +/* 38.4MHz */ +.word 325, 23, 0, 1 + +core_36x_dpll_param: +/* 12MHz */ +.word 100, 2, 0, 1 +/* 13MHz */ +.word 400, 12, 0, 1 +/* 19.2MHz */ +.word 375, 17, 0, 1 +/* 26MHz */ +.word 200, 12, 0, 1 +/* 38.4MHz */ +.word 375, 35, 0, 1 + +per_36x_dpll_param: +/*    SYSCLK    M       N      M2      M3      M4     M5      M6      m2DIV */ +.word 12000,    360,    4,     9,      16,     5,     4,      3,      1 +.word 13000,    864,   12,     9,      16,     9,     4,      3,      1 +.word 19200,    360,    7,     9,      16,     5,     4,      3,      1 +.word 26000,    432,   12,     9,      16,     9,     4,      3,      1 +.word 38400,    360,   15,     9,      16,     5,     4,      3,      1 + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: +	adr	r0, mpu_36x_dpll_param +	mov	pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: +	adr	r0, iva_36x_dpll_param +	mov	pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: +	adr	r0, core_36x_dpll_param +	mov	pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: +	adr	r0, per_36x_dpll_param +	mov	pc, lr + diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 96fd990c7..890522443 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -107,18 +107,12 @@ u32 get_sdr_cs_offset(u32 cs)  /*   * do_sdrc_init -   *  - Initialize the SDRAM for use. - *  - Sets up SDRC timings for CS0   *  - code called once in C-Stack only context for CS0 and a possible 2nd   *    time depending on memory configuration from stack+global context   */  void do_sdrc_init(u32 cs, u32 early)  { -	struct sdrc_actim *sdrc_actim_base; - -	if (cs) -		sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; -	else -		sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; +	struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1;  	if (early) {  		/* reset sdrc controller */ @@ -138,24 +132,29 @@ void do_sdrc_init(u32 cs, u32 early)  		sdelay(0x20000);  	} -	writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY | -			RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 | -			DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg); -	writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl); -	writel(V_ACTIMA_165, &sdrc_actim_base->ctrla); -	writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb); - -	writel(CMD_NOP, &sdrc_base->cs[cs].manual); -	writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); -	writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); -	writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); -  	/* -	 * CAS latency 3, Write Burst = Read Burst, Serial Mode, -	 * Burst length = 4 +	 * SDRC timings are set up by x-load or config header +	 * We don't need to redo them here. +	 * Older x-loads configure only CS0 +	 * configure CS1 to handle this ommission  	 */ -	writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr); +	if (cs) { +		sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; +		sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; +		writel(readl(&sdrc_base->cs[CS0].mcfg), +			&sdrc_base->cs[CS1].mcfg); +		writel(readl(&sdrc_base->cs[CS0].rfr_ctrl), +			&sdrc_base->cs[CS1].rfr_ctrl); +		writel(readl(&sdrc_actim_base0->ctrla), +			&sdrc_actim_base1->ctrla); +		writel(readl(&sdrc_actim_base0->ctrlb), +			&sdrc_actim_base1->ctrlb); +	} +	/* +	 * Test ram in this bank +	 * Disable if bad or not present +	 */  	if (!mem_ok(cs))  		writel(0, &sdrc_base->cs[cs].mcfg);  } diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c index 1df4401d4..549ac1918 100644 --- a/arch/arm/cpu/armv7/omap3/sys_info.c +++ b/arch/arm/cpu/armv7/omap3/sys_info.c @@ -38,7 +38,10 @@ static char *rev_s[CPU_3XX_MAX_REV] = {  				"2.0",  				"2.1",  				"3.0", -				"3.1"}; +				"3.1", +				"UNKNOWN", +				"UNKNOWN", +				"3.1.2"};  /*****************************************************************   * dieid_num_r(void) - read and set die ID @@ -75,32 +78,81 @@ u32 get_cpu_type(void)  }  /****************************************** - * get_cpu_rev(void) - extract version info + * get_cpu_id(void) - extract cpu id + * returns 0 for ES1.0, cpuid otherwise   ******************************************/ -u32 get_cpu_rev(void) +u32 get_cpu_id(void)  { -	u32 cpuid = 0;  	struct ctrl_id *id_base; +	u32 cpuid = 0;  	/*  	 * On ES1.0 the IDCODE register is not exposed on L4  	 * so using CPU ID to differentiate between ES1.0 and > ES1.0.  	 */  	__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); -	if ((cpuid & 0xf) == 0x0) -		return CPU_3XX_ES10; -	else { +	if ((cpuid & 0xf) == 0x0) { +		return 0; +	} else {  		/* Decode the IDs on > ES1.0 */  		id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE; -		cpuid = (readl(&id_base->idcode) >> CPU_3XX_ID_SHIFT) & 0xf; +		cpuid = readl(&id_base->idcode); +	} + +	return cpuid; +} + +/****************************************** + * get_cpu_family(void) - extract cpu info + ******************************************/ +u32 get_cpu_family(void) +{ +	u16 hawkeye; +	u32 cpu_family; +	u32 cpuid = get_cpu_id(); -		/* Some early ES2.0 seem to report ID 0, fix this */ -		if(cpuid == 0) -			cpuid = CPU_3XX_ES20; +	if (cpuid == 0) +		return CPU_OMAP34XX; -		return cpuid; +	hawkeye = (cpuid >> HAWKEYE_SHIFT) & 0xffff; +	switch (hawkeye) { +	case HAWKEYE_OMAP34XX: +		cpu_family = CPU_OMAP34XX; +		break; +	case HAWKEYE_AM35XX: +		cpu_family = CPU_AM35XX; +		break; +	case HAWKEYE_OMAP36XX: +		cpu_family = CPU_OMAP36XX; +		break; +	default: +		cpu_family = CPU_OMAP34XX;  	} + +	return cpu_family; +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ +	u32 cpuid = get_cpu_id(); + +	if (cpuid == 0) +		return CPU_3XX_ES10; +	else +		return (cpuid >> CPU_3XX_ID_SHIFT) & 0xf; +} + +/***************************************************************** + * get_sku_id(void) - read sku_id to get info on max clock rate + *****************************************************************/ +u32 get_sku_id(void) +{ +	struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; +	return readl(&id_base->sku_id) & SKUID_CLK_MASK;  }  /*************************************************************************** @@ -213,24 +265,66 @@ u32 get_device_type(void)   */  int print_cpuinfo (void)  { -	char *cpu_s, *sec_s; +	char *cpu_family_s, *cpu_s, *sec_s, *max_clk; + +	switch (get_cpu_family()) { +	case CPU_OMAP34XX: +		cpu_family_s = "OMAP"; +		switch (get_cpu_type()) { +		case OMAP3503: +			cpu_s = "3503"; +			break; +		case OMAP3515: +			cpu_s = "3515"; +			break; +		case OMAP3525: +			cpu_s = "3525"; +			break; +		case OMAP3530: +			cpu_s = "3530"; +			break; +		default: +			cpu_s = "35XX"; +			break; +		} +		if ((get_cpu_rev() >= CPU_3XX_ES31) && +		    (get_sku_id() == SKUID_CLK_720MHZ)) +			max_clk = "720 mHz"; +		else +			max_clk = "600 mHz"; -	switch (get_cpu_type()) { -	case OMAP3503: -		cpu_s = "3503"; -		break; -	case OMAP3515: -		cpu_s = "3515";  		break; -	case OMAP3525: -		cpu_s = "3525"; +	case CPU_AM35XX: +		cpu_family_s = "AM"; +		switch (get_cpu_type()) { +		case AM3505: +			cpu_s = "3505"; +			break; +		case AM3517: +			cpu_s = "3517"; +			break; +		default: +			cpu_s = "35XX"; +			break; +		} +		max_clk = "600 Mhz";  		break; -	case OMAP3530: -		cpu_s = "3530"; +	case CPU_OMAP36XX: +		cpu_family_s = "OMAP"; +		switch (get_cpu_type()) { +		case OMAP3730: +			cpu_s = "3630/3730"; +			break; +		default: +			cpu_s = "36XX/37XX"; +			break; +		} +		max_clk = "1 Ghz";  		break;  	default: +		cpu_family_s = "OMAP";  		cpu_s = "35XX"; -		break; +		max_clk = "600 Mhz";  	}  	switch (get_device_type()) { @@ -250,8 +344,9 @@ int print_cpuinfo (void)  		sec_s = "?";  	} -	printf("OMAP%s-%s ES%s, CPU-OPP2 L3-165MHz\n", -			cpu_s, sec_s, rev_s[get_cpu_rev()]); +	printf("%s%s-%s ES%s, CPU-OPP2, L3-165MHz, Max CPU Clock %s\n", +			cpu_family_s, cpu_s, sec_s, +			rev_s[get_cpu_rev()], max_clk);  	return 0;  } diff --git a/arch/arm/cpu/armv7/s5p-common/Makefile b/arch/arm/cpu/armv7/s5p-common/Makefile new file mode 100644 index 000000000..37371f6fd --- /dev/null +++ b/arch/arm/cpu/armv7/s5p-common/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2009 Samsung Electronics +# Minkyu Kang <mk7.kang@samsung.com> +# +# 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 as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)libs5p-common.a + +COBJS-y		+= cpu_info.o +COBJS-y		+= timer.o + +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS-y) $(SOBJS)) + +all:	 $(obj).depend $(LIB) + +$(LIB):	$(OBJS) +	$(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/s5pc1xx/cpu_info.c b/arch/arm/cpu/armv7/s5p-common/cpu_info.c index f16c0ff13..2f6c70855 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/cpu_info.c +++ b/arch/arm/cpu/armv7/s5p-common/cpu_info.c @@ -25,15 +25,14 @@  #include <asm/arch/clk.h>  /* Default is s5pc100 */ -unsigned int s5pc1xx_cpu_id = 0xC100; +unsigned int s5p_cpu_id = 0xC100;  #ifdef CONFIG_ARCH_CPU_INIT  int arch_cpu_init(void)  { -	s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); -	s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); +	s5p_set_cpu_id(); -	s5pc1xx_clock_init(); +	s5p_clock_init();  	return 0;  } @@ -41,7 +40,7 @@ int arch_cpu_init(void)  u32 get_device_type(void)  { -	return s5pc1xx_cpu_id; +	return s5p_cpu_id;  }  #ifdef CONFIG_DISPLAY_CPUINFO @@ -50,7 +49,7 @@ int print_cpuinfo(void)  	char buf[32];  	printf("CPU:\tS5P%X@%sMHz\n", -			s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); +			s5p_cpu_id, strmhz(buf, get_arm_clk()));  	return 0;  } diff --git a/arch/arm/cpu/armv7/s5pc1xx/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c index c5df5c5ab..04906503e 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/timer.c +++ b/arch/arm/cpu/armv7/s5p-common/timer.c @@ -44,23 +44,20 @@ static unsigned long long timestamp;	/* Monotonic incrementing timer */  static unsigned long lastdec;		/* Last decremneter snapshot */  /* macro to read the 16 bit timer */ -static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) +static inline struct s5p_timer *s5p_get_base_timer(void)  { -	if (cpu_is_s5pc110()) -		return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; -	else -		return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; +	return (struct s5p_timer *)samsung_get_base_timer();  }  int timer_init(void)  { -	struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); +	struct s5p_timer *const timer = s5p_get_base_timer();  	u32 val;  	/*  	 * @ PWM Timer 4  	 * Timer Freq(HZ) = -	 *	PCLK / { (prescaler_value + 1) * (divider_value) } +	 *	PWM_CLK / { (prescaler_value + 1) * (divider_value) }  	 */  	/* set prescaler : 16 */ @@ -71,7 +68,7 @@ int timer_init(void)  	if (count_value == 0) {  		/* reset initial value */  		/* count_value = 2085937.5(HZ) (per 1 sec)*/ -		count_value = get_pclk() / ((PRESCALER_1 + 1) * +		count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *  				(MUX_DIV_2 + 1));  		/* count_value / 100 = 20859.375(HZ) (per 10 msec) */ @@ -83,13 +80,13 @@ int timer_init(void)  	lastdec = count_value;  	val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) | -		S5PC1XX_TCON4_AUTO_RELOAD; +		TCON4_AUTO_RELOAD;  	/* auto reload & manual update */ -	writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon); +	writel(val | TCON4_UPDATE, &timer->tcon);  	/* start PWM timer 4 */ -	writel(val | S5PC1XX_TCON4_START, &timer->tcon); +	writel(val | TCON4_START, &timer->tcon);  	timestamp = 0; @@ -154,7 +151,7 @@ void __udelay(unsigned long usec)  void reset_timer_masked(void)  { -	struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); +	struct s5p_timer *const timer = s5p_get_base_timer();  	/* reset time */  	lastdec = readl(&timer->tcnto4); @@ -163,7 +160,7 @@ void reset_timer_masked(void)  unsigned long get_timer_masked(void)  { -	struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); +	struct s5p_timer *const timer = s5p_get_base_timer();  	unsigned long now = readl(&timer->tcnto4);  	if (lastdec >= now) diff --git a/arch/arm/cpu/armv7/s5pc1xx/Makefile b/arch/arm/cpu/armv7/s5pc1xx/Makefile index 3785593d2..263945f4e 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/Makefile +++ b/arch/arm/cpu/armv7/s5pc1xx/Makefile @@ -32,9 +32,7 @@ SOBJS	= cache.o  SOBJS	+= reset.o  COBJS	+= clock.o -COBJS	+= cpu_info.o  COBJS	+= sromc.o -COBJS	+= timer.o  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/s5pc1xx/clock.c b/arch/arm/cpu/armv7/s5pc1xx/clock.c index 19619f92c..98a27e551 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/clock.c +++ b/arch/arm/cpu/armv7/s5pc1xx/clock.c @@ -38,14 +38,16 @@  #define CONFIG_SYS_CLK_FREQ_C110	24000000  #endif -unsigned long (*get_pclk)(void); +unsigned long (*get_uart_clk)(int dev_index); +unsigned long (*get_pwm_clk)(void);  unsigned long (*get_arm_clk)(void);  unsigned long (*get_pll_clk)(int);  /* s5pc110: return pll clock frequency */  static unsigned long s5pc100_get_pll_clk(int pllreg)  { -	struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc100_clock *clk = +		(struct s5pc100_clock *)samsung_get_base_clock();  	unsigned long r, m, p, s, mask, fout;  	unsigned int freq; @@ -95,7 +97,8 @@ static unsigned long s5pc100_get_pll_clk(int pllreg)  /* s5pc100: return pll clock frequency */  static unsigned long s5pc110_get_pll_clk(int pllreg)  { -	struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc110_clock *clk = +		(struct s5pc110_clock *)samsung_get_base_clock();  	unsigned long r, m, p, s, mask, fout;  	unsigned int freq; @@ -151,7 +154,8 @@ static unsigned long s5pc110_get_pll_clk(int pllreg)  /* s5pc110: return ARM clock frequency */  static unsigned long s5pc110_get_arm_clk(void)  { -	struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc110_clock *clk = +		(struct s5pc110_clock *)samsung_get_base_clock();  	unsigned long div;  	unsigned long dout_apll, armclk;  	unsigned int apll_ratio; @@ -170,7 +174,8 @@ static unsigned long s5pc110_get_arm_clk(void)  /* s5pc100: return ARM clock frequency */  static unsigned long s5pc100_get_arm_clk(void)  { -	struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc100_clock *clk = +		(struct s5pc100_clock *)samsung_get_base_clock();  	unsigned long div;  	unsigned long dout_apll, armclk;  	unsigned int apll_ratio, arm_ratio; @@ -191,7 +196,8 @@ static unsigned long s5pc100_get_arm_clk(void)  /* s5pc100: return HCLKD0 frequency */  static unsigned long get_hclk(void)  { -	struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc100_clock *clk = +		(struct s5pc100_clock *)samsung_get_base_clock();  	unsigned long hclkd0;  	uint div, d0_bus_ratio; @@ -207,7 +213,8 @@ static unsigned long get_hclk(void)  /* s5pc100: return PCLKD1 frequency */  static unsigned long get_pclkd1(void)  { -	struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc100_clock *clk = +		(struct s5pc100_clock *)samsung_get_base_clock();  	unsigned long d1_bus, pclkd1;  	uint div, d1_bus_ratio, pclkd1_ratio; @@ -227,7 +234,8 @@ static unsigned long get_pclkd1(void)  /* s5pc110: return HCLKs frequency */  static unsigned long get_hclk_sys(int dom)  { -	struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc110_clock *clk = +		(struct s5pc110_clock *)samsung_get_base_clock();  	unsigned long hclk;  	unsigned int div;  	unsigned int offset; @@ -255,7 +263,8 @@ static unsigned long get_hclk_sys(int dom)  /* s5pc110: return PCLKs frequency */  static unsigned long get_pclk_sys(int dom)  { -	struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; +	struct s5pc110_clock *clk = +		(struct s5pc110_clock *)samsung_get_base_clock();  	unsigned long pclk;  	unsigned int div;  	unsigned int offset; @@ -289,15 +298,33 @@ static unsigned long s5pc100_get_pclk(void)  	return get_pclkd1();  } -void s5pc1xx_clock_init(void) +/* s5pc1xx: return uart clock frequency */ +static unsigned long s5pc1xx_get_uart_clk(int dev_index) +{ +	if (cpu_is_s5pc110()) +		return s5pc110_get_pclk(); +	else +		return s5pc100_get_pclk(); +} + +/* s5pc1xx: return pwm clock frequency */ +static unsigned long s5pc1xx_get_pwm_clk(void) +{ +	if (cpu_is_s5pc110()) +		return s5pc110_get_pclk(); +	else +		return s5pc100_get_pclk(); +} + +void s5p_clock_init(void)  {  	if (cpu_is_s5pc110()) {  		get_pll_clk = s5pc110_get_pll_clk;  		get_arm_clk = s5pc110_get_arm_clk; -		get_pclk = s5pc110_get_pclk;  	} else {  		get_pll_clk = s5pc100_get_pll_clk;  		get_arm_clk = s5pc100_get_arm_clk; -		get_pclk = s5pc100_get_pclk;  	} +	get_uart_clk = s5pc1xx_get_uart_clk; +	get_pwm_clk = s5pc1xx_get_pwm_clk;  } diff --git a/arch/arm/cpu/armv7/s5pc1xx/reset.S b/arch/arm/cpu/armv7/s5pc1xx/reset.S index 7f6ff9c35..70fa146cf 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/reset.S +++ b/arch/arm/cpu/armv7/s5pc1xx/reset.S @@ -28,7 +28,7 @@  .globl reset_cpu  reset_cpu: -	ldr	r1, =S5PC1XX_PRO_ID +	ldr	r1, =S5PC100_PRO_ID  	ldr	r2, [r1]  	ldr	r4, =0x00010000  	and	r4, r2, r4 diff --git a/arch/arm/cpu/armv7/s5pc1xx/sromc.c b/arch/arm/cpu/armv7/s5pc1xx/sromc.c index 380be81be..044d12298 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/sromc.c +++ b/arch/arm/cpu/armv7/s5pc1xx/sromc.c @@ -35,12 +35,8 @@  void s5pc1xx_config_sromc(u32 srom_bank, u32 smc_bw_conf, u32 smc_bc_conf)  {  	u32 tmp; -	struct s5pc1xx_smc *srom; - -	if (cpu_is_s5pc100()) -		srom = (struct s5pc1xx_smc *)S5PC100_SROMC_BASE; -	else -		srom = (struct s5pc1xx_smc *)S5PC110_SROMC_BASE; +	struct s5pc1xx_smc *srom = +		(struct s5pc1xx_smc *)samsung_get_base_sromc();  	/* Configure SMC_BW register to handle proper SROMC bank */  	tmp = srom->bw; diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index 01840eede..0067190a2 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -27,6 +27,7 @@  void at91_can_hw_init(void);  void at91_macb_hw_init(void); +void at91_mci_hw_init(void);  void at91_serial_hw_init(void);  void at91_serial0_hw_init(void);  void at91_serial1_hw_init(void); diff --git a/arch/arm/include/asm/arch-at91/at91_dbu.h b/arch/arm/include/asm/arch-at91/at91_dbu.h new file mode 100644 index 000000000..342929353 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_dbu.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Debug Unit + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_DBU_H +#define AT91_DBU_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_dbu { +	u32	cr;	/* Control Register WO */ +	u32	mr;	/* Mode Register  RW */ +	u32	ier;	/* Interrupt Enable Register WO */ +	u32	idr;	/* Interrupt Disable Register WO */ +	u32	imr;	/* Interrupt Mask Register RO */ +	u32	sr;	/* Status Register RO */ +	u32	rhr;	/* Receive Holding Register RO */ +	u32	thr;	/* Transmit Holding Register WO */ +	u32	brgr;	/* Baud Rate Generator Register RW */ +	u32	res1[7];/* 0x0024 - 0x003C Reserved */ +	u32	cidr;	/* Chip ID Register RO */ +	u32	exid;	/* Chip ID Extension Register RO */ +	u32	fnr;	/* Force NTRST Register RW */ +} at91_dbu_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_DBU_CID_ARCH_MASK		0x0ff00000 +#define AT91_DBU_CID_ARCH_9xx		0x01900000 +#define AT91_DBU_CID_ARCH_9XExx	0x02900000 + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91_eefc.h b/arch/arm/include/asm/arch-at91/at91_eefc.h new file mode 100644 index 000000000..d45b3deca --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_eefc.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Enhanced Embedded Flash Controller + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_EEFC_H +#define AT91_EEFC_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_eefc { +	u32	fmr;	/* Flash Mode Register RW */ +	u32	fcr;	/* Flash Command Register WO */ +	u32	fsr;	/* Flash Status Register RO */ +	u32	frr;	/* Flash Result Register RO */ +} at91_eefc_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_EEFC_FMR_FWS_MASK	0x00000f00 +#define AT91_EEFC_FMR_FRDY_BIT	0x00000001 + +#define AT91_EEFC_FCR_KEY		0x5a000000 +#define AT91_EEFC_FCR_FARG_MASK	0x00ffff00 +#define AT91_EEFC_FCR_FARG_SHIFT	8 +#define AT91_EEFC_FCR_FCMD_GETD	0x0 +#define AT91_EEFC_FCR_FCMD_WP		0x1 +#define AT91_EEFC_FCR_FCMD_WPL		0x2 +#define AT91_EEFC_FCR_FCMD_EWP		0x3 +#define AT91_EEFC_FCR_FCMD_EWPL	0x4 +#define AT91_EEFC_FCR_FCMD_EA		0x5 +#define AT91_EEFC_FCR_FCMD_SLB		0x8 +#define AT91_EEFC_FCR_FCMD_CLB		0x9 +#define AT91_EEFC_FCR_FCMD_GLB		0xA +#define AT91_EEFC_FCR_FCMD_SGPB	0xB +#define AT91_EEFC_FCR_FCMD_CGPB	0xC +#define AT91_EEFC_FCR_FCMD_GGPB	0xD + +#define AT91_EEFC_FSR_FRDY	1 +#define AT91_EEFC_FSR_FCMDE	2 +#define AT91_EEFC_FSR_FLOCKE	4 + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91_gpbr.h b/arch/arm/include/asm/arch-at91/at91_gpbr.h new file mode 100644 index 000000000..cf1d790dd --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_gpbr.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * General Purpose Backup Registers + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_GPBR_H +#define AT91_GPBR_H + +/* + * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile + * 32 Bit registers (buffered by the Vbu power). + * + * Please consider carefully before using this resource for tasks + * that do not really need nonvolatile registers. Maybe you can + * store information in EEPROM or FLASH instead. + * + * However, if you use a GPBR please document its use here and + * reference the define in your code! + * + * known typical uses of the GPBRs: + * GPBR[0]: offset for RTT timekeeping (u-boot, kernel) + * GPBR[1]: unused + * GPBR[2]: unused + * GPBR[3]: bootcount (u-boot) + */ +#define AT91_GPBR_INDEX_TIMEOFF 0 +#define AT91_GPBR_INDEX_BOOTCOUNT 3 + +#ifndef __ASSEMBLY__ + +typedef struct at91_gpbr { +	u32 reg[4]; +} at91_gpbr_t; + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pit.h b/arch/arm/include/asm/arch-at91/at91_pit.h index 5615a0206..61aca7941 100644 --- a/arch/arm/include/asm/arch-at91/at91_pit.h +++ b/arch/arm/include/asm/arch-at91/at91_pit.h @@ -25,7 +25,7 @@ typedef struct at91_pit {  #define		AT91_PIT_MR_IEN		0x02000000  #define		AT91_PIT_MR_EN		0x01000000 -#define		AT91_PIT_MR_PIV_MASK	(x & 0x000fffff) +#define		AT91_PIT_MR_PIV_MASK(x)	(x & 0x000fffff)  #define		AT91_PIT_MR_PIV(x)	(x & AT91_PIT_MR_PIV_MASK)  #ifdef CONFIG_AT91_LEGACY diff --git a/arch/arm/include/asm/arch-at91/at91_rtt.h b/arch/arm/include/asm/arch-at91/at91_rtt.h new file mode 100644 index 000000000..e0253ef82 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_rtt.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Real-time Timer + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_RTT_H +#define AT91_RTT_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_rtt { +	u32	mr;	/* Mode Register   RW 0x00008000 */ +	u32	ar;	/* Alarm Register  RW 0xFFFFFFFF */ +	u32	vr;	/* Value Register  RO 0x00000000 */ +	u32	sr;	/* Status Register RO 0x00000000 */ +} at91_rtt_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_RTT_MR_RTPRES	0x0000ffff +#define AT91_RTT_MR_ALMIEN	0x00010000 +#define AT91_RTT_RTTINCIEN	0x00020000 +#define AT91_RTT_RTTRST	0x00040000 + +#define AT91_RTT_SR_ALMS	0x00000001 +#define AT91_RTT_SR_RTTINC	0x00000002 + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9260.h b/arch/arm/include/asm/arch-at91/at91sam9260.h index ec0431803..cb34a94a3 100644 --- a/arch/arm/include/asm/arch-at91/at91sam9260.h +++ b/arch/arm/include/asm/arch-at91/at91sam9260.h @@ -59,7 +59,15 @@  #define AT91_RTT_BASE		0xfffffd20  #define AT91_PIT_BASE		0xfffffd30  #define AT91_WDT_BASE		0xfffffd40 -#define AT91_GPR_BASE		0xfffffd50 +/* + * The AT91SAM9XE has the GPBRs at a different address than + * the AT91SAM9260/9G20. + */ +#ifdef CONFIG_AT91SAM9XE +# define AT91_GPR_BASE		0xfffffd60 +#else +# define AT91_GPR_BASE		0xfffffd50 +#endif  #ifdef CONFIG_AT91_LEGACY @@ -140,10 +148,12 @@  /*   * Cpu Name   */ -#if defined(CONFIG_AT91SAM9260) -#define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9260" +#if defined(CONFIG_AT91SAM9XE) +# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9XE" +#elif defined(CONFIG_AT91SAM9260) +# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9260"  #elif defined(CONFIG_AT91SAM9G20) -#define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9G20" +# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9G20"  #endif  #endif diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h index f642dd995..457e6c9b2 100644 --- a/arch/arm/include/asm/arch-at91/clk.h +++ b/arch/arm/include/asm/arch-at91/clk.h @@ -59,5 +59,10 @@ static inline unsigned long get_twi_clk_rate(unsigned int dev_id)  	return get_mck_clk_rate();  } +static inline unsigned long get_mci_clk_rate(void) +{ +	return get_mck_clk_rate(); +} +  int at91_clock_init(unsigned long main_clock);  #endif /* __ASM_ARM_ARCH_CLK_H__ */ diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h index 4ddb3155d..9f732a738 100644 --- a/arch/arm/include/asm/arch-at91/hardware.h +++ b/arch/arm/include/asm/arch-at91/hardware.h @@ -20,6 +20,7 @@  #include <asm/arch-at91/at91rm9200.h>  #elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20)  #include <asm/arch/at91sam9260.h> +#define AT91_BASE_MCI	AT91SAM9260_BASE_MCI  #define AT91_BASE_SPI	AT91SAM9260_BASE_SPI0  #define AT91_ID_UHP	AT91SAM9260_ID_UHP  #define AT91_PMC_UHP	AT91SAM926x_PMC_UHP diff --git a/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h b/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h new file mode 100644 index 000000000..0bc527913 --- /dev/null +++ b/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2010 + * Matthias Weisser <weisserm@arcor.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef ASM_OFFSETS_H +#define ASM_OFFSETS_H + +/* + * Offset definitions for DDR controller + */ +#define DDR2_DRIC		0x00 +#define DDR2_DRIC1		0x02 +#define DDR2_DRIC2		0x04 +#define DDR2_DRCA		0x06 +#define DDR2_DRCM		0x08 +#define DDR2_DRCST1		0x0a +#define DDR2_DRCST2		0x0c +#define DDR2_DRCR		0x0e +#define DDR2_DRCF		0x20 +#define DDR2_DRASR		0x30 +#define DDR2_DRIMS		0x50 +#define DDR2_DROS		0x60 +#define DDR2_DRIBSODT1		0x64 +#define DDR2_DROABA		0x70 +#define DDR2_DROBS		0x84 + +/* + * Offset definitions Chip Control Module + */ +#define CCNT_CDCRC		0xec + +/* + * Offset definitions clock reset generator + */ +#define CRG_CRPR		0x00 +#define CRG_CRHA		0x18 +#define CRG_CRPA		0x1c +#define CRG_CRPB		0x20 +#define CRG_CRHB		0x24 +#define CRG_CRAM		0x28 + +/* + * Offset definitions External bus interface + */ +#define MEMC_MCFMODE0		0x00 +#define MEMC_MCFMODE2		0x08 +#define MEMC_MCFMODE4		0x10 +#define MEMC_MCFTIM0		0x20 +#define MEMC_MCFTIM2		0x28 +#define MEMC_MCFTIM4		0x30 +#define MEMC_MCFAREA0		0x40 +#define MEMC_MCFAREA2		0x48 +#define MEMC_MCFAREA4		0x50 + +#endif /* ASM_OFFSETS_H */ diff --git a/arch/arm/include/asm/arch-mb86r0x/hardware.h b/arch/arm/include/asm/arch-mb86r0x/hardware.h new file mode 100644 index 000000000..d1e57c034 --- /dev/null +++ b/arch/arm/include/asm/arch-mb86r0x/hardware.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2007 + * + * Author : Carsten Schneider, mycable GmbH + *          <cs@mycable.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include <asm/sizes.h> +#include <asm/arch/mb86r0x.h> + +#endif diff --git a/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h b/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h new file mode 100644 index 000000000..36a28b7af --- /dev/null +++ b/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h @@ -0,0 +1,573 @@ +/* + * (C) Copyright 2007 + * + * mb86r0x definitions + * + * Author : Carsten Schneider, mycable GmbH + *          <cs@mycable.de> + * + * (C) Copyright 2010 + * Matthias Weisser <weisserm@arcor.de> + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef MB86R0X_H +#define MB86R0X_H + +#ifndef __ASSEMBLY__ + +/* GPIO registers */ +struct mb86r0x_gpio { +	uint32_t gpdr0; +	uint32_t gpdr1; +	uint32_t gpdr2; +	uint32_t res; +	uint32_t gpddr0; +	uint32_t gpddr1; +	uint32_t gpddr2; +}; + +/* PWM registers */ +struct mb86r0x_pwm { +	uint32_t bcr; +	uint32_t tpr; +	uint32_t pr; +	uint32_t dr; +	uint32_t cr; +	uint32_t sr; +	uint32_t ccr; +	uint32_t ir; +}; + +/* The mb86r0x chip control (CCNT) register set. */ +struct mb86r0x_ccnt { +	uint32_t ccid; +	uint32_t csrst; +	uint32_t pad0[2]; +	uint32_t cist; +	uint32_t cistm; +	uint32_t cgpio_ist; +	uint32_t cgpio_istm; +	uint32_t cgpio_ip; +	uint32_t cgpio_im; +	uint32_t caxi_bw; +	uint32_t caxi_ps; +	uint32_t cmux_md; +	uint32_t cex_pin_st; +	uint32_t cmlb; +	uint32_t pad1[1]; +	uint32_t cusb; +	uint32_t pad2[41]; +	uint32_t cbsc; +	uint32_t cdcrc; +	uint32_t cmsr0; +	uint32_t cmsr1; +	uint32_t pad3[2]; +}; + +/* The mb86r0x clock reset generator */ +struct mb86r0x_crg { +	uint32_t crpr; +	uint32_t pad0; +	uint32_t crwr; +	uint32_t crsr; +	uint32_t crda; +	uint32_t crdb; +	uint32_t crha; +	uint32_t crpa; +	uint32_t crpb; +	uint32_t crhb; +	uint32_t cram; +}; + +/* The mb86r0x timer */ +struct mb86r0x_timer { +	uint32_t load; +	uint32_t value; +	uint32_t control; +	uint32_t intclr; +	uint32_t ris; +	uint32_t mis; +	uint32_t bgload; +}; + +/* mb86r0x gdc display controller */ +struct mb86r0x_gdc_dsp { +	/* Display settings */ +	uint32_t dcm0; +	uint16_t pad00; +	uint16_t htp; +	uint16_t hdp; +	uint16_t hdb; +	uint16_t hsp; +	uint8_t  hsw; +	uint8_t  vsw; +	uint16_t pad01; +	uint16_t vtr; +	uint16_t vsp; +	uint16_t vdp; +	uint16_t wx; +	uint16_t wy; +	uint16_t ww; +	uint16_t wh; + +	/* Layer 0 */ +	uint32_t l0m; +	uint32_t l0oa; +	uint32_t l0da; +	uint16_t l0dx; +	uint16_t l0dy; + +	/* Layer 1 */ +	uint32_t l1m; +	uint32_t cbda0; +	uint32_t cbda1; +	uint32_t pad02; + +	/* Layer 2 */ +	uint32_t l2m; +	uint32_t l2oa0; +	uint32_t l2da0; +	uint32_t l2oa1; +	uint32_t l2da1; +	uint16_t l2dx; +	uint16_t l2dy; + +	/* Layer 3 */ +	uint32_t l3m; +	uint32_t l3oa0; +	uint32_t l3da0; +	uint32_t l3oa1; +	uint32_t l3da1; +	uint16_t l3dx; +	uint16_t l3dy; + +	/* Layer 4 */ +	uint32_t l4m; +	uint32_t l4oa0; +	uint32_t l4da0; +	uint32_t l4oa1; +	uint32_t l4da1; +	uint16_t l4dx; +	uint16_t l4dy; + +	/* Layer 5 */ +	uint32_t l5m; +	uint32_t l5oa0; +	uint32_t l5da0; +	uint32_t l5oa1; +	uint32_t l5da1; +	uint16_t l5dx; +	uint16_t l5dy; + +	/* Cursor */ +	uint16_t cutc; +	uint8_t  cpm; +	uint8_t  csize; +	uint32_t cuoa0; +	uint16_t cux0; +	uint16_t cuy0; +	uint32_t cuoa1; +	uint16_t cux1; +	uint16_t cuy1; + +	/* Layer blending */ +	uint32_t l0bld; +	uint32_t pad03; +	uint32_t l0tc; +	uint16_t l3tc; +	uint16_t l2tc; +	uint32_t pad04[15]; + +	/* Display settings */ +	uint32_t dcm1; +	uint32_t dcm2; +	uint32_t dcm3; +	uint32_t pad05; + +	/* Layer 0 extended */ +	uint32_t l0em; +	uint16_t l0wx; +	uint16_t l0wy; +	uint16_t l0ww; +	uint16_t l0wh; +	uint32_t pad06; + +	/* Layer 1 extended */ +	uint32_t l1em; +	uint16_t l1wx; +	uint16_t l1wy; +	uint16_t l1ww; +	uint16_t l1wh; +	uint32_t pad07; + +	/* Layer 2 extended */ +	uint32_t l2em; +	uint16_t l2wx; +	uint16_t l2wy; +	uint16_t l2ww; +	uint16_t l2wh; +	uint32_t pad08; + +	/* Layer 3 extended */ +	uint32_t l3em; +	uint16_t l3wx; +	uint16_t l3wy; +	uint16_t l3ww; +	uint16_t l3wh; +	uint32_t pad09; + +	/* Layer 4 extended */ +	uint32_t l4em; +	uint16_t l4wx; +	uint16_t l4wy; +	uint16_t l4ww; +	uint16_t l4wh; +	uint32_t pad10; + +	/* Layer 5 extended */ +	uint32_t l5em; +	uint16_t l5wx; +	uint16_t l5wy; +	uint16_t l5ww; +	uint16_t l5wh; +	uint32_t pad11; + +	/* Multi screen control */ +	uint32_t msc; +	uint32_t pad12[3]; +	uint32_t dls; +	uint32_t dbgc; + +	/* Layer blending */ +	uint32_t l1bld; +	uint32_t l2bld; +	uint32_t l3bld; +	uint32_t l4bld; +	uint32_t l5bld; +	uint32_t pad13; + +	/* Extended transparency control */ +	uint32_t l0etc; +	uint32_t l1etc; +	uint32_t l2etc; +	uint32_t l3etc; +	uint32_t l4etc; +	uint32_t l5etc; +	uint32_t pad14[10]; + +	/* YUV coefficients */ +	uint32_t l1ycr0; +	uint32_t l1ycr1; +	uint32_t l1ycg0; +	uint32_t l1ycg1; +	uint32_t l1ycb0; +	uint32_t l1ycb1; +	uint32_t pad15[130]; + +	/* Layer palletes */ +	uint32_t l0pal[256]; +	uint32_t l1pal[256]; +	uint32_t pad16[256]; +	uint32_t l2pal[256]; +	uint32_t l3pal[256]; +	uint32_t pad17[256]; + +	/* PWM settings */ +	uint32_t vpwmm; +	uint16_t vpwms; +	uint16_t vpwme; +	uint32_t vpwmc; +	uint32_t pad18[253]; +}; + +/* mb86r0x gdc capture controller */ +struct mb86r0x_gdc_cap { +	uint32_t vcm; +	uint32_t csc; +	uint32_t vcs; +	uint32_t pad01; + +	uint32_t cbm; +	uint32_t cboa; +	uint32_t cbla; +	uint16_t cihstr; +	uint16_t civstr; +	uint16_t cihend; +	uint16_t civend; +	uint32_t pad02; + +	uint32_t chp; +	uint32_t cvp; +	uint32_t pad03[4]; + +	uint32_t clpf; +	uint32_t pad04; +	uint32_t cmss; +	uint32_t cmds; +	uint32_t pad05[12]; + +	uint32_t rgbhc; +	uint32_t rgbhen; +	uint32_t rgbven; +	uint32_t pad06; +	uint32_t rgbs; +	uint32_t pad07[11]; + +	uint32_t rgbcmy; +	uint32_t rgbcmcb; +	uint32_t rgbcmcr; +	uint32_t rgbcmb; +	uint32_t pad08[12 + 1984]; +}; + +/* mb86r0x gdc draw */ +struct mb86r0x_gdc_draw { +	uint32_t ys; +	uint32_t xs; +	uint32_t dxdy; +	uint32_t xus; +	uint32_t dxudy; +	uint32_t xls; +	uint32_t dxldy; +	uint32_t usn; +	uint32_t lsn; +	uint32_t pad01[7]; +	uint32_t rs; +	uint32_t drdx; +	uint32_t drdy; +	uint32_t gs; +	uint32_t dgdx; +	uint32_t dgdy; +	uint32_t bs; +	uint32_t dbdx; +	uint32_t dbdy; +	uint32_t pad02[7]; +	uint32_t zs; +	uint32_t dzdx; +	uint32_t dzdy; +	uint32_t pad03[13]; +	uint32_t ss; +	uint32_t dsdx; +	uint32_t dsdy; +	uint32_t ts; +	uint32_t dtdx; +	uint32_t dtdy; +	uint32_t qs; +	uint32_t dqdx; +	uint32_t dqdy; +	uint32_t pad04[23]; +	uint32_t lpn; +	uint32_t lxs; +	uint32_t lxde; +	uint32_t lys; +	uint32_t lyde; +	uint32_t lzs; +	uint32_t lzde; +	uint32_t pad05[13]; +	uint32_t pxdc; +	uint32_t pydc; +	uint32_t pzdc; +	uint32_t pad06[25]; +	uint32_t rxs; +	uint32_t rys; +	uint32_t rsizex; +	uint32_t rsizey; +	uint32_t pad07[12]; +	uint32_t saddr; +	uint32_t sstride; +	uint32_t srx; +	uint32_t sry; +	uint32_t daddr; +	uint32_t dstride; +	uint32_t drx; +	uint32_t dry; +	uint32_t brsizex; +	uint32_t brsizey; +	uint32_t tcolor; +	uint32_t pad08[93]; +	uint32_t blpo; +	uint32_t pad09[7]; +	uint32_t ctr; +	uint32_t ifsr; +	uint32_t ifcnt; +	uint32_t sst; +	uint32_t ds; +	uint32_t pst; +	uint32_t est; +	uint32_t pad10; +	uint32_t mdr0; +	uint32_t mdr1; +	uint32_t mdr2; +	uint32_t mdr3; +	uint32_t mdr4; +	uint32_t pad14[2]; +	uint32_t mdr7; +	uint32_t fbr; +	uint32_t xres; +	uint32_t zbr; +	uint32_t tbr; +	uint32_t pfbr; +	uint32_t cxmin; +	uint32_t cxmax; +	uint32_t cymin; +	uint32_t cymax; +	uint32_t txs; +	uint32_t tis; +	uint32_t toa; +	uint32_t sho; +	uint32_t abr; +	uint32_t pad15[2]; +	uint32_t fc; +	uint32_t bc; +	uint32_t alf; +	uint32_t blp; +	uint32_t pad16; +	uint32_t tbc; +	uint32_t pad11[42]; +	uint32_t lx0dc; +	uint32_t ly0dc; +	uint32_t lx1dc; +	uint32_t ly1dc; +	uint32_t pad12[12]; +	uint32_t x0dc; +	uint32_t y0dc; +	uint32_t x1dc; +	uint32_t y1dc; +	uint32_t x2dc; +	uint32_t y2dc; +	uint32_t pad13[666]; +}; + +/* mb86r0x gdc geometry engine */ +struct mb86r0x_gdc_geom { +	uint32_t gctr; +	uint32_t pad00[15]; +	uint32_t gmdr0; +	uint32_t gmdr1; +	uint32_t gmdr2; +	uint32_t pad01[237]; +	uint32_t dfifog; +	uint32_t pad02[767]; +}; + +/* mb86r0x gdc */ +struct mb86r0x_gdc { +	uint32_t pad00[2]; +	uint32_t lts; +	uint32_t pad01; +	uint32_t lsta; +	uint32_t pad02[3]; +	uint32_t ist; +	uint32_t imask; +	uint32_t pad03[6]; +	uint32_t lsa; +	uint32_t lco; +	uint32_t lreq; + +	uint32_t pad04[16*1024 - 19]; +	struct mb86r0x_gdc_dsp dsp0; +	struct mb86r0x_gdc_dsp dsp1; +	uint32_t pad05[4*1024 - 2]; +	uint32_t vccc; +	uint32_t vcsr; +	struct mb86r0x_gdc_cap cap0; +	struct mb86r0x_gdc_cap cap1; +	uint32_t pad06[4*1024]; +	uint32_t texture_base[16*1024]; +	struct mb86r0x_gdc_draw draw; +	uint32_t pad07[7*1024]; +	struct mb86r0x_gdc_geom geom; +	uint32_t pad08[7*1024]; +}; + +#endif /* __ASSEMBLY__ */ + +/* + * Physical Address Defines + */ +#define MB86R0x_DDR2_BASE		0xf3000000 +#define MB86R0x_GDC_BASE		0xf1fc0000 +#define MB86R0x_CCNT_BASE		0xfff42000 +#define MB86R0x_CAN0_BASE		0xfff54000 +#define MB86R0x_CAN1_BASE		0xfff55000 +#define MB86R0x_I2C0_BASE		0xfff56000 +#define MB86R0x_I2C1_BASE		0xfff57000 +#define MB86R0x_EHCI_BASE		0xfff80000 +#define MB86R0x_OHCI_BASE		0xfff81000 +#define MB86R0x_IRC1_BASE		0xfffb0000 +#define MB86R0x_MEMC_BASE		0xfffc0000 +#define MB86R0x_TIMER_BASE		0xfffe0000 +#define MB86R0x_UART0_BASE		0xfffe1000 +#define MB86R0x_UART1_BASE		0xfffe2000 +#define MB86R0x_IRCE_BASE		0xfffe4000 +#define MB86R0x_CRG_BASE		0xfffe7000 +#define MB86R0x_IRC0_BASE		0xfffe8000 +#define MB86R0x_GPIO_BASE		0xfffe9000 +#define MB86R0x_PWM0_BASE		0xfff41000 +#define MB86R0x_PWM1_BASE		0xfff41100 + +#define MB86R0x_CRSR_SWRSTREQ 		(1 << 1) + +/* + * Timer register bits + */ +#define MB86R0x_TIMER_ENABLE		(1 << 7) +#define MB86R0x_TIMER_MODE_MSK		(1 << 6) +#define MB86R0x_TIMER_MODE_FR		(0 << 6) +#define MB86R0x_TIMER_MODE_PD		(1 << 6) + +#define MB86R0x_TIMER_INT_EN		(1 << 5) +#define MB86R0x_TIMER_PRS_MSK		(3 << 2) +#define MB86R0x_TIMER_PRS_4S		(1 << 2) +#define MB86R0x_TIMER_PRS_8S		(1 << 3) +#define MB86R0x_TIMER_SIZE_32		(1 << 1) +#define MB86R0x_TIMER_ONE_SHT		(1 << 0) + +/* + * Clock reset generator bits + */ +#define MB86R0x_CRG_CRPR_PLLRDY		(1 << 8) +#define MB86R0x_CRG_CRPR_PLLMODE	(0x1f << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X49	(0 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X46	(1 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X37	(2 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X20	(3 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X47	(4 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X44	(5 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X36	(6 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X19	(7 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X39	(8 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X38	(9 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X30	(10 << 0) +#define MB86R0x_CRG_CRPR_PLLMODE_X15	(11 << 0) +/* + * DDR2 controller bits + */ +#define MB86R0x_DDR2_DRCI_DRINI		(1 << 15) +#define MB86R0x_DDR2_DRCI_CKEN		(1 << 14) +#define MB86R0x_DDR2_DRCI_DRCMD		(1 << 0) +#define MB86R0x_DDR2_DRCI_CMD		(MB86R0x_DDR2_DRCI_DRINI | \ +					MB86R0x_DDR2_DRCI_CKEN | \ +					MB86R0x_DDR2_DRCI_DRCMD) +#define MB86R0x_DDR2_DRCI_INIT		(MB86R0x_DDR2_DRCI_DRINI | \ +					MB86R0x_DDR2_DRCI_CKEN) +#define MB86R0x_DDR2_DRCI_NORMAL	MB86R0x_DDR2_DRCI_CKEN +#endif /* MB86R0X_H */ diff --git a/arch/arm/include/asm/arch-omap3/clocks.h b/arch/arm/include/asm/arch-omap3/clocks.h index 71a0cb6ae..40f80baf6 100644 --- a/arch/arm/include/asm/arch-omap3/clocks.h +++ b/arch/arm/include/asm/arch-omap3/clocks.h @@ -51,12 +51,29 @@ typedef struct {  	unsigned int m2;  } dpll_param; +struct dpll_per_36x_param { +	unsigned int sys_clk; +	unsigned int m; +	unsigned int n; +	unsigned int m2; +	unsigned int m3; +	unsigned int m4; +	unsigned int m5; +	unsigned int m6; +	unsigned int m2div; +}; +  /* Following functions are exported from lowlevel_init.S */  extern dpll_param *get_mpu_dpll_param(void);  extern dpll_param *get_iva_dpll_param(void);  extern dpll_param *get_core_dpll_param(void);  extern dpll_param *get_per_dpll_param(void); +extern dpll_param *get_36x_mpu_dpll_param(void); +extern dpll_param *get_36x_iva_dpll_param(void); +extern dpll_param *get_36x_core_dpll_param(void); +extern dpll_param *get_36x_per_dpll_param(void); +  extern void *_end_vect, *_start;  #endif diff --git a/arch/arm/include/asm/arch-omap3/clocks_omap3.h b/arch/arm/include/asm/arch-omap3/clocks_omap3.h index 661407b56..30ef690fa 100644 --- a/arch/arm/include/asm/arch-omap3/clocks_omap3.h +++ b/arch/arm/include/asm/arch-omap3/clocks_omap3.h @@ -282,4 +282,31 @@  #define PER_FSEL_38P4		0x07  #define PER_M2_38P4		0x09 +/* 36XX PER DPLL */ + +#define PER_36XX_M_12		0x1B0 +#define PER_36XX_N_12		0x05 +#define PER_36XX_FSEL_12	0x07 +#define PER_36XX_M2_12		0x09 + +#define PER_36XX_M_13		0x360 +#define PER_36XX_N_13		0x0C +#define PER_36XX_FSEL_13	0x03 +#define PER_36XX_M2_13		0x09 + +#define PER_36XX_M_19P2		0x1C2 +#define PER_36XX_N_19P2		0x09 +#define PER_36XX_FSEL_19P2	0x07 +#define PER_36XX_M2_19P2	0x09 + +#define PER_36XX_M_26		0x1B0 +#define PER_36XX_N_26		0x0C +#define PER_36XX_FSEL_26	0x07 +#define PER_36XX_M2_26		0x09 + +#define PER_36XX_M_38P4		0x1C2 +#define PER_36XX_N_38P4		0x13 +#define PER_36XX_FSEL_38P4	0x07 +#define PER_36XX_M2_38P4	0x09 +  #endif	/* endif _CLOCKS_OMAP3_H_ */ diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h index 390b00794..962d6d40a 100644 --- a/arch/arm/include/asm/arch-omap3/cpu.h +++ b/arch/arm/include/asm/arch-omap3/cpu.h @@ -60,19 +60,14 @@ struct ctrl {  #endif /* __ASSEMBLY__ */  #endif /* __KERNEL_STRICT_NAMES */ -/* cpu type */ -#define OMAP3503		0x5c00 -#define OMAP3515		0x1c00 -#define OMAP3525		0x4c00 -#define OMAP3530		0x0c00 -  #ifndef __KERNEL_STRICT_NAMES  #ifndef __ASSEMBLY__  struct ctrl_id {  	u8 res1[0x4];  	u32 idcode;		/* 0x04 */  	u32 prod_id;		/* 0x08 */ -	u8 res2[0x0C]; +	u32 sku_id;		/* 0x0c */ +	u8 res2[0x08];  	u32 die_id_0;		/* 0x18 */  	u32 die_id_1;		/* 0x1C */  	u32 die_id_2;		/* 0x20 */ @@ -89,6 +84,11 @@ struct ctrl_id {  #define HS_DEVICE		0x2  #define GP_DEVICE		0x3 +/* device speed */ +#define SKUID_CLK_MASK		0xf +#define SKUID_CLK_600MHZ	0x0 +#define SKUID_CLK_720MHZ	0x8 +  #define GPMC_BASE		(OMAP34XX_GPMC_BASE)  #define GPMC_CONFIG_CS0		0x60  #define GPMC_CONFIG_CS0_BASE	(GPMC_BASE + GPMC_CONFIG_CS0) @@ -419,6 +419,7 @@ struct prm {  };  #else /* __ASSEMBLY__ */  #define PRM_RSTCTRL		0x48307250 +#define PRM_RSTCTRL_RESET	0x04  #endif /* __ASSEMBLY__ */  #endif /* __KERNEL_STRICT_NAMES */ diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h index 12815f694..3957c796f 100644 --- a/arch/arm/include/asm/arch-omap3/omap3.h +++ b/arch/arm/include/asm/arch-omap3/omap3.h @@ -176,11 +176,41 @@ struct gpio {  #define CPU_3XX_ES21		2  #define CPU_3XX_ES30		3  #define CPU_3XX_ES31		4 -#define CPU_3XX_MAX_REV		(CPU_3XX_ES31 + 1) +#define CPU_3XX_ES312		7 +#define CPU_3XX_MAX_REV		8  #define CPU_3XX_ID_SHIFT	28  #define WIDTH_8BIT		0x0000  #define WIDTH_16BIT		0x1000	/* bit pos for 16 bit in gpmc */ +/* + * Hawkeye values + */ +#define HAWKEYE_OMAP34XX	0xb7ae +#define HAWKEYE_AM35XX		0xb868 +#define HAWKEYE_OMAP36XX	0xb891 + +#define HAWKEYE_SHIFT		12 + +/* + * Define CPU families + */ +#define CPU_OMAP34XX		0x3400	/* OMAP34xx/OMAP35 devices */ +#define CPU_AM35XX		0x3500	/* AM35xx devices          */ +#define CPU_OMAP36XX		0x3600	/* OMAP36xx devices        */ + +/* + * Control status register values corresponding to cpu variants + */ +#define OMAP3503		0x5c00 +#define OMAP3515		0x1c00 +#define OMAP3525		0x4c00 +#define OMAP3530		0x0c00 + +#define AM3505			0x5c00 +#define AM3517			0x1c00 + +#define OMAP3730		0x0c00 +  #endif diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index db7b42aed..4a28ba1c4 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -41,7 +41,9 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,  void watchdog_init(void);  void set_muxconf_regs(void); +u32 get_cpu_family(void);  u32 get_cpu_rev(void); +u32 get_sku_id(void);  u32 get_mem_type(void);  u32 get_sysboot_value(void);  u32 is_gpmc_muxed(void); diff --git a/arch/arm/include/asm/arch-omap4/omap4.h b/arch/arm/include/asm/arch-omap4/omap4.h index 79ff22cf3..d0c808d12 100644 --- a/arch/arm/include/asm/arch-omap4/omap4.h +++ b/arch/arm/include/asm/arch-omap4/omap4.h @@ -88,6 +88,7 @@  #define PRM_DEVICE_BASE		(PRM_BASE + 0x1B00)  #define PRM_RSTCTRL		PRM_DEVICE_BASE +#define PRM_RSTCTRL_RESET	0x01  #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index ad0c640df..4813e9e21 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -33,6 +33,9 @@ void watchdog_init(void);  u32 get_device_type(void);  void invalidate_dcache(u32);  void set_muxconf_regs(void); +void sr32(void *, u32, u32, u32); +u32 wait_on_value(u32, u32, void *, u32); +void sdelay(unsigned long);  extern const struct omap_sysinfo sysinfo; diff --git a/arch/arm/include/asm/arch-orion5x/cpu.h b/arch/arm/include/asm/arch-orion5x/cpu.h index 80717f8a5..6ce02a921 100644 --- a/arch/arm/include/asm/arch-orion5x/cpu.h +++ b/arch/arm/include/asm/arch-orion5x/cpu.h @@ -76,7 +76,7 @@ enum orion5x_cpu_attrib {  /*   * Device Address MAP BAR values -/* + *   * All addresses and sizes not defined by board code   * will be given default values here.   */ diff --git a/arch/arm/include/asm/arch-s5pc1xx/clk.h b/arch/arm/include/asm/arch-s5pc1xx/clk.h index 3e59abe78..3488eb7c1 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/clk.h +++ b/arch/arm/include/asm/arch-s5pc1xx/clk.h @@ -29,10 +29,11 @@  #define HPLL	3  #define VPLL	4 -void s5pc1xx_clock_init(void); +void s5p_clock_init(void);  extern unsigned long (*get_pll_clk)(int pllreg);  extern unsigned long (*get_arm_clk)(void); -extern unsigned long (*get_pclk)(void); +extern unsigned long (*get_pwm_clk)(void); +extern unsigned long (*get_uart_clk)(int dev_index);  #endif diff --git a/arch/arm/include/asm/arch-s5pc1xx/cpu.h b/arch/arm/include/asm/arch-s5pc1xx/cpu.h index b3af8cc78..e74959fe2 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/cpu.h +++ b/arch/arm/include/asm/arch-s5pc1xx/cpu.h @@ -25,9 +25,9 @@  #define S5PC1XX_ADDR_BASE	0xE0000000 -#define S5PC1XX_CLOCK_BASE	0xE0100000 -  /* S5PC100 */ +#define S5PC100_PRO_ID		0xE0000000 +#define S5PC100_CLOCK_BASE	0xE0100000  #define S5PC100_GPIO_BASE	0xE0300000  #define S5PC100_VIC0_BASE	0xE4000000  #define S5PC100_VIC1_BASE	0xE4100000 @@ -41,6 +41,8 @@  #define S5PC100_MMC_BASE	0xED800000  /* S5PC110 */ +#define S5PC110_PRO_ID		0xE0000000 +#define S5PC110_CLOCK_BASE	0xE0100000  #define S5PC110_GPIO_BASE	0xE0200000  #define S5PC110_PWMTIMER_BASE	0xE2500000  #define S5PC110_WATCHDOG_BASE	0xE2700000 @@ -54,21 +56,44 @@  #define S5PC110_VIC2_BASE	0xF2200000  #define S5PC110_VIC3_BASE	0xF2300000 -/* Chip ID */ -#define S5PC1XX_PRO_ID		0xE0000000 -  #ifndef __ASSEMBLY__ +#include <asm/io.h>  /* CPU detection macros */ -extern unsigned int s5pc1xx_cpu_id; +extern unsigned int s5p_cpu_id; + +static inline void s5p_set_cpu_id(void) +{ +	s5p_cpu_id = readl(S5PC100_PRO_ID); +	s5p_cpu_id = 0xC000 | ((s5p_cpu_id & 0x00FFF000) >> 12); +}  #define IS_SAMSUNG_TYPE(type, id)			\  static inline int cpu_is_##type(void)			\  {							\ -	return s5pc1xx_cpu_id == id ? 1 : 0;		\ +	return s5p_cpu_id == id ? 1 : 0;		\  }  IS_SAMSUNG_TYPE(s5pc100, 0xc100)  IS_SAMSUNG_TYPE(s5pc110, 0xc110) + +#define SAMSUNG_BASE(device, base)				\ +static inline unsigned int samsung_get_base_##device(void)	\ +{								\ +	if (cpu_is_s5pc100())					\ +		return S5PC100_##base;				\ +	else if (cpu_is_s5pc110())				\ +		return S5PC110_##base;				\ +	else							\ +		return 0;					\ +} + +SAMSUNG_BASE(clock, CLOCK_BASE) +SAMSUNG_BASE(gpio, GPIO_BASE) +SAMSUNG_BASE(pro_id, PRO_ID) +SAMSUNG_BASE(mmc, MMC_BASE) +SAMSUNG_BASE(sromc, SROMC_BASE) +SAMSUNG_BASE(timer, PWMTIMER_BASE) +SAMSUNG_BASE(uart, UART_BASE)  #endif  #endif	/* _S5PC1XX_CPU_H */ diff --git a/arch/arm/include/asm/arch-s5pc1xx/gpio.h b/arch/arm/include/asm/arch-s5pc1xx/gpio.h index 9a7faed31..2df33a607 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/gpio.h +++ b/arch/arm/include/asm/arch-s5pc1xx/gpio.h @@ -33,96 +33,96 @@ struct s5p_gpio_bank {  };  struct s5pc100_gpio { -	struct s5p_gpio_bank gpio_a0; -	struct s5p_gpio_bank gpio_a1; -	struct s5p_gpio_bank gpio_b; -	struct s5p_gpio_bank gpio_c; -	struct s5p_gpio_bank gpio_d; -	struct s5p_gpio_bank gpio_e0; -	struct s5p_gpio_bank gpio_e1; -	struct s5p_gpio_bank gpio_f0; -	struct s5p_gpio_bank gpio_f1; -	struct s5p_gpio_bank gpio_f2; -	struct s5p_gpio_bank gpio_f3; -	struct s5p_gpio_bank gpio_g0; -	struct s5p_gpio_bank gpio_g1; -	struct s5p_gpio_bank gpio_g2; -	struct s5p_gpio_bank gpio_g3; -	struct s5p_gpio_bank gpio_i; -	struct s5p_gpio_bank gpio_j0; -	struct s5p_gpio_bank gpio_j1; -	struct s5p_gpio_bank gpio_j2; -	struct s5p_gpio_bank gpio_j3; -	struct s5p_gpio_bank gpio_j4; -	struct s5p_gpio_bank gpio_k0; -	struct s5p_gpio_bank gpio_k1; -	struct s5p_gpio_bank gpio_k2; -	struct s5p_gpio_bank gpio_k3; -	struct s5p_gpio_bank gpio_l0; -	struct s5p_gpio_bank gpio_l1; -	struct s5p_gpio_bank gpio_l2; -	struct s5p_gpio_bank gpio_l3; -	struct s5p_gpio_bank gpio_l4; -	struct s5p_gpio_bank gpio_h0; -	struct s5p_gpio_bank gpio_h1; -	struct s5p_gpio_bank gpio_h2; -	struct s5p_gpio_bank gpio_h3; +	struct s5p_gpio_bank a0; +	struct s5p_gpio_bank a1; +	struct s5p_gpio_bank b; +	struct s5p_gpio_bank c; +	struct s5p_gpio_bank d; +	struct s5p_gpio_bank e0; +	struct s5p_gpio_bank e1; +	struct s5p_gpio_bank f0; +	struct s5p_gpio_bank f1; +	struct s5p_gpio_bank f2; +	struct s5p_gpio_bank f3; +	struct s5p_gpio_bank g0; +	struct s5p_gpio_bank g1; +	struct s5p_gpio_bank g2; +	struct s5p_gpio_bank g3; +	struct s5p_gpio_bank i; +	struct s5p_gpio_bank j0; +	struct s5p_gpio_bank j1; +	struct s5p_gpio_bank j2; +	struct s5p_gpio_bank j3; +	struct s5p_gpio_bank j4; +	struct s5p_gpio_bank k0; +	struct s5p_gpio_bank k1; +	struct s5p_gpio_bank k2; +	struct s5p_gpio_bank k3; +	struct s5p_gpio_bank l0; +	struct s5p_gpio_bank l1; +	struct s5p_gpio_bank l2; +	struct s5p_gpio_bank l3; +	struct s5p_gpio_bank l4; +	struct s5p_gpio_bank h0; +	struct s5p_gpio_bank h1; +	struct s5p_gpio_bank h2; +	struct s5p_gpio_bank h3;  };  struct s5pc110_gpio { -	struct s5p_gpio_bank gpio_a0; -	struct s5p_gpio_bank gpio_a1; -	struct s5p_gpio_bank gpio_b; -	struct s5p_gpio_bank gpio_c0; -	struct s5p_gpio_bank gpio_c1; -	struct s5p_gpio_bank gpio_d0; -	struct s5p_gpio_bank gpio_d1; -	struct s5p_gpio_bank gpio_e0; -	struct s5p_gpio_bank gpio_e1; -	struct s5p_gpio_bank gpio_f0; -	struct s5p_gpio_bank gpio_f1; -	struct s5p_gpio_bank gpio_f2; -	struct s5p_gpio_bank gpio_f3; -	struct s5p_gpio_bank gpio_g0; -	struct s5p_gpio_bank gpio_g1; -	struct s5p_gpio_bank gpio_g2; -	struct s5p_gpio_bank gpio_g3; -	struct s5p_gpio_bank gpio_i; -	struct s5p_gpio_bank gpio_j0; -	struct s5p_gpio_bank gpio_j1; -	struct s5p_gpio_bank gpio_j2; -	struct s5p_gpio_bank gpio_j3; -	struct s5p_gpio_bank gpio_j4; -	struct s5p_gpio_bank gpio_mp0_1; -	struct s5p_gpio_bank gpio_mp0_2; -	struct s5p_gpio_bank gpio_mp0_3; -	struct s5p_gpio_bank gpio_mp0_4; -	struct s5p_gpio_bank gpio_mp0_5; -	struct s5p_gpio_bank gpio_mp0_6; -	struct s5p_gpio_bank gpio_mp0_7; -	struct s5p_gpio_bank gpio_mp1_0; -	struct s5p_gpio_bank gpio_mp1_1; -	struct s5p_gpio_bank gpio_mp1_2; -	struct s5p_gpio_bank gpio_mp1_3; -	struct s5p_gpio_bank gpio_mp1_4; -	struct s5p_gpio_bank gpio_mp1_5; -	struct s5p_gpio_bank gpio_mp1_6; -	struct s5p_gpio_bank gpio_mp1_7; -	struct s5p_gpio_bank gpio_mp1_8; -	struct s5p_gpio_bank gpio_mp2_0; -	struct s5p_gpio_bank gpio_mp2_1; -	struct s5p_gpio_bank gpio_mp2_2; -	struct s5p_gpio_bank gpio_mp2_3; -	struct s5p_gpio_bank gpio_mp2_4; -	struct s5p_gpio_bank gpio_mp2_5; -	struct s5p_gpio_bank gpio_mp2_6; -	struct s5p_gpio_bank gpio_mp2_7; -	struct s5p_gpio_bank gpio_mp2_8; +	struct s5p_gpio_bank a0; +	struct s5p_gpio_bank a1; +	struct s5p_gpio_bank b; +	struct s5p_gpio_bank c0; +	struct s5p_gpio_bank c1; +	struct s5p_gpio_bank d0; +	struct s5p_gpio_bank d1; +	struct s5p_gpio_bank e0; +	struct s5p_gpio_bank e1; +	struct s5p_gpio_bank f0; +	struct s5p_gpio_bank f1; +	struct s5p_gpio_bank f2; +	struct s5p_gpio_bank f3; +	struct s5p_gpio_bank g0; +	struct s5p_gpio_bank g1; +	struct s5p_gpio_bank g2; +	struct s5p_gpio_bank g3; +	struct s5p_gpio_bank i; +	struct s5p_gpio_bank j0; +	struct s5p_gpio_bank j1; +	struct s5p_gpio_bank j2; +	struct s5p_gpio_bank j3; +	struct s5p_gpio_bank j4; +	struct s5p_gpio_bank mp0_1; +	struct s5p_gpio_bank mp0_2; +	struct s5p_gpio_bank mp0_3; +	struct s5p_gpio_bank mp0_4; +	struct s5p_gpio_bank mp0_5; +	struct s5p_gpio_bank mp0_6; +	struct s5p_gpio_bank mp0_7; +	struct s5p_gpio_bank mp1_0; +	struct s5p_gpio_bank mp1_1; +	struct s5p_gpio_bank mp1_2; +	struct s5p_gpio_bank mp1_3; +	struct s5p_gpio_bank mp1_4; +	struct s5p_gpio_bank mp1_5; +	struct s5p_gpio_bank mp1_6; +	struct s5p_gpio_bank mp1_7; +	struct s5p_gpio_bank mp1_8; +	struct s5p_gpio_bank mp2_0; +	struct s5p_gpio_bank mp2_1; +	struct s5p_gpio_bank mp2_2; +	struct s5p_gpio_bank mp2_3; +	struct s5p_gpio_bank mp2_4; +	struct s5p_gpio_bank mp2_5; +	struct s5p_gpio_bank mp2_6; +	struct s5p_gpio_bank mp2_7; +	struct s5p_gpio_bank mp2_8;  	struct s5p_gpio_bank res1[48]; -	struct s5p_gpio_bank gpio_h0; -	struct s5p_gpio_bank gpio_h1; -	struct s5p_gpio_bank gpio_h2; -	struct s5p_gpio_bank gpio_h3; +	struct s5p_gpio_bank h0; +	struct s5p_gpio_bank h1; +	struct s5p_gpio_bank h2; +	struct s5p_gpio_bank h3;  };  /* functions */ diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h index ac560c270..68c59d13e 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h +++ b/arch/arm/include/asm/arch-s5pc1xx/mmc.h @@ -56,7 +56,7 @@ struct s5p_mmc {  	unsigned int	control4;  	unsigned char	res4[0x6e];  	unsigned short	hcver; -	unsigned char	res5[0xFFF00]; +	unsigned char	res5[0xFFF02];  };  struct mmc_host { diff --git a/arch/arm/include/asm/arch-s5pc1xx/pwm.h b/arch/arm/include/asm/arch-s5pc1xx/pwm.h index e02a8d8fb..0369968d4 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/pwm.h +++ b/arch/arm/include/asm/arch-s5pc1xx/pwm.h @@ -22,19 +22,15 @@  #ifndef __ASM_ARM_ARCH_PWM_H_  #define __ASM_ARM_ARCH_PWM_H_ -/* PWM timer addressing */ -#define S5PC100_TIMER_BASE	S5PC100_PWMTIMER_BASE -#define S5PC110_TIMER_BASE	S5PC110_PWMTIMER_BASE -  /* Interval mode(Auto Reload) of PWM Timer 4 */ -#define S5PC1XX_TCON4_AUTO_RELOAD	(1 << 22) +#define TCON4_AUTO_RELOAD	(1 << 22)  /* Update TCNTB4 */ -#define S5PC1XX_TCON4_UPDATE		(1 << 21) +#define TCON4_UPDATE		(1 << 21)  /* start bit of PWM Timer 4 */ -#define S5PC1XX_TCON4_START		(1 << 20) +#define TCON4_START		(1 << 20)  #ifndef __ASSEMBLY__ -struct s5pc1xx_timer { +struct s5p_timer {  	unsigned int	tcfg0;  	unsigned int	tcfg1;  	unsigned int	tcon; diff --git a/arch/avr32/cpu/at32ap700x/Makefile b/arch/avr32/cpu/at32ap700x/Makefile index 46e6ef661..30ea92590 100644 --- a/arch/avr32/cpu/at32ap700x/Makefile +++ b/arch/avr32/cpu/at32ap700x/Makefile @@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk  LIB	:= $(obj)lib$(SOC).a -COBJS	:= portmux.o clk.o +COBJS	:= portmux.o clk.o mmu.o  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/avr32/cpu/at32ap700x/mmu.c b/arch/avr32/cpu/at32ap700x/mmu.c new file mode 100644 index 000000000..c3a1b9367 --- /dev/null +++ b/arch/avr32/cpu/at32ap700x/mmu.c @@ -0,0 +1,78 @@ +#include <common.h> +#include <asm/arch/mmu.h> +#include <asm/sysreg.h> + +void mmu_init_r(unsigned long dest_addr) +{ +	uintptr_t	vmr_table_addr; + +	/* Round monitor address down to the nearest page boundary */ +	dest_addr &= PAGE_ADDR_MASK; + +	/* Initialize TLB entry 0 to cover the monitor, and lock it */ +	sysreg_write(TLBEHI, dest_addr | SYSREG_BIT(TLBEHI_V)); +	sysreg_write(TLBELO, dest_addr | MMU_VMR_CACHE_WRBACK); +	sysreg_write(MMUCR, SYSREG_BF(DRP, 0) | SYSREG_BF(DLA, 1) +			| SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M)); +	__builtin_tlbw(); + +	/* +	 * Calculate the address of the VM range table in a PC-relative +	 * manner to make sure we hit the SDRAM and not the flash. +	 */ +	vmr_table_addr = (uintptr_t)&mmu_vmr_table; +	sysreg_write(PTBR, vmr_table_addr); +	printf("VMR table @ 0x%08x\n", vmr_table_addr); + +	/* Enable paging */ +	sysreg_write(MMUCR, SYSREG_BF(DRP, 1) | SYSREG_BF(DLA, 1) +			| SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M) | SYSREG_BIT(E)); +} + +int mmu_handle_tlb_miss(void) +{ +	const struct mmu_vm_range *vmr_table; +	const struct mmu_vm_range *vmr; +	unsigned int fault_pgno; +	int first, last; + +	fault_pgno = sysreg_read(TLBEAR) >> PAGE_SHIFT; +	vmr_table = (const struct mmu_vm_range *)sysreg_read(PTBR); + +	/* Do a binary search through the VM ranges */ +	first = 0; +	last = CONFIG_SYS_NR_VM_REGIONS; +	while (first < last) { +		unsigned int start; +		int middle; + +		/* Pick the entry in the middle of the remaining range */ +		middle = (first + last) >> 1; +		vmr = &vmr_table[middle]; +		start = vmr->virt_pgno; + +		/* Do the bisection thing */ +		if (fault_pgno < start) { +			last = middle; +		} else if (fault_pgno >= (start + vmr->nr_pages)) { +			first = middle + 1; +		} else { +			/* Got it; let's slam it into the TLB */ +			uint32_t tlbelo; + +			tlbelo = vmr->phys & ~PAGE_ADDR_MASK; +			tlbelo |= fault_pgno << PAGE_SHIFT; +			sysreg_write(TLBELO, tlbelo); +			__builtin_tlbw(); + +			/* Zero means success */ +			return 0; +		} +	} + +	/* +	 * Didn't find any matching entries. Return a nonzero value to +	 * indicate that this should be treated as a fatal exception. +	 */ +	return -1; +} diff --git a/arch/avr32/cpu/exception.c b/arch/avr32/cpu/exception.c index dc9c3002a..b21ef1f92 100644 --- a/arch/avr32/cpu/exception.c +++ b/arch/avr32/cpu/exception.c @@ -59,7 +59,8 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)  {  	unsigned int mode; -	printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc); +	printf("\n *** Unhandled exception %u at PC=0x%08lx [%08lx]\n", +			ecr, regs->pc, regs->pc - gd->reloc_off);  	switch (ecr) {  	case ECR_BUS_ERROR_WRITE: diff --git a/arch/avr32/cpu/start.S b/arch/avr32/cpu/start.S index 99c9e06cb..06bf4c692 100644 --- a/arch/avr32/cpu/start.S +++ b/arch/avr32/cpu/start.S @@ -82,12 +82,19 @@ _evba:  	.org	0x44  	rjmp	unknown_exception	/* DTLB Modified */ -	.org	0x50 -	rjmp	unknown_exception	/* ITLB Miss */ -	.org	0x60 -	rjmp	unknown_exception	/* DTLB Miss (read) */ -	.org	0x70 -	rjmp	unknown_exception	/* DTLB Miss (write) */ +	.org	0x50			/* ITLB Miss */ +	pushm   r8-r12,lr +	rjmp	1f +	.org	0x60			/* DTLB Miss (read) */ +	pushm   r8-r12,lr +	rjmp	1f +	.org	0x70			/* DTLB Miss (write) */ +	pushm   r8-r12,lr +1:	mov	r12, sp +	rcall	mmu_handle_tlb_miss +	popm	r8-r12,lr +	brne	unknown_exception +	rete  	.size	_evba, . - _evba diff --git a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h index 409eee353..4edc1bd70 100644 --- a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h +++ b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h @@ -75,10 +75,7 @@ static inline void * phys_to_virt(unsigned long address)  static inline void *  map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)  { -	if (flags == MAP_WRBACK) -		return (void *)P1SEGADDR(paddr); -	else -		return (void *)P2SEGADDR(paddr); +	return (void *)paddr;  }  #endif /* __ASM_AVR32_ADDRSPACE_H */ diff --git a/arch/avr32/include/asm/arch-at32ap700x/mmu.h b/arch/avr32/include/asm/arch-at32ap700x/mmu.h new file mode 100644 index 000000000..fcd9a0560 --- /dev/null +++ b/arch/avr32/include/asm/arch-at32ap700x/mmu.h @@ -0,0 +1,66 @@ +/* + * In order to deal with the hardcoded u-boot requirement that virtual + * addresses are always mapped 1:1 with physical addresses, we implement + * a small virtual memory manager so that we can use the MMU hardware in + * order to get the caching properties right. + * + * A few pages (or possibly just one) are locked in the TLB permanently + * in order to avoid recursive TLB misses, but most pages are faulted in + * on demand. + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +#include <asm/sysreg.h> + +#define PAGE_SHIFT	20 +#define PAGE_SIZE	(1UL << PAGE_SHIFT) +#define PAGE_ADDR_MASK	(~(PAGE_SIZE - 1)) + +#define MMU_VMR_CACHE_NONE						\ +	(SYSREG_BF(AP, 3) | SYSREG_BF(SZ, 3) | SYSREG_BIT(TLBELO_D)) +#define MMU_VMR_CACHE_WBUF						\ +	(MMU_VMR_CACHE_NONE | SYSREG_BIT(B)) +#define MMU_VMR_CACHE_WRTHRU						\ +	(MMU_VMR_CACHE_NONE | SYSREG_BIT(TLBELO_C) | SYSREG_BIT(W)) +#define MMU_VMR_CACHE_WRBACK						\ +	(MMU_VMR_CACHE_WBUF | SYSREG_BIT(TLBELO_C)) + +/* + * This structure is used in our "page table". Instead of the usual + * x86-inspired radix tree, we let each entry cover an arbitrary-sized + * virtual address range and store them in a binary search tree. This is + * somewhat slower, but should use significantly less RAM, and we + * shouldn't get many TLB misses when using 1 MB pages anyway. + * + * With 1 MB pages, we need 12 bits to store the page number. In + * addition, we stick an Invalid bit in the high bit of virt_pgno (if + * set, it cannot possibly match any faulting page), and all the bits + * that need to be written to TLBELO in phys_pgno. + */ +struct mmu_vm_range { +	uint16_t	virt_pgno; +	uint16_t	nr_pages; +	uint32_t	phys; +}; + +/* + * An array of mmu_vm_range objects describing all pageable addresses. + * The array is sorted by virt_pgno so that the TLB miss exception + * handler can do a binary search to find the correct entry. + */ +extern struct mmu_vm_range mmu_vmr_table[]; + +/* + * Initialize the MMU. This will set up a fixed TLB entry for the static + * u-boot image at dest_addr and enable paging. + */ +void mmu_init_r(unsigned long dest_addr); + +/* + * Handle a TLB miss exception. This function is called directly from + * the exception vector table written in assembly. + */ +int mmu_handle_tlb_miss(void); + +#endif /* __ASM_ARCH_MMU_H */ diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 9e741d22e..aa589bb4b 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -33,6 +33,7 @@  #include <asm/initcalls.h>  #include <asm/sections.h> +#include <asm/arch/mmu.h>  #ifndef CONFIG_IDENT_STRING  #define CONFIG_IDENT_STRING "" @@ -265,6 +266,9 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)  	gd->flags |= GD_FLG_RELOC;  	gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE; +	/* Enable the MMU so that we can keep u-boot simple */ +	mmu_init_r(dest_addr); +  	board_early_init_r();  	monitor_flash_len = _edata - _text; |