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