summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv/dts/jh7110-u-boot.dtsi10
-rw-r--r--arch/riscv/dts/jh7110.dtsi2
-rw-r--r--board/starfive/evb/starfive_evb.c40
-rw-r--r--drivers/cache/cache-sifive-ccache.c93
-rwxr-xr-xdrivers/pinctrl/starfive/pinctrl-starfive.c20
-rw-r--r--include/configs/starfive-evb.h30
6 files changed, 153 insertions, 42 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/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi
index cf9a1eebb2..408787334c 100644
--- a/arch/riscv/dts/jh7110.dtsi
+++ b/arch/riscv/dts/jh7110.dtsi
@@ -555,6 +555,7 @@
reg-names = "control";
interrupts = <91>;
interrupt-controller;
+ gpio-controller;
#gpio-cells = <2>;
ngpios = <64>;
status = "okay";
@@ -566,6 +567,7 @@
reg-names = "control";
interrupts = <90>;
interrupt-controller;
+ gpio-controller;
#gpio-cells = <2>;
ngpios = <4>;
status = "okay";
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/drivers/pinctrl/starfive/pinctrl-starfive.c b/drivers/pinctrl/starfive/pinctrl-starfive.c
index 6e69654550..990d7ac526 100755
--- a/drivers/pinctrl/starfive/pinctrl-starfive.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive.c
@@ -275,10 +275,25 @@ const struct pinctrl_ops starfive_pinctrl_ops = {
.pinconf_set = starfive_pinconf_set,
};
+static int starfive_gpio_get_direction(struct udevice *dev, unsigned int off)
+{
+ struct udevice *pdev = dev->parent;
+ struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
+ struct starfive_pinctrl_soc_info *info = priv->info;
+
+ unsigned int offset = 4 * (off / 4);
+ unsigned int shift = 8 * (off % 4);
+ u32 doen = readl(priv->base + info->doen_reg_base + offset);
+
+ doen = (doen >> shift) & info->doen_mask;
+
+ return doen == GPOEN_ENABLE ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
static int starfive_gpio_direction_input(struct udevice *dev, unsigned int off)
{
struct udevice *pdev = dev->parent;
- struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+ struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
struct starfive_pinctrl_soc_info *info = priv->info;
/* enable input and schmitt trigger */
@@ -297,7 +312,7 @@ static int starfive_gpio_direction_output(struct udevice *dev,
unsigned int off, int val)
{
struct udevice *pdev = dev->parent;
- struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+ struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
struct starfive_pinctrl_soc_info *info = priv->info;
if (info->set_one_pinmux)
@@ -365,6 +380,7 @@ static int starfive_gpio_probe(struct udevice *dev)
}
static const struct dm_gpio_ops starfive_gpio_ops = {
+ .get_function = starfive_gpio_get_direction,
.direction_input = starfive_gpio_direction_input,
.direction_output = starfive_gpio_direction_output,
.get_value = starfive_gpio_get_value,
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" \