All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/6] Added scaler support for komeda
@ 2019-04-15  7:08 ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:08 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

This patch series added scaling and image enhancement support for komeda
driver.
Enabled two different scaling usage:
- layer scaling: scaling a input image before composite it with others
- write-back scaling: scaling the composition result and write it to
  memory.

This patchset depends on:
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58976/
- https://patchwork.freedesktop.org/series/59000/

James Qian Wang (Arm Technology China) (6):
  drm/komeda: Attach scaler to drm as private object
  drm/komeda: Add the initial scaler support for CORE
  drm/komeda: Implement D71 scaler support
  drm/komeda: Add writeback scaling support
  drm/komeda: Add engine clock requirement check for the downscaling
  drm/komeda: Add image enhancement support

 .../arm/display/komeda/d71/d71_component.c    | 177 +++++++++++++++++-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |   2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.h  |   2 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  67 ++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  14 +-
 .../drm/arm/display/komeda/komeda_pipeline.c  |  14 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  33 +++-
 .../display/komeda/komeda_pipeline_state.c    | 164 +++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_plane.c |  77 +++++++-
 .../arm/display/komeda/komeda_private_obj.c   |  49 +++++
 .../arm/display/komeda/komeda_wb_connector.c  |   2 +
 11 files changed, 585 insertions(+), 16 deletions(-)

-- 
2.17.1


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

* [PATCH v1 0/6] Added scaler support for komeda
@ 2019-04-15  7:08 ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:08 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: nd, Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jonathan Chai (Arm Technology China),
	linux-kernel, dri-devel, Julien Yin (Arm Technology China),
	james qian wang (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China)

This patch series added scaling and image enhancement support for komeda
driver.
Enabled two different scaling usage:
- layer scaling: scaling a input image before composite it with others
- write-back scaling: scaling the composition result and write it to
  memory.

This patchset depends on:
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58976/
- https://patchwork.freedesktop.org/series/59000/

James Qian Wang (Arm Technology China) (6):
  drm/komeda: Attach scaler to drm as private object
  drm/komeda: Add the initial scaler support for CORE
  drm/komeda: Implement D71 scaler support
  drm/komeda: Add writeback scaling support
  drm/komeda: Add engine clock requirement check for the downscaling
  drm/komeda: Add image enhancement support

 .../arm/display/komeda/d71/d71_component.c    | 177 +++++++++++++++++-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |   2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.h  |   2 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  67 ++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  14 +-
 .../drm/arm/display/komeda/komeda_pipeline.c  |  14 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  33 +++-
 .../display/komeda/komeda_pipeline_state.c    | 164 +++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_plane.c |  77 +++++++-
 .../arm/display/komeda/komeda_private_obj.c   |  49 +++++
 .../arm/display/komeda/komeda_wb_connector.c  |   2 +
 11 files changed, 585 insertions(+), 16 deletions(-)

-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 1/6] drm/komeda: Attach scaler to drm as private object
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

According to the komeda pipeline configuration, attach scaler to drm as
private object.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/komeda_private_obj.c   | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
index d53bd6c23c5d..bac90ab8fdc9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
@@ -60,6 +60,49 @@ static int komeda_layer_obj_add(struct komeda_kms_dev *kms,
 	return 0;
 }
 
+static struct drm_private_state *
+komeda_scaler_atomic_duplicate_state(struct drm_private_obj *obj)
+{
+	struct komeda_scaler_state *st;
+
+	st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return NULL;
+
+	komeda_component_state_reset(&st->base);
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
+
+	return &st->base.obj;
+}
+
+static void
+komeda_scaler_atomic_destroy_state(struct drm_private_obj *obj,
+				   struct drm_private_state *state)
+{
+	kfree(to_scaler_st(priv_to_comp_st(state)));
+}
+
+static const struct drm_private_state_funcs komeda_scaler_obj_funcs = {
+	.atomic_duplicate_state	= komeda_scaler_atomic_duplicate_state,
+	.atomic_destroy_state	= komeda_scaler_atomic_destroy_state,
+};
+
+static int komeda_scaler_obj_add(struct komeda_kms_dev *kms,
+				 struct komeda_scaler *scaler)
+{
+	struct komeda_scaler_state *st;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return -ENOMEM;
+
+	st->base.component = &scaler->base;
+	drm_atomic_private_obj_init(&kms->base,
+				    &scaler->base.obj, &st->base.obj,
+				    &komeda_scaler_obj_funcs);
+	return 0;
+}
+
 static struct drm_private_state *
 komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj)
 {
@@ -258,6 +301,12 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
 				return err;
 		}
 
+		for (j = 0; j < pipe->n_scalers; j++) {
+			err = komeda_scaler_obj_add(kms, pipe->scalers[j]);
+			if (err)
+				return err;
+		}
+
 		err = komeda_compiz_obj_add(kms, pipe->compiz);
 		if (err)
 			return err;
-- 
2.17.1


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

* [PATCH v1 1/6] drm/komeda: Attach scaler to drm as private object
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: nd, Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jonathan Chai (Arm Technology China),
	linux-kernel, dri-devel, Julien Yin (Arm Technology China),
	james qian wang (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China)

According to the komeda pipeline configuration, attach scaler to drm as
private object.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/komeda_private_obj.c   | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
index d53bd6c23c5d..bac90ab8fdc9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
@@ -60,6 +60,49 @@ static int komeda_layer_obj_add(struct komeda_kms_dev *kms,
 	return 0;
 }
 
+static struct drm_private_state *
+komeda_scaler_atomic_duplicate_state(struct drm_private_obj *obj)
+{
+	struct komeda_scaler_state *st;
+
+	st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return NULL;
+
+	komeda_component_state_reset(&st->base);
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
+
+	return &st->base.obj;
+}
+
+static void
+komeda_scaler_atomic_destroy_state(struct drm_private_obj *obj,
+				   struct drm_private_state *state)
+{
+	kfree(to_scaler_st(priv_to_comp_st(state)));
+}
+
+static const struct drm_private_state_funcs komeda_scaler_obj_funcs = {
+	.atomic_duplicate_state	= komeda_scaler_atomic_duplicate_state,
+	.atomic_destroy_state	= komeda_scaler_atomic_destroy_state,
+};
+
+static int komeda_scaler_obj_add(struct komeda_kms_dev *kms,
+				 struct komeda_scaler *scaler)
+{
+	struct komeda_scaler_state *st;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return -ENOMEM;
+
+	st->base.component = &scaler->base;
+	drm_atomic_private_obj_init(&kms->base,
+				    &scaler->base.obj, &st->base.obj,
+				    &komeda_scaler_obj_funcs);
+	return 0;
+}
+
 static struct drm_private_state *
 komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj)
 {
@@ -258,6 +301,12 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
 				return err;
 		}
 
+		for (j = 0; j < pipe->n_scalers; j++) {
+			err = komeda_scaler_obj_add(kms, pipe->scalers[j]);
+			if (err)
+				return err;
+		}
+
 		err = komeda_compiz_obj_add(kms, pipe->compiz);
 		if (err)
 			return err;
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 2/6] drm/komeda: Add the initial scaler support for CORE
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

This patch add the initial and necessary logic for CORE to support scaler:
- Complete the struct komeda_scaler and komeda_scaler_state for adding
  the scaler specific features and capablities.
- Implement komeda_scaler_validate to check the scaler with the data flow
  configurations.
- Enable scaling support for plane input path (layer input data flow).

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.c  |  14 +++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  20 ++-
 .../display/komeda/komeda_pipeline_state.c    | 116 ++++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   8 ++
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 07398efc40f5..d0c27a12ddbe 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -126,6 +126,20 @@ komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
 	return c;
 }
 
+struct komeda_component *
+komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
+				    u32 comp_mask)
+{
+	struct komeda_component *c = NULL;
+	int id;
+
+	id = find_first_bit((unsigned long *)&comp_mask, 32);
+	if (id < 32)
+		c = komeda_pipeline_get_component(pipe, id);
+
+	return c;
+}
+
 /** komeda_component_add - Add a component to &komeda_pipeline */
 struct komeda_component *
 komeda_component_add(struct komeda_pipeline *pipe,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index ba5bc0810c81..85d7ec341acc 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -244,11 +244,17 @@ struct komeda_layer_state {
 
 struct komeda_scaler {
 	struct komeda_component base;
-	/* scaler features and caps */
+	struct malidp_range hsize, vsize;
+	u32 max_upscaling;
+	u32 max_downscaling;
 };
 
 struct komeda_scaler_state {
 	struct komeda_component_state base;
+	u16 hsize_in, vsize_in;
+	u16 hsize_out, vsize_out;
+	u8 en_scaling : 1,
+	   en_alpha : 1; /* enable alpha processing */
 };
 
 struct komeda_compiz {
@@ -307,6 +313,7 @@ struct komeda_data_flow_cfg {
 	u32 rot;
 	int blending_zorder;
 	u8 pixel_blend_mode, layer_alpha;
+	u8 needs_scaling : 1;
 };
 
 /** struct komeda_pipeline_funcs */
@@ -407,6 +414,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev,
 int komeda_assemble_pipelines(struct komeda_dev *mdev);
 struct komeda_component *
 komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id);
+struct komeda_component *
+komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
+				    u32 comp_mask);
 
 void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
 				   struct seq_file *sf);
