Path: blob/master/arch/powerpc/platforms/85xx/sbc8560.c
10820 views
/*1* Wind River SBC8560 setup and early boot code.2*3* Copyright 2007 Wind River Systems Inc.4*5* By Paul Gortmaker (see MAINTAINERS for contact information)6*7* Based largely on the MPC8560ADS support - Copyright 2005 Freescale Inc.8*9* This program is free software; you can redistribute it and/or modify it10* under the terms of the GNU General Public License as published by the11* Free Software Foundation; either version 2 of the License, or (at your12* option) any later version.13*/1415#include <linux/stddef.h>16#include <linux/kernel.h>17#include <linux/pci.h>18#include <linux/kdev_t.h>19#include <linux/delay.h>20#include <linux/seq_file.h>21#include <linux/of_platform.h>2223#include <asm/system.h>24#include <asm/time.h>25#include <asm/machdep.h>26#include <asm/pci-bridge.h>27#include <asm/mpic.h>28#include <mm/mmu_decl.h>29#include <asm/udbg.h>3031#include <sysdev/fsl_soc.h>32#include <sysdev/fsl_pci.h>3334#ifdef CONFIG_CPM235#include <asm/cpm2.h>36#include <sysdev/cpm2_pic.h>37#endif3839#ifdef CONFIG_CPM24041static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)42{43struct irq_chip *chip = irq_desc_get_chip(desc);44int cascade_irq;4546while ((cascade_irq = cpm2_get_irq()) >= 0)47generic_handle_irq(cascade_irq);4849chip->irq_eoi(&desc->irq_data);50}5152#endif /* CONFIG_CPM2 */5354static void __init sbc8560_pic_init(void)55{56struct mpic *mpic;57struct resource r;58struct device_node *np = NULL;59#ifdef CONFIG_CPM260int irq;61#endif6263np = of_find_node_by_type(np, "open-pic");64if (!np) {65printk(KERN_ERR "Could not find open-pic node\n");66return;67}6869if (of_address_to_resource(np, 0, &r)) {70printk(KERN_ERR "Could not map mpic register space\n");71of_node_put(np);72return;73}7475mpic = mpic_alloc(np, r.start,76MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,770, 256, " OpenPIC ");78BUG_ON(mpic == NULL);79of_node_put(np);8081mpic_init(mpic);8283#ifdef CONFIG_CPM284/* Setup CPM2 PIC */85np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic");86if (np == NULL) {87printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");88return;89}90irq = irq_of_parse_and_map(np, 0);9192cpm2_pic_init(np);93of_node_put(np);94irq_set_chained_handler(irq, cpm2_cascade);95#endif96}9798/*99* Setup the architecture100*/101#ifdef CONFIG_CPM2102struct cpm_pin {103int port, pin, flags;104};105106static const struct cpm_pin sbc8560_pins[] = {107/* SCC1 */108{3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},109{3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},110{3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},111112/* SCC2 */113{3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},114{3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},115{3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},116117/* FCC2 */118{1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},119{1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},120{1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},121{1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},122{1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},123{1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},124{1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},125{1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},126{1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},127{1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},128{1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},129{1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},130{1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},131{1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},132{2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK14 */133{2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK13 */134135/* FCC3 */136{1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},137{1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},138{1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},139{1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},140{1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},141{1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},142{1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},143{1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},144{1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},145{1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},146{1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},147{1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},148{1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},149{1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},150{2, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK16 */151{2, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK15 */152};153154static void __init init_ioports(void)155{156int i;157158for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) {159const struct cpm_pin *pin = &sbc8560_pins[i];160cpm2_set_pin(pin->port, pin->pin, pin->flags);161}162163cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);164cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);165cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX);166cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX);167cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);168cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);169cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX);170cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX);171}172#endif173174static void __init sbc8560_setup_arch(void)175{176#ifdef CONFIG_PCI177struct device_node *np;178#endif179180if (ppc_md.progress)181ppc_md.progress("sbc8560_setup_arch()", 0);182183#ifdef CONFIG_CPM2184cpm2_reset();185init_ioports();186#endif187188#ifdef CONFIG_PCI189for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")190fsl_add_bridge(np, 1);191#endif192}193194static void sbc8560_show_cpuinfo(struct seq_file *m)195{196uint pvid, svid, phid1;197198pvid = mfspr(SPRN_PVR);199svid = mfspr(SPRN_SVR);200201seq_printf(m, "Vendor\t\t: Wind River\n");202seq_printf(m, "PVR\t\t: 0x%x\n", pvid);203seq_printf(m, "SVR\t\t: 0x%x\n", svid);204205/* Display cpu Pll setting */206phid1 = mfspr(SPRN_HID1);207seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));208}209210static struct of_device_id __initdata of_bus_ids[] = {211{ .name = "soc", },212{ .type = "soc", },213{ .name = "cpm", },214{ .name = "localbus", },215{ .compatible = "simple-bus", },216{ .compatible = "gianfar", },217{},218};219220static int __init declare_of_platform_devices(void)221{222of_platform_bus_probe(NULL, of_bus_ids, NULL);223224return 0;225}226machine_device_initcall(sbc8560, declare_of_platform_devices);227228/*229* Called very early, device-tree isn't unflattened230*/231static int __init sbc8560_probe(void)232{233unsigned long root = of_get_flat_dt_root();234235return of_flat_dt_is_compatible(root, "SBC8560");236}237238#ifdef CONFIG_RTC_DRV_M48T59239static int __init sbc8560_rtc_init(void)240{241struct device_node *np;242struct resource res;243struct platform_device *rtc_dev;244245np = of_find_compatible_node(NULL, NULL, "m48t59");246if (np == NULL) {247printk("No RTC in DTB. Has it been eaten by wild dogs?\n");248return -ENODEV;249}250251of_address_to_resource(np, 0, &res);252of_node_put(np);253254printk("Found RTC (m48t59) at i/o 0x%x\n", res.start);255256rtc_dev = platform_device_register_simple("rtc-m48t59", 0, &res, 1);257258if (IS_ERR(rtc_dev)) {259printk("Registering sbc8560 RTC device failed\n");260return PTR_ERR(rtc_dev);261}262263return 0;264}265266arch_initcall(sbc8560_rtc_init);267268#endif /* M48T59 */269270static __u8 __iomem *brstcr;271272static int __init sbc8560_bdrstcr_init(void)273{274struct device_node *np;275struct resource res;276277np = of_find_compatible_node(NULL, NULL, "wrs,sbc8560-brstcr");278if (np == NULL) {279printk(KERN_WARNING "sbc8560: No board specific RSTCR in DTB.\n");280return -ENODEV;281}282283of_address_to_resource(np, 0, &res);284285printk(KERN_INFO "sbc8560: Found BRSTCR at i/o 0x%x\n", res.start);286287brstcr = ioremap(res.start, res.end - res.start);288if(!brstcr)289printk(KERN_WARNING "sbc8560: ioremap of brstcr failed.\n");290291of_node_put(np);292293return 0;294}295296arch_initcall(sbc8560_bdrstcr_init);297298void sbc8560_rstcr_restart(char * cmd)299{300local_irq_disable();301if(brstcr)302clrbits8(brstcr, 0x80);303304while(1);305}306307define_machine(sbc8560) {308.name = "SBC8560",309.probe = sbc8560_probe,310.setup_arch = sbc8560_setup_arch,311.init_IRQ = sbc8560_pic_init,312.show_cpuinfo = sbc8560_show_cpuinfo,313.get_irq = mpic_get_irq,314.restart = sbc8560_rstcr_restart,315.calibrate_decr = generic_calibrate_decr,316.progress = udbg_progress,317};318319320