diff options
Diffstat (limited to 'arch/blackfin/mach-common/clocks-init.c')
| -rw-r--r-- | arch/blackfin/mach-common/clocks-init.c | 153 | 
1 files changed, 152 insertions, 1 deletions
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index d5cfe611b77..7ad2407d157 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c @@ -15,10 +15,121 @@  #include <asm/mem_init.h>  #include <asm/dpmc.h> +#ifdef CONFIG_BF60x +#define CSEL_P			0 +#define S0SEL_P			5 +#define SYSSEL_P		8 +#define S1SEL_P			13 +#define DSEL_P			16 +#define OSEL_P			22 +#define ALGN_P			29 +#define UPDT_P			30 +#define LOCK_P			31 + +#define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF) +#define CGU_DIV_VAL \ +	((CONFIG_CCLK_DIV   << CSEL_P)   | \ +	(CONFIG_SCLK_DIV << SYSSEL_P)   | \ +	(CONFIG_SCLK0_DIV  << S0SEL_P)  | \ +	(CONFIG_SCLK1_DIV  << S1SEL_P)  | \ +	(CONFIG_DCLK_DIV   << DSEL_P)) + +#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000) +#if ((CONFIG_BFIN_DCLK != 125) && \ +	(CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \ +	(CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \ +	(CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250)) +#error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz" +#endif +struct ddr_config { +	u32 ddr_clk; +	u32 dmc_ddrctl; +	u32 dmc_ddrcfg; +	u32 dmc_ddrtr0; +	u32 dmc_ddrtr1; +	u32 dmc_ddrtr2; +	u32 dmc_ddrmr; +	u32 dmc_ddrmr1; +}; + +struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = { +	[0] = { +		.ddr_clk    = 125, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20705212, +		.dmc_ddrtr1 = 0x201003CF, +		.dmc_ddrtr2 = 0x00320107, +		.dmc_ddrmr  = 0x00000422, +		.dmc_ddrmr1 = 0x4, +	}, +	[1] = { +		.ddr_clk    = 133, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20806313, +		.dmc_ddrtr1 = 0x2013040D, +		.dmc_ddrtr2 = 0x00320108, +		.dmc_ddrmr  = 0x00000632, +		.dmc_ddrmr1 = 0x4, +	}, +	[2] = { +		.ddr_clk    = 150, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20A07323, +		.dmc_ddrtr1 = 0x20160492, +		.dmc_ddrtr2 = 0x00320209, +		.dmc_ddrmr  = 0x00000632, +		.dmc_ddrmr1 = 0x4, +	}, +	[3] = { +		.ddr_clk    = 166, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20A07323, +		.dmc_ddrtr1 = 0x2016050E, +		.dmc_ddrtr2 = 0x00320209, +		.dmc_ddrmr  = 0x00000632, +		.dmc_ddrmr1 = 0x4, +	}, +	[4] = { +		.ddr_clk    = 200, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20a07323, +		.dmc_ddrtr1 = 0x2016050f, +		.dmc_ddrtr2 = 0x00320509, +		.dmc_ddrmr  = 0x00000632, +		.dmc_ddrmr1 = 0x4, +	}, +	[5] = { +		.ddr_clk    = 225, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20E0A424, +		.dmc_ddrtr1 = 0x302006DB, +		.dmc_ddrtr2 = 0x0032020D, +		.dmc_ddrmr  = 0x00000842, +		.dmc_ddrmr1 = 0x4, +	}, +	[6] = { +		.ddr_clk    = 250, +		.dmc_ddrctl = 0x00000904, +		.dmc_ddrcfg = 0x00000422, +		.dmc_ddrtr0 = 0x20E0A424, +		.dmc_ddrtr1 = 0x3020079E, +		.dmc_ddrtr2 = 0x0032020D, +		.dmc_ddrmr  = 0x00000842, +		.dmc_ddrmr1 = 0x4, +	}, +}; +#else  #define SDGCTL_WIDTH (1 << 31)	/* SDRAM external data path width */  #define PLL_CTL_VAL \  	(((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ -	 (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) +		(PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) +#endif  __attribute__((l1_text))  static void do_sync(void) @@ -33,6 +144,44 @@ void init_clocks(void)  	 * in the middle of reprogramming things, and that'll screw us up.  	 * For example, any automatic DMAs left by U-Boot for splash screens.  	 */ + +#ifdef CONFIG_BF60x +	int i, dlldatacycle, dll_ctl; +	bfin_write32(CGU0_DIV, CGU_DIV_VAL); +	bfin_write32(CGU0_CTL, CGU_CTL_VAL); +	while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4)) +		continue; + +	bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P)); +	while (bfin_read32(CGU0_STAT) & (1 << 3)) +		continue; + +	for (i = 0; i < 7; i++) { +		if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) { +			bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg); +			bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0); +			bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1); +			bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2); +			bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr); +			bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1); +			bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl); +			break; +		} +	} + +	do_sync(); +	while (!(bfin_read_DDR0_STAT() & 0x4)) +		continue; + +	dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; +	dll_ctl = bfin_read_DDR0_DLLCTL(); +	dll_ctl &= 0x0ff; +	bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); + +	do_sync(); +	while (!(bfin_read_DDR0_STAT() & 0x2000)) +		continue; +#else  	size_t i;  	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {  		struct dma_register *dma = dma_io_base_addr[i]; @@ -91,6 +240,8 @@ void init_clocks(void)  	bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);  #endif  #endif +#endif  	do_sync();  	bfin_read16(0); +  }  |