Commit 88ebf5830fe25cfdfbbee726cb36ea71b111173a

Authored by Dinh Nguyen
Committed by Tom Rini
1 parent 84b124db35

dm: cache: add the pl310 cache controller driver

Add a PL310 cache controller driver that is usually found on
ARMv7(32-bit) devices. The driver configures the cache settings that can
be found in the device tree files.

This initial revision only configures basic settings(data & instruction
prefetch, shared-override, data & tag latency). I believe these are the
settings that affect performance the most. Comprehensive settings can be
done by the OS.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>

Showing 3 changed files with 86 additions and 0 deletions Side-by-side Diff

drivers/cache/Kconfig
... ... @@ -13,5 +13,14 @@
13 13 is usually located on the same chip. This uclass can be used for
14 14 configuring settings that be found from a device tree file.
15 15  
  16 +config L2X0_CACHE
  17 + tristate "PL310 cache driver"
  18 + select CACHE
  19 + depends on ARM
  20 + help
  21 + This driver is for the PL310 cache controller commonly found on
  22 + ARMv7(32-bit) devices. The driver configures the cache settings
  23 + found in the device tree.
  24 +
16 25 endmenu
drivers/cache/Makefile
1 1  
2 2 obj-$(CONFIG_CACHE) += cache-uclass.o
3 3 obj-$(CONFIG_SANDBOX) += sandbox_cache.o
  4 +obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o
drivers/cache/cache-l2x0.c
  1 +// SPDX-License-Identifier: GPL-2.0
  2 +/*
  3 + * Copyright (C) 2019 Intel Corporation <www.intel.com>
  4 + */
  5 +#include <common.h>
  6 +#include <command.h>
  7 +#include <dm.h>
  8 +
  9 +#include <asm/io.h>
  10 +#include <asm/pl310.h>
  11 +
  12 +static void l2c310_of_parse_and_init(struct udevice *dev)
  13 +{
  14 + u32 tag[3] = { 0, 0, 0 };
  15 + u32 saved_reg, prefetch;
  16 + struct pl310_regs *regs = (struct pl310_regs *)dev_read_addr(dev);
  17 +
  18 + /* Disable the L2 Cache */
  19 + clrbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
  20 +
  21 + saved_reg = readl(&regs->pl310_aux_ctrl);
  22 + if (!dev_read_u32(dev, "prefetch-data", &prefetch)) {
  23 + if (prefetch)
  24 + saved_reg |= L310_AUX_CTRL_DATA_PREFETCH_MASK;
  25 + else
  26 + saved_reg &= ~L310_AUX_CTRL_DATA_PREFETCH_MASK;
  27 + }
  28 +
  29 + if (!dev_read_u32(dev, "prefetch-instr", &prefetch)) {
  30 + if (prefetch)
  31 + saved_reg |= L310_AUX_CTRL_INST_PREFETCH_MASK;
  32 + else
  33 + saved_reg &= ~L310_AUX_CTRL_INST_PREFETCH_MASK;
  34 + }
  35 +
  36 + saved_reg |= dev_read_bool(dev, "arm,shared-override");
  37 + writel(saved_reg, &regs->pl310_aux_ctrl);
  38 +
  39 + saved_reg = readl(&regs->pl310_tag_latency_ctrl);
  40 + if (!dev_read_u32_array(dev, "arm,tag-latency", tag, 3))
  41 + saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
  42 + L310_LATENCY_CTRL_WR(tag[1] - 1) |
  43 + L310_LATENCY_CTRL_SETUP(tag[2] - 1);
  44 + writel(saved_reg, &regs->pl310_tag_latency_ctrl);
  45 +
  46 + saved_reg = readl(&regs->pl310_data_latency_ctrl);
  47 + if (!dev_read_u32_array(dev, "arm,data-latency", tag, 3))
  48 + saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
  49 + L310_LATENCY_CTRL_WR(tag[1] - 1) |
  50 + L310_LATENCY_CTRL_SETUP(tag[2] - 1);
  51 + writel(saved_reg, &regs->pl310_data_latency_ctrl);
  52 +
  53 + /* Enable the L2 cache */
  54 + setbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
  55 +}
  56 +
  57 +static int l2x0_probe(struct udevice *dev)
  58 +{
  59 + l2c310_of_parse_and_init(dev);
  60 +
  61 + return 0;
  62 +}
  63 +
  64 +
  65 +static const struct udevice_id l2x0_ids[] = {
  66 + { .compatible = "arm,pl310-cache" },
  67 + {}
  68 +};
  69 +
  70 +U_BOOT_DRIVER(pl310_cache) = {
  71 + .name = "pl310_cache",
  72 + .id = UCLASS_CACHE,
  73 + .of_match = l2x0_ids,
  74 + .probe = l2x0_probe,
  75 + .flags = DM_FLAG_PRE_RELOC,
  76 +};