blob: 56b21fd84b3f2f897675aad7bbb1099bbc0f373e [file] [log] [blame]
Greg Ungerer3196cf82006-06-26 10:33:10 +10001/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/532x/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000, Lineo (www.lineo.com)
8 * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
9 * Copyright Freescale Semiconductor, Inc 2006
10 * Copyright (c) 2006, emlix, Sebastian Hess <sh@emlix.com>
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
Greg Ungerer3196cf82006-06-26 10:33:10 +100020#include <linux/kernel.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100021#include <linux/param.h>
22#include <linux/init.h>
Greg Ungererb2e18102008-02-01 17:34:58 +100023#include <linux/io.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100024#include <asm/machdep.h>
25#include <asm/coldfire.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100026#include <asm/mcfsim.h>
Greg Ungererb2e18102008-02-01 17:34:58 +100027#include <asm/mcfuart.h>
Greg Ungerer3196cf82006-06-26 10:33:10 +100028#include <asm/mcfdma.h>
29#include <asm/mcfwdebug.h>
30
31/***************************************************************************/
32
Greg Ungererfa1fc242011-12-24 12:56:10 +100033#ifdef CONFIG_SPI_COLDFIRE_QSPI
Steven King91d60412010-01-22 12:43:03 -080034
35static void __init m532x_qspi_init(void)
36{
37 /* setup QSPS pins for QSPI with gpio CS control */
38 writew(0x01f0, MCF_GPIO_PAR_QSPI);
39}
Steven King91d60412010-01-22 12:43:03 -080040
Greg Ungererfa1fc242011-12-24 12:56:10 +100041#endif /* CONFIG_SPI_COLDFIRE_QSPI */
Greg Ungererb2e18102008-02-01 17:34:58 +100042
43/***************************************************************************/
44
Greg Ungererb2e18102008-02-01 17:34:58 +100045static void __init m532x_uarts_init(void)
46{
Greg Ungerera75bc612011-12-24 01:04:22 +100047 /* UART GPIO initialization */
48 MCF_GPIO_PAR_UART |= 0x0FFF;
Greg Ungererb2e18102008-02-01 17:34:58 +100049}
Greg Ungerera75bc612011-12-24 01:04:22 +100050
Greg Ungererffba3f42009-02-26 22:40:38 -080051/***************************************************************************/
52
53static void __init m532x_fec_init(void)
54{
Greg Ungererffba3f42009-02-26 22:40:38 -080055 /* Set multi-function pins to ethernet mode for fec0 */
56 MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
57 MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
58 MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
59 MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
60}
Greg Ungerer3196cf82006-06-26 10:33:10 +100061
62/***************************************************************************/
63
Greg Ungerer384feb92009-04-30 22:03:43 +100064static void m532x_cpu_reset(void)
65{
66 local_irq_disable();
67 __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
68}
69
70/***************************************************************************/
71
Greg Ungererb2e18102008-02-01 17:34:58 +100072void __init config_BSP(char *commandp, int size)
Greg Ungerer3196cf82006-06-26 10:33:10 +100073{
Greg Ungererbc724502007-07-25 22:07:20 +100074#if !defined(CONFIG_BOOTPARAM)
Greg Ungerer3196cf82006-06-26 10:33:10 +100075 /* Copy command line from FLASH to local buffer... */
76 memcpy(commandp, (char *) 0x4000, 4);
77 if(strncmp(commandp, "kcl ", 4) == 0){
78 memcpy(commandp, (char *) 0x4004, size);
79 commandp[size-1] = 0;
80 } else {
81 memset(commandp, 0, size);
82 }
83#endif
84
Greg Ungerer35aefb22012-01-23 15:34:58 +100085 mach_sched_init = hw_timer_init;
Greg Ungererc05793c2011-12-24 13:06:33 +100086 mach_reset = m532x_cpu_reset;
87 m532x_uarts_init();
88 m532x_fec_init();
89#ifdef CONFIG_SPI_COLDFIRE_QSPI
90 m532x_qspi_init();
91#endif
Greg Ungerer35aefb22012-01-23 15:34:58 +100092
Greg Ungererb2e18102008-02-01 17:34:58 +100093#ifdef CONFIG_BDM_DISABLE
Greg Ungerer3196cf82006-06-26 10:33:10 +100094 /*
95 * Disable the BDM clocking. This also turns off most of the rest of
96 * the BDM device. This is good for EMC reasons. This option is not
97 * incompatible with the memory protection option.
98 */
99 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
100#endif
101}
102
103/***************************************************************************/
Greg Ungererb2e18102008-02-01 17:34:58 +1000104/* Board initialization */
105/***************************************************************************/
Greg Ungerer3196cf82006-06-26 10:33:10 +1000106/*
107 * PLL min/max specifications
108 */
109#define MAX_FVCO 500000 /* KHz */
110#define MAX_FSYS 80000 /* KHz */
111#define MIN_FSYS 58333 /* KHz */
112#define FREF 16000 /* KHz */
113
114
115#define MAX_MFD 135 /* Multiplier */
116#define MIN_MFD 88 /* Multiplier */
117#define BUSDIV 6 /* Divider */
118
119/*
120 * Low Power Divider specifications
121 */
122#define MIN_LPD (1 << 0) /* Divider (not encoded) */
123#define MAX_LPD (1 << 15) /* Divider (not encoded) */
124#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
125
126#define SYS_CLK_KHZ 80000
127#define SYSTEM_PERIOD 12.5
128/*
129 * SDRAM Timing Parameters
130 */
131#define SDRAM_BL 8 /* # of beats in a burst */
132#define SDRAM_TWR 2 /* in clocks */
133#define SDRAM_CASL 2.5 /* CASL in clocks */
134#define SDRAM_TRCD 2 /* in clocks */
135#define SDRAM_TRP 2 /* in clocks */
136#define SDRAM_TRFC 7 /* in clocks */
137#define SDRAM_TREFI 7800 /* in ns */
138
139#define EXT_SRAM_ADDRESS (0xC0000000)
140#define FLASH_ADDRESS (0x00000000)
141#define SDRAM_ADDRESS (0x40000000)
142
143#define NAND_FLASH_ADDRESS (0xD0000000)
144
145int sys_clk_khz = 0;
146int sys_clk_mhz = 0;
147
148void wtm_init(void);
149void scm_init(void);
150void gpio_init(void);
151void fbcs_init(void);
152void sdramc_init(void);
153int clock_pll (int fsys, int flags);
154int clock_limp (int);
155int clock_exit_limp (void);
156int get_sys_clock (void);
157
158asmlinkage void __init sysinit(void)
159{
160 sys_clk_khz = clock_pll(0, 0);
161 sys_clk_mhz = sys_clk_khz/1000;
162
163 wtm_init();
164 scm_init();
165 gpio_init();
166 fbcs_init();
167 sdramc_init();
168}
169
170void wtm_init(void)
171{
172 /* Disable watchdog timer */
173 MCF_WTM_WCR = 0;
174}
175
176#define MCF_SCM_BCR_GBW (0x00000100)
177#define MCF_SCM_BCR_GBR (0x00000200)
178
179void scm_init(void)
180{
181 /* All masters are trusted */
182 MCF_SCM_MPR = 0x77777777;
183
184 /* Allow supervisor/user, read/write, and trusted/untrusted
185 access to all slaves */
186 MCF_SCM_PACRA = 0;
187 MCF_SCM_PACRB = 0;
188 MCF_SCM_PACRC = 0;
189 MCF_SCM_PACRD = 0;
190 MCF_SCM_PACRE = 0;
191 MCF_SCM_PACRF = 0;
192
193 /* Enable bursts */
194 MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
195}
196
197
198void fbcs_init(void)
199{
200 MCF_GPIO_PAR_CS = 0x0000003E;
201
202 /* Latch chip select */
203 MCF_FBCS1_CSAR = 0x10080000;
204
205 MCF_FBCS1_CSCR = 0x002A3780;
206 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
207
208 /* Initialize latch to drive signals to inactive states */
209 *((u16 *)(0x10080000)) = 0xFFFF;
210
211 /* External SRAM */
212 MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
213 MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
214 | MCF_FBCS_CSCR_AA
215 | MCF_FBCS_CSCR_SBM
216 | MCF_FBCS_CSCR_WS(1));
217 MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
218 | MCF_FBCS_CSMR_V);
219
220 /* Boot Flash connected to FBCS0 */
221 MCF_FBCS0_CSAR = FLASH_ADDRESS;
222 MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
223 | MCF_FBCS_CSCR_BEM
224 | MCF_FBCS_CSCR_AA
225 | MCF_FBCS_CSCR_SBM
226 | MCF_FBCS_CSCR_WS(7));
227 MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
228 | MCF_FBCS_CSMR_V);
229}
230
231void sdramc_init(void)
232{
233 /*
234 * Check to see if the SDRAM has already been initialized
235 * by a run control tool
236 */
237 if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
238 /* SDRAM chip select initialization */
239
240 /* Initialize SDRAM chip select */
241 MCF_SDRAMC_SDCS0 = (0
242 | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
243 | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
244
245 /*
246 * Basic configuration and initialization
247 */
248 MCF_SDRAMC_SDCFG1 = (0
249 | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
250 | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
251 | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
252 | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
253 | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
254 | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
255 | MCF_SDRAMC_SDCFG1_WTLAT(3));
256 MCF_SDRAMC_SDCFG2 = (0
257 | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
258 | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
259 | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
260 | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
261
262
263 /*
264 * Precharge and enable write to SDMR
265 */
266 MCF_SDRAMC_SDCR = (0
267 | MCF_SDRAMC_SDCR_MODE_EN
268 | MCF_SDRAMC_SDCR_CKE
269 | MCF_SDRAMC_SDCR_DDR
270 | MCF_SDRAMC_SDCR_MUX(1)
271 | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
272 | MCF_SDRAMC_SDCR_PS_16
273 | MCF_SDRAMC_SDCR_IPALL);
274
275 /*
276 * Write extended mode register
277 */
278 MCF_SDRAMC_SDMR = (0
279 | MCF_SDRAMC_SDMR_BNKAD_LEMR
280 | MCF_SDRAMC_SDMR_AD(0x0)
281 | MCF_SDRAMC_SDMR_CMD);
282
283 /*
284 * Write mode register and reset DLL
285 */
286 MCF_SDRAMC_SDMR = (0
287 | MCF_SDRAMC_SDMR_BNKAD_LMR
288 | MCF_SDRAMC_SDMR_AD(0x163)
289 | MCF_SDRAMC_SDMR_CMD);
290
291 /*
292 * Execute a PALL command
293 */
294 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
295
296 /*
297 * Perform two REF cycles
298 */
299 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
300 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
301
302 /*
303 * Write mode register and clear reset DLL
304 */
305 MCF_SDRAMC_SDMR = (0
306 | MCF_SDRAMC_SDMR_BNKAD_LMR
307 | MCF_SDRAMC_SDMR_AD(0x063)
308 | MCF_SDRAMC_SDMR_CMD);
309
310 /*
311 * Enable auto refresh and lock SDMR
312 */
313 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
314 MCF_SDRAMC_SDCR |= (0
315 | MCF_SDRAMC_SDCR_REF
316 | MCF_SDRAMC_SDCR_DQS_OE(0xC));
317 }
318}
319
320void gpio_init(void)
321{
322 /* Enable UART0 pins */
323 MCF_GPIO_PAR_UART = ( 0
324 | MCF_GPIO_PAR_UART_PAR_URXD0
325 | MCF_GPIO_PAR_UART_PAR_UTXD0);
326
327 /* Initialize TIN3 as a GPIO output to enable the write
328 half of the latch */
329 MCF_GPIO_PAR_TIMER = 0x00;
sfking@fdwdc.com7846fe82009-06-19 18:11:10 -0700330 __raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
331 __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
Greg Ungerer3196cf82006-06-26 10:33:10 +1000332
333}
334
335int clock_pll(int fsys, int flags)
336{
337 int fref, temp, fout, mfd;
338 u32 i;
339
340 fref = FREF;
341
342 if (fsys == 0) {
343 /* Return current PLL output */
344 mfd = MCF_PLL_PFDR;
345
346 return (fref * mfd / (BUSDIV * 4));
347 }
348
349 /* Check bounds of requested system clock */
350 if (fsys > MAX_FSYS)
351 fsys = MAX_FSYS;
352 if (fsys < MIN_FSYS)
353 fsys = MIN_FSYS;
354
355 /* Multiplying by 100 when calculating the temp value,
356 and then dividing by 100 to calculate the mfd allows
357 for exact values without needing to include floating
358 point libraries. */
359 temp = 100 * fsys / fref;
360 mfd = 4 * BUSDIV * temp / 100;
361
362 /* Determine the output frequency for selected values */
363 fout = (fref * mfd / (BUSDIV * 4));
364
365 /*
366 * Check to see if the SDRAM has already been initialized.
367 * If it has then the SDRAM needs to be put into self refresh
368 * mode before reprogramming the PLL.
369 */
370 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
371 /* Put SDRAM into self refresh mode */
372 MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
373
374 /*
375 * Initialize the PLL to generate the new system clock frequency.
376 * The device must be put into LIMP mode to reprogram the PLL.
377 */
378
379 /* Enter LIMP mode */
380 clock_limp(DEFAULT_LPD);
381
382 /* Reprogram PLL for desired fsys */
383 MCF_PLL_PODR = (0
384 | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
385 | MCF_PLL_PODR_BUSDIV(BUSDIV));
386
387 MCF_PLL_PFDR = mfd;
388
389 /* Exit LIMP mode */
390 clock_exit_limp();
391
392 /*
393 * Return the SDRAM to normal operation if it is in use.
394 */
395 if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
396 /* Exit self refresh mode */
397 MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
398
399 /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
400 MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
401
402 /* wait for DQS logic to relock */
403 for (i = 0; i < 0x200; i++)
404 ;
405
406 return fout;
407}
408
409int clock_limp(int div)
410{
411 u32 temp;
412
413 /* Check bounds of divider */
414 if (div < MIN_LPD)
415 div = MIN_LPD;
416 if (div > MAX_LPD)
417 div = MAX_LPD;
418
419 /* Save of the current value of the SSIDIV so we don't
420 overwrite the value*/
421 temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
422
423 /* Apply the divider to the system clock */
424 MCF_CCM_CDR = ( 0
425 | MCF_CCM_CDR_LPDIV(div)
426 | MCF_CCM_CDR_SSIDIV(temp));
427
428 MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
429
430 return (FREF/(3*(1 << div)));
431}
432
433int clock_exit_limp(void)
434{
435 int fout;
436
437 /* Exit LIMP mode */
438 MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
439
440 /* Wait for PLL to lock */
441 while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
442 ;
443
444 fout = get_sys_clock();
445
446 return fout;
447}
448
449int get_sys_clock(void)
450{
451 int divider;
452
453 /* Test to see if device is in LIMP mode */
454 if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
455 divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
456 return (FREF/(2 << divider));
457 }
458 else
459 return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
460}