1 /* 2 * 3 * Utility functions for the Freescale MPC52xx. 4 * 5 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com> 6 * 7 * This file is licensed under the terms of the GNU General Public License 8 * version 2. This program is licensed "as is" without any warranty of any 9 * kind, whether express or implied. 10 * 11 */ 12 13 #undef DEBUG 14 15 #include <linux/kernel.h> 16 17 #include <asm/io.h> 18 #include <asm/prom.h> 19 #include <asm/of_platform.h> 20 #include <asm/mpc52xx.h> 21 22 23 void __iomem * 24 mpc52xx_find_and_map(const char *compatible) 25 { 26 struct device_node *ofn; 27 const u32 *regaddr_p; 28 u64 regaddr64, size64; 29 30 ofn = of_find_compatible_node(NULL, NULL, compatible); 31 if (!ofn) 32 return NULL; 33 34 regaddr_p = of_get_address(ofn, 0, &size64, NULL); 35 if (!regaddr_p) { 36 of_node_put(ofn); 37 return NULL; 38 } 39 40 regaddr64 = of_translate_address(ofn, regaddr_p); 41 42 of_node_put(ofn); 43 44 return ioremap((u32)regaddr64, (u32)size64); 45 } 46 EXPORT_SYMBOL(mpc52xx_find_and_map); 47 48 49 /** 50 * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device 51 * @node: device node 52 * 53 * Returns IPB bus frequency, or 0 if the bus frequency cannot be found. 54 */ 55 unsigned int 56 mpc52xx_find_ipb_freq(struct device_node *node) 57 { 58 struct device_node *np; 59 const unsigned int *p_ipb_freq = NULL; 60 61 of_node_get(node); 62 while (node) { 63 p_ipb_freq = of_get_property(node, "bus-frequency", NULL); 64 if (p_ipb_freq) 65 break; 66 67 np = of_get_parent(node); 68 of_node_put(node); 69 node = np; 70 } 71 if (node) 72 of_node_put(node); 73 74 return p_ipb_freq ? *p_ipb_freq : 0; 75 } 76 EXPORT_SYMBOL(mpc52xx_find_ipb_freq); 77 78 79 void __init 80 mpc52xx_setup_cpu(void) 81 { 82 struct mpc52xx_cdm __iomem *cdm; 83 struct mpc52xx_xlb __iomem *xlb; 84 85 /* Map zones */ 86 cdm = mpc52xx_find_and_map("mpc5200-cdm"); 87 xlb = mpc52xx_find_and_map("mpc5200-xlb"); 88 89 if (!cdm || !xlb) { 90 printk(KERN_ERR __FILE__ ": " 91 "Error while mapping CDM/XLB during mpc52xx_setup_cpu. " 92 "Expect some abnormal behavior\n"); 93 goto unmap_regs; 94 } 95 96 /* Use internal 48 Mhz */ 97 out_8(&cdm->ext_48mhz_en, 0x00); 98 out_8(&cdm->fd_enable, 0x01); 99 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ 100 out_be16(&cdm->fd_counters, 0x0001); 101 else 102 out_be16(&cdm->fd_counters, 0x5555); 103 104 /* Configure the XLB Arbiter priorities */ 105 out_be32(&xlb->master_pri_enable, 0xff); 106 out_be32(&xlb->master_priority, 0x11111111); 107 108 /* Disable XLB pipelining */ 109 /* (cfr errate 292. We could do this only just before ATA PIO 110 transaction and re-enable it afterwards ...) */ 111 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); 112 113 /* Unmap zones */ 114 unmap_regs: 115 if (cdm) iounmap(cdm); 116 if (xlb) iounmap(xlb); 117 } 118 119 void __init 120 mpc52xx_declare_of_platform_devices(void) 121 { 122 /* Find every child of the SOC node and add it to of_platform */ 123 if (of_platform_bus_probe(NULL, NULL, NULL)) 124 printk(KERN_ERR __FILE__ ": " 125 "Error while probing of_platform bus\n"); 126 } 127 128