linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management
@ 2021-05-25 13:13 Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 1/7] drm/msm/mdp5: use drm atomic helpers to handle base drm plane state Dmitry Baryshkov
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Update MDP5 display driver to support current implementation of
alpha/blend mode/zpos properties. On top of that port bandwidth
management from DPU display driver.

The following changes since commit 8dbde399044b0f5acf704ab5f8116bd8b1dfcf95:

  drm/msm/dp: handle irq_hpd with sink_count = 0 correctly (2021-05-24 16:08:33 -0700)

are available in the Git repository at:

  https://git.linaro.org/people/dmitry.baryshkov/kernel.git mdp5-update

for you to fetch changes up to 501c3f8c40e139d97b17240e0a5492a12b6c722d:

  drm/msm/mdp5: provide dynamic bandwidth management (2021-05-25 16:10:17 +0300)

----------------------------------------------------------------
Dmitry Baryshkov (6):
      drm/msm/mdp5: use drm atomic helpers to handle base drm plane state
      drm/msm/mdp5: use drm_plane_state for storing alpha value
      drm/msm/mdp5: use drm_plane_state for pixel blend mode
      drm/msm/mdp5: add support for alpha/blend_mode properties
      drm/msm/mdp5: switch to standard zpos property
      drm/msm/mdp5: provide dynamic bandwidth management

James Willcox (1):
      drm/msm/mdp5: add perf blocks for holding fudge factors

 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c   |  35 ++++++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h   |   7 ++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  |  56 ++++++++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   | 119 +++++++++++++------
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   |  17 ++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 177 ++++++++++-------------------
 6 files changed, 249 insertions(+), 162 deletions(-)



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] drm/msm/mdp5: use drm atomic helpers to handle base drm plane state
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 2/7] drm/msm/mdp5: use drm_plane_state for storing alpha value Dmitry Baryshkov
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Use generic helpers code to manage drm_plane_state part of mdp5_plane
state instead of manually coding all the details.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 8c9f2f492178..8c29026d770d 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -176,8 +176,8 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 {
 	struct mdp5_plane_state *mdp5_state;
 
-	if (plane->state && plane->state->fb)
-		drm_framebuffer_put(plane->state->fb);
+	if (plane->state)
+		__drm_atomic_helper_plane_destroy_state(plane->state);
 
 	kfree(to_mdp5_plane_state(plane->state));
 	mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL);
@@ -191,9 +191,7 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 	else
 		mdp5_state->zpos = STAGE0 + drm_plane_index(plane);
 
-	mdp5_state->base.plane = plane;
-
-	plane->state = &mdp5_state->base;
+	__drm_atomic_helper_plane_reset(plane, &mdp5_state->base);
 }
 
 static struct drm_plane_state *
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/7] drm/msm/mdp5: use drm_plane_state for storing alpha value
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 1/7] drm/msm/mdp5: use drm atomic helpers to handle base drm plane state Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 3/7] drm/msm/mdp5: use drm_plane_state for pixel blend mode Dmitry Baryshkov
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Use drm_plane_state's 'alpha' field rather than adding extra 'alpha'
field to mdp5_plane_state.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  | 4 ++--
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   | 1 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index f5d71b274079..b98d5abafd1f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -291,8 +291,8 @@ static void blend_setup(struct drm_crtc *crtc)
 		plane = pstates[i]->base.plane;
 		blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
 			MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST);
-		fg_alpha = pstates[i]->alpha;
-		bg_alpha = 0xFF - pstates[i]->alpha;
+		fg_alpha = pstates[i]->base.alpha >> 8;
+		bg_alpha = 0xFF - fg_alpha;
 
 		if (!format->alpha_enable && bg_alpha_enabled)
 			mixer_op_mode = 0;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
index 128866742593..d7e04e99fb4e 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
@@ -101,7 +101,6 @@ struct mdp5_plane_state {
 	/* aligned with property */
 	uint8_t premultiplied;
 	uint8_t zpos;
-	uint8_t alpha;
 
 	/* assigned by crtc blender */
 	enum mdp_mixer_stage_id stage;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 8c29026d770d..0fd1d10352aa 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -168,7 +168,7 @@ mdp5_plane_atomic_print_state(struct drm_printer *p,
 					      "(null)");
 	drm_printf(p, "\tpremultiplied=%u\n", pstate->premultiplied);
 	drm_printf(p, "\tzpos=%u\n", pstate->zpos);
-	drm_printf(p, "\talpha=%u\n", pstate->alpha);
+	drm_printf(p, "\talpha=%u\n", pstate->base.alpha);
 	drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
 }
 
@@ -183,7 +183,6 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 	mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL);
 
 	/* assign default blend parameters */
