blackfin: bf60x: make clock changeable in kernel menuconfig
authorBob Liu <lliubbo@gmail.com>
Thu, 17 May 2012 09:15:40 +0000 (17:15 +0800)
committerBob Liu <lliubbo@gmail.com>
Mon, 21 May 2012 06:54:49 +0000 (14:54 +0800)
Add clock changeable support in kernel menuconfig for bf60x.

Signed-off-by: Bob Liu <lliubbo@gmail.com>
arch/blackfin/Kconfig
arch/blackfin/include/asm/bfin-global.h
arch/blackfin/kernel/setup.c
arch/blackfin/mach-bf609/clock.c
arch/blackfin/mach-common/clocks-init.c

index 23bae9a3f7875a7c34095578d2ee20664627363d..4e48e72291a9cd2fa79bd6acbc938a727b2c85d3 100644 (file)
@@ -435,7 +435,7 @@ config BFIN_KERNEL_CLOCK
 
 config PLL_BYPASS
        bool "Bypass PLL"
-       depends on BFIN_KERNEL_CLOCK
+       depends on BFIN_KERNEL_CLOCK && (!BF60x)
        default n
 
 config CLKIN_HALF
@@ -454,7 +454,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
@@ -486,12 +486,45 @@ 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).
+         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
+         source from which SCLK0 and SCLK1 are derived.
          This can be between 1 and 15
          System Clock = (PLL frequency) / (this setting)
 
+config SCLK0_DIV
+       int "System Clock0 Divider"
+       depends on BFIN_KERNEL_CLOCK && BF60x
+       range 1 15
+       default 1
+       help
+         This sets the frequency of the system clock0 for PVP and all other
+         peripherals not clocked by SCLK1.
+         This can be between 1 and 15
+         System Clock0 = (System Clock) / (this setting)
+
+config SCLK1_DIV
+       int "System Clock1 Divider"
+       depends on BFIN_KERNEL_CLOCK && BF60x
+       range 1 15
+       default 1
+       help
+         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)
+
+config DCLK_DIV
+       int "DDR Clock Divider"
+       depends on BFIN_KERNEL_CLOCK && BF60x
+       range 1 15
+       default 2
+       help
+         This sets the frequency of the DDR memory.
+         This can be between 1 and 15
+         DDR Clock = (PLL frequency) / (this setting)
+
 choice
        prompt "DDR SDRAM Chip Type"
        depends on BFIN_KERNEL_CLOCK
@@ -507,7 +540,7 @@ endchoice
 
 choice
        prompt "DDR/SDRAM Timing"
-       depends on BFIN_KERNEL_CLOCK
+       depends on BFIN_KERNEL_CLOCK && !BF60x
        default BFIN_KERNEL_CLOCK_MEMINIT_CALC
        help
          This option allows you to specify Blackfin SDRAM/DDR Timing parameters
@@ -589,6 +622,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
@@ -596,6 +630,7 @@ config MIN_VCO_HZ
 
 config MAX_SCLK_HZ
        int
+       default 200000000 if BF609
        default 133333333
 
 config MIN_SCLK_HZ
index a83e922a878d64ac9ca9c9b50038ec7c1d478c0a..608be5e6d25c50c69202f7101e9e8061e8148681 100644 (file)
@@ -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);
index ed041541ea193a1f3f493f1f84208d8ec9cd1b03..55fb42b50463d99e81fa6b7152a095099423a5a3 100644 (file)
@@ -892,9 +892,6 @@ void __init setup_arch(char **cmdline_p)
 {
        u32 mmr;
        unsigned long sclk, cclk;
-#ifdef CONFIG_BF60x
-       struct clk *clk;
-#endif
 
        native_machine_early_platform_add_devices();
 
@@ -959,24 +956,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");
@@ -1062,8 +1043,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();
 
index b50412c8cab0309a2330a062f9dab0dbd25ad42e..7f8f529693aeaae16f156cabcd7b6a920f5cc743 100644 (file)
@@ -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,
 };
 
index 1e6beca8d40382b2fe59701067460aee2e044e77..7ad2407d157102cc035cccaccaedb9c34f6feb08 100644 (file)
 #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.
         */
 
-#if 0
+#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];
@@ -92,9 +239,9 @@ void init_clocks(void)
 #ifdef CONFIG_MEM_EBIU_DDRQUE
        bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
 #endif
+#endif
 #endif
        do_sync();
        bfin_read16(0);
 
-#endif
 }