PageRenderTime 38ms CodeModel.GetById 11ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 1ms

/arch/arm/mach-kirkwood/common.c

https://github.com/AICP/kernel_google_msm
C | 549 lines | 365 code | 85 blank | 99 comment | 61 complexity | 18532e4dbe9635e34af5cb660b6fc280 MD5 | raw file
  1/*
  2 * arch/arm/mach-kirkwood/common.c
  3 *
  4 * Core functions for Marvell Kirkwood SoCs
  5 *
  6 * This file is licensed under the terms of the GNU General Public
  7 * License version 2.  This program is licensed "as is" without any
  8 * warranty of any kind, whether express or implied.
  9 */
 10
 11#include <linux/kernel.h>
 12#include <linux/init.h>
 13#include <linux/platform_device.h>
 14#include <linux/serial_8250.h>
 15#include <linux/ata_platform.h>
 16#include <linux/mtd/nand.h>
 17#include <linux/dma-mapping.h>
 18#include <net/dsa.h>
 19#include <asm/page.h>
 20#include <asm/timex.h>
 21#include <asm/kexec.h>
 22#include <asm/mach/map.h>
 23#include <asm/mach/time.h>
 24#include <mach/kirkwood.h>
 25#include <mach/bridge-regs.h>
 26#include <plat/audio.h>
 27#include <plat/cache-feroceon-l2.h>
 28#include <plat/mvsdio.h>
 29#include <plat/orion_nand.h>
 30#include <plat/ehci-orion.h>
 31#include <plat/common.h>
 32#include <plat/time.h>
 33#include <plat/addr-map.h>
 34#include "common.h"
 35
 36/*****************************************************************************
 37 * I/O Address Mapping
 38 ****************************************************************************/
 39static struct map_desc kirkwood_io_desc[] __initdata = {
 40	{
 41		.virtual	= KIRKWOOD_PCIE_IO_VIRT_BASE,
 42		.pfn		= __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
 43		.length		= KIRKWOOD_PCIE_IO_SIZE,
 44		.type		= MT_DEVICE,
 45	}, {
 46		.virtual	= KIRKWOOD_PCIE1_IO_VIRT_BASE,
 47		.pfn		= __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
 48		.length		= KIRKWOOD_PCIE1_IO_SIZE,
 49		.type		= MT_DEVICE,
 50	}, {
 51		.virtual	= KIRKWOOD_REGS_VIRT_BASE,
 52		.pfn		= __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
 53		.length		= KIRKWOOD_REGS_SIZE,
 54		.type		= MT_DEVICE,
 55	},
 56};
 57
 58void __init kirkwood_map_io(void)
 59{
 60	iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
 61}
 62
 63/*
 64 * Default clock control bits.  Any bit _not_ set in this variable
 65 * will be cleared from the hardware after platform devices have been
 66 * registered.  Some reserved bits must be set to 1.
 67 */
 68unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
 69
 70
 71/*****************************************************************************
 72 * EHCI0
 73 ****************************************************************************/
 74void __init kirkwood_ehci_init(void)
 75{
 76	kirkwood_clk_ctrl |= CGC_USB0;
 77	orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
 78}
 79
 80
 81/*****************************************************************************
 82 * GE00
 83 ****************************************************************************/
 84void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 85{
 86	kirkwood_clk_ctrl |= CGC_GE0;
 87
 88	orion_ge00_init(eth_data,
 89			GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
 90			IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
 91}
 92
 93
 94/*****************************************************************************
 95 * GE01
 96 ****************************************************************************/
 97void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 98{
 99
100	kirkwood_clk_ctrl |= CGC_GE1;
101
102	orion_ge01_init(eth_data,
103			GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
104			IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
105}
106
107
108/*****************************************************************************
109 * Ethernet switch
110 ****************************************************************************/
111void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
112{
113	orion_ge00_switch_init(d, irq);
114}
115
116
117/*****************************************************************************
118 * NAND flash
119 ****************************************************************************/
120static struct resource kirkwood_nand_resource = {
121	.flags		= IORESOURCE_MEM,
122	.start		= KIRKWOOD_NAND_MEM_PHYS_BASE,
123	.end		= KIRKWOOD_NAND_MEM_PHYS_BASE +
124				KIRKWOOD_NAND_MEM_SIZE - 1,
125};
126
127static struct orion_nand_data kirkwood_nand_data = {
128	.cle		= 0,
129	.ale		= 1,
130	.width		= 8,
131};
132
133static struct platform_device kirkwood_nand_flash = {
134	.name		= "orion_nand",
135	.id		= -1,
136	.dev		= {
137		.platform_data	= &kirkwood_nand_data,
138	},
139	.resource	= &kirkwood_nand_resource,
140	.num_resources	= 1,
141};
142
143void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
144			       int chip_delay)
145{
146	kirkwood_clk_ctrl |= CGC_RUNIT;
147	kirkwood_nand_data.parts = parts;
148	kirkwood_nand_data.nr_parts = nr_parts;
149	kirkwood_nand_data.chip_delay = chip_delay;
150	platform_device_register(&kirkwood_nand_flash);
151}
152
153void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
154				   int (*dev_ready)(struct mtd_info *))
155{
156	kirkwood_clk_ctrl |= CGC_RUNIT;
157	kirkwood_nand_data.parts = parts;
158	kirkwood_nand_data.nr_parts = nr_parts;
159	kirkwood_nand_data.dev_ready = dev_ready;
160	platform_device_register(&kirkwood_nand_flash);
161}
162
163/*****************************************************************************
164 * SoC RTC
165 ****************************************************************************/
166static void __init kirkwood_rtc_init(void)
167{
168	orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
169}
170
171
172/*****************************************************************************
173 * SATA
174 ****************************************************************************/
175void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
176{
177	kirkwood_clk_ctrl |= CGC_SATA0;
178	if (sata_data->n_ports > 1)
179		kirkwood_clk_ctrl |= CGC_SATA1;
180
181	orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
182}
183
184
185/*****************************************************************************
186 * SD/SDIO/MMC
187 ****************************************************************************/
188static struct resource mvsdio_resources[] = {
189	[0] = {
190		.start	= SDIO_PHYS_BASE,
191		.end	= SDIO_PHYS_BASE + SZ_1K - 1,
192		.flags	= IORESOURCE_MEM,
193	},
194	[1] = {
195		.start	= IRQ_KIRKWOOD_SDIO,
196		.end	= IRQ_KIRKWOOD_SDIO,
197		.flags	= IORESOURCE_IRQ,
198	},
199};
200
201static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
202
203static struct platform_device kirkwood_sdio = {
204	.name		= "mvsdio",
205	.id		= -1,
206	.dev		= {
207		.dma_mask = &mvsdio_dmamask,
208		.coherent_dma_mask = DMA_BIT_MASK(32),
209	},
210	.num_resources	= ARRAY_SIZE(mvsdio_resources),
211	.resource	= mvsdio_resources,
212};
213
214void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
215{
216	u32 dev, rev;
217
218	kirkwood_pcie_id(&dev, &rev);
219	if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
220		mvsdio_data->clock = 100000000;
221	else
222		mvsdio_data->clock = 200000000;
223	kirkwood_clk_ctrl |= CGC_SDIO;
224	kirkwood_sdio.dev.platform_data = mvsdio_data;
225	platform_device_register(&kirkwood_sdio);
226}
227
228
229/*****************************************************************************
230 * SPI
231 ****************************************************************************/
232void __init kirkwood_spi_init()
233{
234	kirkwood_clk_ctrl |= CGC_RUNIT;
235	orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
236}
237
238
239/*****************************************************************************
240 * I2C
241 ****************************************************************************/
242void __init kirkwood_i2c_init(void)
243{
244	orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
245}
246
247
248/*****************************************************************************
249 * UART0
250 ****************************************************************************/
251
252void __init kirkwood_uart0_init(void)
253{
254	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
255			 IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
256}
257
258
259/*****************************************************************************
260 * UART1
261 ****************************************************************************/
262void __init kirkwood_uart1_init(void)
263{
264	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
265			 IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
266}
267
268/*****************************************************************************
269 * Cryptographic Engines and Security Accelerator (CESA)
270 ****************************************************************************/
271void __init kirkwood_crypto_init(void)
272{
273	kirkwood_clk_ctrl |= CGC_CRYPTO;
274	orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
275			  KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
276}
277
278
279/*****************************************************************************
280 * XOR0
281 ****************************************************************************/
282void __init kirkwood_xor0_init(void)
283{
284	kirkwood_clk_ctrl |= CGC_XOR0;
285
286	orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
287			IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
288}
289
290
291/*****************************************************************************
292 * XOR1
293 ****************************************************************************/
294void __init kirkwood_xor1_init(void)
295{
296	kirkwood_clk_ctrl |= CGC_XOR1;
297
298	orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
299			IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
300}
301
302
303/*****************************************************************************
304 * Watchdog
305 ****************************************************************************/
306void __init kirkwood_wdt_init(void)
307{
308	orion_wdt_init(kirkwood_tclk);
309}
310
311
312/*****************************************************************************
313 * Time handling
314 ****************************************************************************/
315void __init kirkwood_init_early(void)
316{
317	orion_time_set_base(TIMER_VIRT_BASE);
318}
319
320int kirkwood_tclk;
321
322static int __init kirkwood_find_tclk(void)
323{
324	u32 dev, rev;
325
326	kirkwood_pcie_id(&dev, &rev);
327
328	if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
329		if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
330			return 200000000;
331
332	return 166666667;
333}
334
335static void __init kirkwood_timer_init(void)
336{
337	kirkwood_tclk = kirkwood_find_tclk();
338
339	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
340			IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
341}
342
343struct sys_timer kirkwood_timer = {
344	.init = kirkwood_timer_init,
345};
346
347/*****************************************************************************
348 * Audio
349 ****************************************************************************/
350static struct resource kirkwood_i2s_resources[] = {
351	[0] = {
352		.start  = AUDIO_PHYS_BASE,
353		.end    = AUDIO_PHYS_BASE + SZ_16K - 1,
354		.flags  = IORESOURCE_MEM,
355	},
356	[1] = {
357		.start  = IRQ_KIRKWOOD_I2S,
358		.end    = IRQ_KIRKWOOD_I2S,
359		.flags  = IORESOURCE_IRQ,
360	},
361};
362
363static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
364	.burst       = 128,
365};
366
367static struct platform_device kirkwood_i2s_device = {
368	.name		= "kirkwood-i2s",
369	.id		= -1,
370	.num_resources	= ARRAY_SIZE(kirkwood_i2s_resources),
371	.resource	= kirkwood_i2s_resources,
372	.dev		= {
373		.platform_data	= &kirkwood_i2s_data,
374	},
375};
376
377static struct platform_device kirkwood_pcm_device = {
378	.name		= "kirkwood-pcm-audio",
379	.id		= -1,
380};
381
382void __init kirkwood_audio_init(void)
383{
384	kirkwood_clk_ctrl |= CGC_AUDIO;
385	platform_device_register(&kirkwood_i2s_device);
386	platform_device_register(&kirkwood_pcm_device);
387}
388
389/*****************************************************************************
390 * General
391 ****************************************************************************/
392/*
393 * Identify device ID and revision.
394 */
395char * __init kirkwood_id(void)
396{
397	u32 dev, rev;
398
399	kirkwood_pcie_id(&dev, &rev);
400
401	if (dev == MV88F6281_DEV_ID) {
402		if (rev == MV88F6281_REV_Z0)
403			return "MV88F6281-Z0";
404		else if (rev == MV88F6281_REV_A0)
405			return "MV88F6281-A0";
406		else if (rev == MV88F6281_REV_A1)
407			return "MV88F6281-A1";
408		else
409			return "MV88F6281-Rev-Unsupported";
410	} else if (dev == MV88F6192_DEV_ID) {
411		if (rev == MV88F6192_REV_Z0)
412			return "MV88F6192-Z0";
413		else if (rev == MV88F6192_REV_A0)
414			return "MV88F6192-A0";
415		else if (rev == MV88F6192_REV_A1)
416			return "MV88F6192-A1";
417		else
418			return "MV88F6192-Rev-Unsupported";
419	} else if (dev == MV88F6180_DEV_ID) {
420		if (rev == MV88F6180_REV_A0)
421			return "MV88F6180-Rev-A0";
422		else if (rev == MV88F6180_REV_A1)
423			return "MV88F6180-Rev-A1";
424		else
425			return "MV88F6180-Rev-Unsupported";
426	} else if (dev == MV88F6282_DEV_ID) {
427		if (rev == MV88F6282_REV_A0)
428			return "MV88F6282-Rev-A0";
429		else if (rev == MV88F6282_REV_A1)
430			return "MV88F6282-Rev-A1";
431		else
432			return "MV88F6282-Rev-Unsupported";
433	} else {
434		return "Device-Unknown";
435	}
436}
437
438void __init kirkwood_l2_init(void)
439{
440#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
441	writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
442	feroceon_l2_init(1);
443#else
444	writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
445	feroceon_l2_init(0);
446#endif
447}
448
449void __init kirkwood_init(void)
450{
451	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
452		kirkwood_id(), kirkwood_tclk);
453
454	/*
455	 * Disable propagation of mbus errors to the CPU local bus,
456	 * as this causes mbus errors (which can occur for example
457	 * for PCI aborts) to throw CPU aborts, which we're not set
458	 * up to deal with.
459	 */
460	writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
461
462	kirkwood_setup_cpu_mbus();
463
464#ifdef CONFIG_CACHE_FEROCEON_L2
465	kirkwood_l2_init();
466#endif
467
468	/* internal devices that every board has */
469	kirkwood_rtc_init();
470	kirkwood_wdt_init();
471	kirkwood_xor0_init();
472	kirkwood_xor1_init();
473	kirkwood_crypto_init();
474
475#ifdef CONFIG_KEXEC 
476	kexec_reinit = kirkwood_enable_pcie;
477#endif
478}
479
480static int __init kirkwood_clock_gate(void)
481{
482	unsigned int curr = readl(CLOCK_GATING_CTRL);
483	u32 dev, rev;
484
485	kirkwood_pcie_id(&dev, &rev);
486	printk(KERN_DEBUG "Gating clock of unused units\n");
487	printk(KERN_DEBUG "before: 0x%08x\n", curr);
488
489	/* Make sure those units are accessible */
490	writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
491
492	/* For SATA: first shutdown the phy */
493	if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
494		/* Disable PLL and IVREF */
495		writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
496		/* Disable PHY */
497		writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
498	}
499	if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
500		/* Disable PLL and IVREF */
501		writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
502		/* Disable PHY */
503		writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
504	}
505	
506	/* For PCIe: first shutdown the phy */
507	if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
508		writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
509		while (1)
510			if (readl(PCIE_STATUS) & 0x1)
511				break;
512		writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
513	}
514
515	/* For PCIe 1: first shutdown the phy */
516	if (dev == MV88F6282_DEV_ID) {
517		if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
518			writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
519			while (1)
520				if (readl(PCIE1_STATUS) & 0x1)
521					break;
522			writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
523		}
524	} else  /* keep this bit set for devices that don't have PCIe1 */
525		kirkwood_clk_ctrl |= CGC_PEX1;
526
527	/* Now gate clock the required units */
528	writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
529	printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
530
531	return 0;
532}
533late_initcall(kirkwood_clock_gate);
534
535void kirkwood_restart(char mode, const char *cmd)
536{
537	/*
538	 * Enable soft reset to assert RSTOUTn.
539	 */
540	writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
541
542	/*
543	 * Assert soft reset.
544	 */
545	writel(SOFT_RESET, SYSTEM_SOFT_RESET);
546
547	while (1)
548		;
549}