blob: 7ad2407d157102cc035cccaccaedb9c34f6feb08 [file] [log] [blame]
Michael Hennerich73feb5c2009-01-07 23:14:39 +08001/*
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>
Mike Frysinger761ec442009-10-15 17:12:05 +000016#include <asm/dpmc.h>
Michael Hennerich73feb5c2009-01-07 23:14:39 +080017
Bob Liu7c141c12012-05-17 17:15:40 +080018#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
44struct 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
55struct 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
Michael Hennerich33169312009-02-04 16:49:45 +0800128#define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800129#define PLL_CTL_VAL \
130 (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
Bob Liu7c141c12012-05-17 17:15:40 +0800131 (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000))
132#endif
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800133
134__attribute__((l1_text))
135static void do_sync(void)
136{
137 __builtin_bfin_ssync();
138}
139
140__attribute__((l1_text))
141void 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 */
Steven Miao96900312012-05-16 17:49:52 +0800147
Bob Liu7c141c12012-05-17 17:15:40 +0800148#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
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800185 size_t i;
Mike Frysinger211daf92009-01-07 23:14:39 +0800186 for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800187 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();
Mike Frysinger97b070c2009-04-24 03:17:07 +0000225 /* We always write PLL_CTL thus avoiding Anomaly 05000242 */
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800226 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);
Michael Hennerich33169312009-02-04 16:49:45 +0800231 bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL);
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800232#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
Bob Liu7c141c12012-05-17 17:15:40 +0800243#endif
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800244 do_sync();
245 bfin_read16(0);
Steven Miao96900312012-05-16 17:49:52 +0800246
Michael Hennerich73feb5c2009-01-07 23:14:39 +0800247}