Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
m532x.c
Go to the documentation of this file.
1 /***************************************************************************/
2 
3 /*
4  * linux/arch/m68knommu/platform/532x/config.c
5  *
6  * Copyright (C) 1999-2002, Greg Ungerer ([email protected])
7  * Copyright (C) 2000, Lineo (www.lineo.com)
8  * Yaroslav Vinogradov [email protected]
9  * Copyright Freescale Semiconductor, Inc 2006
10  * Copyright (c) 2006, emlix, Sebastian Hess <[email protected]>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  */
17 
18 /***************************************************************************/
19 
20 #include <linux/kernel.h>
21 #include <linux/param.h>
22 #include <linux/init.h>
23 #include <linux/io.h>
24 #include <asm/machdep.h>
25 #include <asm/coldfire.h>
26 #include <asm/mcfsim.h>
27 #include <asm/mcfuart.h>
28 #include <asm/mcfdma.h>
29 #include <asm/mcfwdebug.h>
30 #include <asm/mcfclk.h>
31 
32 /***************************************************************************/
33 
34 DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
35 DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
36 DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
37 DEFINE_CLK(0, "edma", 17, MCF_CLK);
38 DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
39 DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
40 DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
41 DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
42 DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
43 DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
44 DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
45 DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
46 DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
47 DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
48 DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
49 DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
50 
51 DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
52 DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
53 DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
54 DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
55 DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
56 DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
57 DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
58 DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
59 DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
60 DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
61 DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
62 DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
63 DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
64 DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
65 DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
66 DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
67 
68 DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
69 DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
70 DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
71 
72 struct clk *mcf_clks[] = {
73  &__clk_0_2, /* flexbus */
74  &__clk_0_8, /* mcfcan.0 */
75  &__clk_0_12, /* fec.0 */
76  &__clk_0_17, /* edma */
77  &__clk_0_18, /* intc.0 */
78  &__clk_0_19, /* intc.1 */
79  &__clk_0_21, /* iack.0 */
80  &__clk_0_22, /* mcfi2c.0 */
81  &__clk_0_23, /* mcfqspi.0 */
82  &__clk_0_24, /* mcfuart.0 */
83  &__clk_0_25, /* mcfuart.1 */
84  &__clk_0_26, /* mcfuart.2 */
85  &__clk_0_28, /* mcftmr.0 */
86  &__clk_0_29, /* mcftmr.1 */
87  &__clk_0_30, /* mcftmr.2 */
88  &__clk_0_31, /* mcftmr.3 */
89 
90  &__clk_0_32, /* mcfpit.0 */
91  &__clk_0_33, /* mcfpit.1 */
92  &__clk_0_34, /* mcfpit.2 */
93  &__clk_0_35, /* mcfpit.3 */
94  &__clk_0_36, /* mcfpwm.0 */
95  &__clk_0_37, /* mcfeport.0 */
96  &__clk_0_38, /* mcfwdt.0 */
97  &__clk_0_40, /* sys.0 */
98  &__clk_0_41, /* gpio.0 */
99  &__clk_0_42, /* mcfrtc.0 */
100  &__clk_0_43, /* mcflcd.0 */
101  &__clk_0_44, /* mcfusb-otg.0 */
102  &__clk_0_45, /* mcfusb-host.0 */
103  &__clk_0_46, /* sdram.0 */
104  &__clk_0_47, /* ssi.0 */
105  &__clk_0_48, /* pll.0 */
106 
107  &__clk_1_32, /* mdha.0 */
108  &__clk_1_33, /* skha.0 */
109  &__clk_1_34, /* rng.0 */
110  NULL,
111 };
112 
113 static struct clk * const enable_clks[] __initconst = {
114  &__clk_0_2, /* flexbus */
115  &__clk_0_18, /* intc.0 */
116  &__clk_0_19, /* intc.1 */
117  &__clk_0_21, /* iack.0 */
118  &__clk_0_24, /* mcfuart.0 */
119  &__clk_0_25, /* mcfuart.1 */
120  &__clk_0_26, /* mcfuart.2 */
121 
122  &__clk_0_32, /* mcfpit.0 */
123  &__clk_0_33, /* mcfpit.1 */
124  &__clk_0_37, /* mcfeport.0 */
125  &__clk_0_40, /* sys.0 */
126  &__clk_0_41, /* gpio.0 */
127  &__clk_0_46, /* sdram.0 */
128  &__clk_0_48, /* pll.0 */
129 };
130 
131 static struct clk * const disable_clks[] __initconst = {
132  &__clk_0_8, /* mcfcan.0 */
133  &__clk_0_12, /* fec.0 */
134  &__clk_0_17, /* edma */
135  &__clk_0_22, /* mcfi2c.0 */
136  &__clk_0_23, /* mcfqspi.0 */
137  &__clk_0_28, /* mcftmr.0 */
138  &__clk_0_29, /* mcftmr.1 */
139  &__clk_0_30, /* mcftmr.2 */
140  &__clk_0_31, /* mcftmr.3 */
141  &__clk_0_34, /* mcfpit.2 */
142  &__clk_0_35, /* mcfpit.3 */
143  &__clk_0_36, /* mcfpwm.0 */
144  &__clk_0_38, /* mcfwdt.0 */
145  &__clk_0_42, /* mcfrtc.0 */
146  &__clk_0_43, /* mcflcd.0 */
147  &__clk_0_44, /* mcfusb-otg.0 */
148  &__clk_0_45, /* mcfusb-host.0 */
149  &__clk_0_47, /* ssi.0 */
150  &__clk_1_32, /* mdha.0 */
151  &__clk_1_33, /* skha.0 */
152  &__clk_1_34, /* rng.0 */
153 };
154 
155 
156 static void __init m532x_clk_init(void)
157 {
158  unsigned i;
159 
160  /* make sure these clocks are enabled */
161  for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
162  __clk_init_enabled(enable_clks[i]);
163  /* make sure these clocks are disabled */
164  for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
165  __clk_init_disabled(disable_clks[i]);
166 }
167 
168 /***************************************************************************/
169 
170 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
171 
172 static void __init m532x_qspi_init(void)
173 {
174  /* setup QSPS pins for QSPI with gpio CS control */
175  writew(0x01f0, MCFGPIO_PAR_QSPI);
176 }
177 
178 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
179 
180 /***************************************************************************/
181 
182 static void __init m532x_uarts_init(void)
183 {
184  /* UART GPIO initialization */
186 }
187 
188 /***************************************************************************/
189 
190 static void __init m532x_fec_init(void)
191 {
192  u8 v;
193 
194  /* Set multi-function pins to ethernet mode for fec0 */
199 
200  v = readb(MCFGPIO_PAR_FEC);
203 }
204 
205 /***************************************************************************/
206 
207 void __init config_BSP(char *commandp, int size)
208 {
209 #if !defined(CONFIG_BOOTPARAM)
210  /* Copy command line from FLASH to local buffer... */
211  memcpy(commandp, (char *) 0x4000, 4);
212  if(strncmp(commandp, "kcl ", 4) == 0){
213  memcpy(commandp, (char *) 0x4004, size);
214  commandp[size-1] = 0;
215  } else {
216  memset(commandp, 0, size);
217  }
218 #endif
220  m532x_clk_init();
221  m532x_uarts_init();
222  m532x_fec_init();
223 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
224  m532x_qspi_init();
225 #endif
226 
227 #ifdef CONFIG_BDM_DISABLE
228  /*
229  * Disable the BDM clocking. This also turns off most of the rest of
230  * the BDM device. This is good for EMC reasons. This option is not
231  * incompatible with the memory protection option.
232  */
234 #endif
235 }
236 
237 /***************************************************************************/
238 /* Board initialization */
239 /***************************************************************************/
240 /*
241  * PLL min/max specifications
242  */
243 #define MAX_FVCO 500000 /* KHz */
244 #define MAX_FSYS 80000 /* KHz */
245 #define MIN_FSYS 58333 /* KHz */
246 #define FREF 16000 /* KHz */
247 
248 
249 #define MAX_MFD 135 /* Multiplier */
250 #define MIN_MFD 88 /* Multiplier */
251 #define BUSDIV 6 /* Divider */
252 
253 /*
254  * Low Power Divider specifications
255  */
256 #define MIN_LPD (1 << 0) /* Divider (not encoded) */
257 #define MAX_LPD (1 << 15) /* Divider (not encoded) */
258 #define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
259 
260 #define SYS_CLK_KHZ 80000
261 #define SYSTEM_PERIOD 12.5
262 /*
263  * SDRAM Timing Parameters
264  */
265 #define SDRAM_BL 8 /* # of beats in a burst */
266 #define SDRAM_TWR 2 /* in clocks */
267 #define SDRAM_CASL 2.5 /* CASL in clocks */
268 #define SDRAM_TRCD 2 /* in clocks */
269 #define SDRAM_TRP 2 /* in clocks */
270 #define SDRAM_TRFC 7 /* in clocks */
271 #define SDRAM_TREFI 7800 /* in ns */
272 
273 #define EXT_SRAM_ADDRESS (0xC0000000)
274 #define FLASH_ADDRESS (0x00000000)
275 #define SDRAM_ADDRESS (0x40000000)
276 
277 #define NAND_FLASH_ADDRESS (0xD0000000)
278 
279 int sys_clk_khz = 0;
280 int sys_clk_mhz = 0;
281 
282 void wtm_init(void);
283 void scm_init(void);
284 void gpio_init(void);
285 void fbcs_init(void);
286 void sdramc_init(void);
287 int clock_pll (int fsys, int flags);
288 int clock_limp (int);
289 int clock_exit_limp (void);
290 int get_sys_clock (void);
291 
293 {
294  sys_clk_khz = clock_pll(0, 0);
295  sys_clk_mhz = sys_clk_khz/1000;
296 
297  wtm_init();
298  scm_init();
299  gpio_init();
300  fbcs_init();
301  sdramc_init();
302 }
303 
304 void wtm_init(void)
305 {
306  /* Disable watchdog timer */
307  writew(0, MCF_WTM_WCR);
308 }
309 
310 #define MCF_SCM_BCR_GBW (0x00000100)
311 #define MCF_SCM_BCR_GBR (0x00000200)
312 
313 void scm_init(void)
314 {
315  /* All masters are trusted */
316  writel(0x77777777, MCF_SCM_MPR);
317 
318  /* Allow supervisor/user, read/write, and trusted/untrusted
319  access to all slaves */
320  writel(0, MCF_SCM_PACRA);
321  writel(0, MCF_SCM_PACRB);
322  writel(0, MCF_SCM_PACRC);
323  writel(0, MCF_SCM_PACRD);
324  writel(0, MCF_SCM_PACRE);
325  writel(0, MCF_SCM_PACRF);
326 
327  /* Enable bursts */
329 }
330 
331 
332 void fbcs_init(void)
333 {
334  writeb(0x3E, MCFGPIO_PAR_CS);
335 
336  /* Latch chip select */
337  writel(0x10080000, MCF_FBCS1_CSAR);
338 
339  writel(0x002A3780, MCF_FBCS1_CSCR);
341 
342  /* Initialize latch to drive signals to inactive states */
343  writew(0xffff, 0x10080000);
344 
345  /* External SRAM */
350  MCF_FBCS_CSCR_WS(1),
353 
354  /* Boot Flash connected to FBCS0 */
360  MCF_FBCS_CSCR_WS(7),
363 }
364 
365 void sdramc_init(void)
366 {
367  /*
368  * Check to see if the SDRAM has already been initialized
369  * by a run control tool
370  */
372  /* SDRAM chip select initialization */
373 
374  /* Initialize SDRAM chip select */
378 
379  /*
380  * Basic configuration and initialization
381  */
382  writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
384  MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
385  MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
386  MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
387  MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
392  MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
395 
396 
397  /*
398  * Precharge and enable write to SDMR
399  */
404  MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
408 
409  /*
410  * Write extended mode register
411  */
413  MCF_SDRAMC_SDMR_AD(0x0) |
416 
417  /*
418  * Write mode register and reset DLL
419  */
421  MCF_SDRAMC_SDMR_AD(0x163) |
424 
425  /*
426  * Execute a PALL command
427  */
429 
430  /*
431  * Perform two REF cycles
432  */
435 
436  /*
437  * Write mode register and clear reset DLL
438  */
440  MCF_SDRAMC_SDMR_AD(0x063) |
443 
444  /*
445  * Enable auto refresh and lock SDMR
446  */
449  writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
451  }
452 }
453 
454 void gpio_init(void)
455 {
456  /* Enable UART0 pins */
459 
460  /*
461  * Initialize TIN3 as a GPIO output to enable the write
462  * half of the latch.
463  */
464  writeb(0x00, MCFGPIO_PAR_TIMER);
465  writeb(0x08, MCFGPIO_PDDR_TIMER);
467 }
468 
469 int clock_pll(int fsys, int flags)
470 {
471  int fref, temp, fout, mfd;
472  u32 i;
473 
474  fref = FREF;
475 
476  if (fsys == 0) {
477  /* Return current PLL output */
478  mfd = readb(MCF_PLL_PFDR);
479 
480  return (fref * mfd / (BUSDIV * 4));
481  }
482 
483  /* Check bounds of requested system clock */
484  if (fsys > MAX_FSYS)
485  fsys = MAX_FSYS;
486  if (fsys < MIN_FSYS)
487  fsys = MIN_FSYS;
488 
489  /* Multiplying by 100 when calculating the temp value,
490  and then dividing by 100 to calculate the mfd allows
491  for exact values without needing to include floating
492  point libraries. */
493  temp = 100 * fsys / fref;
494  mfd = 4 * BUSDIV * temp / 100;
495 
496  /* Determine the output frequency for selected values */
497  fout = (fref * mfd / (BUSDIV * 4));
498 
499  /*
500  * Check to see if the SDRAM has already been initialized.
501  * If it has then the SDRAM needs to be put into self refresh
502  * mode before reprogramming the PLL.
503  */
505  /* Put SDRAM into self refresh mode */
508 
509  /*
510  * Initialize the PLL to generate the new system clock frequency.
511  * The device must be put into LIMP mode to reprogram the PLL.
512  */
513 
514  /* Enter LIMP mode */
516 
517  /* Reprogram PLL for desired fsys */
519  MCF_PLL_PODR);
520 
521  writeb(mfd, MCF_PLL_PFDR);
522 
523  /* Exit LIMP mode */
524  clock_exit_limp();
525 
526  /*
527  * Return the SDRAM to normal operation if it is in use.
528  */
530  /* Exit self refresh mode */
533 
534  /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
536 
537  /* wait for DQS logic to relock */
538  for (i = 0; i < 0x200; i++)
539  ;
540 
541  return fout;
542 }
543 
544 int clock_limp(int div)
545 {
546  u32 temp;
547 
548  /* Check bounds of divider */
549  if (div < MIN_LPD)
550  div = MIN_LPD;
551  if (div > MAX_LPD)
552  div = MAX_LPD;
553 
554  /* Save of the current value of the SSIDIV so we don't
555  overwrite the value*/
556  temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
557 
558  /* Apply the divider to the system clock */
560 
562 
563  return (FREF/(3*(1 << div)));
564 }
565 
567 {
568  int fout;
569 
570  /* Exit LIMP mode */
572 
573  /* Wait for PLL to lock */
575  ;
576 
577  fout = get_sys_clock();
578 
579  return fout;
580 }
581 
582 int get_sys_clock(void)
583 {
584  int divider;
585 
586  /* Test to see if device is in LIMP mode */
588  divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
589  return (FREF/(2 << divider));
590  }
591  else
592  return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
593 }