@@ -423,6 +433,14 @@ komeda_component_add(struct komeda_pipeline *pipe,
 void komeda_component_destroy(struct komeda_dev *mdev,
 			      struct komeda_component *c);
 
+static inline struct komeda_component *
+komeda_component_pickup_output(struct komeda_component *c, u32 avail_comps)
+{
+	u32 avail_inputs = c->supported_outputs & (avail_comps);
+
+	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
+}
+
 struct komeda_plane_state;
 struct komeda_crtc_state;
 struct komeda_crtc;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 9b29e9a9f49c..1dec321c727b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -247,6 +247,26 @@ komeda_component_validate_private(struct komeda_component *c,
 	return err;
 }
 
+/* Get current available scaler from the component->supported_outputs */
+static struct komeda_scaler *
+komeda_component_get_avail_scaler(struct komeda_component *c,
+				  struct drm_atomic_state *state)
+{
+	struct komeda_pipeline_state *pipe_st;
+	u32 avail_scalers;
+
+	pipe_st = komeda_pipeline_get_state(c->pipeline, state);
+	if (!pipe_st)
+		return NULL;
+
+	avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^
+			KOMEDA_PIPELINE_SCALERS;
+
+	c = komeda_component_pickup_output(c, avail_scalers);
+
+	return to_scaler(c);
+}
+
 static int
 komeda_layer_check_cfg(struct komeda_layer *layer,
 		       struct komeda_plane_state *kplane_st,
@@ -353,6 +373,98 @@ komeda_wb_layer_validate(struct komeda_layer *wb_layer,
 	return 0;
 }
 
+static bool scaling_ratio_valid(u32 size_in, u32 size_out,
+				u32 max_upscaling, u32 max_downscaling)
+{
+	if (size_out > size_in * max_upscaling)
+		return false;
+	else if (size_in > size_out * max_downscaling)
+		return false;
+	return true;
+}
+
+static int
+komeda_scaler_check_cfg(struct komeda_scaler *scaler,
+			struct komeda_data_flow_cfg *dflow)
+{
+	u32 hsize_in, vsize_in, hsize_out, vsize_out;
+
+	hsize_in = dflow->in_w;
+	vsize_in = dflow->in_h;
+	hsize_out = dflow->out_w;
+	vsize_out = dflow->out_h;
+
+	if (!in_range(&scaler->hsize, hsize_in) ||
+	    !in_range(&scaler->hsize, hsize_out)) {
+		DRM_DEBUG_ATOMIC("Invalid horizontal sizes");
+		return -EINVAL;
+	}
+
+	if (!in_range(&scaler->vsize, vsize_in) ||
+	    !in_range(&scaler->vsize, vsize_out)) {
+		DRM_DEBUG_ATOMIC("Invalid vertical sizes");
+		return -EINVAL;
+	}
+
+	if (!scaling_ratio_valid(hsize_in, hsize_out, scaler->max_upscaling,
+				 scaler->max_downscaling)) {
+		DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio");
+		return -EINVAL;
+	}
+
+	if (!scaling_ratio_valid(vsize_in, vsize_out, scaler->max_upscaling,
+				 scaler->max_downscaling)) {
+		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int
+komeda_scaler_validate(void *user,
+		       struct komeda_crtc_state *kcrtc_st,
+		       struct komeda_data_flow_cfg *dflow)
+{
+	struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+	struct komeda_component_state *c_st;
+	struct komeda_scaler_state *st;
+	struct komeda_scaler *scaler;
+	int err = 0;
+
+	if (!dflow->needs_scaling)
+		return 0;
+
+	scaler = komeda_component_get_avail_scaler(dflow->input.component,
+						   drm_st);
+	if (!scaler) {
+		DRM_DEBUG_ATOMIC("No scaler available");
+		return -EINVAL;
+	}
+
+	err = komeda_scaler_check_cfg(scaler, dflow);
+	if (err)
+		return err;
+
+	c_st = komeda_component_get_state_and_set_user(&scaler->base,
+			drm_st, user, kcrtc_st->base.crtc);
+	if (IS_ERR(c_st))
+		return PTR_ERR(c_st);
+
+	st = to_scaler_st(c_st);
+
+	st->hsize_in = dflow->in_w;
+	st->vsize_in = dflow->in_h;
+	st->hsize_out = dflow->out_w;
+	st->vsize_out = dflow->out_w;
+	st->en_scaling = dflow->needs_scaling;
+	/* Enable alpha processing if the next stage needs the pixel alpha */
+	st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE;
+
+	komeda_component_add_input(&st->base, &dflow->input, 0);
+	komeda_component_set_output(&dflow->input, &scaler->base, 0);
+	return err;
+}
+
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
 			       u16 *hsize, u16 *vsize)
 {
@@ -518,6 +630,10 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 	if (err)
 		return err;
 
+	err = komeda_scaler_validate(plane, kcrtc_st, dflow);
+	if (err)
+		return err;
+
 	err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow);
 
 	return err;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 14d68612052f..38c94e8f0ce2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -15,6 +15,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
 	struct drm_framebuffer *fb = st->fb;
+	u32 w, h;
 
 	memset(dflow, 0, sizeof(*dflow));
 
@@ -35,6 +36,13 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
+	w = dflow->in_w;
+	h = dflow->in_h;
+	if (drm_rotation_90_or_270(dflow->rot))
+		swap(w, h);
+
+	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+
 	return 0;
 }
 
-- 
2.17.1


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

* [PATCH v1 2/6] drm/komeda: Add the initial scaler support for CORE
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

This patch add the initial and necessary logic for CORE to support scaler:
- Complete the struct komeda_scaler and komeda_scaler_state for adding
  the scaler specific features and capablities.
- Implement komeda_scaler_validate to check the scaler with the data flow
  configurations.
- Enable scaling support for plane input path (layer input data flow).

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.c  |  14 +++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  20 ++-
 .../display/komeda/komeda_pipeline_state.c    | 116 ++++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   8 ++
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 07398efc40f5..d0c27a12ddbe 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -126,6 +126,20 @@ komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
 	return c;
 }
 
+struct komeda_component *
+komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
+				    u32 comp_mask)
+{
+	struct komeda_component *c = NULL;
+	int id;
+
+	id = find_first_bit((unsigned long *)&comp_mask, 32);
+	if (id < 32)
+		c = komeda_pipeline_get_component(pipe, id);
+
+	return c;
+}
+
 /** komeda_component_add - Add a component to &komeda_pipeline */
 struct komeda_component *
 komeda_component_add(struct komeda_pipeline *pipe,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index ba5bc0810c81..85d7ec341acc 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -244,11 +244,17 @@ struct komeda_layer_state {
 
 struct komeda_scaler {
 	struct komeda_component base;
-	/* scaler features and caps */
+	struct malidp_range hsize, vsize;
+	u32 max_upscaling;
+	u32 max_downscaling;
 };
 
 struct komeda_scaler_state {
 	struct komeda_component_state base;
+	u16 hsize_in, vsize_in;
+	u16 hsize_out, vsize_out;
+	u8 en_scaling : 1,
+	   en_alpha : 1; /* enable alpha processing */
 };
 
 struct komeda_compiz {
@@ -307,6 +313,7 @@ struct komeda_data_flow_cfg {
 	u32 rot;
 	int blending_zorder;
 	u8 pixel_blend_mode, layer_alpha;
+	u8 needs_scaling : 1;
 };
 
 /** struct komeda_pipeline_funcs */
@@ -407,6 +414,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev,
 int komeda_assemble_pipelines(struct komeda_dev *mdev);
 struct komeda_component *
 komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id);
+struct komeda_component *
+komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
+				    u32 comp_mask);
 
 void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
 				   struct seq_file *sf);
