VisionFive2 Linux kernel

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

More than 9999 Commits   30 Branches   50 Tags
author: Andy Hu <andy.hu@starfivetech.com> 2023-09-21 17:49:10 +0800 committer: Andy Hu <andy.hu@starfivetech.com> 2023-09-21 17:49:10 +0800 commit: 40846e71c0bdfa2d9bead9a07d6c068ddbc10102 parent: bcf6f90f838aa5b98617f0faa6d2b0d90c9041b1
Commit Summary:
Merge tag 'JH7110_515_SDK_v5.7.4' into vf2-515-devel
Diffstat:
4 files changed, 53 insertions, 8 deletions
diff --git a/drivers/gpu/drm/verisilicon/inno_hdmi.c b/drivers/gpu/drm/verisilicon/inno_hdmi.c
old mode 100755
new mode 100644
index 854c923bbb2c..051e751cfb9f
--- a/drivers/gpu/drm/verisilicon/inno_hdmi.c
+++ b/drivers/gpu/drm/verisilicon/inno_hdmi.c
@@ -722,7 +722,16 @@ static int
 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
 				       uint32_t maxX, uint32_t maxY)
 {
-	return drm_helper_probe_single_connector_modes(connector, 3840, 2160);
+	struct inno_hdmi *hdmi = to_inno_hdmi(connector);
+
+	int ret = pm_runtime_get_sync(hdmi->dev);
+	if (ret < 0)
+	   return ret;
+
+	ret = drm_helper_probe_single_connector_modes(connector, 3840, 2160);
+
+	pm_runtime_put(hdmi->dev);
+	return ret;
 }
 
 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
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);
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 25e434e68ee1..d02665688f35 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -674,6 +674,8 @@ static int dw8250_runtime_suspend(struct device *dev)
 {
 	struct dw8250_data *data = dev_get_drvdata(dev);
 
+	reset_control_assert(data->rst);
+
 	clk_disable_unprepare(data->clk);
 
 	clk_disable_unprepare(data->pclk);
@@ -689,6 +691,8 @@ static int dw8250_runtime_resume(struct device *dev)
 
 	clk_prepare_enable(data->clk);
 
+	reset_control_deassert(data->rst);
+
 	return 0;
 }
 #endif