common.c 14.6 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
}


/*****************************************************************************
 * SATA
 ****************************************************************************/
void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
{
177 178 179
	kirkwood_clk_ctrl |= CGC_SATA0;
	if (sata_data->n_ports > 1)
		kirkwood_clk_ctrl |= CGC_SATA1;
180 181 182

	orion_sata_init(sata_data, &kirkwood_mbus_dram_info,
			SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
183 184 185
}


186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/*****************************************************************************
 * 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,
	},
};

202
static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
203 204 205 206 207 208

static struct platform_device kirkwood_sdio = {
	.name		= "mvsdio",
	.id		= -1,
	.dev		= {
		.dma_mask = &mvsdio_dmamask,
209
		.coherent_dma_mask = DMA_BIT_MASK(32),
210 211 212 213 214 215 216 217 218 219
	},
	.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);
220
	if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
221 222 223 224
		mvsdio_data->clock = 100000000;
	else
		mvsdio_data->clock = 200000000;
	mvsdio_data->dram = &kirkwood_mbus_dram_info;
225
	kirkwood_clk_ctrl |= CGC_SDIO;
226 227 228 229 230
	kirkwood_sdio.dev.platform_data = mvsdio_data;
	platform_device_register(&kirkwood_sdio);
}


231 232 233 234 235
/*****************************************************************************
 * SPI
 ****************************************************************************/
void __init kirkwood_spi_init()
{
236
	kirkwood_clk_ctrl |= CGC_RUNIT;
237
	orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
238 239 240
}


M
Martin Michlmayr 已提交
241 242 243 244 245
/*****************************************************************************
 * I2C
 ****************************************************************************/
void __init kirkwood_i2c_init(void)
{
246
	orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
M
Martin Michlmayr 已提交
247 248 249
}


250 251 252 253 254 255
/*****************************************************************************
 * UART0
 ****************************************************************************/

void __init kirkwood_uart0_init(void)
{
256 257
	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
			 IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
258 259 260 261 262 263 264 265
}


/*****************************************************************************
 * UART1
 ****************************************************************************/
void __init kirkwood_uart1_init(void)
{
266 267
	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
			 IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
268 269
}

270 271 272 273 274 275
/*****************************************************************************
 * Cryptographic Engines and Security Accelerator (CESA)
 ****************************************************************************/
void __init kirkwood_crypto_init(void)
{
	kirkwood_clk_ctrl |= CGC_CRYPTO;
276 277
	orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
			  KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
278 279 280
}


281 282 283
/*****************************************************************************
 * XOR0
 ****************************************************************************/
284
static void __init kirkwood_xor0_init(void)
285
{
286
	kirkwood_clk_ctrl |= CGC_XOR0;
287 288 289 290

	orion_xor0_init(&kirkwood_mbus_dram_info,
			XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
			IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
291 292 293 294 295 296
}


/*****************************************************************************
 * XOR1
 ****************************************************************************/
297
static void __init kirkwood_xor1_init(void)
298
{
299
	kirkwood_clk_ctrl |= CGC_XOR1;
300 301 302

	orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
			IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
303 304 305
}


306 307 308 309 310
/*****************************************************************************
 * Watchdog
 ****************************************************************************/
static void __init kirkwood_wdt_init(void)
{
311
	orion_wdt_init(kirkwood_tclk);
312 313 314
}


315 316 317
/*****************************************************************************
 * Time handling
 ****************************************************************************/
318 319 320 321 322
void __init kirkwood_init_early(void)
{
	orion_time_set_base(TIMER_VIRT_BASE);
}

323 324
int kirkwood_tclk;

325
static int __init kirkwood_find_tclk(void)
326
{
327 328 329
	u32 dev, rev;

	kirkwood_pcie_id(&dev, &rev);
330

331 332 333
	if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
		if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
			return 200000000;
334

335 336 337
	return 166666667;
}

L
Li Jie 已提交
338
static void __init kirkwood_timer_init(void)
339
{
340
	kirkwood_tclk = kirkwood_find_tclk();
341 342 343

	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
			IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
344 345 346 347 348 349
}

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

350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
/*****************************************************************************
 * 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,
	},
};

381
static struct platform_device kirkwood_pcm_device = {
382
	.name		= "kirkwood-pcm-audio",
383 384 385
	.id		= -1,
};

386 387 388 389
void __init kirkwood_audio_init(void)
{
	kirkwood_clk_ctrl |= CGC_AUDIO;
	platform_device_register(&kirkwood_i2s_device);
390
	platform_device_register(&kirkwood_pcm_device);
391
}
392 393 394 395

/*****************************************************************************
 * General
 ****************************************************************************/
396 397 398
/*
 * Identify device ID and revision.
 */
399 400
static char * __init kirkwood_id(void)
{
401 402 403 404 405 406 407 408 409
	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";
410 411
		else if (rev == MV88F6281_REV_A1)
			return "MV88F6281-A1";
412 413 414 415 416 417 418
		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";
419 420
		else if (rev == MV88F6192_REV_A1)
			return "MV88F6192-A1";
421 422 423 424 425
		else
			return "MV88F6192-Rev-Unsupported";
	} else if (dev == MV88F6180_DEV_ID) {
		if (rev == MV88F6180_REV_A0)
			return "MV88F6180-Rev-A0";
426 427
		else if (rev == MV88F6180_REV_A1)
			return "MV88F6180-Rev-A1";
428 429
		else
			return "MV88F6180-Rev-Unsupported";
430 431 432
	} else if (dev == MV88F6282_DEV_ID) {
		if (rev == MV88F6282_REV_A0)
			return "MV88F6282-Rev-A0";
433 434
		else if (rev == MV88F6282_REV_A1)
			return "MV88F6282-Rev-A1";
435 436
		else
			return "MV88F6282-Rev-Unsupported";
437 438
	} else {
		return "Device-Unknown";
439 440 441
	}
}

442
static void __init kirkwood_l2_init(void)
443
{
444 445 446 447 448 449 450
#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
451 452
}

453 454 455
void __init kirkwood_init(void)
{
	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
456
		kirkwood_id(), kirkwood_tclk);
457
	kirkwood_i2s_data.tclk = kirkwood_tclk;
458

459 460 461 462 463 464 465 466
	/*
	 * 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);

467 468 469
	kirkwood_setup_cpu_mbus();

#ifdef CONFIG_CACHE_FEROCEON_L2
470
	kirkwood_l2_init();
471
#endif
472 473 474

	/* internal devices that every board has */
	kirkwood_rtc_init();
475
	kirkwood_wdt_init();
476 477
	kirkwood_xor0_init();
	kirkwood_xor1_init();
478
	kirkwood_crypto_init();
479 480 481 482

#ifdef CONFIG_KEXEC 
	kexec_reinit = kirkwood_enable_pcie;
#endif
483
}
484 485 486 487

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

490
	kirkwood_pcie_id(&dev, &rev);
491 492 493 494
	printk(KERN_DEBUG "Gating clock of unused units\n");
	printk(KERN_DEBUG "before: 0x%08x\n", curr);

	/* Make sure those units are accessible */
495
	writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519

	/* 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);
	}

520 521 522 523 524 525 526 527 528 529 530 531
	/* 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;

532 533 534 535 536 537 538
	/* 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);