@@ -423,6 +433,14 @@ komeda_component_add(struct komeda_pipeline *pipe,
 void komeda_component_destroy(struct komeda_dev *mdev,
 			      struct komeda_component *c);
 
+static inline struct komeda_component *
+komeda_component_pickup_output(struct komeda_component *c, u32 avail_comps)
+{
+	u32 avail_inputs = c->supported_outputs & (avail_comps);
+
+	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
+}
+
 struct komeda_plane_state;
 struct komeda_crtc_state;
 struct komeda_crtc;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 9b29e9a9f49c..1dec321c727b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -247,6 +247,26 @@ komeda_component_validate_private(struct komeda_component *c,
 	return err;
 }
 
+/* Get current available scaler from the component->supported_outputs */
+static struct komeda_scaler *
+komeda_component_get_avail_scaler(struct komeda_component *c,
+				  struct drm_atomic_state *state)
+{
+	struct komeda_pipeline_state *pipe_st;
+	u32 avail_scalers;
+
+	pipe_st = komeda_pipeline_get_state(c->pipeline, state);
+	if (!pipe_st)
+		return NULL;
+
+	avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^
+			KOMEDA_PIPELINE_SCALERS;
+
+	c = komeda_component_pickup_output(c, avail_scalers);
+
+	return to_scaler(c);
+}
+
 static int
 komeda_layer_check_cfg(struct komeda_layer *layer,
 		       struct komeda_plane_state *kplane_st,
@@ -353,6 +373,98 @@ komeda_wb_layer_validate(struct komeda_layer *wb_layer,
 	return 0;
 }
 
+static bool scaling_ratio_valid(u32 size_in, u32 size_out,
+				u32 max_upscaling, u32 max_downscaling)
+{
+	if (size_out > size_in * max_upscaling)
+		return false;
+	else if (size_in > size_out * max_downscaling)
+		return false;
+	return true;
+}
+
+static int
+komeda_scaler_check_cfg(struct komeda_scaler *scaler,
+			struct komeda_data_flow_cfg *dflow)
+{
+	u32 hsize_in, vsize_in, hsize_out, vsize_out;
+
+	hsize_in = dflow->in_w;
+	vsize_in = dflow->in_h;
+	hsize_out = dflow->out_w;
+	vsize_out = dflow->out_h;
+
+	if (!in_range(&scaler->hsize, hsize_in) ||
+	    !in_range(&scaler->hsize, hsize_out)) {
+		DRM_DEBUG_ATOMIC("Invalid horizontal sizes");
+		return -EINVAL;
+	}
+
+	if (!in_range(&scaler->vsize, vsize_in) ||
+	    !in_range(&scaler->vsize, vsize_out)) {
+		DRM_DEBUG_ATOMIC("Invalid vertical sizes");
+		return -EINVAL;
+	}
+
+	if (!scaling_ratio_valid(hsize_in, hsize_out, scaler->max_upscaling,
+				 scaler->max_downscaling)) {
+		DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio");
+		return -EINVAL;
+	}
+
+	if (!scaling_ratio_valid(vsize_in, vsize_out, scaler->max_upscaling,
+				 scaler->max_downscaling)) {
+		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int
+komeda_scaler_validate(void *user,
+		       struct komeda_crtc_state *kcrtc_st,
+		       struct komeda_data_flow_cfg *dflow)
+{
+	struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+	struct komeda_component_state *c_st;
+	struct komeda_scaler_state *st;
+	struct komeda_scaler *scaler;
+	int err = 0;
+
+	if (!dflow->needs_scaling)
+		return 0;
+
+	scaler = komeda_component_get_avail_scaler(dflow->input.component,
+						   drm_st);
+	if (!scaler) {
+		DRM_DEBUG_ATOMIC("No scaler available");
+		return -EINVAL;
+	}
+
+	err = komeda_scaler_check_cfg(scaler, dflow);
+	if (err)
+		return err;
+
+	c_st = komeda_component_get_state_and_set_user(&scaler->base,
+			drm_st, user, kcrtc_st->base.crtc);
+	if (IS_ERR(c_st))
+		return PTR_ERR(c_st);
+
+	st = to_scaler_st(c_st);
+
+	st->hsize_in = dflow->in_w;
+	st->vsize_in = dflow->in_h;
+	st->hsize_out = dflow->out_w;
+	st->vsize_out = dflow->out_w;
+	st->en_scaling = dflow->needs_scaling;
+	/* Enable alpha processing if the next stage needs the pixel alpha */
+	st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE;
+
+	komeda_component_add_input(&st->base, &dflow->input, 0);
+	komeda_component_set_output(&dflow->input, &scaler->base, 0);
+	return err;
+}
+
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
 			       u16 *hsize, u16 *vsize)
 {
@@ -518,6 +630,10 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 	if (err)
 		return err;
 
+	err = komeda_scaler_validate(plane, kcrtc_st, dflow);
+	if (err)
+		return err;
+
 	err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow);
 
 	return err;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 14d68612052f..38c94e8f0ce2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -15,6 +15,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
 	struct drm_framebuffer *fb = st->fb;
+	u32 w, h;
 
 	memset(dflow, 0, sizeof(*dflow));
 
@@ -35,6 +36,13 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
+	w = dflow->in_w;
+	h = dflow->in_h;
+	if (drm_rotation_90_or_270(dflow->rot))
+		swap(w, h);
+
+	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+
 	return 0;
 }
 
-- 
2.17.1


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

* [PATCH v1 3/6] drm/komeda: Implement D71 scaler support
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

1. Add scaler component and initialize it according to D71 HW.
2. Implement d71_scaler_update/disable/dump

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    | 131 +++++++++++++++++-
 1 file changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 33ca1718b5cd..5a4c8fd122da 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -551,6 +551,132 @@ static int d71_compiz_init(struct d71_dev *d71,
 	return 0;
 }
 
+static void d71_scaler_update_filter_lut(u32 __iomem *reg, u32 hsize_in,
+					 u32 vsize_in, u32 hsize_out,
+					 u32 vsize_out)
+{
+	u32 val = 0;
+
+	if (hsize_in <= hsize_out)
+		val  |= 0x62;
+	else if (hsize_in <= (hsize_out + hsize_out / 2))
+		val |= 0x63;
+	else if (hsize_in <= hsize_out * 2)
+		val |= 0x64;
+	else if (hsize_in <= hsize_out * 2 + (hsize_out * 3) / 4)
+		val |= 0x65;
+	else
+		val |= 0x66;
+
+	if (vsize_in <= vsize_out)
+		val  |= SC_VTSEL(0x6A);
+	else if (vsize_in <= (vsize_out + vsize_out / 2))
+		val |= SC_VTSEL(0x6B);
+	else if (vsize_in <= vsize_out * 2)
+		val |= SC_VTSEL(0x6C);
+	else if (vsize_in <= vsize_out * 2 + vsize_out * 3 / 4)
+		val |= SC_VTSEL(0x6D);
+	else
+		val |= SC_VTSEL(0x6E);
+
+	malidp_write32(reg, SC_COEFFTAB, val);
+}
+
+static void d71_scaler_update(struct komeda_component *c,
+			      struct komeda_component_state *state)
+{
+	struct komeda_scaler_state *st = to_scaler_st(state);
+	u32 __iomem *reg = c->reg;
+	u32 init_ph, delta_ph, ctrl;
+
+	d71_scaler_update_filter_lut(reg, st->hsize_in, st->vsize_in,
+				     st->hsize_out, st->vsize_out);
+
+	malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize_in, st->vsize_in));
+	malidp_write32(reg, SC_OUT_SIZE, HV_SIZE(st->hsize_out, st->vsize_out));
+
+	init_ph = (st->hsize_in << 15) / st->hsize_out;
+	malidp_write32(reg, SC_H_INIT_PH, init_ph);
+
+	delta_ph = (st->hsize_in << 16) / st->hsize_out;
+	malidp_write32(reg, SC_H_DELTA_PH, delta_ph);
+
+	init_ph = (st->vsize_in << 15) / st->vsize_out;
+	malidp_write32(reg, SC_V_INIT_PH, init_ph);
+
+	delta_ph = (st->vsize_in << 16) / st->vsize_out;
+	malidp_write32(reg, SC_V_DELTA_PH, delta_ph);
+
+	ctrl = 0;
+	ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
+	ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+
+	malidp_write32(reg, BLK_CONTROL, ctrl);
+	malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
+}
+
+static void d71_scaler_dump(struct komeda_component *c, struct seq_file *sf)
+{
+	u32 v[9];
+
+	dump_block_header(sf, c->reg);
+
+	get_values_from_reg(c->reg, 0x80, 1, v);
+	seq_printf(sf, "SC_INPUT_ID0:\t\t0x%X\n", v[0]);
+
+	get_values_from_reg(c->reg, 0xD0, 1, v);
+	seq_printf(sf, "SC_CONTROL:\t\t0x%X\n", v[0]);
+
+	get_values_from_reg(c->reg, 0xDC, 9, v);
+	seq_printf(sf, "SC_COEFFTAB:\t\t0x%X\n", v[0]);
+	seq_printf(sf, "SC_IN_SIZE:\t\t0x%X\n", v[1]);
+	seq_printf(sf, "SC_OUT_SIZE:\t\t0x%X\n", v[2]);
+	seq_printf(sf, "SC_H_CROP:\t\t0x%X\n", v[3]);
+	seq_printf(sf, "SC_V_CROP:\t\t0x%X\n", v[4]);
+	seq_printf(sf, "SC_H_INIT_PH:\t\t0x%X\n", v[5]);
+	seq_printf(sf, "SC_H_DELTA_PH:\t\t0x%X\n", v[6]);
+	seq_printf(sf, "SC_V_INIT_PH:\t\t0x%X\n", v[7]);
+	seq_printf(sf, "SC_V_DELTA_PH:\t\t0x%X\n", v[8]);
+}
+
+static struct komeda_component_funcs d71_scaler_funcs = {
+	.update		= d71_scaler_update,
+	.disable	= d71_component_disable,
+	.dump_register	= d71_scaler_dump,
+};
+
+static int d71_scaler_init(struct d71_dev *d71,
+			   struct block_header *blk, u32 __iomem *reg)
+{
+	struct komeda_component *c;
+	struct komeda_scaler *scaler;
+	u32 pipe_id, comp_id;
+
+	get_resources_id(blk->block_info, &pipe_id, &comp_id);
+
+	c = komeda_component_add(&d71->pipes[pipe_id]->base, sizeof(*scaler),
+				 comp_id, BLOCK_INFO_INPUT_ID(blk->block_info),
+				 &d71_scaler_funcs,
+				 1, get_valid_inputs(blk), 1, reg,
+				 "CU%d_SCALER%d",
+				 pipe_id, BLOCK_INFO_BLK_ID(blk->block_info));
+
+	if (!c) {
+		DRM_ERROR("Failed to initialize scaler");
+		return -1;
+	}
+
+	scaler = to_scaler(c);
+	set_range(&scaler->hsize, 4, d71->max_line_size);
+	set_range(&scaler->vsize, 4, 4096);
+	scaler->max_downscaling = 6;
+	scaler->max_upscaling = 64;
+
+	malidp_write32(c->reg, BLK_CONTROL, 0);
+
+	return 0;
+}
+
 static void d71_improc_update(struct komeda_component *c,
 			      struct komeda_component_state *state)
 {
@@ -770,8 +896,11 @@ int d71_probe_block(struct d71_dev *d71,
 		err = d71_compiz_init(d71, blk, reg);
 		break;
 
-	case D71_BLK_TYPE_CU_SPLITTER:
 	case D71_BLK_TYPE_CU_SCALER:
+		err = d71_scaler_init(d71, blk, reg);
+		break;
+
+	case D71_BLK_TYPE_CU_SPLITTER:
 	case D71_BLK_TYPE_CU_MERGER:
 		break;
 
-- 
2.17.1


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

* [PATCH v1 3/6] drm/komeda: Implement D71 scaler support
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: nd, Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jonathan Chai (Arm Technology China),
	linux-kernel, dri-devel, Julien Yin (Arm Technology China),
	james qian wang (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China)

1. Add scaler component and initialize it according to D71 HW.
2. Implement d71_scaler_update/disable/dump

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    | 131 +++++++++++++++++-
 1 file changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 33ca1718b5cd..5a4c8fd122da 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -551,6 +551,132 @@ static int d71_compiz_init(struct d71_dev *d71,
 	return 0;
 }
 
+static void d71_scaler_update_filter_lut(u32 __iomem *reg, u32 hsize_in,
+					 u32 vsize_in, u32 hsize_out,
+					 u32 vsize_out)
+{
+	u32 val = 0;
+
+	if (hsize_in <= hsize_out)
+		val  |= 0x62;
+	else if (hsize_in <= (hsize_out + hsize_out / 2))
+		val |= 0x63;
+	else if (hsize_in <= hsize_out * 2)
+		val |= 0x64;
+	else if (hsize_in <= hsize_out * 2 + (hsize_out * 3) / 4)
+		val |= 0x65;
+	else
+		val |= 0x66;
+
+	if (vsize_in <= vsize_out)
+		val  |= SC_VTSEL(0x6A);
+	else if (vsize_in <= (vsize_out + vsize_out / 2))
+		val |= SC_VTSEL(0x6B);
+	else if (vsize_in <= vsize_out * 2)
+		val |= SC_VTSEL(0x6C);
+	else if (vsize_in <= vsize_out * 2 + vsize_out * 3 / 4)
+		val |= SC_VTSEL(0x6D);
+	else
+		val |= SC_VTSEL(0x6E);
+
+	malidp_write32(reg, SC_COEFFTAB, val);
+}
+
+static void d71_scaler_update(struct komeda_component *c,
+			      struct komeda_component_state *state)
+{
+	struct komeda_scaler_state *st = to_scaler_st(state);
+	u32 __iomem *reg = c->reg;
+	u32 init_ph, delta_ph, ctrl;
+
+	d71_scaler_update_filter_lut(reg, st->hsize_in, st->vsize_in,
+				     st->hsize_out, st->vsize_out);
+
+	malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize_in, st->vsize_in));
+	malidp_write32(reg, SC_OUT_SIZE, HV_SIZE(st->hsize_out, st->vsize_out));
+
+	init_ph = (st->hsize_in << 15) / st->hsize_out;
+	malidp_write32(reg, SC_H_INIT_PH, init_ph);
+
+	delta_ph = (st->hsize_in << 16) / st->hsize_out;
+	malidp_write32(reg, SC_H_DELTA_PH, delta_ph);
+
+	init_ph = (st->vsize_in << 15) / st->vsize_out;
+	malidp_write32(reg, SC_V_INIT_PH, init_ph);
+
+	delta_ph = (st->vsize_in << 16) / st->vsize_out;
+	malidp_write32(reg, SC_V_DELTA_PH, delta_ph);
+
+	ctrl = 0;
+	ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
+	ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+
+	malidp_write32(reg, BLK_CONTROL, ctrl);
+	malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
+}
+
+static void d71_scaler_dump(struct komeda_component *c, struct seq_file *sf)
+{
+	u32 v[9];
+
+	dump_block_header(sf, c->reg);
+
+	get_values_from_reg(c->reg, 0x80, 1, v);
+	seq_printf(sf, "SC_INPUT_ID0:\t\t0x%X\n", v[0]);
+
+	get_values_from_reg(c->reg, 0xD0, 1, v);
+	seq_printf(sf, "SC_CONTROL:\t\t0x%X\n", v[0]);
+
+	get_values_from_reg(c->reg, 0xDC, 9, v);
+	seq_printf(sf, "SC_COEFFTAB:\t\t0x%X\n", v[0]);
+	seq_printf(sf, "SC_IN_SIZE:\t\t0x%X\n", v[1]);
+	seq_printf(sf, "SC_OUT_SIZE:\t\t0x%X\n", v[2]);
+	seq_printf(sf, "SC_H_CROP:\t\t0x%X\n", v[3]);
+	seq_printf(sf, "SC_V_CROP:\t\t0x%X\n", v[4]);
+	seq_printf(sf, "SC_H_INIT_PH:\t\t0x%X\n", v[5]);
+	seq_printf(sf, "SC_H_DELTA_PH:\t\t0x%X\n", v[6]);
+	seq_printf(sf, "SC_V_INIT_PH:\t\t0x%X\n", v[7]);
+	seq_printf(sf, "SC_V_DELTA_PH:\t\t0x%X\n", v[8]);
+}
+
+static struct komeda_component_funcs d71_scaler_funcs = {
+	.update		= d71_scaler_update,
+	.disable	= d71_component_disable,
+	.dump_register	= d71_scaler_dump,
+};
+
+static int d71_scaler_init(struct d71_dev *d71,
+			   struct block_header *blk, u32 __iomem *reg)
+{
+	struct komeda_component *c;
+	struct komeda_scaler *scaler;
+	u32 pipe_id, comp_id;
+
+	get_resources_id(blk->block_info, &pipe_id, &comp_id);
+
+	c = komeda_component_add(&d71->pipes[pipe_id]->base, sizeof(*scaler),
+				 comp_id, BLOCK_INFO_INPUT_ID(blk->block_info),
+				 &d71_scaler_funcs,
+				 1, get_valid_inputs(blk), 1, reg,
+				 "CU%d_SCALER%d",
+				 pipe_id, BLOCK_INFO_BLK_ID(blk->block_info));
+
+	if (!c) {
+		DRM_ERROR("Failed to initialize scaler");
+		return -1;
+	}
+
+	scaler = to_scaler(c);
+	set_range(&scaler->hsize, 4, d71->max_line_size);
+	set_range(&scaler->vsize, 4, 4096);
+	scaler->max_downscaling = 6;
+	scaler->max_upscaling = 64;
+
+	malidp_write32(c->reg, BLK_CONTROL, 0);
+
+	return 0;
+}
+
 static void d71_improc_update(struct komeda_component *c,
 			      struct komeda_component_state *state)
 {
@@ -770,8 +896,11 @@ int d71_probe_block(struct d71_dev *d71,
 		err = d71_compiz_init(d71, blk, reg);
 		break;
 
-	case D71_BLK_TYPE_CU_SPLITTER:
 	case D71_BLK_TYPE_CU_SCALER:
+		err = d71_scaler_init(d71, blk, reg);
+		break;
+
+	case D71_BLK_TYPE_CU_SPLITTER:
 	case D71_BLK_TYPE_CU_MERGER:
 		break;
 
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 4/6] drm/komeda: Add writeback scaling support
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

1. Add scaler to writeback pipeline to enable the writeback scaling support
2. Display HW can not do upscaling for writeback, check it when validate.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  2 ++
 .../display/komeda/komeda_pipeline_state.c    | 36 +++++++++++++++----
 .../gpu/drm/arm/display/komeda/komeda_plane.c |  8 +----
 .../arm/display/komeda/komeda_wb_connector.c  |  2 ++
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 85d7ec341acc..bfad7d03f801 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -470,4 +470,6 @@ void komeda_pipeline_disable(struct komeda_pipeline *pipe,
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
 			    struct drm_atomic_state *old_state);
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 1dec321c727b..c6f19969fc10 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -388,6 +388,7 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 			struct komeda_data_flow_cfg *dflow)
 {
 	u32 hsize_in, vsize_in, hsize_out, vsize_out;
+	u32 max_upscaling;
 
 	hsize_in = dflow->in_w;
 	vsize_in = dflow->in_h;
@@ -406,13 +407,21 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 		return -EINVAL;
 	}
 