-	mdp5_state->alpha = 255;
 	mdp5_state->premultiplied = 0;
 
 	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/7] drm/msm/mdp5: use drm_plane_state for pixel blend mode
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 1/7] drm/msm/mdp5: use drm atomic helpers to handle base drm plane state Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 2/7] drm/msm/mdp5: use drm_plane_state for storing alpha value Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 4/7] drm/msm/mdp5: add support for alpha/blend_mode properties Dmitry Baryshkov
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Use drm_plane_state's 'pixel_blend_mode' field rather than using
'premultiplied' field to mdp5_plane_state.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  | 6 ++++--
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   | 1 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 5 +----
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index b98d5abafd1f..ed4d91420417 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -301,7 +301,8 @@ static void blend_setup(struct drm_crtc *crtc)
 
 		DBG("Stage %d fg_alpha %x bg_alpha %x", i, fg_alpha, bg_alpha);
 
-		if (format->alpha_enable && pstates[i]->premultiplied) {
+		if (format->alpha_enable &&
+		    pstates[i]->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) {
 			blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
 				MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
 			if (fg_alpha != 0xff) {
@@ -312,7 +313,8 @@ static void blend_setup(struct drm_crtc *crtc)
 			} else {
 				blend_op |= MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA;
 			}
-		} else if (format->alpha_enable) {
+		} else if (format->alpha_enable &&
+			   pstates[i]->base.pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
 			blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_PIXEL) |
 				MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
 			if (fg_alpha != 0xff) {
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
index d7e04e99fb4e..d124c9bcdc60 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
@@ -99,7 +99,6 @@ struct mdp5_plane_state {
 	struct mdp5_hw_pipe *r_hwpipe;	/* right hwpipe */
 
 	/* aligned with property */
-	uint8_t premultiplied;
 	uint8_t zpos;
 
 	/* assigned by crtc blender */
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 0fd1d10352aa..90cd825df16b 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -166,7 +166,7 @@ mdp5_plane_atomic_print_state(struct drm_printer *p,
 		drm_printf(p, "\tright-hwpipe=%s\n",
 			   pstate->r_hwpipe ? pstate->r_hwpipe->name :
 					      "(null)");
-	drm_printf(p, "\tpremultiplied=%u\n", pstate->premultiplied);
+	drm_printf(p, "\tblend_mode=%u\n", pstate->base.pixel_blend_mode);
 	drm_printf(p, "\tzpos=%u\n", pstate->zpos);
 	drm_printf(p, "\talpha=%u\n", pstate->base.alpha);
 	drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
@@ -182,9 +182,6 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 	kfree(to_mdp5_plane_state(plane->state));
 	mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL);
 
-	/* assign default blend parameters */
-	mdp5_state->premultiplied = 0;
-
 	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 		mdp5_state->zpos = STAGE_BASE;
 	else
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/7] drm/msm/mdp5: add support for alpha/blend_mode properties
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2021-05-25 13:13 ` [PATCH 3/7] drm/msm/mdp5: use drm_plane_state for pixel blend mode Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 5/7] drm/msm/mdp5: switch to standard zpos property Dmitry Baryshkov
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Hook alpha and pixel blend mode support to be exported as proper DRM
plane properties. This allows using this functionality from the
userspace.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 90cd825df16b..9c678e336e7a 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -91,6 +91,11 @@ static void mdp5_plane_install_properties(struct drm_plane *plane,
 	INSTALL_RANGE_PROPERTY(zpos, ZPOS, 1, 255, 1);
 
 	mdp5_plane_install_rotation_property(dev, plane);
+	drm_plane_create_alpha_property(plane);
+	drm_plane_create_blend_mode_property(plane,
+			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+			BIT(DRM_MODE_BLEND_PREMULTI) |
+			BIT(DRM_MODE_BLEND_COVERAGE));
 
 #undef INSTALL_RANGE_PROPERTY
 #undef INSTALL_ENUM_PROPERTY
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/7] drm/msm/mdp5: switch to standard zpos property
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
                   ` (3 preceding siblings ...)
  2021-05-25 13:13 ` [PATCH 4/7] drm/msm/mdp5: add support for alpha/blend_mode properties Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 6/7] drm/msm/mdp5: add perf blocks for holding fudge factors Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management Dmitry Baryshkov
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Instead of implemeting zpos property on our own, use standard zpos
property support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  |   2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   |   3 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 114 ++-------------------
 3 files changed, 10 insertions(+), 109 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index ed4d91420417..f482e0911d03 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -650,7 +650,7 @@ static int pstate_cmp(const void *a, const void *b)
 {
 	struct plane_state *pa = (struct plane_state *)a;
 	struct plane_state *pb = (struct plane_state *)b;
-	return pa->state->zpos - pb->state->zpos;
+	return pa->state->base.normalized_zpos - pb->state->base.normalized_zpos;
 }
 
 /* is there a helper for this? */
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
index d124c9bcdc60..ac269a6802df 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
@@ -98,9 +98,6 @@ struct mdp5_plane_state {
 	struct mdp5_hw_pipe *hwpipe;
 	struct mdp5_hw_pipe *r_hwpipe;	/* right hwpipe */
 
-	/* aligned with property */
-	uint8_t zpos;
-
 	/* assigned by crtc blender */
 	enum mdp_mixer_stage_id stage;
 };
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 9c678e336e7a..c6b69afcbac8 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -44,8 +44,9 @@ static void mdp5_plane_destroy(struct drm_plane *plane)
 	kfree(mdp5_plane);
 }
 
-static void mdp5_plane_install_rotation_property(struct drm_device *dev,
-		struct drm_plane *plane)
+/* helper to install properties which are common to planes and crtcs */
+static void mdp5_plane_install_properties(struct drm_plane *plane,
+		struct drm_mode_object *obj)
 {
 	drm_plane_create_rotation_property(plane,
 					   DRM_MODE_ROTATE_0,
@@ -53,109 +54,12 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev,
 					   DRM_MODE_ROTATE_180 |
 					   DRM_MODE_REFLECT_X |
 					   DRM_MODE_REFLECT_Y);
-}
-
-/* helper to install properties which are common to planes and crtcs */
-static void mdp5_plane_install_properties(struct drm_plane *plane,
-		struct drm_mode_object *obj)
-{
-	struct drm_device *dev = plane->dev;
-	struct msm_drm_private *dev_priv = dev->dev_private;
-	struct drm_property *prop;
-
-#define INSTALL_PROPERTY(name, NAME, init_val, fnc, ...) do { \
-		prop = dev_priv->plane_property[PLANE_PROP_##NAME]; \
-		if (!prop) { \
-			prop = drm_property_##fnc(dev, 0, #name, \
-				##__VA_ARGS__); \
-			if (!prop) { \
-				dev_warn(dev->dev, \
-					"Create property %s failed\n", \
-					#name); \
-				return; \
-			} \
-			dev_priv->plane_property[PLANE_PROP_##NAME] = prop; \
-		} \
-		drm_object_attach_property(&plane->base, prop, init_val); \
-	} while (0)
-
-#define INSTALL_RANGE_PROPERTY(name, NAME, min, max, init_val) \
-		INSTALL_PROPERTY(name, NAME, init_val, \
-				create_range, min, max)
-
-#define INSTALL_ENUM_PROPERTY(name, NAME, init_val) \
-		INSTALL_PROPERTY(name, NAME, init_val, \
-				create_enum, name##_prop_enum_list, \
-				ARRAY_SIZE(name##_prop_enum_list))
-
-	INSTALL_RANGE_PROPERTY(zpos, ZPOS, 1, 255, 1);
-
-	mdp5_plane_install_rotation_property(dev, plane);
 	drm_plane_create_alpha_property(plane);
 	drm_plane_create_blend_mode_property(plane,
 			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
 			BIT(DRM_MODE_BLEND_PREMULTI) |
 			BIT(DRM_MODE_BLEND_COVERAGE));
-
-#undef INSTALL_RANGE_PROPERTY
-#undef INSTALL_ENUM_PROPERTY
-#undef INSTALL_PROPERTY
-}
-
-static int mdp5_plane_atomic_set_property(struct drm_plane *plane,
-		struct drm_plane_state *state, struct drm_property *property,
-		uint64_t val)
-{
-	struct drm_device *dev = plane->dev;
-	struct mdp5_plane_state *pstate;
-	struct msm_drm_private *dev_priv = dev->dev_private;
-	int ret = 0;
-
-	pstate = to_mdp5_plane_state(state);
-
-#define SET_PROPERTY(name, NAME, type) do { \
-		if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \
-			pstate->name = (type)val; \
-			DBG("Set property %s %d", #name, (type)val); \
-			goto done; \
-		} \
-	} while (0)
-
-	SET_PROPERTY(zpos, ZPOS, uint8_t);
-
-	DRM_DEV_ERROR(dev->dev, "Invalid property\n");
-	ret = -EINVAL;
-done:
-	return ret;
-#undef SET_PROPERTY
-}
-
-static int mdp5_plane_atomic_get_property(struct drm_plane *plane,
-		const struct drm_plane_state *state,
-		struct drm_property *property, uint64_t *val)
-{
-	struct drm_device *dev = plane->dev;
-	struct mdp5_plane_state *pstate;
-	struct msm_drm_private *dev_priv = dev->dev_private;
-	int ret = 0;
-
-	pstate = to_mdp5_plane_state(state);
-
-#define GET_PROPERTY(name, NAME, type) do { \
-		if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \
-			*val = pstate->name; \
-			DBG("Get property %s %lld", #name, *val); \
-			goto done; \
-		} \
-	} while (0)
-
-	GET_PROPERTY(zpos, ZPOS, uint8_t);
-
-	DRM_DEV_ERROR(dev->dev, "Invalid property\n");
-	ret = -EINVAL;
-done:
-	return ret;
-#undef SET_PROPERTY
+	drm_plane_create_zpos_property(plane, 1, 1, 255);
 }
 
 static void
@@ -172,7 +76,8 @@ mdp5_plane_atomic_print_state(struct drm_printer *p,
 			   pstate->r_hwpipe ? pstate->r_hwpipe->name :
 					      "(null)");
 	drm_printf(p, "\tblend_mode=%u\n", pstate->base.pixel_blend_mode);
-	drm_printf(p, "\tzpos=%u\n", pstate->zpos);
+	drm_printf(p, "\tzpos=%u\n", pstate->base.zpos);
+	drm_printf(p, "\tnormalized_zpos=%u\n", pstate->base.normalized_zpos);
 	drm_printf(p, "\talpha=%u\n", pstate->base.alpha);
 	drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
 }
@@ -188,9 +93,10 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 	mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL);
 
 	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
-		mdp5_state->zpos = STAGE_BASE;
+		mdp5_state->base.zpos = STAGE_BASE;
 	else
-		mdp5_state->zpos = STAGE0 + drm_plane_index(plane);
+		mdp5_state->base.zpos = STAGE0 + drm_plane_index(plane);
+	mdp5_state->base.normalized_zpos = mdp5_state->base.zpos;
 
 	__drm_atomic_helper_plane_reset(plane, &mdp5_state->base);
 }
@@ -228,8 +134,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
 		.update_plane = drm_atomic_helper_update_plane,
 		.disable_plane = drm_atomic_helper_disable_plane,
 		.destroy = mdp5_plane_destroy,
-		.atomic_set_property = mdp5_plane_atomic_set_property,
-		.atomic_get_property = mdp5_plane_atomic_get_property,
 		.reset = mdp5_plane_reset,
 		.atomic_duplicate_state = mdp5_plane_duplicate_state,
 		.atomic_destroy_state = mdp5_plane_destroy_state,
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/7] drm/msm/mdp5: add perf blocks for holding fudge factors
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
                   ` (4 preceding siblings ...)
  2021-05-25 13:13 ` [PATCH 5/7] drm/msm/mdp5: switch to standard zpos property Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 13:13 ` [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management Dmitry Baryshkov
  6 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno, James Willcox

From: James Willcox <jwillcox@squareup.com>

Prior downstream kernels had "fudge factors" in devicetree which would
be applied to things like interconnect bandwidth calculations. Bring
some of those values back here.

Signed-off-by: James Willcox <jwillcox@squareup.com>
[DB: changed _ff to _inefficiency, fixed patch description]
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 35 ++++++++++++++++++++++++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h |  7 +++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index 94ce62a26daf..9741544ffc35 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -95,6 +95,11 @@ static const struct mdp5_cfg_hw msm8x74v1_config = {
 			[3] = INTF_HDMI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 125
+	},
 	.max_clk = 200000000,
 };
 
@@ -177,6 +182,11 @@ static const struct mdp5_cfg_hw msm8x74v2_config = {
 			[3] = INTF_HDMI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 125
+	},
 	.max_clk = 320000000,
 };
 
@@ -272,6 +282,11 @@ static const struct mdp5_cfg_hw apq8084_config = {
 			[3] = INTF_HDMI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 105
+	},
 	.max_clk = 320000000,
 };
 
