VisionFive2 Linux kernel

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

More than 9999 Commits   29 Branches   45 Tags
author: Andy Hu <andy.hu@starfivetech.com> 2023-11-16 19:55:09 +0800 committer: Andy Hu <andy.hu@starfivetech.com> 2023-11-16 19:55:09 +0800 commit: e5249867764fc4b6fe1ca526eefff36f26389779 parent: bd3bbf384e103d40ae3b4221333d6188c9818954
Commit Summary:
Merge tag 'JH7110_515_SDK_v5.9.2' into vf2-515-devel
Diffstat:
6 files changed, 181 insertions, 183 deletions
diff --git a/drivers/gpu/drm/verisilicon/inno_hdmi.c b/drivers/gpu/drm/verisilicon/inno_hdmi.c
index 051e751cfb9f..804b25cde83f 100644
--- a/drivers/gpu/drm/verisilicon/inno_hdmi.c
+++ b/drivers/gpu/drm/verisilicon/inno_hdmi.c
@@ -385,105 +385,11 @@ static int inno_hdmi_phy_clk_set_rate(struct inno_hdmi *hdmi,unsigned long rate)
 	for (; hdmi->post_cfg->tmdsclock != 0; hdmi->post_cfg++)
 		if (tmdsclock <= hdmi->post_cfg->tmdsclock)
 			break;
-	mdelay(100);
 
 	dev_info(hdmi->dev, "%s hdmi->pre_cfg->pixclock = %lu\n",__func__, hdmi->pre_cfg->pixclock);
 
 	inno_hdmi_config_pll(hdmi);
 
