OSDN Git Service

blackfin: bf60x: make clock changeable in kernel menuconfig
[uclinux-h8/linux.git] / arch / blackfin / mach-common / clocks-init.c
1 /*
2  * arch/blackfin/mach-common/clocks-init.c - reprogram clocks / memory
3  *
4  * Copyright 2004-2008 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <linux/linkage.h>
10 #include <linux/init.h>
11 #include <asm/blackfin.h>
12
13 #include <asm/dma.h>
14 #include <asm/clocks.h>
15 #include <asm/mem_init.h>
16 #include <asm/dpmc.h>
17
18 #ifdef CONFIG_BF60x
19 #define CSEL_P                  0
20 #define S0SEL_P                 5
21 #define SYSSEL_P                8
22 #define S1SEL_P                 13
23 #define DSEL_P                  16
24 #define OSEL_P                  22
25 #define ALGN_P                  29
26 #define UPDT_P                  30
27 #define LOCK_P                  31
28
29 #define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF)
30 #define CGU_DIV_VAL \
31         ((CONFIG_CCLK_DIV   << CSEL_P)   | \
32         (CONFIG_SCLK_DIV << SYSSEL_P)   | \
33         (CONFIG_SCLK0_DIV  << S0SEL_P)  | \
34         (CONFIG_SCLK1_DIV  << S1SEL_P)  | \
35         (CONFIG_DCLK_DIV   << DSEL_P))
36
37 #define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
38 #if ((CONFIG_BFIN_DCLK != 125) && \
39         (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \
40         (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \
41         (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250))
42 #error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
43 #endif
44 struct ddr_config {
45         u32 ddr_clk;
46         u32 dmc_ddrctl;
47         u32 dmc_ddrcfg;
48         u32 dmc_ddrtr0;
49         u32 dmc_ddrtr1;
50         u32 dmc_ddrtr2;
51         u32 dmc_ddrmr;
52         u32 dmc_ddrmr1;
53 };
54
55 struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = {
56         [0] = {
57                 .ddr_clk    = 125,
58                 .dmc_ddrctl = 0x00000904,
59                 .dmc_ddrcfg = 0x00000422,
60                 .dmc_ddrtr0 = 0x20705212,
61                 .dmc_ddrtr1 = 0x201003CF,
62                 .dmc_ddrtr2 = 0x00320107,
63                 .dmc_ddrmr  = 0x00000422,
64                 .dmc_ddrmr1 = 0x4,
65         },
66         [1] = {
67                 .ddr_clk    = 133,
68                 .dmc_ddrctl = 0x00000904,
69                 .dmc_ddrcfg = 0x00000422,
70                 .dmc_ddrtr0 = 0x20806313,
71                 .dmc_ddrtr1 = 0x2013040D,
72                 .dmc_ddrtr2 = 0x00320108,
73                 .dmc_ddrmr  = 0x00000632,
74                 .dmc_ddrmr1 = 0x4,
75         },
76         [2] = {
77                 .ddr_clk    = 150,
78                 .dmc_ddrctl = 0x00000904,
79                 .dmc_ddrcfg = 0x00000422,
80                 .dmc_ddrtr0 = 0x20A07323,
81                 .dmc_ddrtr1 = 0x20160492,
82                 .dmc_ddrtr2 = 0x00320209,
83                 .dmc_ddrmr  = 0x00000632,
84                 .dmc_ddrmr1 = 0x4,
85         },
86         [3] = {
87                 .ddr_clk    = 166,
88                 .dmc_ddrctl = 0x00000904,
89                 .dmc_ddrcfg = 0x00000422,
90                 .dmc_ddrtr0 = 0x20A07323,
91                 .dmc_ddrtr1 = 0x2016050E,
92                 .dmc_ddrtr2 = 0x00320209,
93                 .dmc_ddrmr  = 0x00000632,
94                 .dmc_ddrmr1 = 0x4,
95         },
96         [4] = {
97                 .ddr_clk    = 200,
98                 .dmc_ddrctl = 0x00000904,
99                 .dmc_ddrcfg = 0x00000422,
100                 .dmc_ddrtr0 = 0x20a07323,
101                 .dmc_ddrtr1 = 0x2016050f,
102                 .dmc_ddrtr2 = 0x00320509,
103                 .dmc_ddrmr  = 0x00000632,
104                 .dmc_ddrmr1 = 0x4,
105         },
106         [5] = {
107                 .ddr_clk    = 225,
108                 .dmc_ddrctl = 0x00000904,
109                 .dmc_ddrcfg = 0x00000422,
110                 .dmc_ddrtr0 = 0x20E0A424,
111                 .dmc_ddrtr1 = 0x302006DB,
112                 .dmc_ddrtr2 = 0x0032020D,
113                 .dmc_ddrmr  = 0x00000842,
114                 .dmc_ddrmr1 = 0x4,
115         },
116         [6] = {
117                 .ddr_clk    = 250,
118                 .dmc_ddrctl = 0x00000904,
119                 .dmc_ddrcfg = 0x00000422,
120                 .dmc_ddrtr0 = 0x20E0A424,
121                 .dmc_ddrtr1 = 0x3020079E,
122                 .dmc_ddrtr2 = 0x0032020D,
123                 .dmc_ddrmr  = 0x00000842,
124                 .dmc_ddrmr1 = 0x4,
125         },
126 };
127 #else
128 #define SDGCTL_WIDTH (1 << 31)  /* SDRAM external data path width */
129 #define PLL_CTL_VAL \
130         (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
131                 (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000))
132 #endif
133
134 __attribute__((l1_text))
135 static void do_sync(void)
136 {
137         __builtin_bfin_ssync();
138 }
139
140 __attribute__((l1_text))
141 void init_clocks(void)
142 {
143         /* Kill any active DMAs as they may trigger external memory accesses
144          * in the middle of reprogramming things, and that'll screw us up.
145          * For example, any automatic DMAs left by U-Boot for splash screens.
146          */
147
148 #ifdef CONFIG_BF60x
149         int i, dlldatacycle, dll_ctl;
150         bfin_write32(CGU0_DIV, CGU_DIV_VAL);
151         bfin_write32(CGU0_CTL, CGU_CTL_VAL);
152         while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4))
153                 continue;
154
155         bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P));
156         while (bfin_read32(CGU0_STAT) & (1 << 3))
157                 continue;
158
159         for (i = 0; i < 7; i++) {
160                 if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) {
161                         bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg);
162                         bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0);
163                         bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1);
164                         bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2);
165                         bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr);
166                         bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1);
167                         bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl);
168                         break;
169                 }
170         }
171
172         do_sync();
173         while (!(bfin_read_DDR0_STAT() & 0x4))
174                 continue;
175
176         dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20;
177         dll_ctl = bfin_read_DDR0_DLLCTL();
178         dll_ctl &= 0x0ff;
179         bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8));
180
181         do_sync();
182         while (!(bfin_read_DDR0_STAT() & 0x2000))
183                 continue;
184 #else
185         size_t i;
186         for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
187                 struct dma_register *dma = dma_io_base_addr[i];
188                 dma->cfg = 0;
189         }
190
191         do_sync();
192
193 #ifdef SIC_IWR0
194         bfin_write_SIC_IWR0(IWR_ENABLE(0));
195 # ifdef SIC_IWR1
196         /* BF52x system reset does not properly reset SIC_IWR1 which
197          * will screw up the bootrom as it relies on MDMA0/1 waking it
198          * up from IDLE instructions.  See this report for more info:
199          * http://blackfin.uclinux.org/gf/tracker/4323
200          */
201         if (ANOMALY_05000435)
202                 bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
203         else
204                 bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
205 # endif
206 # ifdef SIC_IWR2
207         bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
208 # endif
209 #else
210         bfin_write_SIC_IWR(IWR_ENABLE(0));
211 #endif
212         do_sync();
213 #ifdef EBIU_SDGCTL
214         bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
215         do_sync();
216 #endif
217
218 #ifdef CLKBUFOE
219         bfin_write16(VR_CTL, bfin_read_VR_CTL() | CLKBUFOE);
220         do_sync();
221         __asm__ __volatile__("IDLE;");
222 #endif
223         bfin_write_PLL_LOCKCNT(0x300);
224         do_sync();
225         /* We always write PLL_CTL thus avoiding Anomaly 05000242 */
226         bfin_write16(PLL_CTL, PLL_CTL_VAL);
227         __asm__ __volatile__("IDLE;");
228         bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
229 #ifdef EBIU_SDGCTL
230         bfin_write_EBIU_SDRRC(mem_SDRRC);
231         bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL);
232 #else
233         bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
234         do_sync();
235         bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1);
236         bfin_write_EBIU_DDRCTL0(mem_DDRCTL0);
237         bfin_write_EBIU_DDRCTL1(mem_DDRCTL1);
238         bfin_write_EBIU_DDRCTL2(mem_DDRCTL2);
239 #ifdef CONFIG_MEM_EBIU_DDRQUE
240         bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
241 #endif
242 #endif
243 #endif
244         do_sync();
245         bfin_read16(0);
246
247 }