diff options
author | andy.hu <andy.hu@starfivetech.com> | 2023-04-07 14:30:48 +0300 |
---|---|---|
committer | andy.hu <andy.hu@starfivetech.com> | 2023-04-07 14:30:48 +0300 |
commit | 6f85c682b9131b9f2723725a070e541361e46072 (patch) | |
tree | 241a3d69d213e867f79da6171398c9bc51e0fac6 | |
parent | 14d90726c4e9b97decca8d26fb235a3953c7d8a8 (diff) | |
parent | 41cad11dbfc69454edf03ba0dc8fb05196bd74a8 (diff) | |
download | u-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.dtsi | 10 | ||||
-rw-r--r-- | board/starfive/evb/starfive_evb.c | 22 | ||||
-rw-r--r-- | drivers/cache/cache-sifive-ccache.c | 93 |
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; } |