-#if 0 //pre pll + post pll configire
-
-	/*pre-pll power down*/
-	hdmi_modb(hdmi, 0x1a0, INNO_PRE_PLL_POWER_DOWN, INNO_PRE_PLL_POWER_DOWN);
-
-	/* Configure pre-pll */
-	hdmi_modb(hdmi, 0x1a0, INNO_PCLK_VCO_DIV_5_MASK, INNO_PCLK_VCO_DIV_5(hdmi->pre_cfg->vco_div_5_en));
-	hdmi_writeb(hdmi, 0x1a1, INNO_PRE_PLL_PRE_DIV(hdmi->pre_cfg->prediv));
-
-	u32 val;
-	val = INNO_SPREAD_SPECTRUM_MOD_DISABLE;
-	if (!hdmi->pre_cfg->fracdiv)
-		val |= INNO_PRE_PLL_FRAC_DIV_DISABLE;
-	hdmi_writeb(hdmi, 0x1a2, INNO_PRE_PLL_FB_DIV_11_8(hdmi->pre_cfg->fbdiv | val));
-
-	hdmi_writeb(hdmi, 0x1a3, INNO_PRE_PLL_FB_DIV_7_0(hdmi->pre_cfg->fbdiv));
-
-	hdmi_writeb(hdmi, 0x1a5, INNO_PRE_PLL_PCLK_DIV_A(hdmi->pre_cfg->pclk_div_a) |
-			INNO_PRE_PLL_PCLK_DIV_B(hdmi->pre_cfg->pclk_div_b));
-
-	hdmi_writeb(hdmi, 0x1a6, INNO_PRE_PLL_PCLK_DIV_C(hdmi->pre_cfg->pclk_div_c) |
-			INNO_PRE_PLL_PCLK_DIV_D(hdmi->pre_cfg->pclk_div_d));
-
-	hdmi_writeb(hdmi, 0x1a4, INNO_PRE_PLL_TMDSCLK_DIV_C(hdmi->pre_cfg->tmds_div_c) |
-			INNO_PRE_PLL_TMDSCLK_DIV_A(hdmi->pre_cfg->tmds_div_a) |
-			INNO_PRE_PLL_TMDSCLK_DIV_B(hdmi->pre_cfg->tmds_div_b));
-
-	hdmi_writeb(hdmi, 0x1d3, INNO_PRE_PLL_FRAC_DIV_7_0(hdmi->pre_cfg->fracdiv));
-	hdmi_writeb(hdmi, 0x1d2, INNO_PRE_PLL_FRAC_DIV_15_8(hdmi->pre_cfg->fracdiv));
-	hdmi_writeb(hdmi, 0x1d1, INNO_PRE_PLL_FRAC_DIV_23_16(hdmi->pre_cfg->fracdiv));
-
-	/*pre-pll power down*/
-	hdmi_modb(hdmi, 0x1a0, INNO_PRE_PLL_POWER_DOWN, 0);
-
-	const struct phy_config *phy_cfg = inno_phy_cfg;
-
-	for (; phy_cfg->tmdsclock != 0; phy_cfg++)
-		if (tmdsclock <= phy_cfg->tmdsclock)
-			break;
-
-	hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POWER_DOWN, INNO_POST_PLL_POWER_DOWN);
-
-	hdmi_writeb(hdmi, 0x1ac, INNO_POST_PLL_FB_DIV_7_0(hdmi->post_cfg->fbdiv));
-
-	if (hdmi->post_cfg->postdiv == 1) {
-		hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_REFCLK_SEL_TMDS, INNO_POST_PLL_REFCLK_SEL_TMDS);
-		hdmi_modb(hdmi, 0x1aa, BIT(4), INNO_POST_PLL_FB_DIV_8(hdmi->post_cfg->fbdiv));
-		hdmi_modb(hdmi, 0x1ab, INNO_POST_PLL_Pre_DIV_MASK, INNO_POST_PLL_PRE_DIV(hdmi->post_cfg->prediv));
-	} else {
-		v = (hdmi->post_cfg->postdiv / 2) - 1;
-		v &= INNO_POST_PLL_POST_DIV_MASK;
-		hdmi_modb(hdmi, 0x1ad, INNO_POST_PLL_POST_DIV_MASK, v);
-		hdmi_modb(hdmi, 0x1aa, BIT(4), INNO_POST_PLL_FB_DIV_8(hdmi->post_cfg->fbdiv));
-		hdmi_modb(hdmi, 0x1ab, INNO_POST_PLL_Pre_DIV_MASK, INNO_POST_PLL_PRE_DIV(hdmi->post_cfg->prediv));
-		hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_REFCLK_SEL_TMDS, INNO_POST_PLL_REFCLK_SEL_TMDS);
-		hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POST_DIV_ENABLE, INNO_POST_PLL_POST_DIV_ENABLE);
-	}
-
-	for (v = 0; v < 14; v++){
-		hdmi_writeb(hdmi, 0x1b5 + v, phy_cfg->regs[v]);
-	}
-
-	if (phy_cfg->tmdsclock > 340000000) {
-		/* Set termination resistor to 100ohm */
-		v = clk_get_rate(hdmi->sys_clk) / 100000;
-	
-		hdmi_writeb(hdmi, 0x1c5, INNO_TERM_RESISTOR_CALIB_SPEED_14_8(v)
-			   | INNO_BYPASS_TERM_RESISTOR_CALIB);
-	
-		hdmi_writeb(hdmi, 0x1c6, INNO_TERM_RESISTOR_CALIB_SPEED_7_0(v));
-		hdmi_writeb(hdmi, 0x1c7, INNO_TERM_RESISTOR_100);		
-		hdmi_modb(hdmi, 0x1c5, INNO_BYPASS_TERM_RESISTOR_CALIB, 0);
-	} else {
-		hdmi_writeb(hdmi, 0x1c5, INNO_BYPASS_TERM_RESISTOR_CALIB);
-
-		/* clk termination resistor is 50ohm (parallel resistors) */
-		if (phy_cfg->tmdsclock > 165000000){
-			hdmi_modb(hdmi, 0x1c8,
-					 INNO_ESD_DETECT_MASK,
-					 INNO_TERM_RESISTOR_200);
-		}
-		/* data termination resistor for D2, D1 and D0 is 150ohm */
-		for (v = 0; v < 3; v++){
-			hdmi_modb(hdmi, 0x1c9 + v,
-					 INNO_ESD_DETECT_MASK,
-					 INNO_TERM_RESISTOR_200);
-		}
-	}
-
-	hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POWER_DOWN, 0);
-
-
-#endif
 	return 0;
 }
 
@@ -618,7 +524,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
 	ret = pm_runtime_get_sync(hdmi->dev);
 	if (ret < 0)
 		return;
-	mdelay(10);
+
 	inno_hdmi_setup(hdmi, &hdmi->previous_mode);
 
 }
