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 65 66
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/mpic.h>

#include "mpc85xx.h"

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

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

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

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

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

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

	/* Publish the QE devices */
150
	of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
151 152 153

	return 0;
}
154
device_initcall(mpc85xx_publish_devices);
155

156
static void __init mpc85xx_mds_pic_init(void)
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
{
	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,
174
			0, 256, " OpenPIC  ");
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	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;

	qe_ic_init(np, 0);
	of_node_put(np);
#endif				/* CONFIG_QUICC_ENGINE */
}

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

194
        return of_flat_dt_is_compatible(root, "MPC85xxMDS");
195 196
}

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