linux/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
<<
>>
Prefs
   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 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                .owner          = THIS_MODULE,
 214                .of_match_table = mpc85xx_l2ctlr_of_match,
 215        },
 216        .probe          = mpc85xx_l2ctlr_of_probe,
 217        .remove         = mpc85xx_l2ctlr_of_remove,
 218};
 219
 220static __init int mpc85xx_l2ctlr_of_init(void)
 221{
 222        return platform_driver_register(&mpc85xx_l2ctlr_of_platform_driver);
 223}
 224
 225static void __exit mpc85xx_l2ctlr_of_exit(void)
 226{
 227        platform_driver_unregister(&mpc85xx_l2ctlr_of_platform_driver);
 228}
 229
 230subsys_initcall(mpc85xx_l2ctlr_of_init);
 231module_exit(mpc85xx_l2ctlr_of_exit);
 232
 233MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init");
 234MODULE_LICENSE("GPL v2");
 235