@@ -339,6 +354,11 @@ static const struct mdp5_cfg_hw msm8x16_config = {
 			[1] = INTF_DSI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
 	.max_clk = 320000000,
 };
 
@@ -414,6 +434,11 @@ static const struct mdp5_cfg_hw msm8x36_config = {
 			[2] = INTF_DSI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
 	.max_clk = 366670000,
 };
 
@@ -509,6 +534,11 @@ static const struct mdp5_cfg_hw msm8x94_config = {
 			[3] = INTF_HDMI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 100,
+		.clk_inefficiency = 105
+	},
 	.max_clk = 400000000,
 };
 
@@ -617,6 +647,11 @@ static const struct mdp5_cfg_hw msm8x96_config = {
 			[3] = INTF_HDMI,
 		},
 	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
 	.max_clk = 412500000,
 };
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
index 1c50d01f15f5..6b03d7899309 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
@@ -76,6 +76,12 @@ struct mdp5_intf_block {
 	u32 connect[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
 };
 
+struct mdp5_perf_block {
+	u32 ab_inefficiency;
+	u32 ib_inefficiency;
+	u32 clk_inefficiency;
+};
+
 struct mdp5_cfg_hw {
 	char  *name;
 
@@ -93,6 +99,7 @@ struct mdp5_cfg_hw {
 	struct mdp5_sub_block dsc;
 	struct mdp5_sub_block cdm;
 	struct mdp5_intf_block intf;
+	struct mdp5_perf_block perf;
 
 	uint32_t max_clk;
 };
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management
  2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
                   ` (5 preceding siblings ...)
  2021-05-25 13:13 ` [PATCH 6/7] drm/msm/mdp5: add perf blocks for holding fudge factors Dmitry Baryshkov
@ 2021-05-25 13:13 ` Dmitry Baryshkov
  2021-05-25 17:15   ` kernel test robot
  6 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2021-05-25 13:13 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Instead of using static bandwidth setup, manage bandwidth dynamically,
depending on the amount of allocated planes, their format and
resolution.

Co-developed-with: James Willcox <jwillcox@squareup.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  |  44 ++++++++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   | 119 ++++++++++++++-------
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   |  12 +++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c |  42 ++++++++
 4 files changed, 181 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index f482e0911d03..a9332078aa13 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -43,6 +43,9 @@ struct mdp5_crtc {
 	/* for unref'ing cursor bo's after scanout completes: */
 	struct drm_flip_work unref_cursor_work;
 
+	/* for lowering down the bandwidth after previous frame is complete */
+	struct drm_flip_work lower_bw_work;
+
 	struct mdp_irq vblank;
 	struct mdp_irq err;
 	struct mdp_irq pp_done;
@@ -171,12 +174,28 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val)
 	drm_gem_object_put(val);
 }
 
+static void lower_bw_worker(struct drm_flip_work *work, void *val)
+{
+	struct mdp5_crtc *mdp5_crtc =
+		container_of(work, struct mdp5_crtc, lower_bw_work);
+	struct drm_crtc *crtc = &mdp5_crtc->base;
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
+
+	if (mdp5_cstate->old_crtc_bw > mdp5_cstate->new_crtc_bw) {
+		DBG("DOWN BW to %lld\n", mdp5_cstate->new_crtc_bw);
+		mdp5_kms_set_bandwidth(mdp5_kms);
+		mdp5_cstate->old_crtc_bw = mdp5_cstate->new_crtc_bw;
+	}
+}
+
 static void mdp5_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 
 	drm_crtc_cleanup(crtc);
 	drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work);
