^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/arm/mach-iop32x/iq31244.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Board support code for the Intel EP80219 and IQ31244 platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Rory Bolt <rorybolt@pacbell.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2002 Rory Bolt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2003 (c) MontaVista, Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2004 Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/serial_8250.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mtd/physmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/cputype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/mach/arch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/mach/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/mach/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/mach-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "irqs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "gpio-iop32x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Until March of 2007 iq31244 platforms and ep80219 platforms shared the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * same machine id, and the processor type was used to select board type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * However this assumption breaks for an iq80219 board which is an iop219
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * processor on an iq31244 board. The force_ep80219 flag has been added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * for old boot loaders using the iq31244 machine id for an ep80219 platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int force_ep80219;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int is_80219(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return !!((read_cpuid_id() & 0xffffffe0) == 0x69052e20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int is_ep80219(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (machine_is_ep80219() || force_ep80219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * EP80219/IQ31244 timer tick configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void __init iq31244_timer_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (is_ep80219()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* 33.333 MHz crystal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) iop_init_time(200000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* 33.000 MHz crystal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) iop_init_time(198000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * IQ31244 I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct map_desc iq31244_io_desc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { /* on-board devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .virtual = IQ31244_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .pfn = __phys_to_pfn(IQ31244_UART),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .length = 0x00100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .type = MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) void __init iq31244_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) iop3xx_map_io();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * EP80219/IQ31244 PCI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ep80219_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (slot == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* CFlash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) irq = IRQ_IOP32X_XINT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } else if (slot == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* 82551 Pro 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) irq = IRQ_IOP32X_XINT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) } else if (slot == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* PCI-X Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) irq = IRQ_IOP32X_XINT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else if (slot == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* SATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) irq = IRQ_IOP32X_XINT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) printk(KERN_ERR "ep80219_pci_map_irq() called for unknown "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) "device PCI:%d:%d:%d\n", dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static struct hw_pci ep80219_pci __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .nr_controllers = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .ops = &iop3xx_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .setup = iop3xx_pci_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .preinit = iop3xx_pci_preinit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .map_irq = ep80219_pci_map_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) iq31244_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (slot == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* CFlash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) irq = IRQ_IOP32X_XINT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) } else if (slot == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* SATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) irq = IRQ_IOP32X_XINT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) } else if (slot == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* PCI-X Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) irq = IRQ_IOP32X_XINT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) } else if (slot == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* 82546 GigE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) irq = IRQ_IOP32X_XINT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) printk(KERN_ERR "iq31244_pci_map_irq called for unknown "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "device PCI:%d:%d:%d\n", dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static struct hw_pci iq31244_pci __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .nr_controllers = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .ops = &iop3xx_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .setup = iop3xx_pci_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .preinit = iop3xx_pci_preinit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .map_irq = iq31244_pci_map_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int __init iq31244_pci_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (is_ep80219())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pci_common_init(&ep80219_pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else if (machine_is_iq31244()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (is_80219()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) printk("note: iq31244 board type has been selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) printk("note: to select ep80219 operation:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) printk("\t1/ specify \"force_ep80219\" on the kernel"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) " command line\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) printk("\t2/ update boot loader to pass"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) " the ep80219 id: %d\n", MACH_TYPE_EP80219);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pci_common_init(&iq31244_pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) subsys_initcall(iq31244_pci_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * IQ31244 machine initialisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static struct physmap_flash_data iq31244_flash_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .width = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static struct resource iq31244_flash_resource = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .start = 0xf0000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .end = 0xf07fffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static struct platform_device iq31244_flash_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .name = "physmap-flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .id = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .platform_data = &iq31244_flash_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .num_resources = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .resource = &iq31244_flash_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static struct plat_serial8250_port iq31244_serial_port[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .mapbase = IQ31244_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .membase = (char *)IQ31244_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .irq = IRQ_IOP32X_XINT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .flags = UPF_SKIP_TEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .iotype = UPIO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .regshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .uartclk = 1843200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static struct resource iq31244_uart_resource = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .start = IQ31244_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .end = IQ31244_UART + 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static struct platform_device iq31244_serial_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .name = "serial8250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .id = PLAT8250_DEV_PLATFORM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .platform_data = iq31244_serial_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .num_resources = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .resource = &iq31244_uart_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * This function will send a SHUTDOWN_COMPLETE message to the PIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * controller over I2C. We are not using the i2c subsystem since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * we are going to power off and it may be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) void ep80219_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Send the Address byte w/ the start condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *IOP3XX_IDBR1 = 0x60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *IOP3XX_ICR1 = 0xE9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * Send the START_MSG byte w/ no start or stop condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *IOP3XX_IDBR1 = 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *IOP3XX_ICR1 = 0xE8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * stop condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *IOP3XX_IDBR1 = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *IOP3XX_ICR1 = 0xE8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Send an ignored byte w/ stop condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *IOP3XX_IDBR1 = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *IOP3XX_ICR1 = 0xEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) while (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static void __init iq31244_init_machine(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) register_iop32x_gpio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) gpiod_add_lookup_table(&iop3xx_i2c1_gpio_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) platform_device_register(&iop3xx_i2c0_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) platform_device_register(&iop3xx_i2c1_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) platform_device_register(&iq31244_flash_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) platform_device_register(&iq31244_serial_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) platform_device_register(&iop3xx_dma_0_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) platform_device_register(&iop3xx_dma_1_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (is_ep80219())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pm_power_off = ep80219_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!is_80219())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) platform_device_register(&iop3xx_aau_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int __init force_ep80219_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) force_ep80219 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) __setup("force_ep80219", force_ep80219_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) MACHINE_START(IQ31244, "Intel IQ31244")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Maintainer: Intel Corp. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .atag_offset = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .map_io = iq31244_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .init_irq = iop32x_init_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .init_time = iq31244_timer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .init_machine = iq31244_init_machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .restart = iop3xx_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) MACHINE_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* There should have been an ep80219 machine identifier from the beginning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Boot roms older than March 2007 do not know the ep80219 machine id. Pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * "force_ep80219" on the kernel command line, otherwise iq31244 operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * will be selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) MACHINE_START(EP80219, "Intel EP80219")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* Maintainer: Intel Corp. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .atag_offset = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .map_io = iq31244_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .init_irq = iop32x_init_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .init_time = iq31244_timer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .init_machine = iq31244_init_machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .restart = iop3xx_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) MACHINE_END