diff options
Diffstat (limited to 'arch/arm/cpu/armv7')
| -rw-r--r-- | arch/arm/cpu/armv7/omap-common/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap-common/reset.S | 4 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap-common/syslib.c (renamed from arch/arm/cpu/armv7/omap3/syslib.c) | 2 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/board.c | 35 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/cache.S | 101 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/clock.c | 543 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/lowlevel_init.S | 69 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/sdrc.c | 43 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/sys_info.c | 147 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5p-common/Makefile | 46 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5p-common/cpu_info.c (renamed from arch/arm/cpu/armv7/s5pc1xx/cpu_info.c) | 11 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5p-common/timer.c (renamed from arch/arm/cpu/armv7/s5pc1xx/timer.c) | 23 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5pc1xx/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5pc1xx/clock.c | 51 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5pc1xx/reset.S | 2 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/s5pc1xx/sromc.c | 8 | 
17 files changed, 765 insertions, 325 deletions
| 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; |