2 * Board setup routines for KVME080.
4 * Copyright 2007 Sangmoon Kim <dogoil@etinsys.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
12 #include <linux/initrd.h>
13 #include <linux/delay.h>
14 #include <linux/ide.h>
15 #include <linux/root_dev.h>
16 #include <linux/bcd.h>
17 #include <linux/mc146818rtc.h>
21 #include <asm/mpc10x.h>
22 #include <asm/pci-bridge.h>
27 unsigned long root = of_get_flat_dt_root();
29 if (of_flat_dt_is_compatible(root, "kvme080"))
35 kvme080_setup_pci(struct device_node *dnp)
38 struct pci_controller *hose;
41 printk("Adding PCI host bridge %s\n", dnp->full_name);
43 bus_range = (int *) get_property(dnp, "bus-range", &len);
44 if (bus_range == NULL || len < 2 * sizeof(int))
45 printk(KERN_WARNING "Can't get bus-range for %s, assume"
46 " bus 0\n", dnp->full_name);
48 hose = pcibios_alloc_controller();
50 printk("PCI Host bridge init failed\n");
53 hose->arch_data = dnp;
54 hose->first_busno = bus_range ? bus_range[0] : 0;
55 hose->last_busno = bus_range ? bus_range[1] : 0xff;
56 hose->set_cfg_type = 1;
57 setup_indirect_pci(hose, 0xfcc00000, 0xfce00000);
59 printk(KERN_INFO "Found PCI host bridge %s", dnp->full_name);
61 /* Interpret the "ranges" property */
62 /* This also maps the I/O region and sets isa_io/mem_base */
63 pci_process_bridge_OF_ranges(hose, dnp, 1);
68 kvme080_setup_arch(void)
70 struct device_node *dnp;
75 #ifdef CONFIG_BLK_DEV_INITRD
80 #ifdef CONFIG_ROOT_NFS
85 for (dnp = NULL; (dnp=of_find_node_by_type(dnp,"pci")) != NULL;)
86 kvme080_setup_pci(dnp);
88 printk(KERN_INFO "Etin Systems KVME080 Board\n");
89 printk(KERN_INFO "Port by Sangmoon Kim (dogoil@etinsys.com)\n");
93 kvme080_init_IRQ(void)
96 struct device_node *dnp;
101 dnp = of_find_node_by_type(NULL, "open-pic");
105 prop = of_get_address(dnp, 0, NULL, NULL);
106 paddr = (phys_addr_t)of_translate_address(dnp, prop);
108 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 0, 0,
110 BUG_ON(mpic == NULL);
112 prop = (u32 *)get_property(dnp, "serial-mode", &size);
114 mpic_set_serial_int(mpic, *(u32 *)prop);
117 mpic_assign_isu(mpic, 0, paddr + 0x10200);
120 mpic_assign_isu(mpic, 1, paddr + 0x11020);
123 mpic_assign_isu(mpic, 2, paddr + 0x11120);
126 mpic_assign_isu(mpic, 3, paddr + 0x11140);
132 kvme080_restart(char *cmd)
151 kvme080_power_off(void)
154 for(;;); /* No way to shut power off with software */
165 extern spinlock_t rtc_lock;
166 static unsigned char *rtc_base = (unsigned char*)NULL;
169 kvme080_time_init(void)
172 struct device_node *dnp;
177 dnp = of_find_node_by_type(NULL, "rtc");
181 prop = of_get_address(dnp, 0, &size, NULL);
185 paddr = (phys_addr_t)of_translate_address(dnp, prop);
186 if (paddr == (phys_addr_t)OF_BAD_ADDR)
189 rtc_base = (unsigned char *)ioremap(paddr, (ssize_t)size);
194 spin_lock(&rtc_lock);
195 val = readb(rtc_base);
197 writeb(val & 0x3f, rtc_base);
198 spin_unlock(&rtc_lock);
204 kvme080_set_rtc_time(struct rtc_time *tp)
209 spin_lock(&rtc_lock);
211 writeb(readb(rtc_base) | 0x80, rtc_base);
213 writeb(BIN2BCD(tp->tm_sec), rtc_base + 1);
214 writeb(BIN2BCD(tp->tm_min), rtc_base + 2);
215 writeb(BIN2BCD(tp->tm_hour), rtc_base + 3);
216 writeb(BIN2BCD(tp->tm_mday), rtc_base + 5);
217 writeb(BIN2BCD(tp->tm_mon), rtc_base + 6);
218 writeb(BIN2BCD(tp->tm_year % 100), rtc_base + 7);
220 writeb((readb(rtc_base) & 0x40) |
221 BIN2BCD((tp->tm_year < 100) ? 20 : 21), rtc_base);
223 spin_unlock(&rtc_lock);
229 kvme080_get_rtc_time(struct rtc_time *tp)
234 spin_lock(&rtc_lock);
236 writeb(readb(rtc_base) | 0x40, rtc_base);
238 tp->tm_sec = readb(rtc_base + 1) & 0x7f;
239 tp->tm_min = readb(rtc_base + 2) & 0x7f;
240 tp->tm_hour = readb(rtc_base + 3) & 0x3f;
241 tp->tm_mday = readb(rtc_base + 5) & 0x3f;
242 tp->tm_mon = readb(rtc_base + 6) & 0x1f;
243 tp->tm_year = readb(rtc_base + 7) & 0xff;
245 writeb(readb(rtc_base) & ~0x40, rtc_base);
247 tp->tm_sec = BCD2BIN(tp->tm_sec);
248 tp->tm_min = BCD2BIN(tp->tm_min);
249 tp->tm_hour = BCD2BIN(tp->tm_hour);
250 tp->tm_mday = BCD2BIN(tp->tm_mday);
251 tp->tm_mon = BCD2BIN(tp->tm_mon);
252 tp->tm_year = BCD2BIN(tp->tm_year);
254 if (tp->tm_year < 80)
257 spin_unlock(&rtc_lock);
261 kvme080_nvram_read_val(int addr)
265 return readb(nvram_base + addr);
269 kvme080_nvram_write_val(int addr, unsigned char val)
273 writeb(val, nvram_base + addr);
277 kvme080_nvram_size(void)
282 define_machine(kvme080) {
284 .probe = kvme080_probe,
285 .setup_arch = kvme080_setup_arch,
286 .init_IRQ = kvme080_init_IRQ,
287 .get_irq = mpic_get_irq,
288 .restart = kvme080_restart,
289 .power_off = kvme080_power_off,
290 .halt = kvme080_halt,
291 .time_init = kvme080_time_init,
292 .set_rtc_time = kvme080_set_rtc_time,
293 .get_rtc_time = kvme080_get_rtc_time,
294 .calibrate_decr = generic_calibrate_decr,
295 .nvram_read_val = kvme080_nvram_read_val,
296 .nvram_write_val = kvme080_nvram_write_val,
297 .nvram_size = kvme080_nvram_size,
298 .progress = udbg_progress,