@@ -665,7 +571,7 @@ inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	ret = pm_runtime_get_sync(hdmi->dev);
 	if (ret < 0)
 		return ret;
-	mdelay(500);
+
 	ret = (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
 		connector_status_connected : connector_status_disconnected;
 
@@ -683,6 +589,10 @@ static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
 	if (!hdmi->ddc)
 		return 0;
 
+	ret = pm_runtime_get_sync(hdmi->dev);
+	if (ret < 0)
+		return ret;
+
 	edid = drm_get_edid(connector, hdmi->ddc);
 	if (edid) {
 		hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
@@ -691,6 +601,7 @@ static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
 		ret = drm_add_edid_modes(connector, edid);
 		kfree(edid);
 	}
+	pm_runtime_put(hdmi->dev);
 
 	return ret;
 }
@@ -1093,8 +1004,6 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
 	if (ret)
 		dev_err(dev, "failed to audio init\n");
 
-	pm_runtime_use_autosuspend(&pdev->dev);
-	pm_runtime_set_autosuspend_delay(&pdev->dev, 5000);
 	pm_runtime_enable(&pdev->dev);
 
 	inno_hdmi_disable_clk_assert_rst(dev, hdmi);
diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c b/drivers/gpu/drm/verisilicon/vs_dc.c
index 3bad16fcb4ba..7c9e8a16c5fc 100644
--- a/drivers/gpu/drm/verisilicon/vs_dc.c
+++ b/drivers/gpu/drm/verisilicon/vs_dc.c
@@ -1242,79 +1242,24 @@ static void update_cursor_size(struct drm_plane_state *state, struct dc_hw_curso
 	cursor->size = size_type;
 }
 
-static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, struct drm_plane *drm_plane,
-									struct drm_atomic_state *drm_state)
-{
-	//struct drm_plane_state *state = plane->base.state;
-	struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state,
-									   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;
-	cursor.y = state->crtc_y;
-	cursor.hot_x = drm_fb->hot_x;
-	cursor.hot_y = drm_fb->hot_y;
-	cursor.display_id = to_vs_display_id(dc, state->crtc);
-	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);
-}
-
 static void vs_dc_update_plane(struct device *dev, struct vs_plane *plane, struct drm_plane *drm_plane,
 								struct drm_atomic_state *drm_state)
 {
 	struct vs_dc *dc = dev_get_drvdata(dev);
-	enum drm_plane_type type = plane->base.type;
 
-	switch (type) {
-	case DRM_PLANE_TYPE_PRIMARY:
-	case DRM_PLANE_TYPE_OVERLAY:
-		update_plane(dc, plane, drm_plane, drm_state);
-		update_qos(dc, plane, drm_plane, drm_state);
-		break;
-	case DRM_PLANE_TYPE_CURSOR:
-		update_cursor_plane(dc, plane, drm_plane, drm_state);
-		break;
-	default:
-		break;
-	}
+	update_plane(dc, plane, drm_plane, drm_state);
+	update_qos(dc, plane, drm_plane, drm_state);
+
 }
 
 static void vs_dc_disable_plane(struct device *dev, struct vs_plane *plane,
 								struct drm_plane_state *old_state)
 {
 	struct vs_dc *dc = dev_get_drvdata(dev);
-	enum drm_plane_type type = plane->base.type;
 	struct dc_hw_fb fb = {0};
-	struct dc_hw_cursor cursor = {0};
 
-	switch (type) {
-	case DRM_PLANE_TYPE_PRIMARY:
-	case DRM_PLANE_TYPE_OVERLAY:
-		fb.enable = false;
-		dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL);
-#ifdef CONFIG_VERISILICON_DEC
-		disable_fbc(dc, plane);
-#endif
-		break;
-	case DRM_PLANE_TYPE_CURSOR:
-		cursor.enable = false;
-		cursor.display_id = to_vs_display_id(dc, old_state->crtc);
-		dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
-		break;
-	default:
-		break;
-	}
+	fb.enable = false;
+	dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL);
 }
 
 static bool vs_dc_mod_supported(const struct vs_plane_info *plane_info,
@@ -1372,6 +1317,80 @@ static int vs_dc_check_plane(struct device *dev, struct drm_plane *plane,
 						  true, true);
 }
 
