diff options
Diffstat (limited to 'arch/blackfin/lib')
| -rw-r--r-- | arch/blackfin/lib/board.c | 25 | ||||
| -rw-r--r-- | arch/blackfin/lib/clocks.c | 112 | ||||
| -rw-r--r-- | arch/blackfin/lib/string.c | 97 | 
3 files changed, 166 insertions, 68 deletions
| diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 9fbbea0d9..288dc829d 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -96,6 +96,13 @@ static void display_global_data(void)  #define CPLB_PAGE_SIZE (4 * 1024 * 1024)  #define CPLB_PAGE_MASK (~(CPLB_PAGE_SIZE - 1)) +#if defined(__ADSPBF60x__) +#define CPLB_EX_PAGE_SIZE (16 * 1024 * 1024) +#define CPLB_EX_PAGE_MASK (~(CPLB_EX_PAGE_SIZE - 1)) +#else +#define CPLB_EX_PAGE_SIZE CPLB_PAGE_SIZE +#define CPLB_EX_PAGE_MASK CPLB_PAGE_MASK +#endif  void init_cplbtables(void)  {  	volatile uint32_t *ICPLB_ADDR, *ICPLB_DATA; @@ -127,6 +134,11 @@ void init_cplbtables(void)  	icplb_add(0xFFA00000, L1_IMEMORY);  	dcplb_add(0xFF800000, L1_DMEMORY);  	++i; +#if defined(__ADSPBF60x__) +	icplb_add(0x0, 0x0); +	dcplb_add(CONFIG_SYS_FLASH_BASE, SDRAM_EBIU); +	++i; +#endif  	if (CONFIG_MEM_SIZE) {  		uint32_t mbase = CONFIG_SYS_MONITOR_BASE; @@ -150,9 +162,11 @@ void init_cplbtables(void)  		}  	} +#ifndef __ADSPBF60x__  	icplb_add(0x20000000, SDRAM_INON_CHBL);  	dcplb_add(0x20000000, SDRAM_EBIU);  	++i; +#endif  	/* Add entries for the rest of external RAM up to the bootrom */  	extern_memory = 0; @@ -167,10 +181,11 @@ void init_cplbtables(void)  	++i;  #endif -	while (i < 16 && extern_memory < (CONFIG_SYS_MONITOR_BASE & CPLB_PAGE_MASK)) { +	while (i < 16 && extern_memory < +		(CONFIG_SYS_MONITOR_BASE & CPLB_EX_PAGE_MASK)) {  		icplb_add(extern_memory, SDRAM_IGENERIC);  		dcplb_add(extern_memory, SDRAM_DGENERIC); -		extern_memory += CPLB_PAGE_SIZE; +		extern_memory += CPLB_EX_PAGE_SIZE;  		++i;  	}  	while (i < 16) { @@ -295,7 +310,13 @@ void board_init_f(ulong bootflag)  	printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));  	printf("Core: %s MHz, ", strmhz(buf, get_cclk())); +#if defined(__ADSPBF60x__) +	printf("System0: %s MHz, ", strmhz(buf, get_sclk0())); +	printf("System1: %s MHz, ", strmhz(buf, get_sclk1())); +	printf("Dclk: %s MHz\n", strmhz(buf, get_dclk())); +#else  	printf("System: %s MHz\n", strmhz(buf, get_sclk())); +#endif  	if (CONFIG_MEM_SIZE) {  		printf("RAM:   "); diff --git a/arch/blackfin/lib/clocks.c b/arch/blackfin/lib/clocks.c index 0be395bb3..d852f5ebe 100644 --- a/arch/blackfin/lib/clocks.c +++ b/arch/blackfin/lib/clocks.c @@ -9,69 +9,139 @@  #include <common.h>  #include <asm/blackfin.h> +#ifdef PLL_CTL +# include <asm/mach-common/bits/pll.h> +# define pll_is_bypassed() (bfin_read_PLL_STAT() & DF) +#else +# include <asm/mach-common/bits/cgu.h> +# define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP) +# define bfin_read_PLL_CTL() bfin_read_CGU_CTL() +# define bfin_read_PLL_DIV() bfin_read_CGU_DIV() +#endif +  /* Get the voltage input multiplier */ -static u_long cached_vco_pll_ctl, cached_vco;  u_long get_vco(void)  { -	u_long msel; +	static u_long cached_vco_pll_ctl, cached_vco; + +	u_long msel, pll_ctl; -	u_long pll_ctl = bfin_read_PLL_CTL(); +	pll_ctl = bfin_read_PLL_CTL();  	if (pll_ctl == cached_vco_pll_ctl)  		return cached_vco;  	else  		cached_vco_pll_ctl = pll_ctl; -	msel = (pll_ctl >> 9) & 0x3F; +	msel = (pll_ctl & MSEL) >> MSEL_P;  	if (0 == msel) -		msel = 64; +		msel = (MSEL >> MSEL_P) + 1;  	cached_vco = CONFIG_CLKIN_HZ; -	cached_vco >>= (1 & pll_ctl);	/* DF bit */ +	cached_vco >>= (pll_ctl & DF);  	cached_vco *= msel;  	return cached_vco;  }  /* Get the Core clock */ -static u_long cached_cclk_pll_div, cached_cclk;  u_long get_cclk(void)  { -	u_long csel, ssel; +	static u_long cached_cclk_pll_div, cached_cclk; +	u_long div, csel, ssel; -	if (bfin_read_PLL_STAT() & 0x1) +	if (pll_is_bypassed())  		return CONFIG_CLKIN_HZ; -	ssel = bfin_read_PLL_DIV(); -	if (ssel == cached_cclk_pll_div) +	div = bfin_read_PLL_DIV(); +	if (div == cached_cclk_pll_div)  		return cached_cclk;  	else -		cached_cclk_pll_div = ssel; +		cached_cclk_pll_div = div; -	csel = ((ssel >> 4) & 0x03); -	ssel &= 0xf; +	csel = (div & CSEL) >> CSEL_P; +#ifndef CGU_DIV +	ssel = (div & SSEL) >> SSEL_P;  	if (ssel && ssel < (1 << csel))	/* SCLK > CCLK */  		cached_cclk = get_vco() / ssel;  	else  		cached_cclk = get_vco() >> csel; +#else +	cached_cclk = get_vco() / csel; +#endif  	return cached_cclk;  }  /* Get the System clock */ +#ifdef CGU_DIV +  static u_long cached_sclk_pll_div, cached_sclk; +static u_long cached_sclk0, cached_sclk1, cached_dclk; +static u_long _get_sclk(u_long *cache) +{ +	u_long div, ssel; + +	if (pll_is_bypassed()) +		return CONFIG_CLKIN_HZ; + +	div = bfin_read_PLL_DIV(); +	if (div == cached_sclk_pll_div) +		return *cache; +	else +		cached_sclk_pll_div = div; + +	ssel = (div & SYSSEL) >> SYSSEL_P; +	cached_sclk = get_vco() / ssel; + +	ssel = (div & S0SEL) >> S0SEL_P; +	cached_sclk0 = cached_sclk / ssel; + +	ssel = (div & S1SEL) >> S1SEL_P; +	cached_sclk1 = cached_sclk / ssel; + +	ssel = (div & DSEL) >> DSEL_P; +	cached_dclk = get_vco() / ssel; + +	return *cache; +} +  u_long get_sclk(void)  { -	u_long ssel; +	return _get_sclk(&cached_sclk); +} + +u_long get_sclk0(void) +{ +	return _get_sclk(&cached_sclk0); +} + +u_long get_sclk1(void) +{ +	return _get_sclk(&cached_sclk1); +} + +u_long get_dclk(void) +{ +	return _get_sclk(&cached_dclk); +} +#else + +u_long get_sclk(void) +{ +	static u_long cached_sclk_pll_div, cached_sclk; +	u_long div, ssel; -	if (bfin_read_PLL_STAT() & 0x1) +	if (pll_is_bypassed())  		return CONFIG_CLKIN_HZ; -	ssel = bfin_read_PLL_DIV(); -	if (ssel == cached_sclk_pll_div) +	div = bfin_read_PLL_DIV(); +	if (div == cached_sclk_pll_div)  		return cached_sclk;  	else -		cached_sclk_pll_div = ssel; - -	ssel &= 0xf; +		cached_sclk_pll_div = div; +	ssel = (div & SSEL) >> SSEL_P;  	cached_sclk = get_vco() / ssel; +  	return cached_sclk;  } + +#endif diff --git a/arch/blackfin/lib/string.c b/arch/blackfin/lib/string.c index e344d3b94..44d8c6d90 100644 --- a/arch/blackfin/lib/string.c +++ b/arch/blackfin/lib/string.c @@ -29,7 +29,7 @@  #include <config.h>  #include <asm/blackfin.h>  #include <asm/io.h> -#include <asm/mach-common/bits/dma.h> +#include <asm/dma.h>  char *strcpy(char *dest, const char *src)  { @@ -117,81 +117,88 @@ int strncmp(const char *cs, const char *ct, size_t count)  	return __res1;  } -#ifdef bfin_write_MDMA1_D0_IRQ_STATUS -# define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS -# define bfin_write_MDMA_D0_START_ADDR bfin_write_MDMA1_D0_START_ADDR -# define bfin_write_MDMA_D0_X_COUNT    bfin_write_MDMA1_D0_X_COUNT -# define bfin_write_MDMA_D0_X_MODIFY   bfin_write_MDMA1_D0_X_MODIFY -# define bfin_write_MDMA_D0_CONFIG     bfin_write_MDMA1_D0_CONFIG -# define bfin_write_MDMA_S0_START_ADDR bfin_write_MDMA1_S0_START_ADDR -# define bfin_write_MDMA_S0_X_COUNT    bfin_write_MDMA1_S0_X_COUNT -# define bfin_write_MDMA_S0_X_MODIFY   bfin_write_MDMA1_S0_X_MODIFY -# define bfin_write_MDMA_S0_CONFIG     bfin_write_MDMA1_S0_CONFIG -# define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS -# define bfin_read_MDMA_D0_IRQ_STATUS  bfin_read_MDMA1_D0_IRQ_STATUS +#ifdef MDMA1_D0_NEXT_DESC_PTR +# define MDMA_D0_NEXT_DESC_PTR MDMA1_D0_NEXT_DESC_PTR +# define MDMA_S0_NEXT_DESC_PTR MDMA1_S0_NEXT_DESC_PTR  #endif + +static void dma_calc_size(unsigned long ldst, unsigned long lsrc, size_t count, +			unsigned long *dshift, unsigned long *bpos) +{ +	unsigned long limit; + +#ifdef MSIZE +	limit = 6; +	*dshift = MSIZE_P; +#else +	limit = 3; +	*dshift = WDSIZE_P; +#endif + +	*bpos = min(limit, ffs(ldst | lsrc | count)) - 1; +} +  /* This version misbehaves for count values of 0 and 2^16+.   * Perhaps we should detect that ?  Nowhere do we actually   * use dma memcpy for those types of lengths though ...   */  void dma_memcpy_nocache(void *dst, const void *src, size_t count)  { -	uint16_t wdsize, mod; +	struct dma_register *mdma_d0 = (void *)MDMA_D0_NEXT_DESC_PTR; +	struct dma_register *mdma_s0 = (void *)MDMA_S0_NEXT_DESC_PTR; +	unsigned long ldst = (unsigned long)dst; +	unsigned long lsrc = (unsigned long)src; +	unsigned long dshift, bpos; +	uint32_t dsize, mod;  	/* Disable DMA in case it's still running (older u-boot's did not  	 * always turn them off).  Do it before the if statement below so  	 * we can be cheap and not do a SSYNC() due to the forced abort.  	 */ -	bfin_write_MDMA_D0_CONFIG(0); -	bfin_write_MDMA_S0_CONFIG(0); -	bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR); +	bfin_write(&mdma_d0->config, 0); +	bfin_write(&mdma_s0->config, 0); +	bfin_write(&mdma_d0->status, DMA_RUN | DMA_DONE | DMA_ERR);  	/* Scratchpad cannot be a DMA source or destination */ -	if (((unsigned long)src >= L1_SRAM_SCRATCH && -	     (unsigned long)src < L1_SRAM_SCRATCH_END) || -	    ((unsigned long)dst >= L1_SRAM_SCRATCH && -	     (unsigned long)dst < L1_SRAM_SCRATCH_END)) +	if ((lsrc >= L1_SRAM_SCRATCH && lsrc < L1_SRAM_SCRATCH_END) || +	    (ldst >= L1_SRAM_SCRATCH && ldst < L1_SRAM_SCRATCH_END))  		hang(); -	if (((unsigned long)dst | (unsigned long)src | count) & 0x1) { -		wdsize = WDSIZE_8; -		mod = 1; -	} else if (((unsigned long)dst | (unsigned long)src | count) & 0x2) { -		wdsize = WDSIZE_16; -		count >>= 1; -		mod = 2; -	} else { -		wdsize = WDSIZE_32; -		count >>= 2; -		mod = 4; -	} +	dma_calc_size(ldst, lsrc, count, &dshift, &bpos); +	dsize = bpos << dshift; +	count >>= bpos; +	mod = 1 << bpos; + +#ifdef PSIZE +	dsize |= min(3, bpos) << PSIZE_P; +#endif  	/* Copy sram functions from sdram to sram */  	/* Setup destination start address */ -	bfin_write_MDMA_D0_START_ADDR(dst); +	bfin_write(&mdma_d0->start_addr, ldst);  	/* Setup destination xcount */ -	bfin_write_MDMA_D0_X_COUNT(count); +	bfin_write(&mdma_d0->x_count, count);  	/* Setup destination xmodify */ -	bfin_write_MDMA_D0_X_MODIFY(mod); +	bfin_write(&mdma_d0->x_modify, mod);  	/* Setup Source start address */ -	bfin_write_MDMA_S0_START_ADDR(src); +	bfin_write(&mdma_s0->start_addr, lsrc);  	/* Setup Source xcount */ -	bfin_write_MDMA_S0_X_COUNT(count); +	bfin_write(&mdma_s0->x_count, count);  	/* Setup Source xmodify */ -	bfin_write_MDMA_S0_X_MODIFY(mod); +	bfin_write(&mdma_s0->x_modify, mod);  	/* Enable source DMA */ -	bfin_write_MDMA_S0_CONFIG(wdsize | DMAEN); -	bfin_write_MDMA_D0_CONFIG(wdsize | DMAEN | WNR | DI_EN); +	bfin_write(&mdma_s0->config, dsize | DMAEN); +	bfin_write(&mdma_d0->config, dsize | DMAEN | WNR | DI_EN);  	SSYNC(); -	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) +	while (!(bfin_read(&mdma_d0->status) & DMA_DONE))  		continue; -	bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR); -	bfin_write_MDMA_D0_CONFIG(0); -	bfin_write_MDMA_S0_CONFIG(0); +	bfin_write(&mdma_d0->status, DMA_RUN | DMA_DONE | DMA_ERR); +	bfin_write(&mdma_d0->config, 0); +	bfin_write(&mdma_s0->config, 0);  }  /* We should do a dcache invalidate on the destination after the dma, but since   * we lack such hardware capability, we'll flush/invalidate the destination |