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                return 0; /* fall back to L2 cache only */
  95
  96        rem = l2cache_size % sram_params.sram_size;
  97        ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size;
  98        if (rem || (ways & (ways - 1))) {
  99                dev_err(&dev->dev, "Illegal cache-sram-size in command line\n");
 100                return -EINVAL;
 101        }
 102
 103        l2ctlr = of_iomap(dev->dev.of_node, 0);
 104        if (!l2ctlr) {
 105                dev_err(&dev->dev, "Can't map L2 controller\n");
 106                return -EINVAL;
 107        }
 108
 109        /*
 110         * Write bits[0-17] to srbar0
 111         */
 112        out_be32(&l2ctlr->srbar0,
 113                lower_32_bits(sram_params.sram_offset) & L2SRAM_BAR_MSK_LO18);
 114
 115        /*
 116         * Write bits[18-21] to srbare0
 117         */
 118#ifdef CONFIG_PHYS_64BIT
 119        out_be32(&l2ctlr->srbarea0,
 120                upper_32_bits(sram_params.sram_offset) & L2SRAM_BARE_MSK_HI4);
 121#endif
 122
 123        clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI);
 124
 125        switch (ways) {
 126        case LOCK_WAYS_EIGHTH:
 127                setbits32(&l2ctlr->ctl,
 128                        L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH);
 129                break;
 130
 131        case LOCK_WAYS_TWO_EIGHTH:
 132                setbits32(&l2ctlr->ctl,
 133                        L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART);
 134                break;
 135
 136        case LOCK_WAYS_HALF:
 137                setbits32(&l2ctlr->ctl,
 138                        L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF);
 139                break;
 140
 141        case LOCK_WAYS_FULL:
 142        default:
 143                setbits32(&l2ctlr->ctl,
 144                        L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL);
 145                break;
 146        }
 147        eieio();
 148
 149        rval = instantiate_cache_sram(dev, sram_params);
 150        if (rval < 0) {
 151                dev_err(&dev->dev, "Can't instantiate Cache-SRAM\n");
 152                iounmap(l2ctlr);
 153                return -EINVAL;
 154        }
 155
 156        return 0;
 157}
 158
 159static int mpc85xx_l2ctlr_of_remove(struct platform_device *dev)
 160{
 161        BUG_ON(!l2ctlr);
 162
 163        iounmap(l2ctlr);
 164        remove_cache_sram(dev);
 165        dev_info(&dev->dev, "MPC85xx L2 controller unloaded\n");
 166
 167        return 0;
 168}
 169
 170static const struct of_device_id mpc85xx_l2ctlr_of_match[] = {
 171        {
 172                .compatible = "fsl,p2020-l2-cache-controller",
 173        },
 174        {
 175                .compatible = "fsl,p2010-l2-cache-controller",
 176        },
 177        {
 178                .compatible = "fsl,p1020-l2-cache-controller",
 179        },
 180        {
 181                .compatible = "fsl,p1011-l2-cache-controller",
 182        },
 183        {
 184                .compatible = "fsl,p1013-l2-cache-controller",
 185        },
 186        {
 187                .compatible = "fsl,p1022-l2-cache-controller",
 188        },
 189        {
 190                .compatible = "fsl,mpc8548-l2-cache-controller",
 191        },
 192        {       .compatible = "fsl,mpc8544-l2-cache-controller",},
 193        {       .compatible = "fsl,mpc8572-l2-cache-controller",},
 194        {       .compatible = "fsl,mpc8536-l2-cache-controller",},
 195        {       .compatible = "fsl,p1021-l2-cache-controller",},
 196        {       .compatible = "fsl,p1012-l2-cache-controller",},
 197        {       .compatible = "fsl,p1025-l2-cache-controller",},
 198        {       .compatible = "fsl,p1016-l2-cache-controller",},
 199        {       .compatible = "fsl,p1024-l2-cache-controller",},
 200        {       .compatible = "fsl,p1015-l2-cache-controller",},
 201        {       .compatible = "fsl,p1010-l2-cache-controller",},
 202        {       .compatible = "fsl,bsc9131-l2-cache-controller",},
 203        {},
 204};
 205
 206static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = {
 207        .driver = {
 208                .name           = "fsl-l2ctlr",
 209                .of_match_table = mpc85xx_l2ctlr_of_match,
 210        },
 211        .probe          = mpc85xx_l2ctlr_of_probe,
 212        .remove         = mpc85xx_l2ctlr_of_remove,
 213};
 214
 215static __init int mpc85xx_l2ctlr_of_init(void)
 216{
 217        return platform_driver_register(&mpc85xx_l2ctlr_of_platform_driver);
 218}
 219
 220static void __exit mpc85xx_l2ctlr_of_exit(void)
 221{
 222        platform_driver_unregister(&mpc85xx_l2ctlr_of_platform_driver);
 223}
 224
 225subsys_initcall(mpc85xx_l2ctlr_of_init);
 226module_exit(mpc85xx_l2ctlr_of_exit);
 227
 228MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init");
 229MODULE_LICENSE("GPL v2");
 230