+static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
+			  struct drm_plane *drm_plane,
+			  struct drm_atomic_state *drm_state)
+{
+  struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state,
+									 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;
+  cursor.y = state->crtc_y;
+  cursor.hot_x = drm_fb->hot_x;
+  cursor.hot_y = drm_fb->hot_y;
+  cursor.display_id = to_vs_display_id(dc, state->crtc);
+  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);
+}
+
+void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
+				 struct drm_plane *drm_plane,
+				 struct drm_atomic_state *drm_state)
+{
+	update_cursor_plane(dc, plane, drm_plane, drm_state);
+}
+
+void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
+				 struct drm_plane_state *old_state)
+{
+	 struct dc_hw_cursor cursor = {0};
+
+	 cursor.enable = false;
+	 cursor.display_id = to_vs_display_id(dc, old_state->crtc);
+	 dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
+}
+
+int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane,
+				  struct drm_atomic_state *state)
+{
+	 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										plane);
+	 struct drm_framebuffer *fb = new_plane_state->fb;
+	 const struct vs_plane_info *plane_info;
+	 struct drm_crtc *crtc = new_plane_state->crtc;
+	 struct drm_crtc_state *crtc_state;
+	 struct vs_plane *vs_plane = to_vs_plane(plane);
+
+	 plane_info = &dc->hw.info->planes[vs_plane->id];
+
+	 if (fb->width < plane_info->min_width ||
+		 fb->width > plane_info->max_width ||
+		 fb->height < plane_info->min_height ||
+		 fb->height > plane_info->max_height)
+		 drm_err_once(plane->dev, "buffer size may not support on plane%d.\n", vs_plane->id);
+
+	 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
+	 if (IS_ERR(crtc_state))
+		 return -EINVAL;
+
+	 return drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+						 plane_info->min_scale,
+						 plane_info->max_scale,
+						 true, true);
+}
+
 static irqreturn_t dc_isr(int irq, void *data)
 {
 	struct vs_dc *dc = data;
@@ -1457,20 +1476,6 @@ static int dc_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
-#ifdef CONFIG_VERISILICON_MMU
-	ret = dc_mmu_construct(priv->dma_dev, &priv->mmu);
-	if (ret) {
-		dev_err(dev, "failed to construct DC MMU\n");
-		goto err_clean_dc;
-	}
-
-	ret = dc_hw_mmu_init(&dc->hw, priv->mmu);
-	if (ret) {
-		dev_err(dev, "failed to init DC MMU\n");
-		goto err_clean_dc;
-	}
-#endif
-
 	ret = vs_drm_iommu_attach_device(drm_dev, dev);
 	if (ret < 0) {
 		dev_err(dev, "Failed to attached iommu device.\n");
diff --git a/drivers/gpu/drm/verisilicon/vs_dc.h b/drivers/gpu/drm/verisilicon/vs_dc.h
index 061a49cc8dcc..6f183108382b 100755
--- a/drivers/gpu/drm/verisilicon/vs_dc.h
+++ b/drivers/gpu/drm/verisilicon/vs_dc.h
@@ -80,5 +80,13 @@ struct vs_dc {
 
 extern struct platform_driver dc_platform_driver;
 
+void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
+			       struct drm_plane *drm_plane,
+			       struct drm_atomic_state *drm_state);
+void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane,
+				struct drm_plane_state *old_state);
+int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane,
+			     struct drm_atomic_state *state);
+
 
 #endif /* __VS_DC_H__ */
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.c b/drivers/gpu/drm/verisilicon/vs_plane.c
index 8cf5f3b9d965..65ac8df0bf6d 100755
--- a/drivers/gpu/drm/verisilicon/vs_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_plane.c
@@ -15,6 +15,7 @@
 #include "vs_plane.h"
 #include "vs_gem.h"
 #include "vs_fb.h"
