1/* 2 * PQ2FADS board support 3 * 4 * Copyright 2007 Freescale Semiconductor, Inc. 5 * Author: Scott Wood <scottwood@freescale.com> 6 * 7 * Loosely based on mp82xx ADS support by Vitaly Bordug <vbordug@ru.mvista.com> 8 * Copyright (c) 2006 MontaVista Software, 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 version 2 as published 12 * by the Free Software Foundation. 13 */ 14 15#include <linux/init.h> 16#include <linux/interrupt.h> 17#include <linux/fsl_devices.h> 18#include <linux/of_address.h> 19#include <linux/of_fdt.h> 20#include <linux/of_platform.h> 21 22#include <asm/io.h> 23#include <asm/cpm2.h> 24#include <asm/udbg.h> 25#include <asm/machdep.h> 26#include <asm/time.h> 27 28#include <sysdev/fsl_soc.h> 29#include <sysdev/cpm2_pic.h> 30 31#include "pq2ads.h" 32#include "pq2.h" 33 34static void __init pq2fads_pic_init(void) 35{ 36 struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); 37 if (!np) { 38 printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); 39 return; 40 } 41 42 cpm2_pic_init(np); 43 of_node_put(np); 44 45 /* Initialize stuff for the 82xx CPLD IC and install demux */ 46 pq2ads_pci_init_irq(); 47} 48 49struct cpm_pin { 50 int port, pin, flags; 51}; 52 53static struct cpm_pin pq2fads_pins[] = { 54 /* SCC1 */ 55 {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 56 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 57 58 /* SCC2 */ 59 {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 60 {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 61 62 /* FCC2 */ 63 {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 64 {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 65 {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 66 {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 67 {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 68 {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 69 {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 70 {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 71 {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 72 {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 73 {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 74 {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 75 {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 76 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 77 {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 78 {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 79 80 /* FCC3 */ 81 {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 82 {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 83 {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 84 {1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 85 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 86 {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 87 {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 88 {1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 89 {1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 90 {1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 91 {1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 92 {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 93 {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 94 {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 95 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 96 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 97}; 98 99static void __init init_ioports(void) 100{ 101 int i; 102 103 for (i = 0; i < ARRAY_SIZE(pq2fads_pins); i++) { 104 struct cpm_pin *pin = &pq2fads_pins[i]; 105 cpm2_set_pin(pin->port, pin->pin, pin->flags); 106 } 107 108 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX); 109 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX); 110 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX); 111 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX); 112 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX); 113 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX); 114 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX); 115 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX); 116} 117 118static void __init pq2fads_setup_arch(void) 119{ 120 struct device_node *np; 121 __be32 __iomem *bcsr; 122 123 if (ppc_md.progress) 124 ppc_md.progress("pq2fads_setup_arch()", 0); 125 126 cpm2_reset(); 127 128 np = of_find_compatible_node(NULL, NULL, "fsl,pq2fads-bcsr"); 129 if (!np) { 130 printk(KERN_ERR "No fsl,pq2fads-bcsr in device tree\n"); 131 return; 132 } 133 134 bcsr = of_iomap(np, 0); 135 of_node_put(np); 136 if (!bcsr) { 137 printk(KERN_ERR "Cannot map BCSR registers\n"); 138 return; 139 } 140 141 /* Enable the serial and ethernet ports */ 142 143 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 144 setbits32(&bcsr[1], BCSR1_FETH_RST); 145 146 clrbits32(&bcsr[3], BCSR3_FETHIEN2); 147 setbits32(&bcsr[3], BCSR3_FETH2_RST); 148 149 iounmap(bcsr); 150 151 init_ioports(); 152 153 /* Enable external IRQs */ 154 clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000); 155 156 pq2_init_pci(); 157 158 if (ppc_md.progress) 159 ppc_md.progress("pq2fads_setup_arch(), finish", 0); 160} 161 162/* 163 * Called very early, device-tree isn't unflattened 164 */ 165static int __init pq2fads_probe(void) 166{ 167 unsigned long root = of_get_flat_dt_root(); 168 return of_flat_dt_is_compatible(root, "fsl,pq2fads"); 169} 170 171static const struct of_device_id of_bus_ids[] __initconst = { 172 { .name = "soc", }, 173 { .name = "cpm", }, 174 { .name = "localbus", }, 175 {}, 176}; 177 178static int __init declare_of_platform_devices(void) 179{ 180 /* Publish the QE devices */ 181 of_platform_bus_probe(NULL, of_bus_ids, NULL); 182 return 0; 183} 184machine_device_initcall(pq2fads, declare_of_platform_devices); 185 186define_machine(pq2fads) 187{ 188 .name = "Freescale PQ2FADS", 189 .probe = pq2fads_probe, 190 .setup_arch = pq2fads_setup_arch, 191 .init_IRQ = pq2fads_pic_init, 192 .get_irq = cpm2_get_irq, 193 .calibrate_decr = generic_calibrate_decr, 194 .restart = pq2_restart, 195 .progress = udbg_progress, 196}; 197