+	drm_flip_work_cleanup(&mdp5_crtc->lower_bw_work);
 
 	kfree(mdp5_crtc);
 }
@@ -691,6 +710,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 									  crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state);
 	struct drm_plane *plane;
 	struct drm_device *dev = crtc->dev;
 	struct plane_state pstates[STAGE_MAX + 1];
@@ -701,6 +721,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	bool need_right_mixer = false;
 	int cnt = 0, i;
 	int ret;
+	u64 crtc_bw = 0;
 	enum mdp_mixer_stage_id start;
 
 	DBG("%s: check", crtc->name);
@@ -718,6 +739,9 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 		 */
 		if (pstates[cnt].state->r_hwpipe)
 			need_right_mixer = true;
+
+		crtc_bw += pstates[cnt].state->plane_bw;
+
 		cnt++;
 
 		if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -730,6 +754,10 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 
 	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 
+	if (hw_cfg->perf.ab_inefficiency)
+		crtc_bw = mult_frac(crtc_bw, hw_cfg->perf.ab_inefficiency, 100);
+	mdp5_cstate->new_crtc_bw = crtc_bw;
+
 	/*
 	 * we need a right hwmixer if the mode's width is greater than a single
 	 * LM's max width
@@ -785,6 +813,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
 {
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
 	struct drm_device *dev = crtc->dev;
 	unsigned long flags;
 
@@ -808,6 +837,12 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
 
 	blend_setup(crtc);
 
+	if (mdp5_cstate->old_crtc_bw < mdp5_cstate->new_crtc_bw) {
+		DBG("UP BW to %lld\n", mdp5_cstate->new_crtc_bw);
+		mdp5_kms_set_bandwidth(mdp5_kms);
+		mdp5_cstate->old_crtc_bw = mdp5_cstate->new_crtc_bw;
+	}
+
 	/* PP_DONE irq is only used by command mode for now.
 	 * It is better to request pending before FLUSH and START trigger
 	 * to make sure no pp_done irq missed.
@@ -1155,6 +1190,7 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
 {
 	struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank);
 	struct drm_crtc *crtc = &mdp5_crtc->base;
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
 	struct msm_drm_private *priv = crtc->dev->dev_private;
 	unsigned pending;
 
@@ -1162,6 +1198,11 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
 
 	pending = atomic_xchg(&mdp5_crtc->pending, 0);
 
+	if (mdp5_cstate->old_crtc_bw > mdp5_cstate->new_crtc_bw) {
+		drm_flip_work_queue(&mdp5_crtc->lower_bw_work, NULL);
+		drm_flip_work_commit(&mdp5_crtc->lower_bw_work, priv->wq);
+	}
+
 	if (pending & PENDING_FLIP) {
 		complete_flip(crtc, NULL);
 	}
@@ -1318,6 +1359,9 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
 	drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
 			"unref cursor", unref_cursor_worker);
 
+	drm_flip_work_init(&mdp5_crtc->lower_bw_work,
+			"lower bw", lower_bw_worker);
+
 	drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs);
 
 	return crtc;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 15aed45022bc..3e1b28d3e41b 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -19,6 +19,8 @@
 #include "msm_mmu.h"
 #include "mdp5_kms.h"
 
+#define MDP5_DEFAULT_BW MBps_to_icc(6400)
+
 static int mdp5_hw_init(struct msm_kms *kms)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -296,6 +298,28 @@ static const struct mdp_kms_funcs kms_funcs = {
 	.set_irqmask         = mdp5_set_irqmask,
 };
 
+void mdp5_kms_set_bandwidth(struct mdp5_kms *mdp5_kms)
+{
+	int i;
+	u32 full_bw = 0;
+	struct drm_crtc *tmp_crtc;
+
+	if (!mdp5_kms->num_paths)
+		return;
+
+	drm_for_each_crtc(tmp_crtc, mdp5_kms->dev) {
+		if (!tmp_crtc->enabled)
+			continue;
+
+		full_bw += Bps_to_icc(to_mdp5_crtc_state(tmp_crtc->state)->new_crtc_bw / mdp5_kms->num_paths);
+	}
+
+	DBG("SET BW to %d\n", full_bw);
+
+	for (i = 0; i < mdp5_kms->num_paths; i++)
+		icc_set_bw(mdp5_kms->paths[i], full_bw, full_bw);
+}
+
 static int mdp5_disable(struct mdp5_kms *mdp5_kms)
 {
 	DBG("");
@@ -313,6 +337,14 @@ static int mdp5_disable(struct mdp5_kms *mdp5_kms)
 	if (mdp5_kms->lut_clk)
 		clk_disable_unprepare(mdp5_kms->lut_clk);
 
+	if (!mdp5_kms->enable_count) {
+		int i;
+
+		for (i = 0; i < mdp5_kms->num_paths; i++)
+			icc_set_bw(mdp5_kms->paths[i], 0, 0);
+		icc_set_bw(mdp5_kms->path_rot, 0, 0);
+	}
+
 	return 0;
 }
 
@@ -322,6 +354,14 @@ static int mdp5_enable(struct mdp5_kms *mdp5_kms)
 
 	mdp5_kms->enable_count++;
 
+	if (mdp5_kms->enable_count == 1) {
+		int i;
+
+		for (i = 0; i < mdp5_kms->num_paths; i++)
+			icc_set_bw(mdp5_kms->paths[i], 0, MDP5_DEFAULT_BW);
+		icc_set_bw(mdp5_kms->path_rot, 0, MDP5_DEFAULT_BW);
+	}
+
 	clk_prepare_enable(mdp5_kms->ahb_clk);
 	clk_prepare_enable(mdp5_kms->axi_clk);
 	clk_prepare_enable(mdp5_kms->core_clk);
@@ -828,6 +868,40 @@ static int interface_init(struct mdp5_kms *mdp5_kms)
 	return 0;
 }
 
+static int mdp5_setup_interconnect(struct mdp5_kms *mdp5_kms)
+{
+	struct icc_path *path0 = of_icc_get(&mdp5_kms->pdev->dev, "mdp0-mem");
+	struct icc_path *path1 = of_icc_get(&mdp5_kms->pdev->dev, "mdp1-mem");
+	struct icc_path *path_rot = of_icc_get(&mdp5_kms->pdev->dev, "rotator-mem");
+
+	if (IS_ERR(path0))
+		return PTR_ERR(path0);
+
+	if (!path0) {
+		/* no interconnect support is not necessarily a fatal
+		 * condition, the platform may simply not have an
+		 * interconnect driver yet.  But warn about it in case
+		 * bootloader didn't setup bus clocks high enough for
+		 * scanout.
+		 */
+		dev_warn(&mdp5_kms->pdev->dev, "No interconnect support may cause display underflows!\n");
+		return 0;
+	}
+
+	mdp5_kms->paths[0] = path0;
+	mdp5_kms->num_paths = 1;
+
+	if (!IS_ERR_OR_NULL(path1)) {
+		mdp5_kms->paths[1] = path1;
+		mdp5_kms->num_paths++;
+	}
+
+	if (!IS_ERR_OR_NULL(path_rot))
+		mdp5_kms->path_rot = path_rot;
+
+	return 0;
+}
+
 static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 {
 	struct msm_drm_private *priv = dev->dev_private;
@@ -835,6 +909,7 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 	struct mdp5_cfg *config;
 	u32 major, minor;
 	int ret;
+	int i;
 
 	mdp5_kms = devm_kzalloc(&pdev->dev, sizeof(*mdp5_kms), GFP_KERNEL);
 	if (!mdp5_kms) {
@@ -859,6 +934,14 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 		goto fail;
 	}
 
+	ret = mdp5_setup_interconnect(mdp5_kms);
+	if (ret)
+		goto fail;
+
+	for (i = 0; i < mdp5_kms->num_paths; i++)
+		icc_set_bw(mdp5_kms->paths[i], 0, MDP5_DEFAULT_BW);
+	icc_set_bw(mdp5_kms->path_rot, 0, MDP5_DEFAULT_BW);
+
 	/* mandatory clocks: */
 	ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus", true);
 	if (ret)
@@ -968,46 +1051,10 @@ static const struct component_ops mdp5_ops = {
 	.unbind = mdp5_unbind,
 };
 
-static int mdp5_setup_interconnect(struct platform_device *pdev)
-{
-	struct icc_path *path0 = of_icc_get(&pdev->dev, "mdp0-mem");
-	struct icc_path *path1 = of_icc_get(&pdev->dev, "mdp1-mem");
-	struct icc_path *path_rot = of_icc_get(&pdev->dev, "rotator-mem");
-
-	if (IS_ERR(path0))
-		return PTR_ERR(path0);
-
-	if (!path0) {
-		/* no interconnect support is not necessarily a fatal
-		 * condition, the platform may simply not have an
-		 * interconnect driver yet.  But warn about it in case
-		 * bootloader didn't setup bus clocks high enough for
-		 * scanout.
-		 */
-		dev_warn(&pdev->dev, "No interconnect support may cause display underflows!\n");
-		return 0;
-	}
-
-	icc_set_bw(path0, 0, MBps_to_icc(6400));
-
-	if (!IS_ERR_OR_NULL(path1))
-		icc_set_bw(path1, 0, MBps_to_icc(6400));
-	if (!IS_ERR_OR_NULL(path_rot))
-		icc_set_bw(path_rot, 0, MBps_to_icc(6400));
-
-	return 0;
-}
-
 static int mdp5_dev_probe(struct platform_device *pdev)
 {
-	int ret;
-
 	DBG("");
 
-	ret = mdp5_setup_interconnect(pdev);
-	if (ret)
-		return ret;
-
 	return component_add(&pdev->dev, &mdp5_ops);
 }
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
index ac269a6802df..918ce1e1bbbd 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
@@ -17,6 +17,7 @@
 #include "mdp5_ctl.h"
 #include "mdp5_smp.h"
 
+struct icc_path;
 struct mdp5_kms {
 	struct mdp_kms base;
 
@@ -68,6 +69,10 @@ struct mdp5_kms {
 	struct mdp_irq error_handler;
 
 	int enable_count;
+
+	int num_paths;
+	struct icc_path *paths[2];
+	struct icc_path *path_rot;
 };
 #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
 
@@ -100,6 +105,8 @@ struct mdp5_plane_state {
 
 	/* assigned by crtc blender */
 	enum mdp_mixer_stage_id stage;
+
+	u64 plane_bw;
 };
 #define to_mdp5_plane_state(x) \
 		container_of(x, struct mdp5_plane_state, base)
@@ -130,6 +137,9 @@ struct mdp5_crtc_state {
 	 * writing CTL[n].START until encoder->enable()
 	 */
 	bool defer_start;
+
+	u64 new_crtc_bw;
+	u64 old_crtc_bw;
 };
 #define to_mdp5_crtc_state(x) \
 		container_of(x, struct mdp5_crtc_state, base)
@@ -292,6 +302,8 @@ void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode);
 int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
 u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
 
+void mdp5_kms_set_bandwidth(struct mdp5_kms *mdp5_kms);
+
 #ifdef CONFIG_DRM_MSM_DSI
 void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
 			       struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index c6b69afcbac8..85275665558b 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -154,6 +154,46 @@ static void mdp5_plane_cleanup_fb(struct drm_plane *plane,
 	msm_framebuffer_cleanup(fb, kms->aspace);
 }
 
+/* based on _dpu_plane_calc_bw */
+static void mdp5_plane_calc_bw(struct drm_plane_state *state, struct drm_crtc_state *crtc_state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
+	struct drm_display_mode *mode = &crtc_state->mode;
+	int bpp;
+	int src_width, src_height, dst_height, fps;
+	u64 plane_bw;
+	u32 hw_latency_lines;
+	u32 prefill_div;
+	u64 scale_factor;
+	int vbp, vpw, vfp;
+
+	src_width = drm_rect_width(&state->src) >> 16;
+	src_height = drm_rect_height(&state->src) >> 16;
+	dst_height = drm_rect_height(&state->dst);
+	fps = drm_mode_vrefresh(mode);
+	vbp = mode->vtotal - mode->vsync_end;
+	vpw = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	scale_factor = src_height > dst_height ?
+		mult_frac(src_height, 1, dst_height) : 1;
+
+	bpp = to_mdp_format(msm_framebuffer_format(fb))->cpp;
+
+	plane_bw = src_width * mode->vtotal * fps * bpp * scale_factor;
+
+	hw_latency_lines = 21; /* or 24? */
+	prefill_div = hw_latency_lines;
+	if (vbp + vpw > hw_latency_lines)
+		prefill_div = vbp + vpw;
+#if 0
+	else if (vbp + vpw + vfp < hw_latency_lines)
+		prefill_div = vbp + vpw + vfp;
+#endif
+
+	pstate->plane_bw = max(plane_bw, mult_frac(plane_bw, hw_latency_lines, prefill_div));
+}
+
 static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
 					      struct drm_plane_state *state)
 {
@@ -297,6 +337,8 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
 			mdp5_pipe_release(state->state, old_hwpipe);
 			mdp5_pipe_release(state->state, old_right_hwpipe);
 		}
