bfin: reorg clock init steps for bf609
Bob Liu [Mon, 23 Jul 2012 02:47:48 +0000 (10:47 +0800)]
So that user can set the clocks through menuconfig.

Signed-off-by: Bob Liu <lliubbo@gmail.com>

arch/blackfin/Kconfig
arch/blackfin/include/asm/mem_init.h
arch/blackfin/mach-bf609/include/mach/defBF60x_base.h
arch/blackfin/mach-common/clocks-init.c

index 2baa493..f9f6f69 100644 (file)
@@ -352,6 +352,11 @@ config MEM_MT48H32M16LFCJ_75
        depends on (BFIN526_EZBRD)
        default y
 
+config MEM_MT47H64M16
+       bool
+       depends on (BFIN609_EZKIT)
+       default y
+
 source "arch/blackfin/mach-bf518/Kconfig"
 source "arch/blackfin/mach-bf527/Kconfig"
 source "arch/blackfin/mach-bf533/Kconfig"
index 2375799..f019e9b 100644 (file)
@@ -6,6 +6,9 @@
  * Licensed under the GPL-2 or later.
  */
 
+#ifndef __MEM_INIT_H__
+#define __MEM_INIT_H__
+
 #if defined(EBIU_SDGCTL)
 #if defined(CONFIG_MEM_MT48LC16M16A2TG_75) || \
     defined(CONFIG_MEM_MT48LC64M4A2FB_7E) || \
 #else
 #define PLL_BYPASS       0
 #endif
+
+#ifdef CONFIG_BF60x
+
+/* DMC status bits */
+#define IDLE                   0x1
+#define MEMINITDONE            0x4
+#define SRACK                  0x8
+#define PDACK                  0x10
+#define DPDACK                 0x20
+#define DLLCALDONE             0x2000
+#define PENDREF                        0xF0000
+#define PHYRDPHASE             0xF00000
+#define PHYRDPHASE_OFFSET      20
+
+/* DMC control bits */
+#define LPDDR                  0x2
+#define INIT                   0x4
+#define        SRREQ                   0x8
+#define PDREQ                  0x10
+#define DPDREQ                 0x20
+#define PREC                   0x40
+#define ADDRMODE               0x100
+#define RDTOWR                 0xE00
+#define PPREF                  0x1000
+#define DLLCAL                 0x2000
+
+/* DMC DLL control bits */
+#define DLLCALRDCNT            0xFF
+#define DATACYC                        0xF00
+#define DATACYC_OFFSET         8
+
+/* CGU Divisor bits */
+#define CSEL_OFFSET            0
+#define S0SEL_OFFSET           5
+#define SYSSEL_OFFSET          8
+#define S1SEL_OFFSET           13
+#define DSEL_OFFSET            16
+#define OSEL_OFFSET            22
+#define ALGN                   0x20000000
+#define UPDT                   0x40000000
+#define LOCK                   0x80000000
+
+/* CGU Status bits */
+#define PLLEN                  0x1
+#define PLLBP                  0x2
+#define PLOCK                  0x4
+#define CLKSALGN               0x8
+
+/* CGU Control bits */
+#define MSEL_MASK              0x7F00
+#define DF_MASK                        0x1
+
+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;
+};
+
+#if defined(CONFIG_MEM_MT47H64M16)
+static 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,
+       },
+};
+#endif
+
+static inline void dmc_enter_self_refresh(void)
+{
+       if (bfin_read_DMC0_STAT() & MEMINITDONE) {
+               bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() | SRREQ);
+               while (!(bfin_read_DMC0_STAT() & SRACK))
+                       continue;
+       }
+}
+
+static inline void dmc_exit_self_refresh(void)
+{
+       if (bfin_read_DMC0_STAT() & MEMINITDONE) {
+               bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() & ~SRREQ);
+               while (bfin_read_DMC0_STAT() & SRACK)
+                       continue;
+       }
+}
+
+static inline void init_cgu(u32 cgu_div, u32 cgu_ctl)
+{
+       dmc_enter_self_refresh();
+
+       /* Don't set the same value of MSEL and DF to CGU_CTL */
+       if ((bfin_read32(CGU0_CTL) & (MSEL_MASK | DF_MASK))
+               != cgu_ctl) {
+               bfin_write32(CGU0_DIV, cgu_div);
+               bfin_write32(CGU0_CTL, cgu_ctl);
+               while ((bfin_read32(CGU0_STAT) & (CLKSALGN | PLLBP)) ||
+                       !(bfin_read32(CGU0_STAT) & PLOCK))
+                       continue;
+       }
+
+       bfin_write32(CGU0_DIV, cgu_div | UPDT);
+       while (bfin_read32(CGU0_STAT) & CLKSALGN)
+               continue;
+
+       dmc_exit_self_refresh();
+}
+
+static inline void init_dmc(u32 dmc_clk)
+{
+       int i, dlldatacycle, dll_ctl;
+
+       for (i = 0; i < 7; i++) {
+               if (ddr_config_table[i].ddr_clk == dmc_clk) {
+                       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;
+               }
+       }
+
+       while (!(bfin_read_DMC0_STAT() & MEMINITDONE))
+               continue;
+
+       dlldatacycle = (bfin_read_DMC0_STAT() & PHYRDPHASE) >> PHYRDPHASE_OFFSET;
+       dll_ctl = bfin_read_DMC0_DLLCTL();
+       dll_ctl &= ~DATACYC;
+       bfin_write_DMC0_DLLCTL(dll_ctl | (dlldatacycle << DATACYC_OFFSET));
+
+       while (!(bfin_read_DMC0_STAT() & DLLCALDONE))
+               continue;
+}
+#endif
+
+#endif /*__MEM_INIT_H__*/
+
index 6aac385..f1a6afa 100644 (file)
 #define DEVSZ_1G                0x400         /* DMC External Bank Size = 1Gbit */
 #define DEVSZ_2G                0x500         /* DMC External Bank Size = 2Gbit */
 
-
 /* =========================
         L2CTL Registers
    ========================= */
index 7ad2407..2308ce5 100644 (file)
 #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))
+       ((CONFIG_CCLK_DIV   << CSEL_OFFSET)   | \
+       (CONFIG_SCLK_DIV << SYSSEL_OFFSET)   | \
+       (CONFIG_SCLK0_DIV  << S0SEL_OFFSET)  | \
+       (CONFIG_SCLK1_DIV  << S1SEL_OFFSET)  | \
+       (CONFIG_DCLK_DIV   << DSEL_OFFSET))
 
 #define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
 #if ((CONFIG_BFIN_DCLK != 125) && \
        (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 \
@@ -144,43 +53,9 @@ 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;
+       init_cgu(CGU_DIV_VAL, CGU_CTL_VAL);
+       init_dmc(CONFIG_BFIN_DCLK);
 #else
        size_t i;
        for (i = 0; i < MAX_DMA_CHANNELS; ++i) {