1fb180322SJohn Rigby /* 2fb180322SJohn Rigby * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. 3fb180322SJohn Rigby * 4fb180322SJohn Rigby * Author: John Rigby <jrigby@freescale.com> 5fb180322SJohn Rigby * 6fb180322SJohn Rigby * Description: 7fb180322SJohn Rigby * MPC512x Shared code 8fb180322SJohn Rigby * 9fb180322SJohn Rigby * This is free software; you can redistribute it and/or modify it 10fb180322SJohn Rigby * under the terms of the GNU General Public License as published by 11fb180322SJohn Rigby * the Free Software Foundation; either version 2 of the License, or 12fb180322SJohn Rigby * (at your option) any later version. 13fb180322SJohn Rigby */ 14fb180322SJohn Rigby 15fb180322SJohn Rigby #include <linux/kernel.h> 16fb180322SJohn Rigby #include <linux/io.h> 17fb180322SJohn Rigby #include <linux/irq.h> 18fb180322SJohn Rigby #include <linux/of_platform.h> 19fb180322SJohn Rigby 20fb180322SJohn Rigby #include <asm/machdep.h> 21fb180322SJohn Rigby #include <asm/ipic.h> 22fb180322SJohn Rigby #include <asm/prom.h> 23fb180322SJohn Rigby #include <asm/time.h> 24a8dbceb7SAnatolij Gustschin #include <asm/mpc5121.h> 252da8cb6aSAnatolij Gustschin #include <asm/mpc52xx_psc.h> 26fb180322SJohn Rigby 27fb180322SJohn Rigby #include "mpc512x.h" 28fb180322SJohn Rigby 29a8dbceb7SAnatolij Gustschin static struct mpc512x_reset_module __iomem *reset_module_base; 30a8dbceb7SAnatolij Gustschin 31a8dbceb7SAnatolij Gustschin static void __init mpc512x_restart_init(void) 32a8dbceb7SAnatolij Gustschin { 33a8dbceb7SAnatolij Gustschin struct device_node *np; 34a8dbceb7SAnatolij Gustschin 35a8dbceb7SAnatolij Gustschin np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset"); 36a8dbceb7SAnatolij Gustschin if (!np) 37a8dbceb7SAnatolij Gustschin return; 38a8dbceb7SAnatolij Gustschin 39a8dbceb7SAnatolij Gustschin reset_module_base = of_iomap(np, 0); 40a8dbceb7SAnatolij Gustschin of_node_put(np); 41a8dbceb7SAnatolij Gustschin } 42a8dbceb7SAnatolij Gustschin 43a8dbceb7SAnatolij Gustschin void mpc512x_restart(char *cmd) 44a8dbceb7SAnatolij Gustschin { 45a8dbceb7SAnatolij Gustschin if (reset_module_base) { 46a8dbceb7SAnatolij Gustschin /* Enable software reset "RSTE" */ 47a8dbceb7SAnatolij Gustschin out_be32(&reset_module_base->rpr, 0x52535445); 48a8dbceb7SAnatolij Gustschin /* Set software hard reset */ 49a8dbceb7SAnatolij Gustschin out_be32(&reset_module_base->rcr, 0x2); 50a8dbceb7SAnatolij Gustschin } else { 51a8dbceb7SAnatolij Gustschin pr_err("Restart module not mapped.\n"); 52a8dbceb7SAnatolij Gustschin } 53a8dbceb7SAnatolij Gustschin for (;;) 54a8dbceb7SAnatolij Gustschin ; 55a8dbceb7SAnatolij Gustschin } 56a8dbceb7SAnatolij Gustschin 57fb180322SJohn Rigby void __init mpc512x_init_IRQ(void) 58fb180322SJohn Rigby { 59fb180322SJohn Rigby struct device_node *np; 60fb180322SJohn Rigby 61fb180322SJohn Rigby np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic"); 62fb180322SJohn Rigby if (!np) 63fb180322SJohn Rigby return; 64fb180322SJohn Rigby 65fb180322SJohn Rigby ipic_init(np, 0); 66fb180322SJohn Rigby of_node_put(np); 67fb180322SJohn Rigby 68fb180322SJohn Rigby /* 69fb180322SJohn Rigby * Initialize the default interrupt mapping priorities, 70fb180322SJohn Rigby * in case the boot rom changed something on us. 71fb180322SJohn Rigby */ 72fb180322SJohn Rigby ipic_set_default_priority(); 73fb180322SJohn Rigby } 74fb180322SJohn Rigby 75fb180322SJohn Rigby /* 76fb180322SJohn Rigby * Nodes to do bus probe on, soc and localbus 77fb180322SJohn Rigby */ 78fb180322SJohn Rigby static struct of_device_id __initdata of_bus_ids[] = { 79fb180322SJohn Rigby { .compatible = "fsl,mpc5121-immr", }, 80fb180322SJohn Rigby { .compatible = "fsl,mpc5121-localbus", }, 81fb180322SJohn Rigby {}, 82fb180322SJohn Rigby }; 83fb180322SJohn Rigby 84fb180322SJohn Rigby void __init mpc512x_declare_of_platform_devices(void) 85fb180322SJohn Rigby { 865b2b6255SAnatolij Gustschin struct device_node *np; 875b2b6255SAnatolij Gustschin 88fb180322SJohn Rigby if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) 89fb180322SJohn Rigby printk(KERN_ERR __FILE__ ": " 90fb180322SJohn Rigby "Error while probing of_platform bus\n"); 915b2b6255SAnatolij Gustschin 925b2b6255SAnatolij Gustschin np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc"); 935b2b6255SAnatolij Gustschin if (np) { 945b2b6255SAnatolij Gustschin of_platform_device_create(np, NULL, NULL); 955b2b6255SAnatolij Gustschin of_node_put(np); 965b2b6255SAnatolij Gustschin } 97fb180322SJohn Rigby } 98fb180322SJohn Rigby 992da8cb6aSAnatolij Gustschin #define DEFAULT_FIFO_SIZE 16 1002da8cb6aSAnatolij Gustschin 1012da8cb6aSAnatolij Gustschin static unsigned int __init get_fifo_size(struct device_node *np, 1022da8cb6aSAnatolij Gustschin char *prop_name) 1032da8cb6aSAnatolij Gustschin { 1042da8cb6aSAnatolij Gustschin const unsigned int *fp; 1052da8cb6aSAnatolij Gustschin 1062da8cb6aSAnatolij Gustschin fp = of_get_property(np, prop_name, NULL); 1072da8cb6aSAnatolij Gustschin if (fp) 1082da8cb6aSAnatolij Gustschin return *fp; 1092da8cb6aSAnatolij Gustschin 1102da8cb6aSAnatolij Gustschin pr_warning("no %s property in %s node, defaulting to %d\n", 1112da8cb6aSAnatolij Gustschin prop_name, np->full_name, DEFAULT_FIFO_SIZE); 1122da8cb6aSAnatolij Gustschin 1132da8cb6aSAnatolij Gustschin return DEFAULT_FIFO_SIZE; 1142da8cb6aSAnatolij Gustschin } 1152da8cb6aSAnatolij Gustschin 1162da8cb6aSAnatolij Gustschin #define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ 1172da8cb6aSAnatolij Gustschin ((u32)(_base) + sizeof(struct mpc52xx_psc))) 1182da8cb6aSAnatolij Gustschin 1192da8cb6aSAnatolij Gustschin /* Init PSC FIFO space for TX and RX slices */ 1202da8cb6aSAnatolij Gustschin void __init mpc512x_psc_fifo_init(void) 1212da8cb6aSAnatolij Gustschin { 1222da8cb6aSAnatolij Gustschin struct device_node *np; 1232da8cb6aSAnatolij Gustschin void __iomem *psc; 1242da8cb6aSAnatolij Gustschin unsigned int tx_fifo_size; 1252da8cb6aSAnatolij Gustschin unsigned int rx_fifo_size; 1262da8cb6aSAnatolij Gustschin int fifobase = 0; /* current fifo address in 32 bit words */ 1272da8cb6aSAnatolij Gustschin 1282da8cb6aSAnatolij Gustschin for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { 1292da8cb6aSAnatolij Gustschin tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); 1302da8cb6aSAnatolij Gustschin rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); 1312da8cb6aSAnatolij Gustschin 1322da8cb6aSAnatolij Gustschin /* size in register is in 4 byte units */ 1332da8cb6aSAnatolij Gustschin tx_fifo_size /= 4; 1342da8cb6aSAnatolij Gustschin rx_fifo_size /= 4; 1352da8cb6aSAnatolij Gustschin if (!tx_fifo_size) 1362da8cb6aSAnatolij Gustschin tx_fifo_size = 1; 1372da8cb6aSAnatolij Gustschin if (!rx_fifo_size) 1382da8cb6aSAnatolij Gustschin rx_fifo_size = 1; 1392da8cb6aSAnatolij Gustschin 1402da8cb6aSAnatolij Gustschin psc = of_iomap(np, 0); 1412da8cb6aSAnatolij Gustschin if (!psc) { 1422da8cb6aSAnatolij Gustschin pr_err("%s: Can't map %s device\n", 1432da8cb6aSAnatolij Gustschin __func__, np->full_name); 1442da8cb6aSAnatolij Gustschin continue; 1452da8cb6aSAnatolij Gustschin } 1462da8cb6aSAnatolij Gustschin 1472da8cb6aSAnatolij Gustschin /* FIFO space is 4KiB, check if requested size is available */ 1482da8cb6aSAnatolij Gustschin if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { 1492da8cb6aSAnatolij Gustschin pr_err("%s: no fifo space available for %s\n", 1502da8cb6aSAnatolij Gustschin __func__, np->full_name); 1512da8cb6aSAnatolij Gustschin iounmap(psc); 1522da8cb6aSAnatolij Gustschin /* 1532da8cb6aSAnatolij Gustschin * chances are that another device requests less 1542da8cb6aSAnatolij Gustschin * fifo space, so we continue. 1552da8cb6aSAnatolij Gustschin */ 1562da8cb6aSAnatolij Gustschin continue; 1572da8cb6aSAnatolij Gustschin } 1582da8cb6aSAnatolij Gustschin 1592da8cb6aSAnatolij Gustschin /* set tx and rx fifo size registers */ 1602da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); 1612da8cb6aSAnatolij Gustschin fifobase += tx_fifo_size; 1622da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); 1632da8cb6aSAnatolij Gustschin fifobase += rx_fifo_size; 1642da8cb6aSAnatolij Gustschin 1652da8cb6aSAnatolij Gustschin /* reset and enable the slices */ 1662da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->txcmd, 0x80); 1672da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->txcmd, 0x01); 1682da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->rxcmd, 0x80); 1692da8cb6aSAnatolij Gustschin out_be32(&FIFOC(psc)->rxcmd, 0x01); 1702da8cb6aSAnatolij Gustschin 1712da8cb6aSAnatolij Gustschin iounmap(psc); 1722da8cb6aSAnatolij Gustschin } 1732da8cb6aSAnatolij Gustschin } 1742da8cb6aSAnatolij Gustschin 175284ed66fSAnatolij Gustschin void __init mpc512x_init(void) 176284ed66fSAnatolij Gustschin { 177284ed66fSAnatolij Gustschin mpc512x_declare_of_platform_devices(); 178284ed66fSAnatolij Gustschin mpc5121_clk_init(); 179a8dbceb7SAnatolij Gustschin mpc512x_restart_init(); 1802da8cb6aSAnatolij Gustschin mpc512x_psc_fifo_init(); 181284ed66fSAnatolij Gustschin } 182