diff --git a/arch/riscv/dts/jh7110-u-boot.dtsi b/arch/riscv/dts/jh7110-u-boot.dtsi index 926b063923..1835ff2ec9 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 dc02aad206..62f7129431 100644 --- a/board/starfive/evb/starfive_evb.c +++ b/board/starfive/evb/starfive_evb.c @@ -27,12 +27,14 @@ enum chip_type_t { }; enum cpu_voltage_type_t { - CPU_VOL_1020 = 0x0e, - CPU_VOL_1040 = 0xff, - CPU_VOL_1060 = 0xf0, - CPU_VOL_1080 = 0xf1, - CPU_VOL_1100 = 0xf2, + CPU_VOL_1020 = 0xef0, + CPU_VOL_1040 = 0xfff, + CPU_VOL_1060 = 0xff0, + CPU_VOL_1080 = 0xfe0, + CPU_VOL_1100 = 0xf80, + CPU_VOL_1120 = 0xf00, }; +#define CPU_VOL_MASK 0xfff #define SYS_CLOCK_ENABLE(clk) \ setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK) @@ -212,8 +214,10 @@ static void get_cpu_voltage_type(struct udevice *dev) if (ret != sizeof(buf)) printf("%s: error reading CPU vol from OTP\n", __func__); else { - buf = 0x0e; - switch ((buf & 0xff)) { + switch ((buf & CPU_VOL_MASK)) { + case CPU_VOL_1120: + env_set("cpu_max_vol", "1120000"); + break; case CPU_VOL_1100: env_set("cpu_max_vol", "1100000"); break; @@ -234,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; } diff --git a/include/configs/starfive-evb.h b/include/configs/starfive-evb.h index ffe90264f2..82d0e842b9 100644 --- a/include/configs/starfive-evb.h +++ b/include/configs/starfive-evb.h @@ -120,20 +120,27 @@ "cpu_vol_1100_set=" \ "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1100000>;\0" +#define CPU_VOL_1120_SET \ + "cpu_vol_1120_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1120000>;\0" + #define CPU_VOL_SET \ - "cpu_vol_set=" \ - "if test ${cpu_max_vol} = 1100000; then " \ - "run cpu_vol_1100_set;" \ - "elif test ${cpu_max_vol} = 1080000; then " \ - "run cpu_vol_1080_set;" \ - "elif test ${cpu_max_vol} = 1060000; then " \ - "run cpu_vol_1060_set;" \ - "elif test ${cpu_max_vol} = 1020000; then " \ - "run cpu_vol_1020_set;" \ - "else " \ - "run cpu_vol_1040_set;" \ + "cpu_vol_set=" \ + "if test ${cpu_max_vol} = 1120000; then " \ + "run cpu_vol_1120_set;" \ + "elif test ${cpu_max_vol} = 1100000; then " \ + "run cpu_vol_1100_set;" \ + "elif test ${cpu_max_vol} = 1080000; then " \ + "run cpu_vol_1080_set;" \ + "elif test ${cpu_max_vol} = 1060000; then " \ + "run cpu_vol_1060_set;" \ + "elif test ${cpu_max_vol} = 1020000; then " \ + "run cpu_vol_1020_set;" \ + "else " \ + "run cpu_vol_1040_set;" \ "fi; \0" + #define CHIPA_GMAC_SET \ "chipa_gmac_set=" \ "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x1>;" \ @@ -174,6 +181,7 @@ CPU_VOL_1060_SET \ CPU_VOL_1080_SET \ CPU_VOL_1100_SET \ + CPU_VOL_1120_SET \ CPU_VOL_SET \ "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \