linux/drivers/bus/arm-cci.c
<<
>>
Prefs
   1/*
   2 * CCI cache coherent interconnect driver
   3 *
   4 * Copyright (C) 2013 ARM Ltd.
   5 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  12 * kind, whether express or implied; without even the implied warranty
  13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/arm-cci.h>
  18#include <linux/io.h>
  19#include <linux/module.h>
  20#include <linux/of_address.h>
  21#include <linux/slab.h>
  22
  23#include <asm/cacheflush.h>
  24#include <asm/smp_plat.h>
  25
  26#define CCI_PORT_CTRL           0x0
  27#define CCI_CTRL_STATUS         0xc
  28
  29#define CCI_ENABLE_SNOOP_REQ    0x1
  30#define CCI_ENABLE_DVM_REQ      0x2
  31#define CCI_ENABLE_REQ          (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
  32
  33struct cci_nb_ports {
  34        unsigned int nb_ace;
  35        unsigned int nb_ace_lite;
  36};
  37
  38enum cci_ace_port_type {
  39        ACE_INVALID_PORT = 0x0,
  40        ACE_PORT,
  41        ACE_LITE_PORT,
  42};
  43
  44struct cci_ace_port {
  45        void __iomem *base;
  46        unsigned long phys;
  47        enum cci_ace_port_type type;
  48        struct device_node *dn;
  49};
  50
  51static struct cci_ace_port *ports;
  52static unsigned int nb_cci_ports;
  53
  54static void __iomem *cci_ctrl_base;
  55static unsigned long cci_ctrl_phys;
  56
  57struct cpu_port {
  58        u64 mpidr;
  59        u32 port;
  60};
  61
  62/*
  63 * Use the port MSB as valid flag, shift can be made dynamic
  64 * by computing number of bits required for port indexes.
  65 * Code disabling CCI cpu ports runs with D-cache invalidated
  66 * and SCTLR bit clear so data accesses must be kept to a minimum
  67 * to improve performance; for now shift is left static to
  68 * avoid one more data access while disabling the CCI port.
  69 */
  70#define PORT_VALID_SHIFT        31
  71#define PORT_VALID              (0x1 << PORT_VALID_SHIFT)
  72
  73static inline void init_cpu_port(struct cpu_port *port, u32 index, u64 mpidr)
  74{
  75        port->port = PORT_VALID | index;
  76        port->mpidr = mpidr;
  77}
  78
  79static inline bool cpu_port_is_valid(struct cpu_port *port)
  80{
  81        return !!(port->port & PORT_VALID);
  82}
  83
  84static inline bool cpu_port_match(struct cpu_port *port, u64 mpidr)
  85{
  86        return port->mpidr == (mpidr & MPIDR_HWID_BITMASK);
  87}
  88
  89static struct cpu_port cpu_port[NR_CPUS];
  90
  91/**
  92 * __cci_ace_get_port - Function to retrieve the port index connected to
  93 *                      a cpu or device.
  94 *
  95 * @dn: device node of the device to look-up
  96 * @type: port type
  97 *
  98 * Return value:
  99 *      - CCI port index if success
 100 *      - -ENODEV if failure
 101 */
 102static int __cci_ace_get_port(struct device_node *dn, int type)
 103{
 104        int i;
 105        bool ace_match;
 106        struct device_node *cci_portn;
 107
 108        cci_portn = of_parse_phandle(dn, "cci-control-port", 0);
 109        for (i = 0; i < nb_cci_ports; i++) {
 110                ace_match = ports[i].type == type;
 111                if (ace_match && cci_portn == ports[i].dn)
 112                        return i;
 113        }
 114        return -ENODEV;
 115}
 116
 117int cci_ace_get_port(struct device_node *dn)
 118{
 119        return __cci_ace_get_port(dn, ACE_LITE_PORT);
 120}
 121EXPORT_SYMBOL_GPL(cci_ace_get_port);
 122
 123static void __init cci_ace_init_ports(void)
 124{
 125        int port, cpu;
 126        struct device_node *cpun;
 127
 128        /*
 129         * Port index look-up speeds up the function disabling ports by CPU,
 130         * since the logical to port index mapping is done once and does
 131         * not change after system boot.
 132         * The stashed index array is initialized for all possible CPUs
 133         * at probe time.
 134         */
 135        for_each_possible_cpu(cpu) {
 136                /* too early to use cpu->of_node */
 137                cpun = of_get_cpu_node(cpu, NULL);
 138
 139                if (WARN(!cpun, "Missing cpu device node\n"))
 140                        continue;
 141
 142                port = __cci_ace_get_port(cpun, ACE_PORT);
 143                if (port < 0)
 144                        continue;
 145
 146                init_cpu_port(&cpu_port[cpu], port, cpu_logical_map(cpu));
 147        }
 148
 149        for_each_possible_cpu(cpu) {
 150                WARN(!cpu_port_is_valid(&cpu_port[cpu]),
 151                        "CPU %u does not have an associated CCI port\n",
 152                        cpu);
 153        }
 154}
 155/*
 156 * Functions to enable/disable a CCI interconnect slave port
 157 *
 158 * They are called by low-level power management code to disable slave
 159 * interfaces snoops and DVM broadcast.
 160 * Since they may execute with cache data allocation disabled and
 161 * after the caches have been cleaned and invalidated the functions provide
 162 * no explicit locking since they may run with D-cache disabled, so normal
 163 * cacheable kernel locks based on ldrex/strex may not work.
 164 * Locking has to be provided by BSP implementations to ensure proper
 165 * operations.
 166 */
 167
 168/**
 169 * cci_port_control() - function to control a CCI port
 170 *
 171 * @port: index of the port to setup
 172 * @enable: if true enables the port, if false disables it
 173 */
 174static void notrace cci_port_control(unsigned int port, bool enable)
 175{
 176        void __iomem *base = ports[port].base;
 177
 178        writel_relaxed(enable ? CCI_ENABLE_REQ : 0, base + CCI_PORT_CTRL);
 179        /*
 180         * This function is called from power down procedures
 181         * and must not execute any instruction that might
 182         * cause the processor to be put in a quiescent state
 183         * (eg wfi). Hence, cpu_relax() can not be added to this
 184         * read loop to optimize power, since it might hide possibly
 185         * disruptive operations.
 186         */
 187        while (readl_relaxed(cci_ctrl_base + CCI_CTRL_STATUS) & 0x1)
 188                        ;
 189}
 190
 191/**
 192 * cci_disable_port_by_cpu() - function to disable a CCI port by CPU
 193 *                             reference
 194 *
 195 * @mpidr: mpidr of the CPU whose CCI port should be disabled
 196 *
 197 * Disabling a CCI port for a CPU implies disabling the CCI port
 198 * controlling that CPU cluster. Code disabling CPU CCI ports
 199 * must make sure that the CPU running the code is the last active CPU
 200 * in the cluster ie all other CPUs are quiescent in a low power state.
 201 *
 202 * Return:
 203 *      0 on success
 204 *      -ENODEV on port look-up failure
 205 */
 206int notrace cci_disable_port_by_cpu(u64 mpidr)
 207{
 208        int cpu;
 209        bool is_valid;
 210        for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
 211                is_valid = cpu_port_is_valid(&cpu_port[cpu]);
 212                if (is_valid && cpu_port_match(&cpu_port[cpu], mpidr)) {
 213                        cci_port_control(cpu_port[cpu].port, false);
 214                        return 0;
 215                }
 216        }
 217        return -ENODEV;
 218}
 219EXPORT_SYMBOL_GPL(cci_disable_port_by_cpu);
 220
 221/**
 222 * cci_enable_port_for_self() - enable a CCI port for calling CPU
 223 *
 224 * Enabling a CCI port for the calling CPU implies enabling the CCI
 225 * port controlling that CPU's cluster. Caller must make sure that the
 226 * CPU running the code is the first active CPU in the cluster and all
 227 * other CPUs are quiescent in a low power state  or waiting for this CPU
 228 * to complete the CCI initialization.
 229 *
 230 * Because this is called when the MMU is still off and with no stack,
 231 * the code must be position independent and ideally rely on callee
 232 * clobbered registers only.  To achieve this we must code this function
 233 * entirely in assembler.
 234 *
 235 * On success this returns with the proper CCI port enabled.  In case of
 236 * any failure this never returns as the inability to enable the CCI is
 237 * fatal and there is no possible recovery at this stage.
 238 */
 239asmlinkage void __naked cci_enable_port_for_self(void)
 240{
 241        asm volatile ("\n"
 242"       .arch armv7-a\n"
 243"       mrc     p15, 0, r0, c0, c0, 5   @ get MPIDR value \n"
 244"       and     r0, r0, #"__stringify(MPIDR_HWID_BITMASK)" \n"
 245"       adr     r1, 5f \n"
 246"       ldr     r2, [r1] \n"
 247"       add     r1, r1, r2              @ &cpu_port \n"
 248"       add     ip, r1, %[sizeof_cpu_port] \n"
 249
 250        /* Loop over the cpu_port array looking for a matching MPIDR */
 251"1:     ldr     r2, [r1, %[offsetof_cpu_port_mpidr_lsb]] \n"
 252"       cmp     r2, r0                  @ compare MPIDR \n"
 253"       bne     2f \n"
 254
 255        /* Found a match, now test port validity */
 256"       ldr     r3, [r1, %[offsetof_cpu_port_port]] \n"
 257"       tst     r3, #"__stringify(PORT_VALID)" \n"
 258"       bne     3f \n"
 259
 260        /* no match, loop with the next cpu_port entry */
 261"2:     add     r1, r1, %[sizeof_struct_cpu_port] \n"
 262"       cmp     r1, ip                  @ done? \n"
 263"       blo     1b \n"
 264
 265        /* CCI port not found -- cheaply try to stall this CPU */
 266"cci_port_not_found: \n"
 267"       wfi \n"
 268"       wfe \n"
 269"       b       cci_port_not_found \n"
 270
 271        /* Use matched port index to look up the corresponding ports entry */
 272"3:     bic     r3, r3, #"__stringify(PORT_VALID)" \n"
 273"       adr     r0, 6f \n"
 274"       ldmia   r0, {r1, r2} \n"
 275"       sub     r1, r1, r0              @ virt - phys \n"
 276"       ldr     r0, [r0, r2]            @ *(&ports) \n"
 277"       mov     r2, %[sizeof_struct_ace_port] \n"
 278"       mla     r0, r2, r3, r0          @ &ports[index] \n"
 279"       sub     r0, r0, r1              @ virt_to_phys() \n"
 280
 281        /* Enable the CCI port */
 282"       ldr     r0, [r0, %[offsetof_port_phys]] \n"
 283"       mov     r3, #"__stringify(CCI_ENABLE_REQ)" \n"
 284"       str     r3, [r0, #"__stringify(CCI_PORT_CTRL)"] \n"
 285
 286        /* poll the status reg for completion */
 287"       adr     r1, 7f \n"
 288"       ldr     r0, [r1] \n"
 289"       ldr     r0, [r0, r1]            @ cci_ctrl_base \n"
 290"4:     ldr     r1, [r0, #"__stringify(CCI_CTRL_STATUS)"] \n"
 291"       tst     r1, #1 \n"
 292"       bne     4b \n"
 293
 294"       mov     r0, #0 \n"
 295"       bx      lr \n"
 296
 297"       .align  2 \n"
 298"5:     .word   cpu_port - . \n"
 299"6:     .word   . \n"
 300"       .word   ports - 6b \n"
 301"7:     .word   cci_ctrl_phys - . \n"
 302        : :
 303        [sizeof_cpu_port] "i" (sizeof(cpu_port)),
 304#ifndef __ARMEB__
 305        [offsetof_cpu_port_mpidr_lsb] "i" (offsetof(struct cpu_port, mpidr)),
 306#else
 307        [offsetof_cpu_port_mpidr_lsb] "i" (offsetof(struct cpu_port, mpidr)+4),
 308#endif
 309        [offsetof_cpu_port_port] "i" (offsetof(struct cpu_port, port)),
 310        [sizeof_struct_cpu_port] "i" (sizeof(struct cpu_port)),
 311        [sizeof_struct_ace_port] "i" (sizeof(struct cci_ace_port)),
 312        [offsetof_port_phys] "i" (offsetof(struct cci_ace_port, phys)) );
 313
 314        unreachable();
 315}
 316
 317/**
 318 * __cci_control_port_by_device() - function to control a CCI port by device
 319 *                                  reference
 320 *
 321 * @dn: device node pointer of the device whose CCI port should be
 322 *      controlled
 323 * @enable: if true enables the port, if false disables it
 324 *
 325 * Return:
 326 *      0 on success
 327 *      -ENODEV on port look-up failure
 328 */
 329int notrace __cci_control_port_by_device(struct device_node *dn, bool enable)
 330{
 331        int port;
 332
 333        if (!dn)
 334                return -ENODEV;
 335
 336        port = __cci_ace_get_port(dn, ACE_LITE_PORT);
 337        if (WARN_ONCE(port < 0, "node %s ACE lite port look-up failure\n",
 338                                dn->full_name))
 339                return -ENODEV;
 340        cci_port_control(port, enable);
 341        return 0;
 342}
 343EXPORT_SYMBOL_GPL(__cci_control_port_by_device);
 344
 345/**
 346 * __cci_control_port_by_index() - function to control a CCI port by port index
 347 *
 348 * @port: port index previously retrieved with cci_ace_get_port()
 349 * @enable: if true enables the port, if false disables it
 350 *
 351 * Return:
 352 *      0 on success
 353 *      -ENODEV on port index out of range
 354 *      -EPERM if operation carried out on an ACE PORT
 355 */
 356int notrace __cci_control_port_by_index(u32 port, bool enable)
 357{
 358        if (port >= nb_cci_ports || ports[port].type == ACE_INVALID_PORT)
 359                return -ENODEV;
 360        /*
 361         * CCI control for ports connected to CPUS is extremely fragile
 362         * and must be made to go through a specific and controlled
 363         * interface (ie cci_disable_port_by_cpu(); control by general purpose
 364         * indexing is therefore disabled for ACE ports.
 365         */
 366        if (ports[port].type == ACE_PORT)
 367                return -EPERM;
 368
 369        cci_port_control(port, enable);
 370        return 0;
 371}
 372EXPORT_SYMBOL_GPL(__cci_control_port_by_index);
 373
 374static const struct cci_nb_ports cci400_ports = {
 375        .nb_ace = 2,
 376        .nb_ace_lite = 3
 377};
 378
 379static const struct of_device_id arm_cci_matches[] = {
 380        {.compatible = "arm,cci-400", .data = &cci400_ports },
 381        {},
 382};
 383
 384static const struct of_device_id arm_cci_ctrl_if_matches[] = {
 385        {.compatible = "arm,cci-400-ctrl-if", },
 386        {},
 387};
 388
 389static int __init cci_probe(void)
 390{
 391        struct cci_nb_ports const *cci_config;
 392        int ret, i, nb_ace = 0, nb_ace_lite = 0;
 393        struct device_node *np, *cp;
 394        struct resource res;
 395        const char *match_str;
 396        bool is_ace;
 397
 398        np = of_find_matching_node(NULL, arm_cci_matches);
 399        if (!np)
 400                return -ENODEV;
 401
 402        cci_config = of_match_node(arm_cci_matches, np)->data;
 403        if (!cci_config)
 404                return -ENODEV;
 405
 406        nb_cci_ports = cci_config->nb_ace + cci_config->nb_ace_lite;
 407
 408        ports = kcalloc(sizeof(*ports), nb_cci_ports, GFP_KERNEL);
 409        if (!ports)
 410                return -ENOMEM;
 411
 412        ret = of_address_to_resource(np, 0, &res);
 413        if (!ret) {
 414                cci_ctrl_base = ioremap(res.start, resource_size(&res));
 415                cci_ctrl_phys = res.start;
 416        }
 417        if (ret || !cci_ctrl_base) {
 418                WARN(1, "unable to ioremap CCI ctrl\n");
 419                ret = -ENXIO;
 420                goto memalloc_err;
 421        }
 422
 423        for_each_child_of_node(np, cp) {
 424                if (!of_match_node(arm_cci_ctrl_if_matches, cp))
 425                        continue;
 426
 427                i = nb_ace + nb_ace_lite;
 428
 429                if (i >= nb_cci_ports)
 430                        break;
 431
 432                if (of_property_read_string(cp, "interface-type",
 433                                        &match_str)) {
 434                        WARN(1, "node %s missing interface-type property\n",
 435                                  cp->full_name);
 436                        continue;
 437                }
 438                is_ace = strcmp(match_str, "ace") == 0;
 439                if (!is_ace && strcmp(match_str, "ace-lite")) {
 440                        WARN(1, "node %s containing invalid interface-type property, skipping it\n",
 441                                        cp->full_name);
 442                        continue;
 443                }
 444
 445                ret = of_address_to_resource(cp, 0, &res);
 446                if (!ret) {
 447                        ports[i].base = ioremap(res.start, resource_size(&res));
 448                        ports[i].phys = res.start;
 449                }
 450                if (ret || !ports[i].base) {
 451                        WARN(1, "unable to ioremap CCI port %d\n", i);
 452                        continue;
 453                }
 454
 455                if (is_ace) {
 456                        if (WARN_ON(nb_ace >= cci_config->nb_ace))
 457                                continue;
 458                        ports[i].type = ACE_PORT;
 459                        ++nb_ace;
 460                } else {
 461                        if (WARN_ON(nb_ace_lite >= cci_config->nb_ace_lite))
 462                                continue;
 463                        ports[i].type = ACE_LITE_PORT;
 464                        ++nb_ace_lite;
 465                }
 466                ports[i].dn = cp;
 467        }
 468
 469         /* initialize a stashed array of ACE ports to speed-up look-up */
 470        cci_ace_init_ports();
 471
 472        /*
 473         * Multi-cluster systems may need this data when non-coherent, during
 474         * cluster power-up/power-down. Make sure it reaches main memory.
 475         */
 476        sync_cache_w(&cci_ctrl_base);
 477        sync_cache_w(&cci_ctrl_phys);
 478        sync_cache_w(&ports);
 479        sync_cache_w(&cpu_port);
 480        __sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports);
 481        pr_info("ARM CCI driver probed\n");
 482        return 0;
 483
 484memalloc_err:
 485
 486        kfree(ports);
 487        return ret;
 488}
 489
 490static int cci_init_status = -EAGAIN;
 491static DEFINE_MUTEX(cci_probing);
 492
 493static int __init cci_init(void)
 494{
 495        if (cci_init_status != -EAGAIN)
 496                return cci_init_status;
 497
 498        mutex_lock(&cci_probing);
 499        if (cci_init_status == -EAGAIN)
 500                cci_init_status = cci_probe();
 501        mutex_unlock(&cci_probing);
 502        return cci_init_status;
 503}
 504
 505/*
 506 * To sort out early init calls ordering a helper function is provided to
 507 * check if the CCI driver has beed initialized. Function check if the driver
 508 * has been initialized, if not it calls the init function that probes
 509 * the driver and updates the return value.
 510 */
 511bool __init cci_probed(void)
 512{
 513        return cci_init() == 0;
 514}
 515EXPORT_SYMBOL_GPL(cci_probed);
 516
 517early_initcall(cci_init);
 518MODULE_LICENSE("GPL");
 519MODULE_DESCRIPTION("ARM CCI support");
 520
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.