common.c 15.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * arch/arm/mach-kirkwood/common.c
 *
 * Core functions for Marvell Kirkwood SoCs
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/mbus.h>
#include <linux/ata_platform.h>
17
#include <linux/mtd/nand.h>
18
#include <linux/dma-mapping.h>
19
#include <net/dsa.h>
20 21
#include <asm/page.h>
#include <asm/timex.h>
22
#include <asm/kexec.h>
23 24
#include <asm/mach/map.h>
#include <asm/mach/time.h>
25
#include <mach/kirkwood.h>
26
#include <mach/bridge-regs.h>
27
#include <plat/audio.h>
28
#include <plat/cache-feroceon-l2.h>
29
#include <plat/mvsdio.h>
30
#include <plat/orion_nand.h>
31
#include <plat/common.h>
32
#include <plat/time.h>
33 34 35 36 37 38 39 40 41 42 43
#include "common.h"

/*****************************************************************************
 * I/O Address Mapping
 ****************************************************************************/
static struct map_desc kirkwood_io_desc[] __initdata = {
	{
		.virtual	= KIRKWOOD_PCIE_IO_VIRT_BASE,
		.pfn		= __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
		.length		= KIRKWOOD_PCIE_IO_SIZE,
		.type		= MT_DEVICE,
44 45 46 47 48
	}, {
		.virtual	= KIRKWOOD_PCIE1_IO_VIRT_BASE,
		.pfn		= __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
		.length		= KIRKWOOD_PCIE1_IO_SIZE,
		.type		= MT_DEVICE,
49 50 51 52 53 54 55 56 57 58 59 60 61
	}, {
		.virtual	= KIRKWOOD_REGS_VIRT_BASE,
		.pfn		= __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
		.length		= KIRKWOOD_REGS_SIZE,
		.type		= MT_DEVICE,
	},
};

void __init kirkwood_map_io(void)
{
	iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
}

62 63 64 65 66 67
/*
 * Default clock control bits.  Any bit _not_ set in this variable
 * will be cleared from the hardware after platform devices have been
 * registered.  Some reserved bits must be set to 1.
 */
unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
68

69 70 71 72 73 74

/*****************************************************************************
 * EHCI0
 ****************************************************************************/
void __init kirkwood_ehci_init(void)
{
75
	kirkwood_clk_ctrl |= CGC_USB0;
76 77
	orion_ehci_init(&kirkwood_mbus_dram_info,
			USB_PHYS_BASE, IRQ_KIRKWOOD_USB);
78 79 80 81 82 83 84 85
}


/*****************************************************************************
 * GE00
 ****************************************************************************/
void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
86
	kirkwood_clk_ctrl |= CGC_GE0;
87

88 89 90
	orion_ge00_init(eth_data, &kirkwood_mbus_dram_info,
			GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
			IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
91 92 93
}


94 95 96 97 98
/*****************************************************************************
 * GE01
 ****************************************************************************/
void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
{
99

100
	kirkwood_clk_ctrl |= CGC_GE1;
101

102 103 104
	orion_ge01_init(eth_data, &kirkwood_mbus_dram_info,
			GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
			IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
105 106 107
}


108 109 110 111 112
/*****************************************************************************
 * Ethernet switch
 ****************************************************************************/
void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
{
113
	orion_ge00_switch_init(d, irq);
114 115 116
}


117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
/*****************************************************************************
 * NAND flash
 ****************************************************************************/
static struct resource kirkwood_nand_resource = {
	.flags		= IORESOURCE_MEM,
	.start		= KIRKWOOD_NAND_MEM_PHYS_BASE,
	.end		= KIRKWOOD_NAND_MEM_PHYS_BASE +
				KIRKWOOD_NAND_MEM_SIZE - 1,
};

static struct orion_nand_data kirkwood_nand_data = {
	.cle		= 0,
	.ale		= 1,
	.width		= 8,
};

static struct platform_device kirkwood_nand_flash = {
	.name		= "orion_nand",
	.id		= -1,
	.dev		= {
		.platform_data	= &kirkwood_nand_data,
	},
	.resource	= &kirkwood_nand_resource,
	.num_resources	= 1,
};

void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
			       int chip_delay)
{
146
	kirkwood_clk_ctrl |= CGC_RUNIT;
147 148 149 150 151 152
	kirkwood_nand_data.parts = parts;
	kirkwood_nand_data.nr_parts = nr_parts;
	kirkwood_nand_data.chip_delay = chip_delay;
	platform_device_register(&kirkwood_nand_flash);
}

