iq80321.c 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 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 89 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
/*
 * arch/arm/mach-iop32x/iq80321.c
 *
 * Board support code for the Intel IQ80321 platform.
 *
 * Author: Rory Bolt <rorybolt@pacbell.net>
 * Copyright (C) 2002 Rory Bolt
 * Copyright (C) 2004 Intel Corp.
 *
 * 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/mm.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
#include <asm/mach/time.h>
#include <asm/mach-types.h>
#include <asm/page.h>
#include <asm/pgtable.h>

/*
 * IQ80321 timer tick configuration.
 */
static void __init iq80321_timer_init(void)
{
	/* 33.333 MHz crystal.  */
	iop3xx_init_time(200000000);
}

static struct sys_timer iq80321_timer = {
	.init		= iq80321_timer_init,
	.offset		= iop3xx_gettimeoffset,
};


/*
 * IQ80321 I/O.
 */
static struct map_desc iq80321_io_desc[] __initdata = {
 	{	/* on-board devices */
		.virtual	= IQ80321_UART,
		.pfn		= __phys_to_pfn(IQ80321_UART),
		.length		= 0x00100000,
		.type		= MT_DEVICE,
	},
};

void __init iq80321_map_io(void)
{
	iop3xx_map_io();
	iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
}


/*
 * IQ80321 PCI.
 */
static inline int __init
iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
	int irq;

	if ((slot == 2 || slot == 6) && pin == 1) {
		/* PCI-X Slot INTA */
		irq = IRQ_IOP321_XINT2;
	} else if ((slot == 2 || slot == 6) && pin == 2) {
		/* PCI-X Slot INTA */
		irq = IRQ_IOP321_XINT3;
	} else if ((slot == 2 || slot == 6) && pin == 3) {
		/* PCI-X Slot INTA */
		irq = IRQ_IOP321_XINT0;
	} else if ((slot == 2 || slot == 6) && pin == 4) {
		/* PCI-X Slot INTA */
		irq = IRQ_IOP321_XINT1;
	} else if (slot == 4 || slot == 8) {
		/* Gig-E */
		irq = IRQ_IOP321_XINT0;
	} else {
		printk(KERN_ERR "iq80321_pci_map_irq() called for unknown "
			"device PCI:%d:%d:%d\n", dev->bus->number,
			PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
		irq = -1;
	}

	return irq;
}

static struct hw_pci iq80321_pci __initdata = {
	.swizzle	= pci_std_swizzle,
	.nr_controllers = 1,
	.setup		= iop3xx_pci_setup,
	.preinit	= iop3xx_pci_preinit,
	.scan		= iop3xx_pci_scan_bus,
	.map_irq	= iq80321_pci_map_irq,
};

static int __init iq80321_pci_init(void)
{
	if (machine_is_iq80321())
		pci_common_init(&iq80321_pci);

	return 0;
}

subsys_initcall(iq80321_pci_init);


/*
 * IQ80321 machine initialisation.
 */
static struct physmap_flash_data iq80321_flash_data = {
	.width		= 1,
};

static struct resource iq80321_flash_resource = {
	.start		= 0xf0000000,
	.end		= 0xf07fffff,
	.flags		= IORESOURCE_MEM,
};

static struct platform_device iq80321_flash_device = {
	.name		= "physmap-flash",
	.id		= 0,
	.dev		= {
		.platform_data	= &iq80321_flash_data,
	},
	.num_resources	= 1,
	.resource	= &iq80321_flash_resource,
};

static struct plat_serial8250_port iq80321_serial_port[] = {
	{
		.mapbase	= IQ80321_UART,
		.membase	= (char *)IQ80321_UART,
		.irq		= IRQ_IOP321_XINT1,
		.flags		= UPF_SKIP_TEST,
		.iotype		= UPIO_MEM,
		.regshift	= 0,
		.uartclk	= 1843200,
	},
	{ },
};

static struct resource iq80321_uart_resource = {
	.start		= IQ80321_UART,
	.end		= IQ80321_UART + 7,
	.flags		= IORESOURCE_MEM,
};

static struct platform_device iq80321_serial_device = {
	.name		= "serial8250",
	.id		= PLAT8250_DEV_PLATFORM,
	.dev		= {
		.platform_data		= iq80321_serial_port,
	},
	.num_resources	= 1,
	.resource	= &iq80321_uart_resource,
};

static void __init iq80321_init_machine(void)
{
	platform_device_register(&iop3xx_i2c0_device);
	platform_device_register(&iop3xx_i2c1_device);
	platform_device_register(&iq80321_flash_device);
	platform_device_register(&iq80321_serial_device);
}

MACHINE_START(IQ80321, "Intel IQ80321")
	/* Maintainer: Intel Corp. */
	.phys_io	= IQ80321_UART,
	.io_pg_offst	= ((IQ80321_UART) >> 18) & 0xfffc,
	.boot_params	= 0xa0000100,
	.map_io		= iq80321_map_io,
	.init_irq	= iop321_init_irq,
	.timer		= &iq80321_timer,
	.init_machine	= iq80321_init_machine,
MACHINE_END