1/* 2 * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc. 3 * 4 * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation 5 * 6 * Author: Vivek Mahajan <vivek.mahajan@freescale.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23#include <linux/kernel.h> 24#include <linux/module.h> 25#include <linux/of_platform.h> 26#include <asm/io.h> 27 28#include "fsl_85xx_cache_ctlr.h" 29 30static char *sram_size; 31static char *sram_offset; 32struct mpc85xx_l2ctlr __iomem *l2ctlr; 33 34static int get_cache_sram_params(struct sram_parameters *sram_params) 35{ 36 unsigned long long addr; 37 unsigned int size; 38 39 if (!sram_size || (kstrtouint(sram_size, 0, &size) < 0)) 40 return -EINVAL; 41 42 if (!sram_offset || (kstrtoull(sram_offset, 0, &addr) < 0)) 43 return -EINVAL; 44 45 sram_params->sram_offset = addr; 46 sram_params->sram_size = size; 47 48 return 0; 49} 50 51static int __init get_size_from_cmdline(char *str) 52{ 53 if (!str) 54 return 0; 55 56 sram_size = str; 57 return 1; 58} 59 60static int __init get_offset_from_cmdline(char *str) 61{ 62 if (!str) 63 return 0; 64 65 sram_offset = str; 66 return 1; 67} 68 69__setup("cache-sram-size=", get_size_from_cmdline); 70__setup("cache-sram-offset=", get_offset_from_cmdline); 71 72static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev) 73{ 74 long rval; 75 unsigned int rem; 76 unsigned char ways; 77 const unsigned int *prop; 78 unsigned int l2cache_size; 79 struct sram_parameters sram_params; 80 81 if (!dev->dev.of_node) { 82 dev_err(&dev->dev, "Device's OF-node is NULL\n"); 83 return -EINVAL; 84 } 85 86 prop = of_get_property(dev->dev.of_node, "cache-size", NULL); 87 if (!prop) { 88 dev_err(&dev->dev, "Missing L2 cache-size\n"); 89 return -EINVAL; 90 } 91 l2cache_size = *prop; 92 93 if (get_cache_sram_params(&sram_params)) { 94 dev_err(&dev->dev, 95 "Entire L2 as cache, provide valid sram offset and size\n"); 96 return -EINVAL; 97 } 98 99 100 rem = l2cache_size % sram_params.sram_size; 101 ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size; 102 if (rem || (ways & (ways - 1))) { 103 dev_err(&dev->dev, "Illegal cache-sram-size in command line\n"); 104 return -EINVAL; 105 } 106 107 l2ctlr = of_iomap(dev->dev.of_node, 0); 108 if (!l2ctlr) { 109 dev_err(&dev->dev, "Can't map L2 controller\n"); 110 return -EINVAL; 111 } 112 113 /* 114 * Write bits[0-17] to srbar0 115 */ 116 out_be32(&l2ctlr->srbar0, 117 lower_32_bits(sram_params.sram_offset) & L2SRAM_BAR_MSK_LO18); 118 119 /* 120 * Write bits[18-21] to srbare0 121 */ 122#ifdef CONFIG_PHYS_64BIT 123 out_be32(&l2ctlr->srbarea0, 124 upper_32_bits(sram_params.sram_offset) & L2SRAM_BARE_MSK_HI4); 125#endif 126 127 clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); 128 129 switch (ways) { 130 case LOCK_WAYS_EIGHTH: 131 setbits32(&l2ctlr->ctl, 132 L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH); 133 break; 134 135 case LOCK_WAYS_TWO_EIGHTH: 136 setbits32(&l2ctlr->ctl, 137 L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART); 138 break; 139 140 case LOCK_WAYS_HALF: 141 setbits32(&l2ctlr->ctl, 142 L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF); 143 break; 144 145 case LOCK_WAYS_FULL: 146 default: 147 setbits32(&l2ctlr->ctl, 148 L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL); 149 break; 150 } 151 eieio(); 152 153 rval = instantiate_cache_sram(dev, sram_params); 154 if (rval < 0) { 155 dev_err(&dev->dev, "Can't instantiate Cache-SRAM\n"); 156 iounmap(l2ctlr); 157 return -EINVAL; 158 } 159 160 return 0; 161} 162 163static int mpc85xx_l2ctlr_of_remove(struct platform_device *dev) 164{ 165 BUG_ON(!l2ctlr); 166 167 iounmap(l2ctlr); 168 remove_cache_sram(dev); 169 dev_info(&dev->dev, "MPC85xx L2 controller unloaded\n"); 170 171 return 0; 172} 173 174static const struct of_device_id mpc85xx_l2ctlr_of_match[] = { 175 { 176 .compatible = "fsl,p2020-l2-cache-controller", 177 }, 178 { 179 .compatible = "fsl,p2010-l2-cache-controller", 180 }, 181 { 182 .compatible = "fsl,p1020-l2-cache-controller", 183 }, 184 { 185 .compatible = "fsl,p1011-l2-cache-controller", 186 }, 187 { 188 .compatible = "fsl,p1013-l2-cache-controller", 189 }, 190 { 191 .compatible = "fsl,p1022-l2-cache-controller", 192 }, 193 { 194 .compatible = "fsl,mpc8548-l2-cache-controller", 195 }, 196 { .compatible = "fsl,mpc8544-l2-cache-controller",}, 197 { .compatible = "fsl,mpc8572-l2-cache-controller",}, 198 { .compatible = "fsl,mpc8536-l2-cache-controller",}, 199 { .compatible = "fsl,p1021-l2-cache-controller",}, 200 { .compatible = "fsl,p1012-l2-cache-controller",}, 201 { .compatible = "fsl,p1025-l2-cache-controller",}, 202 { .compatible = "fsl,p1016-l2-cache-controller",}, 203 { .compatible = "fsl,p1024-l2-cache-controller",}, 204 { .compatible = "fsl,p1015-l2-cache-controller",}, 205 { .compatible = "fsl,p1010-l2-cache-controller",}, 206 { .compatible = "fsl,bsc9131-l2-cache-controller",}, 207 {}, 208}; 209 210static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = { 211 .driver = { 212 .name = "fsl-l2ctlr", 213 .of_match_table = mpc85xx_l2ctlr_of_match, 214 }, 215 .probe = mpc85xx_l2ctlr_of_probe, 216 .remove = mpc85xx_l2ctlr_of_remove, 217}; 218 219static __init int mpc85xx_l2ctlr_of_init(void) 220{ 221 return platform_driver_register(&mpc85xx_l2ctlr_of_platform_driver); 222} 223 224static void __exit mpc85xx_l2ctlr_of_exit(void) 225{ 226 platform_driver_unregister(&mpc85xx_l2ctlr_of_platform_driver); 227} 228 229subsys_initcall(mpc85xx_l2ctlr_of_init); 230module_exit(mpc85xx_l2ctlr_of_exit); 231 232MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init"); 233MODULE_LICENSE("GPL v2"); 234