+
+		mdp5_plane_calc_bw(state, crtc_state);
 	} else {
 		mdp5_pipe_release(state->state, mdp5_state->hwpipe);
 		mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management
  2021-05-25 13:13 ` [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management Dmitry Baryshkov
@ 2021-05-25 17:15   ` kernel test robot
  0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2021-05-25 17:15 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: kbuild-all, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, David Airlie, freedreno

[-- Attachment #1: Type: text/plain, Size: 3492 bytes --]

Hi Dmitry,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13-rc3 next-20210525]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Baryshkov/drm-msm-mdp5-add-properties-and-bandwidth-management/20210525-211559
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a050a6d2b7e80ca52b2f4141eaf3420d201b72b3
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/1077a27642ba4bcb15951c29bffdd94bfc378dbe
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dmitry-Baryshkov/drm-msm-mdp5-add-properties-and-bandwidth-management/20210525-211559
        git checkout 1077a27642ba4bcb15951c29bffdd94bfc378dbe
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c: In function 'mdp5_plane_calc_bw':
>> drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c:169:16: warning: variable 'vfp' set but not used [-Wunused-but-set-variable]
     169 |  int vbp, vpw, vfp;
         |                ^~~


vim +/vfp +169 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c

   156	
   157	/* based on _dpu_plane_calc_bw */
   158	static void mdp5_plane_calc_bw(struct drm_plane_state *state, struct drm_crtc_state *crtc_state)
   159	{
   160		struct drm_framebuffer *fb = state->fb;
   161		struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
   162		struct drm_display_mode *mode = &crtc_state->mode;
   163		int bpp;
   164		int src_width, src_height, dst_height, fps;
   165		u64 plane_bw;
   166		u32 hw_latency_lines;
   167		u32 prefill_div;
   168		u64 scale_factor;
 > 169		int vbp, vpw, vfp;
   170	
   171		src_width = drm_rect_width(&state->src) >> 16;
   172		src_height = drm_rect_height(&state->src) >> 16;
   173		dst_height = drm_rect_height(&state->dst);
   174		fps = drm_mode_vrefresh(mode);
   175		vbp = mode->vtotal - mode->vsync_end;
   176		vpw = mode->vsync_end - mode->vsync_start;
   177		vfp = mode->vsync_start - mode->vdisplay;
   178		scale_factor = src_height > dst_height ?
   179			mult_frac(src_height, 1, dst_height) : 1;
   180	
   181		bpp = to_mdp_format(msm_framebuffer_format(fb))->cpp;
   182	
   183		plane_bw = src_width * mode->vtotal * fps * bpp * scale_factor;
   184	
   185		hw_latency_lines = 21; /* or 24? */
   186		prefill_div = hw_latency_lines;
   187		if (vbp + vpw > hw_latency_lines)
   188			prefill_div = vbp + vpw;
   189	#if 0
   190		else if (vbp + vpw + vfp < hw_latency_lines)
   191			prefill_div = vbp + vpw + vfp;
   192	#endif
   193	
   194		pstate->plane_bw = max(plane_bw, mult_frac(plane_bw, hw_latency_lines, prefill_div));
   195	}
   196	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54736 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-05-25 17:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 13:13 [PATCH 0/7] drm/msm/mdp5: add properties and bandwidth management Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 1/7] drm/msm/mdp5: use drm atomic helpers to handle base drm plane state Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 2/7] drm/msm/mdp5: use drm_plane_state for storing alpha value Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 3/7] drm/msm/mdp5: use drm_plane_state for pixel blend mode Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 4/7] drm/msm/mdp5: add support for alpha/blend_mode properties Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 5/7] drm/msm/mdp5: switch to standard zpos property Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 6/7] drm/msm/mdp5: add perf blocks for holding fudge factors Dmitry Baryshkov
2021-05-25 13:13 ` [PATCH 7/7] drm/msm/mdp5: provide dynamic bandwidth management Dmitry Baryshkov
2021-05-25 17:15   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).