-	if (!scaling_ratio_valid(hsize_in, hsize_out, scaler->max_upscaling,
+	/* If input comes from compiz that means the scaling is for writeback
+	 * and scaler can not do upscaling for writeback
+	 */
+	if (has_bit(dflow->input.component->id, KOMEDA_PIPELINE_COMPIZS))
+		max_upscaling = 1;
+	else
+		max_upscaling = scaler->max_upscaling;
+
+	if (!scaling_ratio_valid(hsize_in, hsize_out, max_upscaling,
 				 scaler->max_downscaling)) {
 		DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio");
 		return -EINVAL;
 	}
 
-	if (!scaling_ratio_valid(vsize_in, vsize_out, scaler->max_upscaling,
+	if (!scaling_ratio_valid(vsize_in, vsize_out, max_upscaling,
 				 scaler->max_downscaling)) {
 		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
 		return -EINVAL;
@@ -612,6 +621,17 @@ komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr,
 	return 0;
 }
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow)
+{
+	u32 w = dflow->in_w;
+	u32 h = dflow->in_h;
+
+	if (drm_rotation_90_or_270(dflow->rot))
+		swap(w, h);
+
+	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+}
+
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
 				 struct komeda_plane_state *kplane_st,
 				 struct komeda_crtc_state *kcrtc_st,
@@ -639,16 +659,18 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 	return err;
 }
 
+/* writeback data path: compiz -> scaler -> wb_layer -> memory */
 int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
 			      struct drm_connector_state *conn_st,
 			      struct komeda_crtc_state *kcrtc_st,
 			      struct komeda_data_flow_cfg *dflow)
 {
-	if ((dflow->in_w != dflow->out_w) ||
-	    (dflow->in_h != dflow->out_h)) {
-		DRM_DEBUG_ATOMIC("current do not support scaling writeback.\n");
-		return -EINVAL;
-	}
+	struct drm_connector *conn = conn_st->connector;
+	int err;
+
+	err = komeda_scaler_validate(conn, kcrtc_st, dflow);
+	if (err)
+		return err;
 
 	return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 38c94e8f0ce2..5de462172151 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -15,7 +15,6 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
 	struct drm_framebuffer *fb = st->fb;
-	u32 w, h;
 
 	memset(dflow, 0, sizeof(*dflow));
 
@@ -36,12 +35,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
-	w = dflow->in_w;
-	h = dflow->in_h;
-	if (drm_rotation_90_or_270(dflow->rot))
-		swap(w, h);
-
-	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+	komeda_complete_data_flow_cfg(dflow);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 0c1a4220c280..eed521218ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -31,6 +31,8 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
 	dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
 	dflow->rot = DRM_MODE_ROTATE_0;
 
+	komeda_complete_data_flow_cfg(dflow);
+
 	return 0;
 }
 
-- 
2.17.1


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

* [PATCH v1 4/6] drm/komeda: Add writeback scaling support
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: nd, Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jonathan Chai (Arm Technology China),
	linux-kernel, dri-devel, Julien Yin (Arm Technology China),
	james qian wang (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China)

1. Add scaler to writeback pipeline to enable the writeback scaling support
2. Display HW can not do upscaling for writeback, check it when validate.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  2 ++
 .../display/komeda/komeda_pipeline_state.c    | 36 +++++++++++++++----
 .../gpu/drm/arm/display/komeda/komeda_plane.c |  8 +----
 .../arm/display/komeda/komeda_wb_connector.c  |  2 ++
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 85d7ec341acc..bfad7d03f801 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -470,4 +470,6 @@ void komeda_pipeline_disable(struct komeda_pipeline *pipe,
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
 			    struct drm_atomic_state *old_state);
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 1dec321c727b..c6f19969fc10 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -388,6 +388,7 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 			struct komeda_data_flow_cfg *dflow)
 {
 	u32 hsize_in, vsize_in, hsize_out, vsize_out;
+	u32 max_upscaling;
 
 	hsize_in = dflow->in_w;
 	vsize_in = dflow->in_h;
@@ -406,13 +407,21 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 		return -EINVAL;
 	}
 
