1 /* 2 * AmigaOne platform setup 3 * 4 * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net) 5 * 6 * Based on original amigaone_setup.c source code 7 * Copyright 2003 by Hans-Joerg Frieden and Thomas Frieden 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/seq_file.h> 17 #include <linux/utsrelease.h> 18 19 #include <asm/machdep.h> 20 #include <asm/cputable.h> 21 #include <asm/prom.h> 22 #include <asm/pci-bridge.h> 23 #include <asm/i8259.h> 24 #include <asm/time.h> 25 #include <asm/udbg.h> 26 27 extern void __flush_disable_L1(void); 28 29 void amigaone_show_cpuinfo(struct seq_file *m) 30 { 31 seq_printf(m, "vendor\t\t: Eyetech Ltd.\n"); 32 } 33 34 static int __init amigaone_add_bridge(struct device_node *dev) 35 { 36 const u32 *cfg_addr, *cfg_data; 37 int len; 38 const int *bus_range; 39 struct pci_controller *hose; 40 41 printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name); 42 43 cfg_addr = of_get_address(dev, 0, NULL, NULL); 44 cfg_data = of_get_address(dev, 1, NULL, NULL); 45 if ((cfg_addr == NULL) || (cfg_data == NULL)) 46 return -ENODEV; 47 48 bus_range = of_get_property(dev, "bus-range", &len); 49 if ((bus_range == NULL) || (len < 2 * sizeof(int))) 50 printk(KERN_WARNING "Can't get bus-range for %s, assume" 51 " bus 0\n", dev->full_name); 52 53 hose = pcibios_alloc_controller(dev); 54 if (hose == NULL) 55 return -ENOMEM; 56 57 hose->first_busno = bus_range ? bus_range[0] : 0; 58 hose->last_busno = bus_range ? bus_range[1] : 0xff; 59 60 setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0); 61 62 /* Interpret the "ranges" property */ 63 /* This also maps the I/O region and sets isa_io/mem_base */ 64 pci_process_bridge_OF_ranges(hose, dev, 1); 65 66 return 0; 67 } 68 69 void __init amigaone_setup_arch(void) 70 { 71 struct device_node *np; 72 int phb = -ENODEV; 73 74 /* Lookup PCI host bridges. */ 75 for_each_compatible_node(np, "pci", "mai-logic,articia-s") 76 phb = amigaone_add_bridge(np); 77 78 BUG_ON(phb != 0); 79 80 if (ppc_md.progress) 81 ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0); 82 } 83 84 void __init amigaone_init_IRQ(void) 85 { 86 struct device_node *pic, *np = NULL; 87 const unsigned long *prop = NULL; 88 unsigned long int_ack = 0; 89 90 /* Search for ISA interrupt controller. */ 91 pic = of_find_compatible_node(NULL, "interrupt-controller", 92 "pnpPNP,000"); 93 BUG_ON(pic == NULL); 94 95 /* Look for interrupt acknowledge address in the PCI root node. */ 96 np = of_find_compatible_node(NULL, "pci", "mai-logic,articia-s"); 97 if (np) { 98 prop = of_get_property(np, "8259-interrupt-acknowledge", NULL); 99 if (prop) 100 int_ack = prop[0]; 101 of_node_put(np); 102 } 103 104 if (int_ack == 0) 105 printk(KERN_WARNING "Cannot find PCI interrupt acknowledge" 106 " address, polling\n"); 107 108 i8259_init(pic, int_ack); 109 ppc_md.get_irq = i8259_irq; 110 irq_set_default_host(i8259_get_host()); 111 } 112 113 void __init amigaone_init(void) 114 { 115 request_region(0x00, 0x20, "dma1"); 116 request_region(0x40, 0x20, "timer"); 117 request_region(0x80, 0x10, "dma page reg"); 118 request_region(0xc0, 0x20, "dma2"); 119 } 120 121 void amigaone_restart(char *cmd) 122 { 123 local_irq_disable(); 124 125 /* Flush and disable caches. */ 126 __flush_disable_L1(); 127 128 /* Set SRR0 to the reset vector and turn on MSR_IP. */ 129 mtspr(SPRN_SRR0, 0xfff00100); 130 mtspr(SPRN_SRR1, MSR_IP); 131 132 /* Do an rfi to jump back to firmware. */ 133 __asm__ __volatile__("rfi" : : : "memory"); 134 135 /* Not reached. */ 136 while (1); 137 } 138 139 static int __init amigaone_probe(void) 140 { 141 unsigned long root = of_get_flat_dt_root(); 142 143 if (of_flat_dt_is_compatible(root, "eyetech,amigaone")) { 144 /* 145 * Coherent memory access cause complete system lockup! Thus 146 * disable this CPU feature, even if the CPU needs it. 147 */ 148 cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT; 149 150 ISA_DMA_THRESHOLD = 0x00ffffff; 151 DMA_MODE_READ = 0x44; 152 DMA_MODE_WRITE = 0x48; 153 154 return 1; 155 } 156 157 return 0; 158 } 159 160 define_machine(amigaone) { 161 .name = "AmigaOne", 162 .probe = amigaone_probe, 163 .setup_arch = amigaone_setup_arch, 164 .init = amigaone_init, 165 .show_cpuinfo = amigaone_show_cpuinfo, 166 .init_IRQ = amigaone_init_IRQ, 167 .restart = amigaone_restart, 168 .calibrate_decr = generic_calibrate_decr, 169 .progress = udbg_progress, 170 }; 171