[U-Boot] [PATCH 11/16] Blackfin: Bf60x: support clock init
Bob Liu
lliubbo at gmail.com
Tue Aug 7 10:07:50 CEST 2012
Add a way to set clock to values getting from config file bf609-ezkit.h
Signed-off-by: Bob Liu <lliubbo at gmail.com>
---
arch/blackfin/cpu/initcode.c | 221 +++++++++++++++++++++-
arch/blackfin/include/asm/mach-common/bits/cgu.h | 2 +
include/configs/bf609-ezkit.h | 35 ++--
3 files changed, 234 insertions(+), 24 deletions(-)
diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c
index 9888f10..3bb2b98 100644
--- a/arch/blackfin/cpu/initcode.c
+++ b/arch/blackfin/cpu/initcode.c
@@ -29,6 +29,121 @@
#include <asm/mach-common/bits/cgu.h>
#endif
+#ifdef __ADSPBF60x__
+#define CONFIG_BFIN_GET_DCLK_M (CONFIG_BFIN_GET_DCLK/1000000)
+
+#ifndef CONFIG_DMC_DDRCFG
+#if ((CONFIG_BFIN_GET_DCLK_M != 125) && \
+ (CONFIG_BFIN_GET_DCLK_M != 133) && \
+ (CONFIG_BFIN_GET_DCLK_M != 150) && \
+ (CONFIG_BFIN_GET_DCLK_M != 166) && \
+ (CONFIG_BFIN_GET_DCLK_M != 200) && \
+ (CONFIG_BFIN_GET_DCLK_M != 225) && \
+ (CONFIG_BFIN_GET_DCLK_M != 250))
+#error "DDR2 CLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
+#endif
+#endif
+
+/* 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 DLL control bits */
+#define DLLCALRDCNT 0xFF
+#define DATACYC_OFFSET 8
+
+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;
+};
+
+static struct ddr_config ddr_config_table[] = {
+ [0] = {
+ .ddr_clk = 125, /* 125MHz */
+ .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, /* 133MHz */
+ .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, /* 150MHz */
+ .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, /* 166MHz */
+ .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, /* 200MHz */
+ .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, /* 225MHz */
+ .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, /* 250MHz */
+ .dmc_ddrctl = 0x00000904,
+ .dmc_ddrcfg = 0x00000422,
+ .dmc_ddrtr0 = 0x20E0A424,
+ .dmc_ddrtr1 = 0x3020079E,
+ .dmc_ddrtr2 = 0x0032020D,
+ .dmc_ddrmr = 0x00000842,
+ .dmc_ddrmr1 = 0x4,
+ },
+};
+#endif
+
__attribute__((always_inline))
static inline void serial_init(void)
{
@@ -174,7 +289,6 @@ program_nmi_handler(void)
#ifndef CONFIG_CGU_DIV_VAL
# define CONFIG_CGU_DIV_VAL \
- (1 << UPDT_P) | \
((CONFIG_CCLK_DIV << CSEL_P) | \
(CONFIG_SCLK0_DIV << S0SEL_P) | \
(CONFIG_SCLK_DIV << SYSSEL_P) | \
@@ -409,12 +523,34 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
serial_putc('a');
#ifdef __ADSPBF60x__
+ if (bfin_read_DMC0_STAT() & MEMINITDONE) {
+ bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() | SRREQ);
+ __builtin_bfin_ssync();
+ while (!(bfin_read_DMC0_STAT() & SRACK))
+ continue;
+ }
+
+ /* Don't set the same value of MSEL and DF to CGU_CTL */
+ if ((bfin_read_CGU_CTL() & (MSEL_MASK | DF_MASK))
+ != CONFIG_CGU_CTL_VAL) {
+ bfin_write_CGU_DIV(CONFIG_CGU_DIV_VAL);
+ bfin_write_CGU_CTL(CONFIG_CGU_CTL_VAL);
+ while ((bfin_read_CGU_STAT() & (CLKSALGN | PLLBP)) ||
+ !(bfin_read_CGU_STAT() & PLLLK))
+ continue;
+ }
- bfin_write_CGU_CTL(CONFIG_CGU_CTL_VAL);
- bfin_write_CGU_DIV(CONFIG_CGU_DIV_VAL);
- while (!(bfin_read_CGU_STAT() & CLKSALGN))
+ bfin_write_CGU_DIV(CONFIG_CGU_DIV_VAL | UPDT);
+ while (bfin_read_CGU_STAT() & CLKSALGN)
continue;
+ if (bfin_read_DMC0_STAT() & MEMINITDONE) {
+ bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() & ~SRREQ);
+ __builtin_bfin_ssync();
+ while (bfin_read_DMC0_STAT() & SRACK)
+ continue;
+ }
+
#else /* __ADSPBF60x__ */
vr_ctl = bfin_read_VR_CTL();
@@ -586,14 +722,87 @@ __attribute__((always_inline)) static inline void
program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs)
{
serial_putc('a');
-
+/*
if (!CONFIG_MEM_SIZE)
return;
-
+*/
serial_putc('b');
#ifdef __ADSPBF60x__
+ int dlldatacycle;
+ int dll_ctl;
+ int i = 0;
+
+ if (CONFIG_BFIN_GET_DCLK_M == 125)
+ i = 0;
+ else if (CONFIG_BFIN_GET_DCLK_M == 133)
+ i = 1;
+ else if (CONFIG_BFIN_GET_DCLK_M == 150)
+ i = 2;
+ else if (CONFIG_BFIN_GET_DCLK_M == 166)
+ i = 3;
+ else if (CONFIG_BFIN_GET_DCLK_M == 200)
+ i = 4;
+ else if (CONFIG_BFIN_GET_DCLK_M == 225)
+ i = 5;
+ else if (CONFIG_BFIN_GET_DCLK_M == 250)
+ i = 6;
+
+#if 0
+ for (i = 0; i < ARRAY_SIZE(ddr_config_table); i++)
+ if (CONFIG_BFIN_GET_DCLK_M == ddr_config_table[i].ddr_clk)
+ break;
+#endif
+
+#ifndef CONFIG_DMC_DDRCFG
+ bfin_write_DMC0_CFG(ddr_config_table[i].dmc_ddrcfg);
+#else
+ bfin_write_DMC0_CFG(CONFIG_DMC_DDRCFG);
+#endif
+#ifndef CONFIG_DMC_DDRTR0
+ bfin_write_DMC0_TR0(ddr_config_table[i].dmc_ddrtr0);
+#else
+ bfin_write_DMC0_TR0(CONFIG_DMC_DDRTR0);
+#endif
+#ifndef CONFIG_DMC_DDRTR1
+ bfin_write_DMC0_TR1(ddr_config_table[i].dmc_ddrtr1);
+#else
+ bfin_write_DMC0_TR1(CONFIG_DMC_DDRTR1);
+#endif
+#ifndef CONFIG_DMC_DDRTR2
+ bfin_write_DMC0_TR2(ddr_config_table[i].dmc_ddrtr2);
+#else
+ bfin_write_DMC0_TR2(CONFIG_DMC_DDRTR2);
+#endif
+#ifndef CONFIG_DMC_DDRMR
+ bfin_write_DMC0_MR(ddr_config_table[i].dmc_ddrmr);
+#else
+ bfin_write_DMC0_MR(CONFIG_DMC_DDRMR);
+#endif
+#ifndef CONFIG_DMC_DDREMR1
+ bfin_write_DMC0_EMR1(ddr_config_table[i].dmc_ddrmr1);
+#else
+ bfin_write_DMC0_EMR1(CONFIG_DMC_DDREMR1);
+#endif
+#ifndef CONFIG_DMC_DDRCTL
+ bfin_write_DMC0_CTL(ddr_config_table[i].dmc_ddrctl);
+#else
+ bfin_write_DMC0_CTL(CONFIG_DMC_DDRCTL);
+#endif
+ __builtin_bfin_ssync();
+ while (!(bfin_read_DMC0_STAT() & MEMINITDONE))
+ continue;
+
+ dlldatacycle = (bfin_read_DMC0_STAT() & PHYRDPHASE) >> PHYRDPHASE_OFFSET;
+ dll_ctl = bfin_read_DMC0_DLLCTL();
+ dll_ctl &= 0x0ff;
+ bfin_write_DMC0_DLLCTL(dll_ctl | (dlldatacycle << DATACYC_OFFSET));
+
+ __builtin_bfin_ssync();
+ while (!(bfin_read_DMC0_STAT() & DLLCALDONE))
+ continue;
+ serial_putc('!');
#else /* __ADSPBF60x__ */
/* Program the external memory controller before we come out of
diff --git a/arch/blackfin/include/asm/mach-common/bits/cgu.h b/arch/blackfin/include/asm/mach-common/bits/cgu.h
index a1c1940..cdf7349 100644
--- a/arch/blackfin/include/asm/mach-common/bits/cgu.h
+++ b/arch/blackfin/include/asm/mach-common/bits/cgu.h
@@ -15,6 +15,8 @@
#define MSEL_P 8
#define WIDLE_P 30
#define LOCK_P 31
+#define MSEL_MASK 0x7F00
+#define DF_MASK 0x1
/* CGU_STAT Masks */
#define PLLEN (1 << 0)
diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
index c7cb834..311b2e4 100644
--- a/include/configs/bf609-ezkit.h
+++ b/include/configs/bf609-ezkit.h
@@ -7,7 +7,6 @@
#include <asm/config-pre.h>
-
/*
* Processor Settings
*/
@@ -30,41 +29,41 @@
* SCLK1 = SCLK / SCLK1_DIV
*/
/* CONFIG_CLKIN_HZ is any value in Hz */
-#define CONFIG_CLKIN_HZ 25000000
+#define CONFIG_CLKIN_HZ (25000000)
/* CLKIN_HALF controls the DF bit in PLL_CTL 0 = CLKIN */
/* 1 = CLKIN / 2 */
-#define CONFIG_CLKIN_HALF 0
+#define CONFIG_CLKIN_HALF (0)
/* VCO_MULT controls the MSEL (multiplier) bits in PLL_CTL */
/* Values can range from 0-127 (where 0 means 128) */
-#define CONFIG_VCO_MULT 15
+#define CONFIG_VCO_MULT (20)
/* CCLK_DIV controls the core clock divider */
/* Values can range from 0-31 (where 0 means 32) */
-#define CONFIG_CCLK_DIV 1
+#define CONFIG_CCLK_DIV (1)
/* SCLK_DIV controls the system clock divider */
/* Values can range from 0-31 (where 0 means 32) */
-#define CONFIG_SYSCLK_DIV 3
+#define CONFIG_SCLK_DIV (4)
/* Values can range from 0-7 (where 0 means 8) */
-#define CONFIG_SCLK0_DIV 1
-#define CONFIG_SCLK1_DIV 1
+#define CONFIG_SCLK0_DIV (1)
+#define CONFIG_SCLK1_DIV (1)
/* DCLK_DIV controls the DDR clock divider */
/* Values can range from 0-31 (where 0 means 32) */
-#define CONFIG_DCLK_DIV 2
+#define CONFIG_DCLK_DIV (2)
/* OCLK_DIV controls the output clock divider */
/* Values can range from 0-127 (where 0 means 128) */
-#define CONFIG_OCLK_DIV 16
+#define CONFIG_OCLK_DIV (16)
-#define CONFIG_BFIN_GET_VCO CONFIG_CLKIN_HZ
-#define CONFIG_PLL_CLK (get_vco()*CONFIG_VCO_MULT)
+#define CONFIG_BFIN_GET_VCO (CONFIG_CLKIN_HZ)
+#define CONFIG_PLL_CLK (get_vco()*CONFIG_VCO_MULT)
-#define CONFIG_BFIN_GET_CCLK (CONFIG_PLL_CLK/CONFIG_CCLK_DIV)
-#define CONFIG_CCLK_HZ CONFIG_BFIN_GET_CCLK
+#define CONFIG_BFIN_GET_CCLK (CONFIG_PLL_CLK/CONFIG_CCLK_DIV)
+#define CONFIG_CCLK_HZ (CONFIG_BFIN_GET_CCLK)
-#define CONFIG_BFIN_GET_SCLK (CONFIG_PLL_CLK/CONFIG_SYSCLK_DIV)
-#define CONFIG_BFIN_GET_SCLK0 (get_sclk()/CONFIG_SCLK0_DIV)
-#define CONFIG_BFIN_GET_SCLK1 (get_sclk()/CONFIG_SCLK1_DIV)
-#define CONFIG_BFIN_GET_DCLK (get_cclk()/CONFIG_DCLK_DIV)
+#define CONFIG_BFIN_GET_SCLK (CONFIG_PLL_CLK/CONFIG_SCLK_DIV)
+#define CONFIG_BFIN_GET_SCLK0 (get_sclk()/CONFIG_SCLK0_DIV)
+#define CONFIG_BFIN_GET_SCLK1 (get_sclk()/CONFIG_SCLK1_DIV)
+#define CONFIG_BFIN_GET_DCLK ((CONFIG_CLKIN_HZ*CONFIG_VCO_MULT)/CONFIG_DCLK_DIV)
/*
* Memory Settings
--
1.7.9.5
More information about the U-Boot
mailing list