commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=cd6f5dc21e68c0bbc4261917813e52d7d9f5a326 branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2012R1
Setup cclk/sclk div to match kernel options and configure DDR2 controller accordingly. Signed-off-by: Bob Liu <[email protected]> --- arch/blackfin/Kconfig | 13 ++- arch/blackfin/include/asm/bfin-global.h | 2 +- arch/blackfin/kernel/setup.c | 22 +---- arch/blackfin/mach-bf609/clock.c | 2 +- arch/blackfin/mach-common/clocks-init.c | 153 ++++++++++++++++++++++++++++++- 5 files changed, 164 insertions(+), 28 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f4fb12e..67182b2 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -453,7 +453,7 @@ config VCO_MULT default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) default "22" if BFIN533_BLUETECHNIX_CM default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) - default "20" if BFIN561_EZKIT + default "20" if (BFIN561_EZKIT || BF609) default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD) default "25" if BFIN527_AD7160EVAL help @@ -485,7 +485,7 @@ config SCLK_DIV int "System Clock Divider" depends on BFIN_KERNEL_CLOCK range 1 15 - default 5 + default 4 help This sets the frequency of the system clock (including SDRAM or DDR) on !BF60x else it set the clock for system buses and provides the @@ -497,7 +497,7 @@ config SCLK0_DIV int "System Clock0 Divider" depends on BFIN_KERNEL_CLOCK && BF60x range 1 15 - default 5 + default 1 help This sets the frequency of the system clock0 for PVP and all other peripherals not clocked by SCLK1. @@ -508,9 +508,9 @@ config SCLK1_DIV int "System Clock1 Divider" depends on BFIN_KERNEL_CLOCK && BF60x range 1 15 - default 5 + default 1 help - This sets the frequency of the system clock1 for SPORT, SPI and ACM. + This sets the frequency of the system clock1 (including SPORT, SPI and ACM). This can be between 1 and 15 System Clock1 = (System Clock) / (this setting) @@ -518,7 +518,7 @@ config DCLK_DIV int "DDR Clock Divider" depends on BFIN_KERNEL_CLOCK && BF60x range 1 15 - default 5 + default 2 help This sets the frequency of the DDR memory. This can be between 1 and 15 @@ -621,6 +621,7 @@ config MAX_VCO_HZ default 600000000 if BF548 default 533333333 if BF549 default 600000000 if BF561 + default 800000000 if BF609 config MIN_VCO_HZ int diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index a83e922..608be5e 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -38,7 +38,7 @@ extern unsigned long get_sclk(void); #ifdef CONFIG_BF60x extern unsigned long get_sclk0(void); extern unsigned long get_sclk1(void); -extern unsigned long get_dramclk(void); +extern unsigned long get_dclk(void); #endif extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs); diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 0c2a1d8..e910f52 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -908,7 +908,6 @@ void __init setup_arch(char **cmdline_p) { u32 mmr; unsigned long sclk, cclk; - struct clk *clk; native_machine_early_platform_add_devices(); @@ -973,24 +972,8 @@ void __init setup_arch(char **cmdline_p) ~HYST_NONEGPIO_MASK) | HYST_NONEGPIO); #endif -#ifdef CONFIG_BF60x - clk = clk_get(NULL, "CCLK"); - if (!IS_ERR(clk)) { - cclk = clk_get_rate(clk); - clk_put(clk); - } else - cclk = 0; - - clk = clk_get(NULL, "SCLK0"); - if (!IS_ERR(clk)) { - sclk = clk_get_rate(clk); - clk_put(clk); - } else - sclk = 0; -#else cclk = get_cclk(); sclk = get_sclk(); -#endif if ((ANOMALY_05000273 || ANOMALY_05000274) && (cclk >> 1) < sclk) panic("ANOMALY 05000273 or 05000274: CCLK must be >= 2*SCLK"); @@ -1076,8 +1059,13 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); +#ifdef CONFIG_BF60x + printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n", + cclk / 1000000, sclk / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000); +#else printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", cclk / 1000000, sclk / 1000000); +#endif setup_bootmem_allocator(); diff --git a/arch/blackfin/mach-bf609/clock.c b/arch/blackfin/mach-bf609/clock.c index b50412c..7f8f529 100644 --- a/arch/blackfin/mach-bf609/clock.c +++ b/arch/blackfin/mach-bf609/clock.c @@ -351,7 +351,7 @@ static struct clk dclk = { .rate = 500000000, .mask = CGU0_DIV_DSEL_MASK, .shift = CGU0_DIV_DSEL_SHIFT, - .parent = &pll_clk, + .parent = &sys_clkin, .ops = &sys_clk_ops, }; diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index a8f53d2..090a229 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) @@ -34,7 +145,43 @@ void init_clocks(void) * For example, any automatic DMAs left by U-Boot for splash screens. */ -#ifndef CONFIG_BF60x +#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_DMC0_CFG(ddr_config_table[i].dmc_ddrcfg); + bfin_write_DMC0_TR0(ddr_config_table[i].dmc_ddrtr0); + bfin_write_DMC0_TR1(ddr_config_table[i].dmc_ddrtr1); + bfin_write_DMC0_TR2(ddr_config_table[i].dmc_ddrtr2); + bfin_write_DMC0_MR(ddr_config_table[i].dmc_ddrmr); + bfin_write_DMC0_EMR1(ddr_config_table[i].dmc_ddrmr1); + bfin_write_DMC0_CTL(ddr_config_table[i].dmc_ddrctl); + break; + } + } + + do_sync(); + while (!(bfin_read_DMC0_STAT() & 0x4)) + continue; + + dlldatacycle = (bfin_read_DMC0_STAT() & 0x00f00000) >> 20; + dll_ctl = bfin_read_DMC0_DLLCTL(); + dll_ctl &= 0x0ff; + bfin_write_DMC0_DLLCTL(dll_ctl | (dlldatacycle << 8)); + + do_sync(); + while (!(bfin_read_DMC0_STAT() & 0x2000)) + continue; +#else size_t i; for (i = 0; i < MAX_DMA_CHANNELS; ++i) { struct dma_register *dma = dma_io_base_addr[i]; @@ -93,8 +240,8 @@ void init_clocks(void) bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); #endif #endif +#endif do_sync(); bfin_read16(0); -#endif }
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
