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