153 154 155 156 157 158 159 160 161
void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
				   int (*dev_ready)(struct mtd_info *))
{
	kirkwood_clk_ctrl |= CGC_RUNIT;
	kirkwood_nand_data.parts = parts;
	kirkwood_nand_data.nr_parts = nr_parts;
	kirkwood_nand_data.dev_ready = dev_ready;
	platform_device_register(&kirkwood_nand_flash);
}
162

163 164 165
/*****************************************************************************
 * SoC RTC
 ****************************************************************************/
166
static void __init kirkwood_rtc_init(void)
167
{
168
	orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
}


/*****************************************************************************
 * SATA
 ****************************************************************************/
static struct resource kirkwood_sata_resources[] = {
	{
		.name	= "sata base",
		.start	= SATA_PHYS_BASE,
		.end	= SATA_PHYS_BASE + 0x5000 - 1,
		.flags	= IORESOURCE_MEM,
	}, {
		.name	= "sata irq",
		.start	= IRQ_KIRKWOOD_SATA,
		.end	= IRQ_KIRKWOOD_SATA,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device kirkwood_sata = {
	.name		= "sata_mv",
	.id		= 0,
	.dev		= {
193
		.coherent_dma_mask	= DMA_BIT_MASK(32),
194 195 196 197 198 199 200
	},
	.num_resources	= ARRAY_SIZE(kirkwood_sata_resources),
	.resource	= kirkwood_sata_resources,
};

void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
{
201 202 203
	kirkwood_clk_ctrl |= CGC_SATA0;
	if (sata_data->n_ports > 1)
		kirkwood_clk_ctrl |= CGC_SATA1;
204 205 206 207 208 209
	sata_data->dram = &kirkwood_mbus_dram_info;
	kirkwood_sata.dev.platform_data = sata_data;
	platform_device_register(&kirkwood_sata);
}


210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
/*****************************************************************************
 * SD/SDIO/MMC
 ****************************************************************************/
static struct resource mvsdio_resources[] = {
	[0] = {
		.start	= SDIO_PHYS_BASE,
		.end	= SDIO_PHYS_BASE + SZ_1K - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= IRQ_KIRKWOOD_SDIO,
		.end	= IRQ_KIRKWOOD_SDIO,
		.flags	= IORESOURCE_IRQ,
	},
};

226
static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
227 228 229 230 231 232

static struct platform_device kirkwood_sdio = {
	.name		= "mvsdio",
	.id		= -1,
	.dev		= {
		.dma_mask = &mvsdio_dmamask,
233
		.coherent_dma_mask = DMA_BIT_MASK(32),
234 235 236 237 238 239 240 241 242 243
	},
	.num_resources	= ARRAY_SIZE(mvsdio_resources),
	.resource	= mvsdio_resources,
};

void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
{
	u32 dev, rev;

	kirkwood_pcie_id(&dev, &rev);
244
	if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
245 246 247 248
		mvsdio_data->clock = 100000000;
	else
		mvsdio_data->clock = 200000000;
	mvsdio_data->dram = &kirkwood_mbus_dram_info;
249
	kirkwood_clk_ctrl |= CGC_SDIO;
250 251 252 253 254
	kirkwood_sdio.dev.platform_data = mvsdio_data;
	platform_device_register(&kirkwood_sdio);
}


255 256 257 258 259
/*****************************************************************************
 * SPI
 ****************************************************************************/
void __init kirkwood_spi_init()
{
260
	kirkwood_clk_ctrl |= CGC_RUNIT;
261
	orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
262 263 264
}


M
Martin Michlmayr 已提交
265 266 267 268 269
/*****************************************************************************
 * I2C
 ****************************************************************************/
void __init kirkwood_i2c_init(void)
{
270
	orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
M
Martin Michlmayr 已提交
271 272 273
}


274 275 276 277 278 279
/*****************************************************************************
 * UART0
 ****************************************************************************/

void __init kirkwood_uart0_init(void)
{
280 281
	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
			 IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
282 283 284 285 286 287 288 289
}


/*****************************************************************************
 * UART1
 ****************************************************************************/
void __init kirkwood_uart1_init(void)
{
290 291
	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
			 IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
292 293
}

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
/*****************************************************************************
 * Cryptographic Engines and Security Accelerator (CESA)
 ****************************************************************************/

static struct resource kirkwood_crypto_res[] = {
	{
		.name   = "regs",
		.start  = CRYPTO_PHYS_BASE,
		.end    = CRYPTO_PHYS_BASE + 0xffff,
		.flags  = IORESOURCE_MEM,
	}, {
		.name   = "sram",
		.start  = KIRKWOOD_SRAM_PHYS_BASE,
		.end    = KIRKWOOD_SRAM_PHYS_BASE + KIRKWOOD_SRAM_SIZE - 1,
		.flags  = IORESOURCE_MEM,
	}, {
		.name   = "crypto interrupt",
		.start  = IRQ_KIRKWOOD_CRYPTO,
		.end    = IRQ_KIRKWOOD_CRYPTO,
		.flags  = IORESOURCE_IRQ,
	},
};

static struct platform_device kirkwood_crypto_device = {
	.name           = "mv_crypto",
	.id             = -1,
	.num_resources  = ARRAY_SIZE(kirkwood_crypto_res),
	.resource       = kirkwood_crypto_res,
};

void __init kirkwood_crypto_init(void)
{
	kirkwood_clk_ctrl |= CGC_CRYPTO;
	platform_device_register(&kirkwood_crypto_device);
}


331 332 333
/*****************************************************************************
 * XOR0
 ****************************************************************************/
334
static void __init kirkwood_xor0_init(void)
335
{
336
	kirkwood_clk_ctrl |= CGC_XOR0;
337 338 339 340

	orion_xor0_init(&kirkwood_mbus_dram_info,
			XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
			IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
341 342 343 344 345 346
}


/*****************************************************************************
 * XOR1
 ****************************************************************************/
347
static void __init kirkwood_xor1_init(void)
348
{
349
	kirkwood_clk_ctrl |= CGC_XOR1;
350 351 352

	orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
			IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
353 354 355
}


356 357 358 359 360
/*****************************************************************************
 * Watchdog
 ****************************************************************************/
static void __init kirkwood_wdt_init(void)
{
361
	orion_wdt_init(kirkwood_tclk);
362 363 364
}


365 366 367
/*****************************************************************************
 * Time handling
 ****************************************************************************/
368 369 370 371 372
void __init kirkwood_init_early(void)
{
	orion_time_set_base(TIMER_VIRT_BASE);
}

373 374
int kirkwood_tclk;

375
static int __init kirkwood_find_tclk(void)
376
{
377 378 379
	u32 dev, rev;

	kirkwood_pcie_id(&dev, &rev);
380

381 382 383
	if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
		if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
			return 200000000;
384

385 386 387
	return 166666667;
}

L
Li Jie 已提交
388
static void __init kirkwood_timer_init(void)
389
{
390
	kirkwood_tclk = kirkwood_find_tclk();
391 392 393

	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
			IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
394 395 396 397 398 399
}

struct sys_timer kirkwood_timer = {
	.init = kirkwood_timer_init,
};

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
/*****************************************************************************
 * Audio
 ****************************************************************************/
static struct resource kirkwood_i2s_resources[] = {
	[0] = {
		.start  = AUDIO_PHYS_BASE,
		.end    = AUDIO_PHYS_BASE + SZ_16K - 1,
		.flags  = IORESOURCE_MEM,
	},
	[1] = {
		.start  = IRQ_KIRKWOOD_I2S,
		.end    = IRQ_KIRKWOOD_I2S,
		.flags  = IORESOURCE_IRQ,
	},
};

static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
	.dram        = &kirkwood_mbus_dram_info,
	.burst       = 128,
};

static struct platform_device kirkwood_i2s_device = {
	.name		= "kirkwood-i2s",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(kirkwood_i2s_resources),
	.resource	= kirkwood_i2s_resources,
	.dev		= {
		.platform_data	= &kirkwood_i2s_data,
	},
};

431
static struct platform_device kirkwood_pcm_device = {
432
	.name		= "kirkwood-pcm-audio",
433 434 435
	.id		= -1,
};

436 437 438 439
void __init kirkwood_audio_init(void)
{
	kirkwood_clk_ctrl |= CGC_AUDIO;
	platform_device_register(&kirkwood_i2s_device);
440
	platform_device_register(&kirkwood_pcm_device);
441
}
442 443 444 445

/*****************************************************************************
 * General
 ****************************************************************************/
446 447 448
/*
 * Identify device ID and revision.
 */
449 450
static char * __init kirkwood_id(void)
{
451 452 453 454 455 456 457 458 459
	u32 dev, rev;

	kirkwood_pcie_id(&dev, &rev);

	if (dev == MV88F6281_DEV_ID) {
		if (rev == MV88F6281_REV_Z0)
			return "MV88F6281-Z0";
		else if (rev == MV88F6281_REV_A0)
			return "MV88F6281-A0";
460 461
		else if (rev == MV88F6281_REV_A1)
			return "MV88F6281-A1";
462 463 464 465 466 467 468
		else
			return "MV88F6281-Rev-Unsupported";
	} else if (dev == MV88F6192_DEV_ID) {
		if (rev == MV88F6192_REV_Z0)
			return "MV88F6192-Z0";
		else if (rev == MV88F6192_REV_A0)
			return "MV88F6192-A0";
469 470
		else if (rev == MV88F6192_REV_A1)
			return "MV88F6192-A1";
471 472 473 474 475
		else
			return "MV88F6192-Rev-Unsupported";
	} else if (dev == MV88F6180_DEV_ID) {
		if (rev == MV88F6180_REV_A0)
			return "MV88F6180-Rev-A0";
476 477
		else if (rev == MV88F6180_REV_A1)
			return "MV88F6180-Rev-A1";
478 479
		else
			return "MV88F6180-Rev-Unsupported";
480 481 482 483 484
	} else if (dev == MV88F6282_DEV_ID) {
		if (rev == MV88F6282_REV_A0)
			return "MV88F6282-Rev-A0";
		else
			return "MV88F6282-Rev-Unsupported";
485 486
	} else {
		return "Device-Unknown";
487 488 489
	}
}

490
static void __init kirkwood_l2_init(void)
491
{
492 493 494 495 496 497 498
#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
	writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
	feroceon_l2_init(1);
#else
	writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
	feroceon_l2_init(0);
#endif
499 500
}

501 502 503
void __init kirkwood_init(void)
{
	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
504
		kirkwood_id(), kirkwood_tclk);
505
	kirkwood_i2s_data.tclk = kirkwood_tclk;
506

507 508 509 510 511 512 513 514
	/*
	 * Disable propagation of mbus errors to the CPU local bus,
	 * as this causes mbus errors (which can occur for example
	 * for PCI aborts) to throw CPU aborts, which we're not set
	 * up to deal with.
	 */
	writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);

515 516 517
	kirkwood_setup_cpu_mbus();

#ifdef CONFIG_CACHE_FEROCEON_L2
518
	kirkwood_l2_init();
519
#endif
520 521 522