-	if (!scaling_ratio_valid(hsize_in, hsize_out, scaler->max_upscaling,
+	/* If input comes from compiz that means the scaling is for writeback
+	 * and scaler can not do upscaling for writeback
+	 */
+	if (has_bit(dflow->input.component->id, KOMEDA_PIPELINE_COMPIZS))
+		max_upscaling = 1;
+	else
+		max_upscaling = scaler->max_upscaling;
+
+	if (!scaling_ratio_valid(hsize_in, hsize_out, max_upscaling,
 				 scaler->max_downscaling)) {
 		DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio");
 		return -EINVAL;
 	}
 
-	if (!scaling_ratio_valid(vsize_in, vsize_out, scaler->max_upscaling,
+	if (!scaling_ratio_valid(vsize_in, vsize_out, max_upscaling,
 				 scaler->max_downscaling)) {
 		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
 		return -EINVAL;
@@ -612,6 +621,17 @@ komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr,
 	return 0;
 }
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow)
+{
+	u32 w = dflow->in_w;
+	u32 h = dflow->in_h;
+
+	if (drm_rotation_90_or_270(dflow->rot))
+		swap(w, h);
+
+	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+}
+
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
 				 struct komeda_plane_state *kplane_st,
 				 struct komeda_crtc_state *kcrtc_st,
@@ -639,16 +659,18 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 	return err;
 }
 
+/* writeback data path: compiz -> scaler -> wb_layer -> memory */
 int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
 			      struct drm_connector_state *conn_st,
 			      struct komeda_crtc_state *kcrtc_st,
 			      struct komeda_data_flow_cfg *dflow)
 {
-	if ((dflow->in_w != dflow->out_w) ||
-	    (dflow->in_h != dflow->out_h)) {
-		DRM_DEBUG_ATOMIC("current do not support scaling writeback.\n");
-		return -EINVAL;
-	}
+	struct drm_connector *conn = conn_st->connector;
+	int err;
+
+	err = komeda_scaler_validate(conn, kcrtc_st, dflow);
+	if (err)
+		return err;
 
 	return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 38c94e8f0ce2..5de462172151 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -15,7 +15,6 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
 	struct drm_framebuffer *fb = st->fb;
-	u32 w, h;
 
 	memset(dflow, 0, sizeof(*dflow));
 
@@ -36,12 +35,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
-	w = dflow->in_w;
-	h = dflow->in_h;
-	if (drm_rotation_90_or_270(dflow->rot))
-		swap(w, h);
-
-	dflow->needs_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+	komeda_complete_data_flow_cfg(dflow);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 0c1a4220c280..eed521218ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -31,6 +31,8 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
 	dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
 	dflow->rot = DRM_MODE_ROTATE_0;
 
+	komeda_complete_data_flow_cfg(dflow);
+
 	return 0;
 }
 
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 5/6] drm/komeda: Add engine clock requirement check for the downscaling
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

For downscaling there is a restriction, the downscaling needed engine
clock can not acceed the real engine clock, and the clock requirement
mostly depend on the specific HW, to solve this problem:
1. Add a pipeline func - downscaling_clk_check for CORE to query the real
   HW if downscaling can be supported.
2. Add new property clock ratio which is the ratio of:
     (mclk << 32) / pxlclk
   then User driver can use this ratio to do the clock check to avoid post
   an invalid downscaling to kernel.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    | 45 +++++++++++++
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.h  |  2 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 67 ++++++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  8 +++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  9 ++-
 .../display/komeda/komeda_pipeline_state.c    | 17 ++++-
 7 files changed, 144 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 5a4c8fd122da..bf214dc9e372 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -677,6 +677,47 @@ static int d71_scaler_init(struct d71_dev *d71,
 	return 0;
 }
 
+static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
+				     struct drm_display_mode *mode,
+				     unsigned long mclk_rate,
+				     struct komeda_data_flow_cfg *dflow)
+{
+	u32 h_in = dflow->in_w;
+	u32 v_in = dflow->in_h;
+	u32 v_out = dflow->out_h;
+	u64 fraction, denominator;
+
+	/* D71 downscaling must satisfy the following equation
+	 *
+	 *   MCLK                   h_in * v_in
+	 * ------- >= ---------------------------------------------
+	 *  PXLCLK     (h_total - (1 + 2 * v_in / v_out)) * v_out
+	 *
+	 * In only horizontal downscaling situation, the right side should be
+	 * multiplied by (h_total - 3) / (h_active - 3), then equation becomes
+	 *
+	 *   MCLK          h_in
+	 * ------- >= ----------------
+	 *  PXLCLK     (h_active - 3)
+	 *
+	 * To avoid precision lost the equation 1 will be convert to:
+	 *
+	 *   MCLK             h_in * v_in
+	 * ------- >= -----------------------------------
+	 *  PXLCLK     (h_total -1 ) * v_out -  2 * v_in
+	 */
+	if (v_in == v_out) {
+		fraction = h_in;
+		denominator = mode->hdisplay - 3;
+	} else {
+		fraction = h_in * v_in;
+		denominator = (mode->htotal - 1) * v_out -  2 * v_in;
+	}
+
+	return mclk_rate * denominator >= mode->clock * 1000 * fraction ?
+	       0 : -EINVAL;
+}
+
 static void d71_improc_update(struct komeda_component *c,
 			      struct komeda_component_state *state)
 {
@@ -938,3 +979,7 @@ int d71_probe_block(struct d71_dev *d71,
 
 	return err;
 }
+
+struct komeda_pipeline_funcs d71_pipeline_funcs = {
+	.downscaling_clk_check = d71_downscaling_clk_check,
+};
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 34506ef7ad40..dd99e06180fd 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -390,7 +390,7 @@ static int d71_enum_resources(struct komeda_dev *mdev)
 
 	for (i = 0; i < d71->num_pipelines; i++) {
 		pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
-					   NULL);
+					   &d71_pipeline_funcs);
 		if (IS_ERR(pipe)) {
 			err = PTR_ERR(pipe);
 			goto err_cleanup;
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
index 7465c57d9774..40f87955ee16 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
@@ -43,6 +43,8 @@ struct d71_dev {
 
 #define to_d71_pipeline(x)	container_of(x, struct d71_pipeline, base)
 
+extern struct komeda_pipeline_funcs d71_pipeline_funcs;
+
 int d71_probe_block(struct d71_dev *d71,
 		    struct block_header *blk, u32 __iomem *reg);
 void d71_read_block_header(u32 __iomem *reg, struct block_header *blk);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index c0e98605def8..817ae892f7b4 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -18,6 +18,22 @@
 #include "komeda_dev.h"
 #include "komeda_kms.h"
 
+static void komeda_crtc_update_clock_ratio(struct komeda_crtc_state *kcrtc_st)
+{
+	u64 pxlclk, mclk;
+
+	if (!kcrtc_st->base.active) {
+		kcrtc_st->clock_ratio = 0;
+		return;
+	}
+
+	pxlclk = kcrtc_st->base.adjusted_mode.clock * 1000;
+	mclk = komeda_calc_mclk(kcrtc_st) << 32;
+
+	do_div(mclk, pxlclk);
+	kcrtc_st->clock_ratio = mclk;
+}
+
 /**
  * komeda_crtc_atomic_check - build display output data flow
  * @crtc: DRM crtc
@@ -38,6 +54,9 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
 	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
 	int err;
 
+	if (drm_atomic_crtc_needs_modeset(state))
+		komeda_crtc_update_clock_ratio(kcrtc_st);
+
 	if (state->active) {
 		err = komeda_build_display_data_flow(kcrtc, kcrtc_st);
 		if (err)
@@ -52,11 +71,12 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
+unsigned long komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
 {
-	unsigned long mclk = kcrtc_st->base.adjusted_mode.clock * 1000;
+	struct komeda_dev *mdev = kcrtc_st->base.crtc->dev->dev_private;
+	unsigned long pxlclk = kcrtc_st->base.adjusted_mode.clock;
 
-	return mclk;
+	return clk_round_rate(mdev->mclk, pxlclk * 1000);
 }
 
 /* For active a crtc, mainly need two parts of preparation
@@ -404,6 +424,7 @@ komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &new->base);
 
 	new->affected_pipes = old->active_pipes;
+	new->clock_ratio = old->clock_ratio;
 
 	return &new->base;
 }
@@ -432,6 +453,25 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
 	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, false);
 }
 
+static int
+komeda_crtc_atomic_get_property(struct drm_crtc *crtc,
+				const struct drm_crtc_state *state,
+				struct drm_property *property, uint64_t *val)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
+
+	if (property == kcrtc->clock_ratio_property) {
+		*val = kcrtc_st->clock_ratio;
+		pr_info("Get property: %llu.\n", kcrtc_st->clock_ratio);
+	} else {
+		DRM_DEBUG_DRIVER("Unknown property %s\n", property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
 	.gamma_set		= drm_atomic_helper_legacy_gamma_set,
 	.destroy		= drm_crtc_cleanup,
@@ -442,6 +482,7 @@ static const struct drm_crtc_funcs komeda_crtc_funcs = {
 	.atomic_destroy_state	= komeda_crtc_atomic_destroy_state,
 	.enable_vblank		= komeda_crtc_vblank_enable,
 	.disable_vblank		= komeda_crtc_vblank_disable,
+	.atomic_get_property	= komeda_crtc_atomic_get_property,
 };
 
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
@@ -477,6 +518,22 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
 	return 0;
 }
 
+static int komeda_crtc_create_clock_ratio_property(struct komeda_crtc *kcrtc)
+{
+	struct drm_crtc *crtc = &kcrtc->base;
+	struct drm_property *prop;
+
+	prop = drm_property_create_range(crtc->dev, DRM_MODE_PROP_ATOMIC,
+					 "CLOCK_RATIO", 0, U64_MAX);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&crtc->base, prop, 0);
+	kcrtc->clock_ratio_property = prop;
+
+	return 0;
+}
+
 static struct drm_plane *
 get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc)
 {
@@ -513,6 +570,10 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
 	crtc->port = kcrtc->master->of_output_port;
 
+	err = komeda_crtc_create_clock_ratio_property(kcrtc);
+	if (err)
+		return err;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index f16e9e577593..db59a9042beb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -79,6 +79,9 @@ struct komeda_crtc {
 
 	/** @disable_done: this flip_done is for tracing the disable */
 	struct completion *disable_done;
+
+	/** @clock_ratio_property: property for ratio of (mclk << 32)/pxlclk */
+	struct drm_property *clock_ratio_property;
 };
 
 /**
@@ -101,6 +104,9 @@ struct komeda_crtc_state {
 	 * the active pipelines in once display instance
 	 */
 	u32 active_pipes;
+
+	/** @clock_ratio: ratio of (mclk << 32)/pxlclk */
+	u64 clock_ratio;
 };
 
 /** struct komeda_kms_dev - for gather KMS related things */
