mpc85xx_mds.c 11.9 KB
Newer Older
1
/*
2
 * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved.
3 4 5 6 7 8 9 10
 *
 * Author: Andy Fleming <afleming@freescale.com>
 *
 * Based on 83xx/mpc8360e_pb.c by:
 *	   Li Yang <LeoLi@freescale.com>
 *	   Yin Olivia <Hong-hua.Yin@freescale.com>
 *
 * Description:
11
 * MPC85xx MDS board specific routines.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/initrd.h>
#include <linux/module.h>
#include <linux/fsl_devices.h>
33 34
#include <linux/of_platform.h>
#include <linux/of_device.h>
35
#include <linux/phy.h>
36
#include <linux/lmb.h>
37 38 39 40 41 42 43 44 45 46 47 48

#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/irq.h>
#include <mm/mmu_decl.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
49
#include <sysdev/fsl_pci.h>
50
#include <sysdev/simple_gpio.h>
51 52 53
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/mpic.h>
54
#include <asm/swiotlb.h>
55 56 57 58 59 60 61 62

#undef DEBUG
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
#define MV88E1111_SCR	0x10
#define MV88E1111_SCR_125CLK	0x0010
static int mpc8568_fixup_125_clock(struct phy_device *phydev)
{
	int scr;
	int err;

	/* Workaround for the 125 CLK Toggle */
	scr = phy_read(phydev, MV88E1111_SCR);

	if (scr < 0)
		return scr;

	err = phy_write(phydev, MV88E1111_SCR, scr & ~(MV88E1111_SCR_125CLK));

	if (err)
		return err;

	err = phy_write(phydev, MII_BMCR, BMCR_RESET);

	if (err)
		return err;

	scr = phy_read(phydev, MV88E1111_SCR);

	if (scr < 0)
89
		return scr;
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 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 146 147 148 149 150 151

	err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);

	return err;
}

static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
{
	int temp;
	int err;

	/* Errata */
	err = phy_write(phydev,29, 0x0006);

	if (err)
		return err;

	temp = phy_read(phydev, 30);

	if (temp < 0)
		return temp;

	temp = (temp & (~0x8000)) | 0x4000;
	err = phy_write(phydev,30, temp);

	if (err)
		return err;

	err = phy_write(phydev,29, 0x000a);

	if (err)
		return err;

	temp = phy_read(phydev, 30);

	if (temp < 0)
		return temp;

	temp = phy_read(phydev, 30);

	if (temp < 0)
		return temp;

	temp &= ~0x0020;

	err = phy_write(phydev,30,temp);

	if (err)
		return err;

	/* Disable automatic MDI/MDIX selection */
	temp = phy_read(phydev, 16);

	if (temp < 0)
		return temp;

	temp &= ~0x0060;
	err = phy_write(phydev,16,temp);

	return err;
}

152 153 154 155 156
/* ************************************************************************
 *
 * Setup the architecture
 *
 */
157 158 159 160
#ifdef CONFIG_SMP
extern void __init mpc85xx_smp_init(void);
#endif

161
static void __init mpc85xx_mds_setup_arch(void)
162 163
{
	struct device_node *np;
164
	static u8 __iomem *bcsr_regs = NULL;
165 166 167 168
#ifdef CONFIG_PCI
	struct pci_controller *hose;
#endif
	dma_addr_t max = 0xffffffff;
169 170

	if (ppc_md.progress)
171
		ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
172 173 174 175 176 177 178 179 180 181 182 183

	/* Map BCSR area */
	np = of_find_node_by_name(NULL, "bcsr");
	if (np != NULL) {
		struct resource res;

		of_address_to_resource(np, 0, &res);
		bcsr_regs = ioremap(res.start, res.end - res.start +1);
		of_node_put(np);
	}

#ifdef CONFIG_PCI
184 185 186 187 188 189 190 191 192
	for_each_node_by_type(np, "pci") {
		if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
		    of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
			struct resource rsrc;
			of_address_to_resource(np, 0, &rsrc);
			if ((rsrc.start & 0xfffff) == 0x8000)
				fsl_add_bridge(np, 1);
			else
				fsl_add_bridge(np, 0);
193 194 195 196

			hose = pci_find_hose_for_OF_device(np);
			max = min(max, hose->dma_window_base_cur +
					hose->dma_window_size);
197 198
		}
	}
199 200
#endif

201 202 203 204
#ifdef CONFIG_SMP
	mpc85xx_smp_init();
#endif

205 206 207 208 209 210 211 212
#ifdef CONFIG_SWIOTLB
	if (lmb_end_of_DRAM() > max) {
		ppc_swiotlb_enable = 1;
		set_pci_dma_ops(&swiotlb_dma_ops);
		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
	}
#endif