	/* internal devices that every board has */
	kirkwood_rtc_init();
523
	kirkwood_wdt_init();
524 525
	kirkwood_xor0_init();
	kirkwood_xor1_init();
526
	kirkwood_crypto_init();
527 528 529 530

#ifdef CONFIG_KEXEC 
	kexec_reinit = kirkwood_enable_pcie;
#endif
531
}
532 533 534 535

static int __init kirkwood_clock_gate(void)
{
	unsigned int curr = readl(CLOCK_GATING_CTRL);
536
	u32 dev, rev;
537

538
	kirkwood_pcie_id(&dev, &rev);
539 540 541 542
	printk(KERN_DEBUG "Gating clock of unused units\n");
	printk(KERN_DEBUG "before: 0x%08x\n", curr);

	/* Make sure those units are accessible */
543
	writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567

	/* For SATA: first shutdown the phy */
	if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
		/* Disable PLL and IVREF */
		writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
		/* Disable PHY */
		writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
	}
	if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
		/* Disable PLL and IVREF */
		writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
		/* Disable PHY */
		writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
	}
	
	/* For PCIe: first shutdown the phy */
	if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
		writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
		while (1)
			if (readl(PCIE_STATUS) & 0x1)
				break;
		writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
	}

568 569 570 571 572 573 574 575 576 577 578 579
	/* For PCIe 1: first shutdown the phy */
	if (dev == MV88F6282_DEV_ID) {
		if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
			writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
			while (1)
				if (readl(PCIE1_STATUS) & 0x1)
					break;
			writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
		}
	} else  /* keep this bit set for devices that don't have PCIe1 */
		kirkwood_clk_ctrl |= CGC_PEX1;

580 581 582 583 584 585 586
	/* Now gate clock the required units */
	writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
	printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));

	return 0;
}
late_initcall(kirkwood_clock_gate);