linux/arch/powerpc/platforms/85xx/sbc8560.c
<<
>>
Prefs
   1/*
   2 * Wind River SBC8560 setup and early boot code.
   3 *
   4 * Copyright 2007 Wind River Systems Inc.
   5 *
   6 * By Paul Gortmaker (see MAINTAINERS for contact information)
   7 *
   8 * Based largely on the MPC8560ADS support - Copyright 2005 Freescale Inc.
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 */
  15
  16#include <linux/stddef.h>
  17#include <linux/kernel.h>
  18#include <linux/pci.h>
  19#include <linux/kdev_t.h>
  20#include <linux/delay.h>
  21#include <linux/seq_file.h>
  22#include <linux/of_platform.h>
  23
  24#include <asm/system.h>
  25#include <asm/time.h>
  26#include <asm/machdep.h>
  27#include <asm/pci-bridge.h>
  28#include <asm/mpic.h>
  29#include <mm/mmu_decl.h>
  30#include <asm/udbg.h>
  31
  32#include <sysdev/fsl_soc.h>
  33#include <sysdev/fsl_pci.h>
  34
  35#include "mpc85xx.h"
  36
  37#ifdef CONFIG_CPM2
  38#include <asm/cpm2.h>
  39#include <sysdev/cpm2_pic.h>
  40#endif
  41
  42static void __init sbc8560_pic_init(void)
  43{
  44        struct mpic *mpic = mpic_alloc(NULL, 0,
  45                        MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
  46                        0, 256, " OpenPIC  ");
  47        BUG_ON(mpic == NULL);
  48        mpic_init(mpic);
  49
  50        mpc85xx_cpm2_pic_init();
  51}
  52
  53/*
  54 * Setup the architecture
  55 */
  56#ifdef CONFIG_CPM2
  57struct cpm_pin {
  58        int port, pin, flags;
  59};
  60
  61static const struct cpm_pin sbc8560_pins[] = {
  62        /* SCC1 */
  63        {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  64        {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  65        {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  66
  67        /* SCC2 */
  68        {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  69        {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  70        {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  71
  72        /* FCC2 */
  73        {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  74        {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  75        {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  76        {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  77        {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  78        {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  79        {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  80        {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  81        {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  82        {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  83        {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  84        {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  85        {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  86        {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  87        {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK14 */
  88        {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK13 */
  89
  90        /* FCC3 */
  91        {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  92        {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  93        {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  94        {1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
  95        {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  96        {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  97        {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  98        {1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
  99        {1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 100        {1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 101        {1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 102        {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 103        {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 104        {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 105        {2, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK16 */
 106        {2, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK15 */
 107};
 108
 109static void __init init_ioports(void)
 110{
 111        int i;
 112
 113        for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) {
 114                const struct cpm_pin *pin = &sbc8560_pins[i];
 115                cpm2_set_pin(pin->port, pin->pin, pin->flags);
 116        }
 117
 118        cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
 119        cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
 120        cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX);
 121        cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX);
 122        cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
 123        cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
 124        cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX);
 125        cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX);
 126}
 127#endif
 128
 129static void __init sbc8560_setup_arch(void)
 130{
 131#ifdef CONFIG_PCI
 132        struct device_node *np;
 133#endif
 134
 135        if (ppc_md.progress)
 136                ppc_md.progress("sbc8560_setup_arch()", 0);
 137
 138#ifdef CONFIG_CPM2
 139        cpm2_reset();
 140        init_ioports();
 141#endif
 142
 143#ifdef CONFIG_PCI
 144        for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
 145                fsl_add_bridge(np, 1);
 146#endif
 147}
 148
 149static void sbc8560_show_cpuinfo(struct seq_file *m)
 150{
 151        uint pvid, svid, phid1;
 152
 153        pvid = mfspr(SPRN_PVR);
 154        svid = mfspr(SPRN_SVR);
 155
 156        seq_printf(m, "Vendor\t\t: Wind River\n");
 157        seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
 158        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 159
 160        /* Display cpu Pll setting */
 161        phid1 = mfspr(SPRN_HID1);
 162        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
 163}
 164
 165machine_device_initcall(sbc8560, mpc85xx_common_publish_devices);
 166
 167/*
 168 * Called very early, device-tree isn't unflattened
 169 */
 170static int __init sbc8560_probe(void)
 171{
 172        unsigned long root = of_get_flat_dt_root();
 173
 174        return of_flat_dt_is_compatible(root, "SBC8560");
 175}
 176
 177#ifdef CONFIG_RTC_DRV_M48T59
 178static int __init sbc8560_rtc_init(void)
 179{
 180        struct device_node *np;
 181        struct resource res;
 182        struct platform_device *rtc_dev;
 183
 184        np = of_find_compatible_node(NULL, NULL, "m48t59");
 185        if (np == NULL) {
 186                printk("No RTC in DTB. Has it been eaten by wild dogs?\n");
 187                return -ENODEV;
 188        }
 189
 190        of_address_to_resource(np, 0, &res);
 191        of_node_put(np);
 192
 193        printk("Found RTC (m48t59) at i/o 0x%x\n", res.start);
 194
 195        rtc_dev = platform_device_register_simple("rtc-m48t59", 0, &res, 1);
 196
 197        if (IS_ERR(rtc_dev)) {
 198                printk("Registering sbc8560 RTC device failed\n");
 199                return PTR_ERR(rtc_dev);
 200        }
 201
 202        return 0;
 203}
 204
 205arch_initcall(sbc8560_rtc_init);
 206
 207#endif  /* M48T59 */
 208
 209static __u8 __iomem *brstcr;
 210
 211static int __init sbc8560_bdrstcr_init(void)
 212{
 213        struct device_node *np;
 214        struct resource res;
 215
 216        np = of_find_compatible_node(NULL, NULL, "wrs,sbc8560-brstcr");
 217        if (np == NULL) {
 218                printk(KERN_WARNING "sbc8560: No board specific RSTCR in DTB.\n");
 219                return -ENODEV;
 220        }
 221
 222        of_address_to_resource(np, 0, &res);
 223
 224        printk(KERN_INFO "sbc8560: Found BRSTCR at %pR\n", &res);
 225
 226        brstcr = ioremap(res.start, resource_size(&res));
 227        if(!brstcr)
 228                printk(KERN_WARNING "sbc8560: ioremap of brstcr failed.\n");
 229
 230        of_node_put(np);
 231
 232        return 0;
 233}
 234
 235arch_initcall(sbc8560_bdrstcr_init);
 236
 237void sbc8560_rstcr_restart(char * cmd)
 238{
 239        local_irq_disable();
 240        if(brstcr)
 241                clrbits8(brstcr, 0x80);
 242
 243        while(1);
 244}
 245
 246define_machine(sbc8560) {
 247        .name                   = "SBC8560",
 248        .probe                  = sbc8560_probe,
 249        .setup_arch             = sbc8560_setup_arch,
 250        .init_IRQ               = sbc8560_pic_init,
 251        .show_cpuinfo           = sbc8560_show_cpuinfo,
 252        .get_irq                = mpic_get_irq,
 253        .restart                = sbc8560_rstcr_restart,
 254        .calibrate_decr         = generic_calibrate_decr,
 255        .progress               = udbg_progress,
 256};
 257