diff options
Diffstat (limited to 'arch/arm/cpu')
28 files changed, 1369 insertions, 351 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; |