Path: blob/master/arch/powerpc/platforms/maple/setup.c
10818 views
/*1* Maple (970 eval board) setup code2*3* (c) Copyright 2004 Benjamin Herrenschmidt ([email protected]),4* IBM Corp.5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public License8* as published by the Free Software Foundation; either version9* 2 of the License, or (at your option) any later version.10*11*/1213#undef DEBUG1415#include <linux/init.h>16#include <linux/errno.h>17#include <linux/sched.h>18#include <linux/kernel.h>19#include <linux/mm.h>20#include <linux/stddef.h>21#include <linux/unistd.h>22#include <linux/ptrace.h>23#include <linux/user.h>24#include <linux/tty.h>25#include <linux/string.h>26#include <linux/delay.h>27#include <linux/ioport.h>28#include <linux/major.h>29#include <linux/initrd.h>30#include <linux/vt_kern.h>31#include <linux/console.h>32#include <linux/pci.h>33#include <linux/adb.h>34#include <linux/cuda.h>35#include <linux/pmu.h>36#include <linux/irq.h>37#include <linux/seq_file.h>38#include <linux/root_dev.h>39#include <linux/serial.h>40#include <linux/smp.h>41#include <linux/bitops.h>42#include <linux/of_device.h>43#include <linux/memblock.h>4445#include <asm/processor.h>46#include <asm/sections.h>47#include <asm/prom.h>48#include <asm/system.h>49#include <asm/pgtable.h>50#include <asm/io.h>51#include <asm/pci-bridge.h>52#include <asm/iommu.h>53#include <asm/machdep.h>54#include <asm/dma.h>55#include <asm/cputable.h>56#include <asm/time.h>57#include <asm/mpic.h>58#include <asm/rtas.h>59#include <asm/udbg.h>60#include <asm/nvram.h>6162#include "maple.h"6364#ifdef DEBUG65#define DBG(fmt...) udbg_printf(fmt)66#else67#define DBG(fmt...)68#endif6970static unsigned long maple_find_nvram_base(void)71{72struct device_node *rtcs;73unsigned long result = 0;7475/* find NVRAM device */76rtcs = of_find_compatible_node(NULL, "nvram", "AMD8111");77if (rtcs) {78struct resource r;79if (of_address_to_resource(rtcs, 0, &r)) {80printk(KERN_EMERG "Maple: Unable to translate NVRAM"81" address\n");82goto bail;83}84if (!(r.flags & IORESOURCE_IO)) {85printk(KERN_EMERG "Maple: NVRAM address isn't PIO!\n");86goto bail;87}88result = r.start;89} else90printk(KERN_EMERG "Maple: Unable to find NVRAM\n");91bail:92of_node_put(rtcs);93return result;94}9596static void maple_restart(char *cmd)97{98unsigned int maple_nvram_base;99const unsigned int *maple_nvram_offset, *maple_nvram_command;100struct device_node *sp;101102maple_nvram_base = maple_find_nvram_base();103if (maple_nvram_base == 0)104goto fail;105106/* find service processor device */107sp = of_find_node_by_name(NULL, "service-processor");108if (!sp) {109printk(KERN_EMERG "Maple: Unable to find Service Processor\n");110goto fail;111}112maple_nvram_offset = of_get_property(sp, "restart-addr", NULL);113maple_nvram_command = of_get_property(sp, "restart-value", NULL);114of_node_put(sp);115116/* send command */117outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);118for (;;) ;119fail:120printk(KERN_EMERG "Maple: Manual Restart Required\n");121}122123static void maple_power_off(void)124{125unsigned int maple_nvram_base;126const unsigned int *maple_nvram_offset, *maple_nvram_command;127struct device_node *sp;128129maple_nvram_base = maple_find_nvram_base();130if (maple_nvram_base == 0)131goto fail;132133/* find service processor device */134sp = of_find_node_by_name(NULL, "service-processor");135if (!sp) {136printk(KERN_EMERG "Maple: Unable to find Service Processor\n");137goto fail;138}139maple_nvram_offset = of_get_property(sp, "power-off-addr", NULL);140maple_nvram_command = of_get_property(sp, "power-off-value", NULL);141of_node_put(sp);142143/* send command */144outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);145for (;;) ;146fail:147printk(KERN_EMERG "Maple: Manual Power-Down Required\n");148}149150static void maple_halt(void)151{152maple_power_off();153}154155#ifdef CONFIG_SMP156struct smp_ops_t maple_smp_ops = {157.probe = smp_mpic_probe,158.message_pass = smp_mpic_message_pass,159.kick_cpu = smp_generic_kick_cpu,160.setup_cpu = smp_mpic_setup_cpu,161.give_timebase = smp_generic_give_timebase,162.take_timebase = smp_generic_take_timebase,163};164#endif /* CONFIG_SMP */165166static void __init maple_use_rtas_reboot_and_halt_if_present(void)167{168if (rtas_service_present("system-reboot") &&169rtas_service_present("power-off")) {170ppc_md.restart = rtas_restart;171ppc_md.power_off = rtas_power_off;172ppc_md.halt = rtas_halt;173}174}175176void __init maple_setup_arch(void)177{178/* init to some ~sane value until calibrate_delay() runs */179loops_per_jiffy = 50000000;180181/* Setup SMP callback */182#ifdef CONFIG_SMP183smp_ops = &maple_smp_ops;184#endif185/* Lookup PCI hosts */186maple_pci_init();187188#ifdef CONFIG_DUMMY_CONSOLE189conswitchp = &dummy_con;190#endif191maple_use_rtas_reboot_and_halt_if_present();192193printk(KERN_DEBUG "Using native/NAP idle loop\n");194195mmio_nvram_init();196}197198/*199* Early initialization.200*/201static void __init maple_init_early(void)202{203DBG(" -> maple_init_early\n");204205iommu_init_early_dart();206207DBG(" <- maple_init_early\n");208}209210/*211* This is almost identical to pSeries and CHRP. We need to make that212* code generic at one point, with appropriate bits in the device-tree to213* identify the presence of an HT APIC214*/215static void __init maple_init_IRQ(void)216{217struct device_node *root, *np, *mpic_node = NULL;218const unsigned int *opprop;219unsigned long openpic_addr = 0;220int naddr, n, i, opplen, has_isus = 0;221struct mpic *mpic;222unsigned int flags = MPIC_PRIMARY;223224/* Locate MPIC in the device-tree. Note that there is a bug225* in Maple device-tree where the type of the controller is226* open-pic and not interrupt-controller227*/228229for_each_node_by_type(np, "interrupt-controller")230if (of_device_is_compatible(np, "open-pic")) {231mpic_node = np;232break;233}234if (mpic_node == NULL)235for_each_node_by_type(np, "open-pic") {236mpic_node = np;237break;238}239if (mpic_node == NULL) {240printk(KERN_ERR241"Failed to locate the MPIC interrupt controller\n");242return;243}244245/* Find address list in /platform-open-pic */246root = of_find_node_by_path("/");247naddr = of_n_addr_cells(root);248opprop = of_get_property(root, "platform-open-pic", &opplen);249if (opprop != 0) {250openpic_addr = of_read_number(opprop, naddr);251has_isus = (opplen > naddr);252printk(KERN_DEBUG "OpenPIC addr: %lx, has ISUs: %d\n",253openpic_addr, has_isus);254}255256BUG_ON(openpic_addr == 0);257258/* Check for a big endian MPIC */259if (of_get_property(np, "big-endian", NULL) != NULL)260flags |= MPIC_BIG_ENDIAN;261262/* XXX Maple specific bits */263flags |= MPIC_U3_HT_IRQS | MPIC_WANTS_RESET;264/* All U3/U4 are big-endian, older SLOF firmware doesn't encode this */265flags |= MPIC_BIG_ENDIAN;266267/* Setup the openpic driver. More device-tree junks, we hard code no268* ISUs for now. I'll have to revisit some stuffs with the folks doing269* the firmware for those270*/271mpic = mpic_alloc(mpic_node, openpic_addr, flags,272/*has_isus ? 16 :*/ 0, 0, " MPIC ");273BUG_ON(mpic == NULL);274275/* Add ISUs */276opplen /= sizeof(u32);277for (n = 0, i = naddr; i < opplen; i += naddr, n++) {278unsigned long isuaddr = of_read_number(opprop + i, naddr);279mpic_assign_isu(mpic, n, isuaddr);280}281282/* All ISUs are setup, complete initialization */283mpic_init(mpic);284ppc_md.get_irq = mpic_get_irq;285of_node_put(mpic_node);286of_node_put(root);287}288289static void __init maple_progress(char *s, unsigned short hex)290{291printk("*** %04x : %s\n", hex, s ? s : "");292}293294295/*296* Called very early, MMU is off, device-tree isn't unflattened297*/298static int __init maple_probe(void)299{300unsigned long root = of_get_flat_dt_root();301302if (!of_flat_dt_is_compatible(root, "Momentum,Maple") &&303!of_flat_dt_is_compatible(root, "Momentum,Apache"))304return 0;305/*306* On U3, the DART (iommu) must be allocated now since it307* has an impact on htab_initialize (due to the large page it308* occupies having to be broken up so the DART itself is not309* part of the cacheable linar mapping310*/311alloc_dart_table();312313hpte_init_native();314315return 1;316}317318define_machine(maple) {319.name = "Maple",320.probe = maple_probe,321.setup_arch = maple_setup_arch,322.init_early = maple_init_early,323.init_IRQ = maple_init_IRQ,324.pci_irq_fixup = maple_pci_irq_fixup,325.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,326.restart = maple_restart,327.power_off = maple_power_off,328.halt = maple_halt,329.get_boot_time = maple_get_boot_time,330.set_rtc_time = maple_set_rtc_time,331.get_rtc_time = maple_get_rtc_time,332.calibrate_decr = generic_calibrate_decr,333.progress = maple_progress,334.power_save = power4_idle,335};336337#ifdef CONFIG_EDAC338/*339* Register a platform device for CPC925 memory controller on340* Motorola ATCA-6101 blade.341*/342#define MAPLE_CPC925_MODEL "Motorola,ATCA-6101"343static int __init maple_cpc925_edac_setup(void)344{345struct platform_device *pdev;346struct device_node *np = NULL;347struct resource r;348const unsigned char *model;349int ret;350351np = of_find_node_by_path("/");352if (!np) {353printk(KERN_ERR "%s: Unable to get root node\n", __func__);354return -ENODEV;355}356357model = (const unsigned char *)of_get_property(np, "model", NULL);358if (!model) {359printk(KERN_ERR "%s: Unabel to get model info\n", __func__);360of_node_put(np);361return -ENODEV;362}363364ret = strcmp(model, MAPLE_CPC925_MODEL);365of_node_put(np);366367if (ret != 0)368return 0;369370np = of_find_node_by_type(NULL, "memory-controller");371if (!np) {372printk(KERN_ERR "%s: Unable to find memory-controller node\n",373__func__);374return -ENODEV;375}376377ret = of_address_to_resource(np, 0, &r);378of_node_put(np);379380if (ret < 0) {381printk(KERN_ERR "%s: Unable to get memory-controller reg\n",382__func__);383return -ENODEV;384}385386pdev = platform_device_register_simple("cpc925_edac", 0, &r, 1);387if (IS_ERR(pdev))388return PTR_ERR(pdev);389390printk(KERN_INFO "%s: CPC925 platform device created\n", __func__);391392return 0;393}394machine_device_initcall(maple, maple_cpc925_edac_setup);395#endif396397398