Kaynağa Gözat

Merge tag 'JH7110_515_SDK_v4.7.0' into vf2-devel

version JH7110_515_SDK_v4.7.0 for JH7110 EVB board

1. #3910: u-boot: update cpu voltage set commands per binning information from OTP
2. #4563: u-boot: configure the l2 prefetcher
ah 1 yıl önce
ebeveyn
işleme
656e49f3f7

+ 10 - 0
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>;

+ 11 - 29
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);
 

+ 93 - 0
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;
 }
 

+ 19 - 11
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" \