diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 12:47:53 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 12:47:53 -0700 |
commit | 8e95a53ba4b060e2d0d46575059ae96ea91a80fd (patch) | |
tree | c5e2cacf18475cb3f3b8fdfaa6223d24c37849e1 /arch/blackfin/mach-common/clocks-init.c | |
parent | cd975ae0ce13e4cbb21f13ae1222bdb6a8996ba0 (diff) | |
parent | 672552adb3197c5db3acc8800c7917bcff180461 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lliubbo/blackfin
Pull blackfin changes from Bob Liu:
"The biggest change was added an new processor(bf60x series).
Bf60x series processor of blackfin can up to 1GHz with Hardware
Support for HD Video Analytics, it use the same blackfin ISA but with
some changes on system buses, interrupt controller and peripheral
devices.
Added dir arch/blackfin/mach-bf609/ and did some changes to the
framework made linux working fine on the reference board bf609-ezkit
now."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lliubbo/blackfin: (41 commits)
blackfin: fix build after add bf60x mach/pm.h
blackfin: twi: include linux/i2c.h
blackfin: bf60x: add head file for crc controller
blackfin: bf60x: twi: work around temporary anomaly 0501001
blackfin: twi: Move TWI MMR access macro to twi head file
blackfin: twi: Move TWI peripheral pin request array to platform data
blackfin: bf60x: anomaly: Add a temporary anomaly 0501001
blackfin: bf60x: Rename the DDR controller macro
blackfin: mach-bf609: pm: cleanup bfin_deepsleep
blackfin: bf60x: cleanup get clock code
blackfin: bf60x: pm: Add a debug option to calculate kernel wakeup time.
blackfin: bf60x: add wakeup source select
blackfin: bf60x: make clock changeable in kernel menuconfig
blackfin:mach-bf609: fix norflash for bf609-ezkit
blackfin: mach-bf609: add can_wakeup to ethernet device
blackfin: remove redundant CONFIG_BF60x macro
blackfin: rotary: Add pm_wakeup flag to platform data structure.
bfin_gpio: fix bf548-ezkit kernel fail to boot
bfin_dma: fix initcall return error in proc_dma_init()
Blackfin: delete fork func
...
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); + } |