1 /* 2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. 3 * 4 * Author: John Rigby <jrigby@freescale.com> 5 * 6 * Description: 7 * MPC512x Shared code 8 * 9 * This is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/io.h> 17 #include <linux/irq.h> 18 #include <linux/of_platform.h> 19 20 #include <asm/machdep.h> 21 #include <asm/ipic.h> 22 #include <asm/prom.h> 23 #include <asm/time.h> 24 #include <asm/mpc5121.h> 25 #include <asm/mpc52xx_psc.h> 26 27 #include "mpc512x.h" 28 29 static struct mpc512x_reset_module __iomem *reset_module_base; 30 31 static void __init mpc512x_restart_init(void) 32 { 33 struct device_node *np; 34 35 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset"); 36 if (!np) 37 return; 38 39 reset_module_base = of_iomap(np, 0); 40 of_node_put(np); 41 } 42 43 void mpc512x_restart(char *cmd) 44 { 45 if (reset_module_base) { 46 /* Enable software reset "RSTE" */ 47 out_be32(&reset_module_base->rpr, 0x52535445); 48 /* Set software hard reset */ 49 out_be32(&reset_module_base->rcr, 0x2); 50 } else { 51 pr_err("Restart module not mapped.\n"); 52 } 53 for (;;) 54 ; 55 } 56 57 void __init mpc512x_init_IRQ(void) 58 { 59 struct device_node *np; 60 61 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic"); 62 if (!np) 63 return; 64 65 ipic_init(np, 0); 66 of_node_put(np); 67 68 /* 69 * Initialize the default interrupt mapping priorities, 70 * in case the boot rom changed something on us. 71 */ 72 ipic_set_default_priority(); 73 } 74 75 /* 76 * Nodes to do bus probe on, soc and localbus 77 */ 78 static struct of_device_id __initdata of_bus_ids[] = { 79 { .compatible = "fsl,mpc5121-immr", }, 80 { .compatible = "fsl,mpc5121-localbus", }, 81 {}, 82 }; 83 84 void __init mpc512x_declare_of_platform_devices(void) 85 { 86 struct device_node *np; 87 88 if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) 89 printk(KERN_ERR __FILE__ ": " 90 "Error while probing of_platform bus\n"); 91 92 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc"); 93 if (np) { 94 of_platform_device_create(np, NULL, NULL); 95 of_node_put(np); 96 } 97 } 98 99 #define DEFAULT_FIFO_SIZE 16 100 101 static unsigned int __init get_fifo_size(struct device_node *np, 102 char *prop_name) 103 { 104 const unsigned int *fp; 105 106 fp = of_get_property(np, prop_name, NULL); 107 if (fp) 108 return *fp; 109 110 pr_warning("no %s property in %s node, defaulting to %d\n", 111 prop_name, np->full_name, DEFAULT_FIFO_SIZE); 112 113 return DEFAULT_FIFO_SIZE; 114 } 115 116 #define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ 117 ((u32)(_base) + sizeof(struct mpc52xx_psc))) 118 119 /* Init PSC FIFO space for TX and RX slices */ 120 void __init mpc512x_psc_fifo_init(void) 121 { 122 struct device_node *np; 123 void __iomem *psc; 124 unsigned int tx_fifo_size; 125 unsigned int rx_fifo_size; 126 int fifobase = 0; /* current fifo address in 32 bit words */ 127 128 for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { 129 tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); 130 rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); 131 132 /* size in register is in 4 byte units */ 133 tx_fifo_size /= 4; 134 rx_fifo_size /= 4; 135 if (!tx_fifo_size) 136 tx_fifo_size = 1; 137 if (!rx_fifo_size) 138 rx_fifo_size = 1; 139 140 psc = of_iomap(np, 0); 141 if (!psc) { 142 pr_err("%s: Can't map %s device\n", 143 __func__, np->full_name); 144 continue; 145 } 146 147 /* FIFO space is 4KiB, check if requested size is available */ 148 if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { 149 pr_err("%s: no fifo space available for %s\n", 150 __func__, np->full_name); 151 iounmap(psc); 152 /* 153 * chances are that another device requests less 154 * fifo space, so we continue. 155 */ 156 continue; 157 } 158 159 /* set tx and rx fifo size registers */ 160 out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); 161 fifobase += tx_fifo_size; 162 out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); 163 fifobase += rx_fifo_size; 164 165 /* reset and enable the slices */ 166 out_be32(&FIFOC(psc)->txcmd, 0x80); 167 out_be32(&FIFOC(psc)->txcmd, 0x01); 168 out_be32(&FIFOC(psc)->rxcmd, 0x80); 169 out_be32(&FIFOC(psc)->rxcmd, 0x01); 170 171 iounmap(psc); 172 } 173 } 174 175 void __init mpc512x_init(void) 176 { 177 mpc512x_declare_of_platform_devices(); 178 mpc5121_clk_init(); 179 mpc512x_restart_init(); 180 mpc512x_psc_fifo_init(); 181 } 182