linux/arch/powerpc/platforms/85xx/ksi8560.c
<<
>>
Prefs
   1/*
   2 * Board setup routines for the Emerson KSI8560
   3 *
   4 * Author: Alexandr Smirnov <asmirnov@ru.mvista.com>
   5 *
   6 * Based on mpc85xx_ads.c maintained by Kumar Gala
   7 *
   8 * 2008 (c) MontaVista, Software, Inc.  This file is licensed under
   9 * the terms of the GNU General Public License version 2.  This program
  10 * is licensed "as is" without any warranty of any kind, whether express
  11 * or implied.
  12 *
  13 */
  14
  15#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>
  22
  23#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>
  30#include <asm/prom.h>
  31
  32#include <sysdev/fsl_soc.h>
  33#include <sysdev/fsl_pci.h>
  34
  35#include <asm/cpm2.h>
  36#include <sysdev/cpm2_pic.h>
  37
  38
  39#define KSI8560_CPLD_HVR                0x04 /* Hardware Version Register */
  40#define KSI8560_CPLD_PVR                0x08 /* PLD Version Register */
  41#define KSI8560_CPLD_RCR1               0x30 /* Reset Command Register 1 */
  42
  43#define KSI8560_CPLD_RCR1_CPUHR         0x80 /* CPU Hard Reset */
  44
  45static void __iomem *cpld_base = NULL;
  46
  47static void machine_restart(char *cmd)
  48{
  49        if (cpld_base)
  50                out_8(cpld_base + KSI8560_CPLD_RCR1, KSI8560_CPLD_RCR1_CPUHR);
  51        else
  52                printk(KERN_ERR "Can't find CPLD base, hang forever\n");
  53
  54        for (;;);
  55}
  56
  57static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
  58{
  59        int cascade_irq;
  60
  61        while ((cascade_irq = cpm2_get_irq()) >= 0)
  62                generic_handle_irq(cascade_irq);
  63
  64        desc->chip->eoi(irq);
  65}
  66
  67static void __init ksi8560_pic_init(void)
  68{
  69        struct mpic *mpic;
  70        struct resource r;
  71        struct device_node *np;
  72#ifdef CONFIG_CPM2
  73        int irq;
  74#endif
  75
  76        np = of_find_node_by_type(NULL, "open-pic");
  77
  78        if (np == NULL) {
  79                printk(KERN_ERR "Could not find open-pic node\n");
  80                return;
  81        }
  82
  83        if (of_address_to_resource(np, 0, &r)) {
  84                printk(KERN_ERR "Could not map mpic register space\n");
  85                of_node_put(np);
  86                return;
  87        }
  88
  89        mpic = mpic_alloc(np, r.start,
  90                        MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
  91                        0, 256, " OpenPIC  ");
  92        BUG_ON(mpic == NULL);
  93        of_node_put(np);
  94
  95        mpic_init(mpic);
  96
  97#ifdef CONFIG_CPM2
  98        /* Setup CPM2 PIC */
  99        np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic");
 100        if (np == NULL) {
 101                printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");
 102                return;
 103        }
 104        irq = irq_of_parse_and_map(np, 0);
 105
 106        cpm2_pic_init(np);
 107        of_node_put(np);
 108        set_irq_chained_handler(irq, cpm2_cascade);
 109#endif
 110}
 111
 112#ifdef CONFIG_CPM2
 113/*
 114 * Setup I/O ports
 115 */
 116struct cpm_pin {
 117        int port, pin, flags;
 118};
 119
 120static struct cpm_pin __initdata ksi8560_pins[] = {
 121        /* SCC1 */
 122        {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 123        {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
 124        {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 125
 126        /* SCC2 */
 127        {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 128        {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 129        {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 130
 131        /* FCC1 */
 132        {0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 133        {0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 134        {0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 135        {0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 136        {0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 137        {0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 138        {0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 139        {0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 140        {0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
 141        {0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
 142        {0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
 143        {0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
 144        {0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
 145        {0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
 146        {2, 23, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK9 */
 147        {2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK10 */
 148
 149};
 150
 151static void __init init_ioports(void)
 152{
 153        int i;
 154
 155        for (i = 0; i < ARRAY_SIZE(ksi8560_pins); i++) {
 156                struct cpm_pin *pin = &ksi8560_pins[i];
 157                cpm2_set_pin(pin->port, pin->pin, pin->flags);
 158        }
 159
 160        cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
 161        cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
 162        cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX);
 163        cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX);
 164        cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK9, CPM_CLK_RX);
 165        cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX);
 166}
 167#endif
 168
 169/*
 170 * Setup the architecture
 171 */
 172static void __init ksi8560_setup_arch(void)
 173{
 174        struct device_node *cpld;
 175
 176        cpld = of_find_compatible_node(NULL, NULL, "emerson,KSI8560-cpld");
 177        if (cpld)
 178                cpld_base = of_iomap(cpld, 0);
 179        else
 180                printk(KERN_ERR "Can't find CPLD in device tree\n");
 181
 182        if (ppc_md.progress)
 183                ppc_md.progress("ksi8560_setup_arch()", 0);
 184
 185#ifdef CONFIG_CPM2
 186        cpm2_reset();
 187        init_ioports();
 188#endif
 189}
 190
 191static void ksi8560_show_cpuinfo(struct seq_file *m)
 192{
 193        uint pvid, svid, phid1;
 194
 195        pvid = mfspr(SPRN_PVR);
 196        svid = mfspr(SPRN_SVR);
 197
 198        seq_printf(m, "Vendor\t\t: Emerson Network Power\n");
 199        seq_printf(m, "Board\t\t: KSI8560\n");
 200
 201        if (cpld_base) {
 202                seq_printf(m, "Hardware rev\t: %d\n",
 203                                        in_8(cpld_base + KSI8560_CPLD_HVR));
 204                seq_printf(m, "CPLD rev\t: %d\n",
 205                                        in_8(cpld_base + KSI8560_CPLD_PVR));
 206        } else
 207                seq_printf(m, "Unknown Hardware and CPLD revs\n");
 208
 209        seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
 210        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 211
 212        /* Display cpu Pll setting */
 213        phid1 = mfspr(SPRN_HID1);
 214        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
 215}
 216
 217static struct of_device_id __initdata of_bus_ids[] = {
 218        { .type = "soc", },
 219        { .type = "simple-bus", },
 220        { .name = "cpm", },
 221        { .name = "localbus", },
 222        { .compatible = "gianfar", },
 223        {},
 224};
 225
 226static int __init declare_of_platform_devices(void)
 227{
 228        of_platform_bus_probe(NULL, of_bus_ids, NULL);
 229
 230        return 0;
 231}
 232machine_device_initcall(ksi8560, declare_of_platform_devices);
 233
 234/*
 235 * Called very early, device-tree isn't unflattened
 236 */
 237static int __init ksi8560_probe(void)
 238{
 239        unsigned long root = of_get_flat_dt_root();
 240
 241        return of_flat_dt_is_compatible(root, "emerson,KSI8560");
 242}
 243
 244define_machine(ksi8560) {
 245        .name                   = "KSI8560",
 246        .probe                  = ksi8560_probe,
 247        .setup_arch             = ksi8560_setup_arch,
 248        .init_IRQ               = ksi8560_pic_init,
 249        .show_cpuinfo           = ksi8560_show_cpuinfo,
 250        .get_irq                = mpic_get_irq,
 251        .restart                = machine_restart,
 252        .calibrate_decr         = generic_calibrate_decr,
 253};
 254