@@ -142,6 +148,8 @@ is_only_changed_connector(struct drm_crtc_state *st, struct drm_connector *conn)
 	return BIT(drm_connector_index(conn)) == changed_connectors;
 }
 
+unsigned long komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st);
+
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
 
 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bfad7d03f801..b26c8552a2d1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -316,8 +316,15 @@ struct komeda_data_flow_cfg {
 	u8 needs_scaling : 1;
 };
 
-/** struct komeda_pipeline_funcs */
+/* struct komeda_pipeline_funcs */
 struct komeda_pipeline_funcs {
+	/* check if the mclk (main engine clock) can satisfy the clock
+	 * requirements of the downscaling that specified by dflow
+	 */
+	int (*downscaling_clk_check)(struct komeda_pipeline *pipe,
+				     struct drm_display_mode *mode,
+				     unsigned long mclk_rate,
+				     struct komeda_data_flow_cfg *dflow);
 	/* dump_register: Optional, dump registers to seq_file */
 	void (*dump_register)(struct komeda_pipeline *pipe,
 			      struct seq_file *sf);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index c6f19969fc10..53eb40941281 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -385,6 +385,7 @@ static bool scaling_ratio_valid(u32 size_in, u32 size_out,
 
 static int
 komeda_scaler_check_cfg(struct komeda_scaler *scaler,
+			struct komeda_crtc_state *kcrtc_st,
 			struct komeda_data_flow_cfg *dflow)
 {
 	u32 hsize_in, vsize_in, hsize_out, vsize_out;
@@ -426,6 +427,20 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
 		return -EINVAL;
 	}
+
+	if (hsize_in > hsize_out || vsize_in > vsize_out) {
+		struct komeda_pipeline *pipe = scaler->base.pipeline;
+		int err;
+
+		err = pipe->funcs->downscaling_clk_check(pipe,
+					&kcrtc_st->base.adjusted_mode,
+					komeda_calc_mclk(kcrtc_st), dflow);
+		if (err) {
+			DRM_DEBUG_ATOMIC("mclk can't satisfy the clock requirement of the downscaling");
+			return err;
+		}
+	}
+
 	return 0;
 }
 
@@ -450,7 +465,7 @@ komeda_scaler_validate(void *user,
 		return -EINVAL;
 	}
 
-	err = komeda_scaler_check_cfg(scaler, dflow);
+	err = komeda_scaler_check_cfg(scaler, kcrtc_st, dflow);
 	if (err)
 		return err;
 
-- 
2.17.1


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

* [PATCH v1 5/6] drm/komeda: Add engine clock requirement check for the downscaling
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: nd, Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jonathan Chai (Arm Technology China),
	linux-kernel, dri-devel, Julien Yin (Arm Technology China),
	james qian wang (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China)

For downscaling there is a restriction, the downscaling needed engine
clock can not acceed the real engine clock, and the clock requirement
mostly depend on the specific HW, to solve this problem:
1. Add a pipeline func - downscaling_clk_check for CORE to query the real
   HW if downscaling can be supported.
2. Add new property clock ratio which is the ratio of:
     (mclk << 32) / pxlclk
   then User driver can use this ratio to do the clock check to avoid post
   an invalid downscaling to kernel.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    | 45 +++++++++++++
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.h  |  2 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 67 ++++++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  8 +++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  9 ++-
 .../display/komeda/komeda_pipeline_state.c    | 17 ++++-
 7 files changed, 144 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 5a4c8fd122da..bf214dc9e372 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -677,6 +677,47 @@ static int d71_scaler_init(struct d71_dev *d71,
 	return 0;
 }
 
+static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
+				     struct drm_display_mode *mode,
+				     unsigned long mclk_rate,
+				     struct komeda_data_flow_cfg *dflow)
+{
+	u32 h_in = dflow->in_w;
+	u32 v_in = dflow->in_h;
+	u32 v_out = dflow->out_h;
+	u64 fraction, denominator;
+
+	/* D71 downscaling must satisfy the following equation
+	 *
+	 *   MCLK                   h_in * v_in
+	 * ------- >= ---------------------------------------------
+	 *  PXLCLK     (h_total - (1 + 2 * v_in / v_out)) * v_out
+	 *
+	 * In only horizontal downscaling situation, the right side should be
+	 * multiplied by (h_total - 3) / (h_active - 3), then equation becomes
+	 *
+	 *   MCLK          h_in
+	 * ------- >= ----------------
+	 *  PXLCLK     (h_active - 3)
+	 *
+	 * To avoid precision lost the equation 1 will be convert to:
+	 *
+	 *   MCLK             h_in * v_in
+	 * ------- >= -----------------------------------
+	 *  PXLCLK     (h_total -1 ) * v_out -  2 * v_in
+	 */
+	if (v_in == v_out) {
+		fraction = h_in;
+		denominator = mode->hdisplay - 3;
+	} else {
+		fraction = h_in * v_in;
+		denominator = (mode->htotal - 1) * v_out -  2 * v_in;
+	}
+
+	return mclk_rate * denominator >= mode->clock * 1000 * fraction ?
+	       0 : -EINVAL;
+}
+
 static void d71_improc_update(struct komeda_component *c,
 			      struct komeda_component_state *state)
 {
@@ -938,3 +979,7 @@ int d71_probe_block(struct d71_dev *d71,
 
 	return err;
 }
+
+struct komeda_pipeline_funcs d71_pipeline_funcs = {
+	.downscaling_clk_check = d71_downscaling_clk_check,
+};
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 34506ef7ad40..dd99e06180fd 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -390,7 +390,7 @@ static int d71_enum_resources(struct komeda_dev *mdev)
 
 	for (i = 0; i < d71->num_pipelines; i++) {
 		pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
-					   NULL);
+					   &d71_pipeline_funcs);
 		if (IS_ERR(pipe)) {
 			err = PTR_ERR(pipe);
 			goto err_cleanup;
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
index 7465c57d9774..40f87955ee16 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h
@@ -43,6 +43,8 @@ struct d71_dev {
 
 #define to_d71_pipeline(x)	container_of(x, struct d71_pipeline, base)
 
+extern struct komeda_pipeline_funcs d71_pipeline_funcs;
+
 int d71_probe_block(struct d71_dev *d71,
 		    struct block_header *blk, u32 __iomem *reg);
 void d71_read_block_header(u32 __iomem *reg, struct block_header *blk);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index c0e98605def8..817ae892f7b4 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -18,6 +18,22 @@
 #include "komeda_dev.h"
 #include "komeda_kms.h"
 
+static void komeda_crtc_update_clock_ratio(struct komeda_crtc_state *kcrtc_st)
+{
+	u64 pxlclk, mclk;
+
+	if (!kcrtc_st->base.active) {
+		kcrtc_st->clock_ratio = 0;
+		return;
+	}
+
+	pxlclk = kcrtc_st->base.adjusted_mode.clock * 1000;
+	mclk = komeda_calc_mclk(kcrtc_st) << 32;
+
+	do_div(mclk, pxlclk);
+	kcrtc_st->clock_ratio = mclk;
+}
+
 /**
  * komeda_crtc_atomic_check - build display output data flow
  * @crtc: DRM crtc
@@ -38,6 +54,9 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
 	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
 	int err;
 
+	if (drm_atomic_crtc_needs_modeset(state))
+		komeda_crtc_update_clock_ratio(kcrtc_st);
+
 	if (state->active) {
 		err = komeda_build_display_data_flow(kcrtc, kcrtc_st);
 		if (err)
@@ -52,11 +71,12 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
+unsigned long komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
 {
-	unsigned long mclk = kcrtc_st->base.adjusted_mode.clock * 1000;
+	struct komeda_dev *mdev = kcrtc_st->base.crtc->dev->dev_private;
+	unsigned long pxlclk = kcrtc_st->base.adjusted_mode.clock;
 
-	return mclk;
+	return clk_round_rate(mdev->mclk, pxlclk * 1000);
 }
 
 /* For active a crtc, mainly need two parts of preparation
@@ -404,6 +424,7 @@ komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &new->base);
 
 	new->affected_pipes = old->active_pipes;
+	new->clock_ratio = old->clock_ratio;
 
 	return &new->base;
 }
@@ -432,6 +453,25 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
 	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, false);
 }
 
+static int
+komeda_crtc_atomic_get_property(struct drm_crtc *crtc,
+				const struct drm_crtc_state *state,
+				struct drm_property *property, uint64_t *val)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
+
+	if (property == kcrtc->clock_ratio_property) {
+		*val = kcrtc_st->clock_ratio;
+		pr_info("Get property: %llu.\n", kcrtc_st->clock_ratio);
+	} else {
+		DRM_DEBUG_DRIVER("Unknown property %s\n", property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
 	.gamma_set		= drm_atomic_helper_legacy_gamma_set,
 	.destroy		= drm_crtc_cleanup,
@@ -442,6 +482,7 @@ static const struct drm_crtc_funcs komeda_crtc_funcs = {
 	.atomic_destroy_state	= komeda_crtc_atomic_destroy_state,
 	.enable_vblank		= komeda_crtc_vblank_enable,
 	.disable_vblank		= komeda_crtc_vblank_disable,
+	.atomic_get_property	= komeda_crtc_atomic_get_property,
 };
 
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
@@ -477,6 +518,22 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
 	return 0;
 }
 
+static int komeda_crtc_create_clock_ratio_property(struct komeda_crtc *kcrtc)
+{
+	struct drm_crtc *crtc = &kcrtc->base;
+	struct drm_property *prop;
+
+	prop = drm_property_create_range(crtc->dev, DRM_MODE_PROP_ATOMIC,
+					 "CLOCK_RATIO", 0, U64_MAX);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&crtc->base, prop, 0);
+	kcrtc->clock_ratio_property = prop;
+
+	return 0;
+}
+
 static struct drm_plane *
 get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc)
 {
@@ -513,6 +570,10 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
 	crtc->port = kcrtc->master->of_output_port;
 
+	err = komeda_crtc_create_clock_ratio_property(kcrtc);
+	if (err)
+		return err;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index f16e9e577593..db59a9042beb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -79,6 +79,9 @@ struct komeda_crtc {
 
 	/** @disable_done: this flip_done is for tracing the disable */
 	struct completion *disable_done;
+
+	/** @clock_ratio_property: property for ratio of (mclk << 32)/pxlclk */
+	struct drm_property *clock_ratio_property;
 };
 
 /**
@@ -101,6 +104,9 @@ struct komeda_crtc_state {
 	 * the active pipelines in once display instance
 	 */
 	u32 active_pipes;
+
+	/** @clock_ratio: ratio of (mclk << 32)/pxlclk */
+	u64 clock_ratio;
 };
 
 /** struct komeda_kms_dev - for gather KMS related things */
