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