1/* 2 * arch/powerpc/platforms/83xx/mpc837x_mds.c 3 * 4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. 5 * 6 * MPC837x MDS board specific routines 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/pci.h> 15#include <linux/of.h> 16#include <linux/of_platform.h> 17 18#include <asm/time.h> 19#include <asm/ipic.h> 20#include <asm/udbg.h> 21#include <asm/prom.h> 22#include <sysdev/fsl_pci.h> 23 24#include "mpc83xx.h" 25 26#define BCSR12_USB_SER_MASK 0x8a 27#define BCSR12_USB_SER_PIN 0x80 28#define BCSR12_USB_SER_DEVICE 0x02 29 30static int mpc837xmds_usb_cfg(void) 31{ 32 struct device_node *np; 33 const void *phy_type, *mode; 34 void __iomem *bcsr_regs = NULL; 35 u8 bcsr12; 36 int ret; 37 38 ret = mpc837x_usb_cfg(); 39 if (ret) 40 return ret; 41 /* Map BCSR area */ 42 np = of_find_compatible_node(NULL, NULL, "fsl,mpc837xmds-bcsr"); 43 if (np) { 44 bcsr_regs = of_iomap(np, 0); 45 of_node_put(np); 46 } 47 if (!bcsr_regs) 48 return -1; 49 50 np = of_find_node_by_name(NULL, "usb"); 51 if (!np) { 52 ret = -ENODEV; 53 goto out; 54 } 55 phy_type = of_get_property(np, "phy_type", NULL); 56 if (phy_type && !strcmp(phy_type, "ulpi")) { 57 clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); 58 } else if (phy_type && !strcmp(phy_type, "serial")) { 59 mode = of_get_property(np, "dr_mode", NULL); 60 bcsr12 = in_8(bcsr_regs + 12) & ~BCSR12_USB_SER_MASK; 61 bcsr12 |= BCSR12_USB_SER_PIN; 62 if (mode && !strcmp(mode, "peripheral")) 63 bcsr12 |= BCSR12_USB_SER_DEVICE; 64 out_8(bcsr_regs + 12, bcsr12); 65 } else { 66 printk(KERN_ERR "USB DR: unsupported PHY\n"); 67 } 68 69 of_node_put(np); 70out: 71 iounmap(bcsr_regs); 72 return ret; 73} 74 75/* ************************************************************************ 76 * 77 * Setup the architecture 78 * 79 */ 80static void __init mpc837x_mds_setup_arch(void) 81{ 82#ifdef CONFIG_PCI 83 struct device_node *np; 84#endif 85 86 if (ppc_md.progress) 87 ppc_md.progress("mpc837x_mds_setup_arch()", 0); 88 89#ifdef CONFIG_PCI 90 for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") 91 mpc83xx_add_bridge(np); 92 for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") 93 mpc83xx_add_bridge(np); 94#endif 95 mpc837xmds_usb_cfg(); 96} 97 98static struct of_device_id mpc837x_ids[] = { 99 { .type = "soc", }, 100 { .compatible = "soc", }, 101 { .compatible = "simple-bus", }, 102 { .compatible = "gianfar", }, 103 {}, 104}; 105 106static int __init mpc837x_declare_of_platform_devices(void) 107{ 108 /* Publish platform_device */ 109 of_platform_bus_probe(NULL, mpc837x_ids, NULL); 110 111 return 0; 112} 113machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices); 114 115static void __init mpc837x_mds_init_IRQ(void) 116{ 117 struct device_node *np; 118 119 np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); 120 if (!np) 121 return; 122 123 ipic_init(np, 0); 124 125 /* Initialize the default interrupt mapping priorities, 126 * in case the boot rom changed something on us. 127 */ 128 ipic_set_default_priority(); 129} 130 131/* 132 * Called very early, MMU is off, device-tree isn't unflattened 133 */ 134static int __init mpc837x_mds_probe(void) 135{ 136 unsigned long root = of_get_flat_dt_root(); 137 138 return of_flat_dt_is_compatible(root, "fsl,mpc837xmds"); 139} 140 141define_machine(mpc837x_mds) { 142 .name = "MPC837x MDS", 143 .probe = mpc837x_mds_probe, 144 .setup_arch = mpc837x_mds_setup_arch, 145 .init_IRQ = mpc837x_mds_init_IRQ, 146 .get_irq = ipic_get_irq, 147 .restart = mpc83xx_restart, 148 .time_init = mpc83xx_time_init, 149 .calibrate_decr = generic_calibrate_decr, 150 .progress = udbg_progress, 151}; 152