@@ -142,6 +148,8 @@ is_only_changed_connector(struct drm_crtc_state *st, struct drm_connector *conn)
 	return BIT(drm_connector_index(conn)) == changed_connectors;
 }
 
+unsigned long komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st);
+
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
 
 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bfad7d03f801..b26c8552a2d1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -316,8 +316,15 @@ struct komeda_data_flow_cfg {
 	u8 needs_scaling : 1;
 };
 
-/** struct komeda_pipeline_funcs */
+/* struct komeda_pipeline_funcs */
 struct komeda_pipeline_funcs {
+	/* check if the mclk (main engine clock) can satisfy the clock
+	 * requirements of the downscaling that specified by dflow
+	 */
+	int (*downscaling_clk_check)(struct komeda_pipeline *pipe,
+				     struct drm_display_mode *mode,
+				     unsigned long mclk_rate,
+				     struct komeda_data_flow_cfg *dflow);
 	/* dump_register: Optional, dump registers to seq_file */
 	void (*dump_register)(struct komeda_pipeline *pipe,
 			      struct seq_file *sf);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index c6f19969fc10..53eb40941281 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -385,6 +385,7 @@ static bool scaling_ratio_valid(u32 size_in, u32 size_out,
 
 static int
 komeda_scaler_check_cfg(struct komeda_scaler *scaler,
+			struct komeda_crtc_state *kcrtc_st,
 			struct komeda_data_flow_cfg *dflow)
 {
 	u32 hsize_in, vsize_in, hsize_out, vsize_out;
@@ -426,6 +427,20 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
 		DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
 		return -EINVAL;
 	}
+
+	if (hsize_in > hsize_out || vsize_in > vsize_out) {
+		struct komeda_pipeline *pipe = scaler->base.pipeline;
+		int err;
+
+		err = pipe->funcs->downscaling_clk_check(pipe,
+					&kcrtc_st->base.adjusted_mode,
+					komeda_calc_mclk(kcrtc_st), dflow);
+		if (err) {
+			DRM_DEBUG_ATOMIC("mclk can't satisfy the clock requirement of the downscaling");
+			return err;
+		}
+	}
+
 	return 0;
 }
 
@@ -450,7 +465,7 @@ komeda_scaler_validate(void *user,
 		return -EINVAL;
 	}
 
-	err = komeda_scaler_check_cfg(scaler, dflow);
+	err = komeda_scaler_check_cfg(scaler, kcrtc_st, dflow);
 	if (err)
 		return err;
 
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 6/6] drm/komeda: Add image enhancement support
  2019-04-15  7:08 ` james qian wang (Arm Technology China)
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  -1 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

Besides scaling, Arm display scaler also can support image enhancement.
For support it, Add a new property "img_enhancement" to plane, then user
can turn on/off it by this property, and kernel follow user's requirement
to maitain the state and enable/disable the real HW image enhancement.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    |  1 +
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  6 +-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  6 +-
 .../display/komeda/komeda_pipeline_state.c    |  3 +-
 .../gpu/drm/arm/display/komeda/komeda_plane.c | 75 ++++++++++++++++++-
 5 files changed, 84 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index bf214dc9e372..21d2b3a5c630 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -610,6 +610,7 @@ static void d71_scaler_update(struct komeda_component *c,
 	ctrl = 0;
 	ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
 	ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+	ctrl |= st->en_img_enhancement ? SC_CTRL_IENH : 0;
 
 	malidp_write32(reg, BLK_CONTROL, ctrl);
 	malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index db59a9042beb..e6e059f2af52 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -32,6 +32,9 @@ struct komeda_plane {
 	 * Layers with same capabilities.
 	 */
 	struct komeda_layer *layer;
+
+	/** @prop_img_enhancement: for on/off image enhancement */
+	struct drm_property *prop_img_enhancement;
 };
 
 /**
@@ -44,7 +47,8 @@ struct komeda_plane_state {
 	/** @base: &drm_plane_state */
 	struct drm_plane_state base;
 
-	/* private properties */
+	/* @img_enhancement: on/off image enhancement */
+	u8 img_enhancement : 1;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index b26c8552a2d1..a32a8d697f34 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -254,7 +254,8 @@ struct komeda_scaler_state {
 	u16 hsize_in, vsize_in;
 	u16 hsize_out, vsize_out;
 	u8 en_scaling : 1,
-	   en_alpha : 1; /* enable alpha processing */
+	   en_alpha : 1, /* enable alpha processing */
+	   en_img_enhancement : 1;
 };
 
 struct komeda_compiz {
@@ -313,7 +314,8 @@ struct komeda_data_flow_cfg {
 	u32 rot;
 	int blending_zorder;
 	u8 pixel_blend_mode, layer_alpha;
-	u8 needs_scaling : 1;
+	u8 needs_scaling : 1,
+	   needs_img_enhancement : 1;
 };
 
 /* struct komeda_pipeline_funcs */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 53eb40941281..2430388a78c3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -455,7 +455,7 @@ komeda_scaler_validate(void *user,
 	struct komeda_scaler *scaler;
 	int err = 0;
 
-	if (!dflow->needs_scaling)
+	if (!(dflow->needs_scaling || dflow->needs_img_enhancement))
 		return 0;
 
 	scaler = komeda_component_get_avail_scaler(dflow->input.component,
@@ -483,6 +483,7 @@ komeda_scaler_validate(void *user,
 	st->en_scaling = dflow->needs_scaling;
 	/* Enable alpha processing if the next stage needs the pixel alpha */
 	st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE;
+	st->en_img_enhancement = dflow->needs_img_enhancement;
 
 	komeda_component_add_input(&st->base, &dflow->input, 0);
 	komeda_component_set_output(&dflow->input, &scaler->base, 0);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 5de462172151..fa455665aa77 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -14,6 +14,7 @@ static int
 komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
+	struct komeda_plane_state *kplane_st = to_kplane_st(st);
 	struct drm_framebuffer *fb = st->fb;
 
 	memset(dflow, 0, sizeof(*dflow));
@@ -22,7 +23,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 
 	/* if format doesn't have alpha, fix blend mode to PIXEL_NONE */
 	dflow->pixel_blend_mode = fb->format->has_alpha ?
-		st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE;
+			st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE;
 	dflow->layer_alpha = st->alpha >> 8;
 
 	dflow->out_x = st->crtc_x;
@@ -35,6 +36,8 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
+	dflow->needs_img_enhancement = kplane_st->img_enhancement;
+
 	komeda_complete_data_flow_cfg(dflow);
 
 	return 0;
@@ -130,7 +133,7 @@ static void komeda_plane_reset(struct drm_plane *plane)
 static struct drm_plane_state *
 komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
 {
-	struct komeda_plane_state *new;
+	struct komeda_plane_state *new, *old;
 
 	if (WARN_ON(!plane->state))
 		return NULL;
@@ -141,6 +144,10 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &new->base);
 
+	old = to_kplane_st(plane->state);
+
+	new->img_enhancement = old->img_enhancement;
+
 	return &new->base;
 }
 
@@ -152,6 +159,40 @@ komeda_plane_atomic_destroy_state(struct drm_plane *plane,
 	kfree(to_kplane_st(state));
 }
 
+static int
+komeda_plane_atomic_get_property(struct drm_plane *plane,
+				 const struct drm_plane_state *state,
+				 struct drm_property *property,
+				 uint64_t *val)
+{
+	struct komeda_plane *kplane = to_kplane(plane);
+	struct komeda_plane_state *st = to_kplane_st(state);
+
+	if (property == kplane->prop_img_enhancement)
+		*val = st->img_enhancement;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+komeda_plane_atomic_set_property(struct drm_plane *plane,
+				 struct drm_plane_state *state,
+				 struct drm_property *property,
+				 uint64_t val)
+{
+	struct komeda_plane *kplane = to_kplane(plane);
+	struct komeda_plane_state *st = to_kplane_st(state);
+
+	if (property == kplane->prop_img_enhancement)
+		st->img_enhancement = !!val;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
 static bool
 komeda_plane_format_mod_supported(struct drm_plane *plane,
 				  u32 format, u64 modifier)
@@ -171,9 +212,33 @@ static const struct drm_plane_funcs komeda_plane_funcs = {
 	.reset			= komeda_plane_reset,
 	.atomic_duplicate_state	= komeda_plane_atomic_duplicate_state,
 	.atomic_destroy_state	= komeda_plane_atomic_destroy_state,
+	.atomic_get_property	= komeda_plane_atomic_get_property,
+	.atomic_set_property	= komeda_plane_atomic_set_property,
 	.format_mod_supported	= komeda_plane_format_mod_supported,
 };
 
+static int
+komeda_plane_create_layer_properties(struct komeda_plane *kplane,
+				     struct komeda_layer *layer)
+{
+	struct drm_device *drm = kplane->base.dev;
+	struct drm_plane *plane = &kplane->base;
+	struct drm_property *prop = NULL;
+
+	/* property: layer image_enhancement */
+	if (layer->base.supported_outputs & KOMEDA_PIPELINE_SCALERS) {
+		prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC,
+						"img_enhancement");
+		if (!prop)
+			return -ENOMEM;
+
+		drm_object_attach_property(&plane->base, prop, 0);
+		kplane->prop_img_enhancement = prop;
+	}
+
+	return 0;
+}
+
 /* for komeda, which is pipeline can be share between crtcs */
 static u32 get_possible_crtcs(struct komeda_kms_dev *kms,
 			      struct komeda_pipeline *pipe)
@@ -241,11 +306,15 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
 	err = drm_plane_create_blend_mode_property(plane,
 			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
-			BIT(DRM_MODE_BLEND_PREMULTI)   |
+			BIT(DRM_MODE_BLEND_PREMULTI) |
 			BIT(DRM_MODE_BLEND_COVERAGE));
 	if (err)
 		goto cleanup;
 
+	err = komeda_plane_create_layer_properties(kplane, layer);
+	if (err)
+		goto cleanup;
+
 	return 0;
 cleanup:
 	komeda_plane_destroy(plane);
-- 
2.17.1


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

* [PATCH v1 6/6] drm/komeda: Add image enhancement support
@ 2019-04-15  7:09   ` james qian wang (Arm Technology China)
  0 siblings, 0 replies; 14+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-04-15  7:09 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey, maarten.lankhorst, sean
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Yiqi Kang (Arm Technology China),
	nd, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