+#include "vs_dc.h"
 
 void vs_plane_destory(struct drm_plane *plane)
 {
@@ -309,12 +310,90 @@ static void vs_plane_atomic_disable(struct drm_plane *plane,
 	vs_plane->funcs->disable(vs_crtc->dev, vs_plane, old_state);
 }
 
-const struct drm_plane_helper_funcs vs_plane_helper_funcs = {
-	.atomic_check	= vs_plane_atomic_check,
-	.atomic_update	= vs_plane_atomic_update,
-	.atomic_disable = vs_plane_atomic_disable,
+static void vs_cursor_plane_atomic_update(struct drm_plane *plane,
+					   struct drm_atomic_state *state)
+{
+	 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+										plane);
+	 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
+										plane);
+	 unsigned char i, num_planes;
+	 struct drm_framebuffer *fb;
+	 struct vs_plane *vs_plane = to_vs_plane(plane);
+	 struct vs_crtc *vs_crtc = to_vs_crtc(new_state->crtc);
+	 struct vs_plane_state *plane_state = to_vs_plane_state(new_state);
+	 struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
+
+	 if (!new_state->fb || !new_state->crtc)
+		 return;
+
+	 fb = new_state->fb;
+
+	 num_planes = vs_get_plane_number(fb);
+
+	 for (i = 0; i < num_planes; i++) {
+		 struct vs_gem_object *vs_obj;
+
+		 vs_obj = vs_fb_get_gem_obj(fb, i);
+		 vs_plane->dma_addr[i] = vs_obj->iova + fb->offsets[i];
+	 }
+
+	 plane_state->status.src = drm_plane_state_src(new_state);
+	 plane_state->status.dest = drm_plane_state_dest(new_state);
+
+	 vs_dc_update_cursor_plane(dc, vs_plane, plane, state);
+}
+
+static void vs_cursor_plane_atomic_disable(struct drm_plane *plane,
+						struct drm_atomic_state *state)
+{
+	 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
+										plane);
+	 struct vs_plane *vs_plane = to_vs_plane(plane);
+	 struct vs_crtc *vs_crtc = to_vs_crtc(old_state->crtc);
+	 struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
+
+	 vs_dc_disable_cursor_plane(dc, vs_plane, old_state);
+}
+
+
+static int vs_cursor_plane_atomic_check(struct drm_plane *plane,
+					struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+									  plane);
+	unsigned char i, num_planes;
+	struct drm_framebuffer *fb = new_plane_state->fb;
+	struct drm_crtc *crtc = new_plane_state->crtc;
+	struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
+	struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
+	struct vs_plane_state *plane_state = to_vs_plane_state(new_plane_state);
+
+	if (!crtc || !fb)
+		return 0;
+
+	return vs_dc_check_cursor_plane(dc, plane, state);
+}
+
+const struct drm_plane_helper_funcs primary_plane_helpers = {
+	 .atomic_check	 = vs_plane_atomic_check,
+	 .atomic_update  = vs_plane_atomic_update,
+	 .atomic_disable = vs_plane_atomic_disable,
+};
+
+const struct drm_plane_helper_funcs overlay_plane_helpers = {
+	 .atomic_check	 = vs_plane_atomic_check,
+	 .atomic_update  = vs_plane_atomic_update,
+	 .atomic_disable = vs_plane_atomic_disable,
 };
 
+const struct drm_plane_helper_funcs cursor_plane_helpers = {
+	 .atomic_check	 = vs_cursor_plane_atomic_check,
+	 .atomic_update  = vs_cursor_plane_atomic_update,
+	 .atomic_disable = vs_cursor_plane_atomic_disable,
+};
+
+
 static const struct drm_prop_enum_list vs_degamma_mode_enum_list[] = {
 	{ VS_DEGAMMA_DISABLE,	"disabled" },
 	{ VS_DEGAMMA_BT709, "preset degamma for BT709" },
@@ -343,7 +422,12 @@ struct vs_plane *vs_plane_create(struct drm_device *drm_dev,
 	if (ret)
 		goto err_free_plane;
 
-	drm_plane_helper_add(&plane->base, &vs_plane_helper_funcs);
+	if (info->type == DRM_PLANE_TYPE_PRIMARY)
+		drm_plane_helper_add(&plane->base, &primary_plane_helpers);
+	else if (info->type == DRM_PLANE_TYPE_CURSOR)
+		drm_plane_helper_add(&plane->base, &cursor_plane_helpers);
+	else
+		drm_plane_helper_add(&plane->base, &overlay_plane_helpers);
 
 	/* Set up the plane properties */
 	if (info->degamma_size) {
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.h b/drivers/gpu/drm/verisilicon/vs_plane.h
index ab4591d54614..3817d93d57f6 100644
--- a/drivers/gpu/drm/verisilicon/vs_plane.h
+++ b/drivers/gpu/drm/verisilicon/vs_plane.h
@@ -35,6 +35,7 @@ struct vs_plane_status {
 struct vs_plane_state {
 	struct drm_plane_state base;
 	struct vs_plane_status status; /* for debugfs */
+	dma_addr_t dma_addr[MAX_NUM_PLANES];
 
 	struct drm_property_blob *watermark;
 	struct drm_property_blob *color_mgmt;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
index 51e09f50628f..9afc6de6bb8b 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
@@ -402,7 +402,7 @@ static int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void * value)
 
 	reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -419,7 +419,7 @@ static int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void * value)
 	reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
 	reg_write(ispbase, reg_addr, reg_value);
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -434,7 +434,7 @@ static int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void * value)
 
 	reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -459,7 +459,7 @@ static int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void * value)
 	reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -472,7 +472,7 @@ static int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	for(i = 0; i < 15; i++, curve++, reg_addr += 4)
 		reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
 
@@ -490,7 +490,7 @@ static int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
 	reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
 	reg_addr += 0x90;
@@ -498,7 +498,7 @@ static int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void * value)
 		reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -511,7 +511,7 @@ static int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
 
 	reg_addr += 0x2ac;	//0x2e0
