mpc85xx_mds.c 4.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved.
 *
 * 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 *
 * 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>

#include <asm/of_device.h>
#include <asm/of_platform.h>
#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/mpc85xx.h>
#include <asm/irq.h>
#include <mm/mmu_decl.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
48
#include <sysdev/fsl_pci.h>
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/mpic.h>

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

/* ************************************************************************
 *
 * Setup the architecture
 *
 */
65
static void __init mpc85xx_mds_setup_arch(void)
66 67 68 69 70
{
	struct device_node *np;
	static u8 *bcsr_regs = NULL;

	if (ppc_md.progress)
71
		ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
72 73 74 75 76 77 78 79 80 81 82 83

	/* 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
84 85 86 87 88 89 90 91 92 93 94
	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);
		}
	}
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
#endif

#ifdef CONFIG_QUICC_ENGINE
	if ((np = of_find_node_by_name(NULL, "qe")) != NULL) {
		qe_reset();
		of_node_put(np);
	}

	if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
		struct device_node *ucc = NULL;

		par_io_init(np);
		of_node_put(np);

		for ( ;(ucc = of_find_node_by_name(ucc, "ucc")) != NULL;)
			par_io_of_config(ucc);

		of_node_put(ucc);
	}

	if (bcsr_regs) {
		u8 bcsr_phy;

		/* Reset the Ethernet PHY */
		bcsr_phy = in_be8(&bcsr_regs[9]);
		bcsr_phy &= ~0x20;
		out_be8(&bcsr_regs[9], bcsr_phy);

		udelay(1000);

		bcsr_phy = in_be8(&bcsr_regs[9]);
		bcsr_phy |= 0x20;
		out_be8(&bcsr_regs[9], bcsr_phy);

		iounmap(bcsr_regs);
	}

#endif	/* CONFIG_QUICC_ENGINE */
}

135
static struct of_device_id mpc85xx_ids[] = {
136 137 138 139 140 141
	{ .type = "soc", },
	{ .compatible = "soc", },
	{ .type = "qe", },
	{},
};

142
static int __init mpc85xx_publish_devices(void)
143
{
144
	if (!machine_is(mpc85xx_mds))
145 146 147
		return 0;

	/* Publish the QE devices */
148
	of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
149 150 151

	return 0;
}
152
device_initcall(mpc85xx_publish_devices);
153

154
static void __init mpc85xx_mds_pic_init(void)
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
{
	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,
			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
172
			0, 256, " OpenPIC  ");
173 174 175 176 177 178 179 180 181 182
	BUG_ON(mpic == NULL);
	of_node_put(np);

	mpic_init(mpic);

#ifdef CONFIG_QUICC_ENGINE
	np = of_find_node_by_type(NULL, "qeic");
	if (!np)
		return;

183
	qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
184 185 186 187
	of_node_put(np);
#endif				/* CONFIG_QUICC_ENGINE */
}

188
static int __init mpc85xx_mds_probe(void)
189
{
190
        unsigned long root = of_get_flat_dt_root();
191

192
        return of_flat_dt_is_compatible(root, "MPC85xxMDS");
193 194
}

195
define_machine(mpc85xx_mds) {
196
	.name		= "MPC85xx MDS",
197 198 199
	.probe		= mpc85xx_mds_probe,
	.setup_arch	= mpc85xx_mds_setup_arch,
	.init_IRQ	= mpc85xx_mds_pic_init,
200
	.get_irq	= mpic_get_irq,
201
	.restart	= fsl_rstcr_restart,
202 203
	.calibrate_decr	= generic_calibrate_decr,
	.progress	= udbg_progress,
204
#ifdef CONFIG_PCI
205
	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
206
#endif
207
};