Besides scaling, Arm display scaler also can support image enhancement.
For support it, Add a new property "img_enhancement" to plane, then user
can turn on/off it by this property, and kernel follow user's requirement
to maitain the state and enable/disable the real HW image enhancement.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../arm/display/komeda/d71/d71_component.c    |  1 +
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  6 +-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  6 +-
 .../display/komeda/komeda_pipeline_state.c    |  3 +-
 .../gpu/drm/arm/display/komeda/komeda_plane.c | 75 ++++++++++++++++++-
 5 files changed, 84 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index bf214dc9e372..21d2b3a5c630 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -610,6 +610,7 @@ static void d71_scaler_update(struct komeda_component *c,
 	ctrl = 0;
 	ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
 	ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+	ctrl |= st->en_img_enhancement ? SC_CTRL_IENH : 0;
 
 	malidp_write32(reg, BLK_CONTROL, ctrl);
 	malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index db59a9042beb..e6e059f2af52 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -32,6 +32,9 @@ struct komeda_plane {
 	 * Layers with same capabilities.
 	 */
 	struct komeda_layer *layer;
+
+	/** @prop_img_enhancement: for on/off image enhancement */
+	struct drm_property *prop_img_enhancement;
 };
 
 /**
@@ -44,7 +47,8 @@ struct komeda_plane_state {
 	/** @base: &drm_plane_state */
 	struct drm_plane_state base;
 
-	/* private properties */
+	/* @img_enhancement: on/off image enhancement */
+	u8 img_enhancement : 1;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index b26c8552a2d1..a32a8d697f34 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -254,7 +254,8 @@ struct komeda_scaler_state {
 	u16 hsize_in, vsize_in;
 	u16 hsize_out, vsize_out;
 	u8 en_scaling : 1,
-	   en_alpha : 1; /* enable alpha processing */
+	   en_alpha : 1, /* enable alpha processing */
+	   en_img_enhancement : 1;
 };
 
 struct komeda_compiz {
@@ -313,7 +314,8 @@ struct komeda_data_flow_cfg {
 	u32 rot;
 	int blending_zorder;
 	u8 pixel_blend_mode, layer_alpha;
-	u8 needs_scaling : 1;
+	u8 needs_scaling : 1,
+	   needs_img_enhancement : 1;
 };
 
 /* struct komeda_pipeline_funcs */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 53eb40941281..2430388a78c3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -455,7 +455,7 @@ komeda_scaler_validate(void *user,
 	struct komeda_scaler *scaler;
 	int err = 0;
 
-	if (!dflow->needs_scaling)
+	if (!(dflow->needs_scaling || dflow->needs_img_enhancement))
 		return 0;
 
 	scaler = komeda_component_get_avail_scaler(dflow->input.component,
@@ -483,6 +483,7 @@ komeda_scaler_validate(void *user,
 	st->en_scaling = dflow->needs_scaling;
 	/* Enable alpha processing if the next stage needs the pixel alpha */
 	st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE;
+	st->en_img_enhancement = dflow->needs_img_enhancement;
 
 	komeda_component_add_input(&st->base, &dflow->input, 0);
 	komeda_component_set_output(&dflow->input, &scaler->base, 0);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 5de462172151..fa455665aa77 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -14,6 +14,7 @@ static int
 komeda_plane_init_data_flow(struct drm_plane_state *st,
 			    struct komeda_data_flow_cfg *dflow)
 {
+	struct komeda_plane_state *kplane_st = to_kplane_st(st);
 	struct drm_framebuffer *fb = st->fb;
 
 	memset(dflow, 0, sizeof(*dflow));
@@ -22,7 +23,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 
 	/* if format doesn't have alpha, fix blend mode to PIXEL_NONE */
 	dflow->pixel_blend_mode = fb->format->has_alpha ?
-		st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE;
+			st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE;
 	dflow->layer_alpha = st->alpha >> 8;
 
 	dflow->out_x = st->crtc_x;
@@ -35,6 +36,8 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
 	dflow->in_w = st->src_w >> 16;
 	dflow->in_h = st->src_h >> 16;
 
+	dflow->needs_img_enhancement = kplane_st->img_enhancement;
+
 	komeda_complete_data_flow_cfg(dflow);
 
 	return 0;
@@ -130,7 +133,7 @@ static void komeda_plane_reset(struct drm_plane *plane)
 static struct drm_plane_state *
 komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
 {
-	struct komeda_plane_state *new;
+	struct komeda_plane_state *new, *old;
 
 	if (WARN_ON(!plane->state))
 		return NULL;
@@ -141,6 +144,10 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &new->base);
 
+	old = to_kplane_st(plane->state);
+
+	new->img_enhancement = old->img_enhancement;
+
 	return &new->base;
 }
 
@@ -152,6 +159,40 @@ komeda_plane_atomic_destroy_state(struct drm_plane *plane,
 	kfree(to_kplane_st(state));
 }
 
+static int
+komeda_plane_atomic_get_property(struct drm_plane *plane,
+				 const struct drm_plane_state *state,
+				 struct drm_property *property,
+				 uint64_t *val)
+{
+	struct komeda_plane *kplane = to_kplane(plane);
+	struct komeda_plane_state *st = to_kplane_st(state);
+
+	if (property == kplane->prop_img_enhancement)
+		*val = st->img_enhancement;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+komeda_plane_atomic_set_property(struct drm_plane *plane,
+				 struct drm_plane_state *state,
+				 struct drm_property *property,
+				 uint64_t val)
+{
+	struct komeda_plane *kplane = to_kplane(plane);
+	struct komeda_plane_state *st = to_kplane_st(state);
+
+	if (property == kplane->prop_img_enhancement)
+		st->img_enhancement = !!val;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
 static bool
 komeda_plane_format_mod_supported(struct drm_plane *plane,
 				  u32 format, u64 modifier)
@@ -171,9 +212,33 @@ static const struct drm_plane_funcs komeda_plane_funcs = {
 	.reset			= komeda_plane_reset,
 	.atomic_duplicate_state	= komeda_plane_atomic_duplicate_state,
 	.atomic_destroy_state	= komeda_plane_atomic_destroy_state,
+	.atomic_get_property	= komeda_plane_atomic_get_property,
+	.atomic_set_property	= komeda_plane_atomic_set_property,
 	.format_mod_supported	= komeda_plane_format_mod_supported,
 };
 
+static int
+komeda_plane_create_layer_properties(struct komeda_plane *kplane,
+				     struct komeda_layer *layer)
+{
+	struct drm_device *drm = kplane->base.dev;
+	struct drm_plane *plane = &kplane->base;
+	struct drm_property *prop = NULL;
+
+	/* property: layer image_enhancement */
+	if (layer->base.supported_outputs & KOMEDA_PIPELINE_SCALERS) {
+		prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC,
+						"img_enhancement");
+		if (!prop)
+			return -ENOMEM;
+
+		drm_object_attach_property(&plane->base, prop, 0);
+		kplane->prop_img_enhancement = prop;
+	}
+
+	return 0;
+}
+
 /* for komeda, which is pipeline can be share between crtcs */
 static u32 get_possible_crtcs(struct komeda_kms_dev *kms,
 			      struct komeda_pipeline *pipe)
@@ -241,11 +306,15 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
 	err = drm_plane_create_blend_mode_property(plane,
 			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
-			BIT(DRM_MODE_BLEND_PREMULTI)   |
+			BIT(DRM_MODE_BLEND_PREMULTI) |
 			BIT(DRM_MODE_BLEND_COVERAGE));
 	if (err)
 		goto cleanup;
 
+	err = komeda_plane_create_layer_properties(kplane, layer);
+	if (err)
+		goto cleanup;
+
 	return 0;
 cleanup:
 	komeda_plane_destroy(plane);
-- 
2.17.1


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

end of thread, other threads:[~2019-04-15  7:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-15  7:08 [PATCH v1 0/6] Added scaler support for komeda james qian wang (Arm Technology China)
2019-04-15  7:08 ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 1/6] drm/komeda: Attach scaler to drm as private object james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 2/6] drm/komeda: Add the initial scaler support for CORE james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 3/6] drm/komeda: Implement D71 scaler support james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 4/6] drm/komeda: Add writeback scaling support james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 5/6] drm/komeda: Add engine clock requirement check for the downscaling james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)
2019-04-15  7:09 ` [PATCH v1 6/6] drm/komeda: Add image enhancement support james qian wang (Arm Technology China)
2019-04-15  7:09   ` james qian wang (Arm Technology China)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.