summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandy.hu <andy.hu@starfivetech.com>2023-04-07 14:30:48 +0300
committerandy.hu <andy.hu@starfivetech.com>2023-04-07 14:30:48 +0300
commit6f85c682b9131b9f2723725a070e541361e46072 (patch)
tree241a3d69d213e867f79da6171398c9bc51e0fac6
parent14d90726c4e9b97decca8d26fb235a3953c7d8a8 (diff)
parent41cad11dbfc69454edf03ba0dc8fb05196bd74a8 (diff)
downloadu-boot-6f85c682b9131b9f2723725a070e541361e46072.tar.xz
Merge branch 'CR_4563_memcpy_samin.guo' into 'jh7110-master'
CR4563:Configure the l2 prefetcher parameter See merge request sdk/u-boot!48
-rw-r--r--arch/riscv/dts/jh7110-u-boot.dtsi10
-rw-r--r--board/starfive/evb/starfive_evb.c22
-rw-r--r--drivers/cache/cache-sifive-ccache.c93
3 files changed, 103 insertions, 22 deletions
diff --git a/arch/riscv/dts/jh7110-u-boot.dtsi b/arch/riscv/dts/jh7110-u-boot.dtsi
index 21a14bdc4d..e45b6cde3b 100644
--- a/arch/riscv/dts/jh7110-u-boot.dtsi
+++ b/arch/riscv/dts/jh7110-u-boot.dtsi
@@ -71,6 +71,16 @@
};
};
+&cachectrl {
+ reg = <0x0 0x2010000 0x0 0x4000>,
+ <0x0 0x2030000 0x0 0x80000>,
+ <0x0 0x8000000 0x0 0x2000000>;
+ reg-names = "control", "prefetcher", "sideband";
+ prefetch-dist-size = <0x4>;
+ prefetch-hart-mask = <0x1e>;
+ prefetch-enable;
+};
+
&uart0 {
clock-frequency = <24000000>;
current-speed = <115200>;
diff --git a/board/starfive/evb/starfive_evb.c b/board/starfive/evb/starfive_evb.c
index e2e1e9b8a7..62f7129431 100644
--- a/board/starfive/evb/starfive_evb.c
+++ b/board/starfive/evb/starfive_evb.c
@@ -238,32 +238,10 @@ static void get_cpu_voltage_type(struct udevice *dev)
}
#endif
-/*enable U74-mc hart1~hart4 prefetcher*/
-static void enable_prefetcher(void)
-{
- u32 hart;
- u32 *reg;
-#define L2_PREFETCHER_BASE_ADDR 0x2030000
-#define L2_PREFETCHER_OFFSET 0x2000
-
- /*hart1~hart4*/
- for (hart = 1; hart < 5; hart++) {
- reg = (u32 *)((u64)(L2_PREFETCHER_BASE_ADDR
- + hart*L2_PREFETCHER_OFFSET));
-
- mb(); /* memory barrier */
- setbits_le32(reg, 0x1);
- mb(); /* memory barrier */
- }
-}
-
int board_init(void)
{
enable_caches();
- /*enable hart1-hart4 prefetcher*/
- enable_prefetcher();
-
jh7110_timer_init();
jh7110_usb_init(true);
diff --git a/drivers/cache/cache-sifive-ccache.c b/drivers/cache/cache-sifive-ccache.c
index 76c0ab26ae..5e6d3a58af 100644
--- a/drivers/cache/cache-sifive-ccache.c
+++ b/drivers/cache/cache-sifive-ccache.c
@@ -15,10 +15,96 @@
#define SIFIVE_CCACHE_WAY_ENABLE 0x008
+
+/* Prefetch */
+#define SIFIVE_PREFET_HARD_BASE(hart) ((hart)*0x2000)
+/* Prefetch Control Register */
+#define SIFIVE_PREFT_EN_MASK BIT(0)
+#define SIFIVE_PREFT_CROSS_PAGE_DIS_MASK BIT(1)
+#define SIFIVE_PREFT_DIST_MASK GENMASK(7, 2)
+#define SIFIVE_PREFT_MAX_ALLOC_DIST_MASK GENMASK(13, 8)
+#define SIFIVE_PREFT_LIN_TO_EXP_THRD_MASK GENMASK(19, 14)
+#define SIFIVE_PREFT_AGE_OUT_EN_MASK BIT(20)
+#define SIFIVE_PREFT_NUM_LDS_AGE_OUT_MASK GENMASK(27, 21)
+#define SIFIVE_PREFT_CROSS_PAGE_EN_MASK BIT(28)
+
+/* Prefetch Advanced Control Register */
+#define SIFIVE_PREFT_ADV_Q_FULL_THRD GENMASK(3, 0)
+#define SIFIVE_PREFT_ADV_HIT_CACHE_THRD GENMASK(8, 4)
+#define SIFIVE_PREFT_ADV_HIT_MSHR_THRD GENMASK(12, 9)
+#define SIFIVE_PREFT_ADV_WINDOW_MASK GENMASK(18, 13)
+
+#define SIFIVE_PREFET_HARD_MASK 0x1e
+#define SIFIVE_MAX_HART_ID 0x20
+#define SIFIVE_PREFT_DIST_VAL 0x3
+#define SIFIVE_PREFT_DIST_MAX 0x3f
+#define SIFIVE_PREFT_EN 0x1
+
struct sifive_ccache {
void __iomem *base;
+ void __iomem *pre_base;
+ u32 pre_hart_mask;
+ u32 pre_dist_size;
};
+static int sifive_prefetcher_parse(struct udevice *dev)
+{
+ struct sifive_ccache *priv = dev_get_priv(dev);
+
+ if (!priv->pre_base)
+ return -EINVAL;
+
+ if (!dev_read_bool(dev, "prefetch-enable"))
+ return -ENOENT;
+
+ priv->pre_hart_mask = dev_read_u32_default(dev, "prefetch-hart-mask",
+ SIFIVE_PREFET_HARD_MASK);
+ priv->pre_dist_size = dev_read_u32_default(dev, "prefetch-dist-size",
+ SIFIVE_PREFT_DIST_VAL);
+ return 0;
+}
+
+static void sifive_prefetcher_cfg_by_id(struct udevice *dev, u32 hart)
+{
+ struct sifive_ccache *priv = dev_get_priv(dev);
+ void __iomem *reg;
+ u32 val;
+
+ /* Prefetch Control Register */
+ reg = priv->pre_base + SIFIVE_PREFET_HARD_BASE(hart);
+
+ val = readl(reg);
+ val &= ~SIFIVE_PREFT_MAX_ALLOC_DIST_MASK;
+ val |= SIFIVE_PREFT_DIST_MAX << __ffs(SIFIVE_PREFT_MAX_ALLOC_DIST_MASK);
+ writel(val, reg);
+
+ val = readl(reg);
+ val &= ~SIFIVE_PREFT_DIST_MASK;
+ val |= priv->pre_dist_size << __ffs(SIFIVE_PREFT_DIST_MASK);
+ writel(val, reg);
+
+ val |= SIFIVE_PREFT_EN << __ffs(SIFIVE_PREFT_EN_MASK);
+ writel(val, reg);
+}
+
+static int sifive_prefetcher_enable(struct udevice *dev)
+{
+ struct sifive_ccache *priv = dev_get_priv(dev);
+ u32 hart;
+ int ret;
+
+ ret = sifive_prefetcher_parse(dev);
+ if (ret)
+ return ret;
+
+ for (hart = 0; hart < SIFIVE_MAX_HART_ID; hart++) {
+ if (BIT(hart) & priv->pre_hart_mask)
+ sifive_prefetcher_cfg_by_id(dev, hart);
+ }
+
+ return 0;
+}
+
static int sifive_ccache_enable(struct udevice *dev)
{
struct sifive_ccache *priv = dev_get_priv(dev);
@@ -31,6 +117,8 @@ static int sifive_ccache_enable(struct udevice *dev)
writel(ways - 1, priv->base + SIFIVE_CCACHE_WAY_ENABLE);
+ sifive_prefetcher_enable(dev);
+
return 0;
}
@@ -51,11 +139,16 @@ static const struct cache_ops sifive_ccache_ops = {
static int sifive_ccache_probe(struct udevice *dev)
{
struct sifive_ccache *priv = dev_get_priv(dev);
+ fdt_addr_t addr;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -EINVAL;
+ addr = dev_read_addr_name(dev, "prefetcher");
+ if (addr != FDT_ADDR_T_NONE)
+ priv->pre_base = (void *)(uintptr_t)addr;
+
return 0;
}