213
#ifdef CONFIG_QUICC_ENGINE
214 215 216 217 218
	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
	if (!np) {
		np = of_find_node_by_name(NULL, "qe");
		if (!np)
			return;
219 220
	}

221 222 223 224 225 226
	qe_reset();
	of_node_put(np);

	np = of_find_node_by_name(NULL, "par_io");
	if (np) {
		struct device_node *ucc;
227 228 229 230

		par_io_init(np);
		of_node_put(np);

231
		for_each_node_by_name(ucc, "ucc")
232 233 234 235
			par_io_of_config(ucc);
	}

	if (bcsr_regs) {
236
		if (machine_is(mpc8568_mds)) {
237 238 239 240 241
#define BCSR_UCC1_GETH_EN	(0x1 << 7)
#define BCSR_UCC2_GETH_EN	(0x1 << 7)
#define BCSR_UCC1_MODE_MSK	(0x3 << 4)
#define BCSR_UCC2_MODE_MSK	(0x3 << 0)

242 243 244
			/* Turn off UCC1 & UCC2 */
			clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
			clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
245

246 247 248
			/* Mode is RGMII, all bits clear */
			clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
						 BCSR_UCC2_MODE_MSK);
249

250 251 252
			/* Turn UCC1 & UCC2 on */
			setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
			setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
253 254 255
		} else if (machine_is(mpc8569_mds)) {
#define BCSR7_UCC12_GETHnRST	(0x1 << 2)
#define BCSR8_UEM_MARVELL_RST	(0x1 << 1)
256 257
#define BCSR_UCC_RGMII		(0x1 << 6)
#define BCSR_UCC_RTBI		(0x1 << 5)
258 259 260 261 262 263 264 265 266 267
			/*
			 * U-Boot mangles interrupt polarity for Marvell PHYs,
			 * so reset built-in and UEM Marvell PHYs, this puts
			 * the PHYs into their normal state.
			 */
			clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
			setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);

			setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
			clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

			for (np = NULL; (np = of_find_compatible_node(np,
							"network",
							"ucc_geth")) != NULL;) {
				const unsigned int *prop;
				int ucc_num;

				prop = of_get_property(np, "cell-index", NULL);
				if (prop == NULL)
					continue;

				ucc_num = *prop - 1;

				prop = of_get_property(np, "phy-connection-type", NULL);
				if (prop == NULL)
					continue;

				if (strcmp("rtbi", (const char *)prop) == 0)
					clrsetbits_8(&bcsr_regs[7 + ucc_num],
						BCSR_UCC_RGMII, BCSR_UCC_RTBI);
			}

290 291 292 293 294
		} else if (machine_is(p1021_mds)) {
#define BCSR11_ENET_MICRST     (0x1 << 5)
			/* Reset Micrel PHY */
			clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
			setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
295
		}
296

297 298
		iounmap(bcsr_regs);
	}
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 331 332

	if (machine_is(p1021_mds)) {
#define MPC85xx_PMUXCR_OFFSET           0x60
#define MPC85xx_PMUXCR_QE0              0x00008000
#define MPC85xx_PMUXCR_QE3              0x00001000
#define MPC85xx_PMUXCR_QE9              0x00000040
#define MPC85xx_PMUXCR_QE12             0x00000008
		static __be32 __iomem *pmuxcr;

		np = of_find_node_by_name(NULL, "global-utilities");

		if (np) {
			pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;

			if (!pmuxcr)
				printk(KERN_EMERG "Error: Alternate function"
					" signal multiplex control register not"
					" mapped!\n");
			else
			/* P1021 has pins muxed for QE and other functions. To
			 * enable QE UEC mode, we need to set bit QE0 for UCC1
			 * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
			 * and QE12 for QE MII management singals in PMUXCR
			 * register.
			 */
				setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 |
						  MPC85xx_PMUXCR_QE3 |
						  MPC85xx_PMUXCR_QE9 |
						  MPC85xx_PMUXCR_QE12);

			of_node_put(np);
		}

	}
333 334 335
#endif	/* CONFIG_QUICC_ENGINE */
}

336 337 338

static int __init board_fixups(void)
{
339
	char phy_id[20];
340 341 342 343 344 345 346 347 348
	char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
	struct device_node *mdio;
	struct resource res;
	int i;

	for (i = 0; i < ARRAY_SIZE(compstrs); i++) {
		mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);

		of_address_to_resource(mdio, 0, &res);
349
		snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
350
			(unsigned long long)res.start, 1);
351 352 353 354 355

		phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
		phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);

		/* Register a workaround for errata */
356
		snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
357
			(unsigned long long)res.start, 7);
358 359 360 361 362 363 364
		phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);

		of_node_put(mdio);
	}

	return 0;
}
365
machine_arch_initcall(mpc8568_mds, board_fixups);
366
machine_arch_initcall(mpc8569_mds, board_fixups);
367