@@ -519,7 +519,7 @@ static int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void * value)
 		reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -535,7 +535,7 @@ static int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void * value)
 	void __iomem *ispbase = vin->isp_base;
 	u32 x, y, slope;
 	s32 i;
-	
+
 	for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
 		x = pts->x & 0x3ff;
 		y = pts->y & 0x3ff;
@@ -565,12 +565,12 @@ static int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	for(i = 0; i < 9; i++, reg_addr += 4)
 		reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -584,7 +584,7 @@ static int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
 		reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
 	reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
@@ -597,7 +597,7 @@ static int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void * value)
 		reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -609,7 +609,7 @@ static int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void * value)
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
 	s32 i;
-	
+
 	for(i = 0; i < 4; i++, reg_addr += 4)
 		reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
 	FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
@@ -622,7 +622,7 @@ static int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void * value)
 	reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -633,11 +633,11 @@ static int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void * value)
 	u32 reg_addr = reg_info->cfg_reg;
 	struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
 	void __iomem *ispbase = vin->isp_base;
-	
+
 	FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
 
 	reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-	
+
 	return 0;
 }
 
@@ -661,11 +661,11 @@ static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
 	reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
 
 	// SC config1
-	reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) | 
+	reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
 		((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
 
 	// SC decimation config
-	reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) | 
+	reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
 		((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
 
 	// SC AWB pixel sum config
@@ -676,7 +676,7 @@ static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
 	reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
 
 	// AF register
-	reg_write(ispbase, 0xc0, 
+	reg_write(ispbase, 0xc0,
 		((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
 		((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
 		((setting->af_config.ver_en & 0x1) << 3) |
@@ -1217,7 +1217,7 @@ static int isp_get_interface_type(struct media_entity *entity)
 static int isp_set_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-	int ret = 0, interface_type;
+	int interface_type;
 	struct v4l2_mbus_framefmt *fmt;
 	struct v4l2_event src_ch = { 0 };
 
@@ -1225,6 +1225,7 @@ static int isp_set_stream(struct v4l2_subdev *sd, int enable)
 	mutex_lock(&isp_dev->stream_lock);
 	if (enable) {
 		if (isp_dev->stream_count == 0) {
+			v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
 			isp_dev->hw_ops->isp_clk_enable(isp_dev);
 			if (!user_config_isp)
 				isp_dev->hw_ops->isp_config_set(isp_dev);
@@ -1256,15 +1257,7 @@ static int isp_set_stream(struct v4l2_subdev *sd, int enable)
 exit:
 	mutex_unlock(&isp_dev->stream_lock);
 
-	mutex_lock(&isp_dev->power_lock);
-	/* restore controls */
-	if (enable && isp_dev->power_count == 1) {
-		mutex_unlock(&isp_dev->power_lock);
-		ret = v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
-	} else
-		mutex_unlock(&isp_dev->power_lock);
-
-	return ret;
+	return 0;
 }
 
 /*Try to match sensor format with sink, and then get the index as default.*/