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>
This commit is contained in:
Dinh Nguyen 2019-04-23 16:55:04 -05:00 committed by Tom Rini
parent 84b124db35
commit 88ebf5830f
3 changed files with 86 additions and 0 deletions

View File

@ -13,4 +13,13 @@ config CACHE
is usually located on the same chip. This uclass can be used for is usually located on the same chip. This uclass can be used for
configuring settings that be found from a device tree file. configuring settings that be found from a device tree file.
config L2X0_CACHE
tristate "PL310 cache driver"
select CACHE
depends on ARM
help
This driver is for the PL310 cache controller commonly found on
ARMv7(32-bit) devices. The driver configures the cache settings
found in the device tree.
endmenu endmenu

View File

@ -1,3 +1,4 @@
obj-$(CONFIG_CACHE) += cache-uclass.o obj-$(CONFIG_CACHE) += cache-uclass.o
obj-$(CONFIG_SANDBOX) += sandbox_cache.o obj-$(CONFIG_SANDBOX) += sandbox_cache.o
obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o

76
drivers/cache/cache-l2x0.c vendored Normal file
View File

@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
*/
#include <common.h>
#include <command.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/pl310.h>
static void l2c310_of_parse_and_init(struct udevice *dev)
{
u32 tag[3] = { 0, 0, 0 };
u32 saved_reg, prefetch;
struct pl310_regs *regs = (struct pl310_regs *)dev_read_addr(dev);
/* Disable the L2 Cache */
clrbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
saved_reg = readl(&regs->pl310_aux_ctrl);
if (!dev_read_u32(dev, "prefetch-data", &prefetch)) {
if (prefetch)
saved_reg |= L310_AUX_CTRL_DATA_PREFETCH_MASK;
else
saved_reg &= ~L310_AUX_CTRL_DATA_PREFETCH_MASK;
}
if (!dev_read_u32(dev, "prefetch-instr", &prefetch)) {
if (prefetch)
saved_reg |= L310_AUX_CTRL_INST_PREFETCH_MASK;
else
saved_reg &= ~L310_AUX_CTRL_INST_PREFETCH_MASK;
}
saved_reg |= dev_read_bool(dev, "arm,shared-override");
writel(saved_reg, &regs->pl310_aux_ctrl);
saved_reg = readl(&regs->pl310_tag_latency_ctrl);
if (!dev_read_u32_array(dev, "arm,tag-latency", tag, 3))
saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
L310_LATENCY_CTRL_WR(tag[1] - 1) |
L310_LATENCY_CTRL_SETUP(tag[2] - 1);
writel(saved_reg, &regs->pl310_tag_latency_ctrl);
saved_reg = readl(&regs->pl310_data_latency_ctrl);
if (!dev_read_u32_array(dev, "arm,data-latency", tag, 3))
saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
L310_LATENCY_CTRL_WR(tag[1] - 1) |
L310_LATENCY_CTRL_SETUP(tag[2] - 1);
writel(saved_reg, &regs->pl310_data_latency_ctrl);
/* Enable the L2 cache */
setbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
}
static int l2x0_probe(struct udevice *dev)
{
l2c310_of_parse_and_init(dev);
return 0;
}
static const struct udevice_id l2x0_ids[] = {
{ .compatible = "arm,pl310-cache" },
{}
};
U_BOOT_DRIVER(pl310_cache) = {
.name = "pl310_cache",
.id = UCLASS_CACHE,
.of_match = l2x0_ids,
.probe = l2x0_probe,
.flags = DM_FLAG_PRE_RELOC,
};