368
static struct of_device_id mpc85xx_ids[] = {
369 370
	{ .type = "soc", },
	{ .compatible = "soc", },
371
	{ .compatible = "simple-bus", },
372
	{ .type = "qe", },
373
	{ .compatible = "fsl,qe", },
374
	{ .compatible = "gianfar", },
375
	{ .compatible = "fsl,rapidio-delta", },
376
	{ .compatible = "fsl,mpc8548-guts", },
377
	{ .compatible = "gpio-leds", },
378 379 380
	{},
};

381 382 383 384 385 386 387 388 389 390
static struct of_device_id p1021_ids[] = {
	{ .type = "soc", },
	{ .compatible = "soc", },
	{ .compatible = "simple-bus", },
	{ .type = "qe", },
	{ .compatible = "fsl,qe", },
	{ .compatible = "gianfar", },
	{},
};

391
static int __init mpc85xx_publish_devices(void)
392
{
393 394
	if (machine_is(mpc8568_mds))
		simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio");
395 396 397
	if (machine_is(mpc8569_mds))
		simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");

398
	/* Publish the QE devices */
399
	of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
400 401 402

	return 0;
}
403 404 405 406 407 408 409 410 411

static int __init p1021_publish_devices(void)
{
	/* Publish the QE devices */
	of_platform_bus_probe(NULL, p1021_ids, NULL);

	return 0;
}

412
machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
413
machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
414
machine_device_initcall(p1021_mds, p1021_publish_devices);
415

416 417
machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
418
machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
419

420
static void __init mpc85xx_mds_pic_init(void)
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
{
	struct mpic *mpic;
	struct resource r;
	struct device_node *np = NULL;

	np = of_find_node_by_type(NULL, "open-pic");
	if (!np)
		return;

	if (of_address_to_resource(np, 0, &r)) {
		printk(KERN_ERR "Failed to map mpic register space\n");
		of_node_put(np);
		return;
	}

	mpic = mpic_alloc(np, r.start,
437
			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
438
			MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
439
			0, 256, " OpenPIC  ");
440 441 442 443 444 445
	BUG_ON(mpic == NULL);
	of_node_put(np);

	mpic_init(mpic);

#ifdef CONFIG_QUICC_ENGINE
446 447 448 449 450 451
	np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
	if (!np) {
		np = of_find_node_by_type(NULL, "qeic");
		if (!np)
			return;
	}
452 453 454 455 456
	if (machine_is(p1021_mds))
		qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
				qe_ic_cascade_high_mpic);
	else
		qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
457 458 459 460
	of_node_put(np);
#endif				/* CONFIG_QUICC_ENGINE */
}

461
static int __init mpc85xx_mds_probe(void)
462
{
463
        unsigned long root = of_get_flat_dt_root();
464

465
        return of_flat_dt_is_compatible(root, "MPC85xxMDS");
466 467
}

468 469
define_machine(mpc8568_mds) {
	.name		= "MPC8568 MDS",
470 471 472
	.probe		= mpc85xx_mds_probe,
	.setup_arch	= mpc85xx_mds_setup_arch,
	.init_IRQ	= mpc85xx_mds_pic_init,
473
	.get_irq	= mpic_get_irq,
474
	.restart	= fsl_rstcr_restart,
475 476
	.calibrate_decr	= generic_calibrate_decr,
	.progress	= udbg_progress,
477
#ifdef CONFIG_PCI
478
	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
479
#endif
480
};
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

static int __init mpc8569_mds_probe(void)
{
	unsigned long root = of_get_flat_dt_root();

	return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
}

define_machine(mpc8569_mds) {
	.name		= "MPC8569 MDS",
	.probe		= mpc8569_mds_probe,
	.setup_arch	= mpc85xx_mds_setup_arch,
	.init_IRQ	= mpc85xx_mds_pic_init,
	.get_irq	= mpic_get_irq,
	.restart	= fsl_rstcr_restart,
	.calibrate_decr	= generic_calibrate_decr,
	.progress	= udbg_progress,
#ifdef CONFIG_PCI
	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
#endif
};
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524

static int __init p1021_mds_probe(void)
{
	unsigned long root = of_get_flat_dt_root();

	return of_flat_dt_is_compatible(root, "fsl,P1021MDS");

}

define_machine(p1021_mds) {
	.name		= "P1021 MDS",
	.probe		= p1021_mds_probe,
	.setup_arch	= mpc85xx_mds_setup_arch,
	.init_IRQ	= mpc85xx_mds_pic_init,
	.get_irq	= mpic_get_irq,
	.restart	= fsl_rstcr_restart,
	.calibrate_decr	= generic_calibrate_decr,
	.progress	= udbg_progress,
#ifdef CONFIG_PCI
	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
#endif
};