• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/m68knommu/platform/532x/
1/***************************************************************************/
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
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/spi/spi.h>
25#include <linux/gpio.h>
26#include <asm/machdep.h>
27#include <asm/coldfire.h>
28#include <asm/mcfsim.h>
29#include <asm/mcfuart.h>
30#include <asm/mcfdma.h>
31#include <asm/mcfwdebug.h>
32#include <asm/mcfqspi.h>
33
34/***************************************************************************/
35
36static struct mcf_platform_uart m532x_uart_platform[] = {
37	{
38		.mapbase	= MCFUART_BASE1,
39		.irq		= MCFINT_VECBASE + MCFINT_UART0,
40	},
41	{
42		.mapbase 	= MCFUART_BASE2,
43		.irq		= MCFINT_VECBASE + MCFINT_UART1,
44	},
45	{
46		.mapbase 	= MCFUART_BASE3,
47		.irq		= MCFINT_VECBASE + MCFINT_UART2,
48	},
49	{ },
50};
51
52static struct platform_device m532x_uart = {
53	.name			= "mcfuart",
54	.id			= 0,
55	.dev.platform_data	= m532x_uart_platform,
56};
57
58static struct resource m532x_fec_resources[] = {
59	{
60		.start		= 0xfc030000,
61		.end		= 0xfc0307ff,
62		.flags		= IORESOURCE_MEM,
63	},
64	{
65		.start		= 64 + 36,
66		.end		= 64 + 36,
67		.flags		= IORESOURCE_IRQ,
68	},
69	{
70		.start		= 64 + 40,
71		.end		= 64 + 40,
72		.flags		= IORESOURCE_IRQ,
73	},
74	{
75		.start		= 64 + 42,
76		.end		= 64 + 42,
77		.flags		= IORESOURCE_IRQ,
78	},
79};
80
81static struct platform_device m532x_fec = {
82	.name			= "fec",
83	.id			= 0,
84	.num_resources		= ARRAY_SIZE(m532x_fec_resources),
85	.resource		= m532x_fec_resources,
86};
87
88#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
89static struct resource m532x_qspi_resources[] = {
90	{
91		.start		= MCFQSPI_IOBASE,
92		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
93		.flags		= IORESOURCE_MEM,
94	},
95	{
96		.start		= MCFINT_VECBASE + MCFINT_QSPI,
97		.end		= MCFINT_VECBASE + MCFINT_QSPI,
98		.flags		= IORESOURCE_IRQ,
99	},
100};
101
102#define MCFQSPI_CS0    84
103#define MCFQSPI_CS1    85
104#define MCFQSPI_CS2    86
105
106static int m532x_cs_setup(struct mcfqspi_cs_control *cs_control)
107{
108	int status;
109
110	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
111	if (status) {
112		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
113		goto fail0;
114	}
115	status = gpio_direction_output(MCFQSPI_CS0, 1);
116	if (status) {
117		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
118		goto fail1;
119	}
120
121	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
122	if (status) {
123		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
124		goto fail1;
125	}
126	status = gpio_direction_output(MCFQSPI_CS1, 1);
127	if (status) {
128		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
129		goto fail2;
130	}
131
132	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
133	if (status) {
134		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
135		goto fail2;
136	}
137	status = gpio_direction_output(MCFQSPI_CS2, 1);
138	if (status) {
139		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
140		goto fail3;
141	}
142
143	return 0;
144
145fail3:
146	gpio_free(MCFQSPI_CS2);
147fail2:
148	gpio_free(MCFQSPI_CS1);
149fail1:
150	gpio_free(MCFQSPI_CS0);
151fail0:
152	return status;
153}
154
155static void m532x_cs_teardown(struct mcfqspi_cs_control *cs_control)
156{
157	gpio_free(MCFQSPI_CS2);
158	gpio_free(MCFQSPI_CS1);
159	gpio_free(MCFQSPI_CS0);
160}
161
162static void m532x_cs_select(struct mcfqspi_cs_control *cs_control,
163			    u8 chip_select, bool cs_high)
164{
165	gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
166}
167
168static void m532x_cs_deselect(struct mcfqspi_cs_control *cs_control,
169			      u8 chip_select, bool cs_high)
170{
171	gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
172}
173
174static struct mcfqspi_cs_control m532x_cs_control = {
175	.setup                  = m532x_cs_setup,
176	.teardown               = m532x_cs_teardown,
177	.select                 = m532x_cs_select,
178	.deselect               = m532x_cs_deselect,
179};
180
181static struct mcfqspi_platform_data m532x_qspi_data = {
182	.bus_num		= 0,
183	.num_chipselect		= 3,
184	.cs_control		= &m532x_cs_control,
185};
186
187static struct platform_device m532x_qspi = {
188	.name			= "mcfqspi",
189	.id			= 0,
190	.num_resources		= ARRAY_SIZE(m532x_qspi_resources),
191	.resource		= m532x_qspi_resources,
192	.dev.platform_data	= &m532x_qspi_data,
193};
194
195static void __init m532x_qspi_init(void)
196{
197	/* setup QSPS pins for QSPI with gpio CS control */
198	writew(0x01f0, MCF_GPIO_PAR_QSPI);
199}
200#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
201
202
203static struct platform_device *m532x_devices[] __initdata = {
204	&m532x_uart,
205	&m532x_fec,
206#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
207	&m532x_qspi,
208#endif
209};
210
211/***************************************************************************/
212
213static void __init m532x_uart_init_line(int line, int irq)
214{
215	if (line == 0) {
216		/* GPIO initialization */
217		MCF_GPIO_PAR_UART |= 0x000F;
218	} else if (line == 1) {
219		/* GPIO initialization */
220		MCF_GPIO_PAR_UART |= 0x0FF0;
221	}
222}
223
224static void __init m532x_uarts_init(void)
225{
226	const int nrlines = ARRAY_SIZE(m532x_uart_platform);
227	int line;
228
229	for (line = 0; (line < nrlines); line++)
230		m532x_uart_init_line(line, m532x_uart_platform[line].irq);
231}
232/***************************************************************************/
233
234static void __init m532x_fec_init(void)
235{
236	/* Set multi-function pins to ethernet mode for fec0 */
237	MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
238		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
239	MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
240		MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
241}
242
243/***************************************************************************/
244
245static void m532x_cpu_reset(void)
246{
247	local_irq_disable();
248	__raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
249}
250
251/***************************************************************************/
252
253void __init config_BSP(char *commandp, int size)
254{
255#if !defined(CONFIG_BOOTPARAM)
256	/* Copy command line from FLASH to local buffer... */
257	memcpy(commandp, (char *) 0x4000, 4);
258	if(strncmp(commandp, "kcl ", 4) == 0){
259		memcpy(commandp, (char *) 0x4004, size);
260		commandp[size-1] = 0;
261	} else {
262		memset(commandp, 0, size);
263	}
264#endif
265
266#ifdef CONFIG_BDM_DISABLE
267	/*
268	 * Disable the BDM clocking.  This also turns off most of the rest of
269	 * the BDM device.  This is good for EMC reasons. This option is not
270	 * incompatible with the memory protection option.
271	 */
272	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
273#endif
274}
275
276/***************************************************************************/
277
278static int __init init_BSP(void)
279{
280	m532x_uarts_init();
281	m532x_fec_init();
282#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
283	m532x_qspi_init();
284#endif
285	platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
286	return 0;
287}
288
289arch_initcall(init_BSP);
290
291/***************************************************************************/
292/* Board initialization */
293/***************************************************************************/
294/*
295 * PLL min/max specifications
296 */
297#define MAX_FVCO	500000	/* KHz */
298#define MAX_FSYS	80000 	/* KHz */
299#define MIN_FSYS	58333 	/* KHz */
300#define FREF		16000   /* KHz */
301
302
303#define MAX_MFD		135     /* Multiplier */
304#define MIN_MFD		88      /* Multiplier */
305#define BUSDIV		6       /* Divider */
306
307/*
308 * Low Power Divider specifications
309 */
310#define MIN_LPD		(1 << 0)    /* Divider (not encoded) */
311#define MAX_LPD		(1 << 15)   /* Divider (not encoded) */
312#define DEFAULT_LPD	(1 << 1)	/* Divider (not encoded) */
313
314#define SYS_CLK_KHZ	80000
315#define SYSTEM_PERIOD	12.5
316/*
317 *  SDRAM Timing Parameters
318 */
319#define SDRAM_BL	8	/* # of beats in a burst */
320#define SDRAM_TWR	2	/* in clocks */
321#define SDRAM_CASL	2.5	/* CASL in clocks */
322#define SDRAM_TRCD	2	/* in clocks */
323#define SDRAM_TRP	2	/* in clocks */
324#define SDRAM_TRFC	7	/* in clocks */
325#define SDRAM_TREFI	7800	/* in ns */
326
327#define EXT_SRAM_ADDRESS	(0xC0000000)
328#define FLASH_ADDRESS		(0x00000000)
329#define SDRAM_ADDRESS		(0x40000000)
330
331#define NAND_FLASH_ADDRESS	(0xD0000000)
332
333int sys_clk_khz = 0;
334int sys_clk_mhz = 0;
335
336void wtm_init(void);
337void scm_init(void);
338void gpio_init(void);
339void fbcs_init(void);
340void sdramc_init(void);
341int  clock_pll (int fsys, int flags);
342int  clock_limp (int);
343int  clock_exit_limp (void);
344int  get_sys_clock (void);
345
346asmlinkage void __init sysinit(void)
347{
348	sys_clk_khz = clock_pll(0, 0);
349	sys_clk_mhz = sys_clk_khz/1000;
350
351	wtm_init();
352	scm_init();
353	gpio_init();
354	fbcs_init();
355	sdramc_init();
356}
357
358void wtm_init(void)
359{
360	/* Disable watchdog timer */
361	MCF_WTM_WCR = 0;
362}
363
364#define MCF_SCM_BCR_GBW		(0x00000100)
365#define MCF_SCM_BCR_GBR		(0x00000200)
366
367void scm_init(void)
368{
369	/* All masters are trusted */
370	MCF_SCM_MPR = 0x77777777;
371
372	/* Allow supervisor/user, read/write, and trusted/untrusted
373	   access to all slaves */
374	MCF_SCM_PACRA = 0;
375	MCF_SCM_PACRB = 0;
376	MCF_SCM_PACRC = 0;
377	MCF_SCM_PACRD = 0;
378	MCF_SCM_PACRE = 0;
379	MCF_SCM_PACRF = 0;
380
381	/* Enable bursts */
382	MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
383}
384
385
386void fbcs_init(void)
387{
388	MCF_GPIO_PAR_CS = 0x0000003E;
389
390	/* Latch chip select */
391	MCF_FBCS1_CSAR = 0x10080000;
392
393	MCF_FBCS1_CSCR = 0x002A3780;
394	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
395
396	/* Initialize latch to drive signals to inactive states */
397	*((u16 *)(0x10080000)) = 0xFFFF;
398
399	/* External SRAM */
400	MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
401	MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
402			| MCF_FBCS_CSCR_AA
403			| MCF_FBCS_CSCR_SBM
404			| MCF_FBCS_CSCR_WS(1));
405	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
406			| MCF_FBCS_CSMR_V);
407
408	/* Boot Flash connected to FBCS0 */
409	MCF_FBCS0_CSAR = FLASH_ADDRESS;
410	MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
411			| MCF_FBCS_CSCR_BEM
412			| MCF_FBCS_CSCR_AA
413			| MCF_FBCS_CSCR_SBM
414			| MCF_FBCS_CSCR_WS(7));
415	MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
416			| MCF_FBCS_CSMR_V);
417}
418
419void sdramc_init(void)
420{
421	/*
422	 * Check to see if the SDRAM has already been initialized
423	 * by a run control tool
424	 */
425	if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
426		/* SDRAM chip select initialization */
427
428		/* Initialize SDRAM chip select */
429		MCF_SDRAMC_SDCS0 = (0
430			| MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
431			| MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
432
433	/*
434	 * Basic configuration and initialization
435	 */
436	MCF_SDRAMC_SDCFG1 = (0
437		| MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
438		| MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
439		| MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
440		| MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
441		| MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
442		| MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
443		| MCF_SDRAMC_SDCFG1_WTLAT(3));
444	MCF_SDRAMC_SDCFG2 = (0
445		| MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
446		| MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
447		| MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
448		| MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
449
450
451	/*
452	 * Precharge and enable write to SDMR
453	 */
454        MCF_SDRAMC_SDCR = (0
455		| MCF_SDRAMC_SDCR_MODE_EN
456		| MCF_SDRAMC_SDCR_CKE
457		| MCF_SDRAMC_SDCR_DDR
458		| MCF_SDRAMC_SDCR_MUX(1)
459		| MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
460		| MCF_SDRAMC_SDCR_PS_16
461		| MCF_SDRAMC_SDCR_IPALL);
462
463	/*
464	 * Write extended mode register
465	 */
466	MCF_SDRAMC_SDMR = (0
467		| MCF_SDRAMC_SDMR_BNKAD_LEMR
468		| MCF_SDRAMC_SDMR_AD(0x0)
469		| MCF_SDRAMC_SDMR_CMD);
470
471	/*
472	 * Write mode register and reset DLL
473	 */
474	MCF_SDRAMC_SDMR = (0
475		| MCF_SDRAMC_SDMR_BNKAD_LMR
476		| MCF_SDRAMC_SDMR_AD(0x163)
477		| MCF_SDRAMC_SDMR_CMD);
478
479	/*
480	 * Execute a PALL command
481	 */
482	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
483
484	/*
485	 * Perform two REF cycles
486	 */
487	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
488	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
489
490	/*
491	 * Write mode register and clear reset DLL
492	 */
493	MCF_SDRAMC_SDMR = (0
494		| MCF_SDRAMC_SDMR_BNKAD_LMR
495		| MCF_SDRAMC_SDMR_AD(0x063)
496		| MCF_SDRAMC_SDMR_CMD);
497
498	/*
499	 * Enable auto refresh and lock SDMR
500	 */
501	MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
502	MCF_SDRAMC_SDCR |= (0
503		| MCF_SDRAMC_SDCR_REF
504		| MCF_SDRAMC_SDCR_DQS_OE(0xC));
505	}
506}
507
508void gpio_init(void)
509{
510	/* Enable UART0 pins */
511	MCF_GPIO_PAR_UART = ( 0
512		| MCF_GPIO_PAR_UART_PAR_URXD0
513		| MCF_GPIO_PAR_UART_PAR_UTXD0);
514
515	/* Initialize TIN3 as a GPIO output to enable the write
516	   half of the latch */
517	MCF_GPIO_PAR_TIMER = 0x00;
518	__raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
519	__raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
520
521}
522
523int clock_pll(int fsys, int flags)
524{
525	int fref, temp, fout, mfd;
526	u32 i;
527
528	fref = FREF;
529
530	if (fsys == 0) {
531		/* Return current PLL output */
532		mfd = MCF_PLL_PFDR;
533
534		return (fref * mfd / (BUSDIV * 4));
535	}
536
537	/* Check bounds of requested system clock */
538	if (fsys > MAX_FSYS)
539		fsys = MAX_FSYS;
540	if (fsys < MIN_FSYS)
541		fsys = MIN_FSYS;
542
543	/* Multiplying by 100 when calculating the temp value,
544	   and then dividing by 100 to calculate the mfd allows
545	   for exact values without needing to include floating
546	   point libraries. */
547	temp = 100 * fsys / fref;
548	mfd = 4 * BUSDIV * temp / 100;
549
550	/* Determine the output frequency for selected values */
551	fout = (fref * mfd / (BUSDIV * 4));
552
553	/*
554	 * Check to see if the SDRAM has already been initialized.
555	 * If it has then the SDRAM needs to be put into self refresh
556	 * mode before reprogramming the PLL.
557	 */
558	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
559		/* Put SDRAM into self refresh mode */
560		MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
561
562	/*
563	 * Initialize the PLL to generate the new system clock frequency.
564	 * The device must be put into LIMP mode to reprogram the PLL.
565	 */
566
567	/* Enter LIMP mode */
568	clock_limp(DEFAULT_LPD);
569
570	/* Reprogram PLL for desired fsys */
571	MCF_PLL_PODR = (0
572		| MCF_PLL_PODR_CPUDIV(BUSDIV/3)
573		| MCF_PLL_PODR_BUSDIV(BUSDIV));
574
575	MCF_PLL_PFDR = mfd;
576
577	/* Exit LIMP mode */
578	clock_exit_limp();
579
580	/*
581	 * Return the SDRAM to normal operation if it is in use.
582	 */
583	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
584		/* Exit self refresh mode */
585		MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
586
587	MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
588
589	/* wait for DQS logic to relock */
590	for (i = 0; i < 0x200; i++)
591		;
592
593	return fout;
594}
595
596int clock_limp(int div)
597{
598	u32 temp;
599
600	/* Check bounds of divider */
601	if (div < MIN_LPD)
602		div = MIN_LPD;
603	if (div > MAX_LPD)
604		div = MAX_LPD;
605
606	/* Save of the current value of the SSIDIV so we don't
607	   overwrite the value*/
608	temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
609
610	/* Apply the divider to the system clock */
611	MCF_CCM_CDR = ( 0
612		| MCF_CCM_CDR_LPDIV(div)
613		| MCF_CCM_CDR_SSIDIV(temp));
614
615	MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
616
617	return (FREF/(3*(1 << div)));
618}
619
620int clock_exit_limp(void)
621{
622	int fout;
623
624	/* Exit LIMP mode */
625	MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
626
627	/* Wait for PLL to lock */
628	while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
629		;
630
631	fout = get_sys_clock();
632
633	return fout;
634}
635
636int get_sys_clock(void)
637{
638	int divider;
639
640	/* Test to see if device is in LIMP mode */
641	if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
642		divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
643		return (FREF/(2 << divider));
644	}
645	else
646		return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
647}
648