VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   30 Branches   50 Tags
author: Windsome Zeng <windsome.zeng@starfivetech.com> 2023-09-19 16:07:01 +0800 committer: Windsome Zeng <windsome.zeng@starfivetech.com> 2023-09-21 15:10:47 +0800 commit: db4e211cba926489629e40bfabbe4919f0581775 parent: 0a6b3bee70066d2162e4f81975ac5210947f5a41
Commit Summary:
Mosaic cursor: Revert commit 30289b2ca780bcaf7acb1ffe88125a65b7e34577 as it will drop 50% performance. Just do real flush data while cursor is about to change. Other plane: According to the behavior of L2 cache controller in U74, only the last 2MB data is needed to be flushed. For 4K resolution, it will reduce flush loops from 518400 to 32768 on each frame update.
Diffstat:
2 files changed, 42 insertions, 7 deletions
diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c b/drivers/gpu/drm/verisilicon/vs_dc.c
index 9669272208f4..085228bc1323 100644
--- a/drivers/gpu/drm/verisilicon/vs_dc.c
+++ b/drivers/gpu/drm/verisilicon/vs_dc.c
@@ -33,6 +33,15 @@
 #include <linux/mfd/syscon.h>
 //syscon panel
 
+#define CURSOR_MEM_SIZE_32X32 (32*32*4)
+#define CURSOR_MEM_SIZE_64X64 (CURSOR_MEM_SIZE_32X32 << 2)
+static u32 l2_cache_size = 0;
+
+static const struct of_device_id sifive_l2_ids[] = {
+        { .compatible = "sifive,fu740-c000-ccache" },
+        { /* end of table */ },
+};
+
 static inline void update_format(u32 format, u64 mod, struct dc_hw_fb *fb)
 {
 	u8 f = FORMAT_A8R8G8B8;
@@ -644,11 +653,22 @@ static void dc_deinit(struct device *dev)
 
 static int dc_init(struct device *dev)
 {
+	struct device_node *np;
 	struct vs_dc *dc = dev_get_drvdata(dev);
 	int ret;
 
 	dc->first_frame = true;
 
+	np = of_find_matching_node(NULL, sifive_l2_ids);
+        if (!np)
+                return -ENODEV;
+
+	ret = of_property_read_u32(np, "cache-size", &l2_cache_size);
+	if (ret) {
+		dev_err(dev, "failed to get l2 cache size\n");
+		return ret;
+        }
+
 	ret = syscon_panel_parse_dt(dev);
 	if (ret){
 		dev_err(dev,"syscon_panel_parse_dt failed\n");
@@ -1005,11 +1025,26 @@ static void update_fb(struct vs_plane *plane, u8 display_id,
 	update_swizzle(drm_fb->format->format, fb);
 	update_watermark(plane_state->watermark, fb);
 
-	starfive_flush_dcache(fb->y_address, fb->height * fb->y_stride);
-	if (fb->u_address)
-		starfive_flush_dcache(fb->u_address, fb->height * fb->u_stride);
-	if (fb->v_address)
-		starfive_flush_dcache(fb->v_address, fb->height * fb->v_stride);
+	if (fb->enable) {
+		u32 flush_addr, flush_size;
+
+#define FLUSH_FB_PLANE(addr, stride)						\
+		if (addr) {							\
+			flush_addr = addr;					\
+			flush_size = fb->height * stride;			\
+			if (flush_size > l2_cache_size) {			\
+				flush_addr += flush_size - l2_cache_size;	\
+				flush_size = l2_cache_size;			\
+			}							\
+			sifive_l2_flush64_range(flush_addr, flush_size);	\
+		}
+
+		FLUSH_FB_PLANE(fb->y_address, fb->y_stride);
+		FLUSH_FB_PLANE(fb->u_address, fb->u_stride);
+		FLUSH_FB_PLANE(fb->v_address, fb->v_stride);
+
+#undef FLUSH_FB_PLANE
+	}
 
 	plane_state->status.tile_mode = fb->tile_mode;
 }
@@ -1247,6 +1282,7 @@ static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, struct
 									   drm_plane);
 	struct drm_framebuffer *drm_fb = state->fb;
 	struct dc_hw_cursor cursor;
+	static u32 pre_address = 0;
 
 	cursor.address = plane->dma_addr[0];
 	cursor.x = state->crtc_x;
@@ -1257,6 +1293,12 @@ static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, struct
 	update_cursor_size(state, &cursor);
 	cursor.enable = true;
 
+	if (cursor.address != pre_address) {
+		sifive_l2_flush64_range(cursor.address, ((cursor.size == CURSOR_SIZE_32X32) ?
+					CURSOR_MEM_SIZE_32X32 : CURSOR_MEM_SIZE_64X64));
+		pre_address = cursor.address;
+	}
+
 	dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
 }
 
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.c b/drivers/gpu/drm/verisilicon/vs_plane.c
index 48cdf29fc296..8cf5f3b9d965 100755
--- a/drivers/gpu/drm/verisilicon/vs_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_plane.c
@@ -9,7 +9,6 @@
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/vs_drm.h>
-#include <soc/starfive/vic7100.h>
 
 #include "vs_type.h"
 #include "vs_crtc.h"
@@ -290,7 +289,6 @@ static void vs_plane_atomic_update(struct drm_plane *plane,
 
 		vs_obj = vs_fb_get_gem_obj(fb, i);
 		vs_plane->dma_addr[i] = vs_obj->iova + fb->offsets[i];
-		starfive_flush_dcache(vs_plane->dma_addr[i], vs_obj->size);
 	}
 
 	plane_state->status.src = drm_plane_state_src(new_state);