diff mbox series

drm/i915/display: Call panel_fitting function from pipe_config

Message ID 20240705094308.73498-1-nemesa.garg@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/display: Call panel_fitting function from pipe_config | expand

Commit Message

Nemesa Garg July 5, 2024, 9:43 a.m. UTC
In panel fitter/pipe scaler scenario the pch_pfit configuration
currently takes place before we account for bigjoiner.
So once the calculation for bigjoiner is done, proper values
of width and height can be used for panel fitting.

Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 11 +++++
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  6 +--
 drivers/gpu/drm/i915/display/intel_panel.c    | 42 ++++++++++++++-----
 4 files changed, 45 insertions(+), 15 deletions(-)

Comments

Nautiyal, Ankit K July 24, 2024, 4:20 a.m. UTC | #1
On 7/5/2024 3:13 PM, Nemesa Garg wrote:
> In panel fitter/pipe scaler scenario the pch_pfit configuration
> currently takes place before we account for bigjoiner.
> So once the calculation for bigjoiner is done, proper values
> of width and height can be used for panel fitting.

I think this seems to be incomplete.


>
> Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_display.c  | 11 +++++
>   .../drm/i915/display/intel_display_types.h    |  1 +
>   drivers/gpu/drm/i915/display/intel_dp.c       |  6 +--
>   drivers/gpu/drm/i915/display/intel_panel.c    | 42 ++++++++++++++-----
>   4 files changed, 45 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index c2c388212e2e..182ffd17a365 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -4774,6 +4774,17 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
>   		    crtc->base.base.id, crtc->base.name,
>   		    base_bpp, crtc_state->pipe_bpp, crtc_state->dither);
>   
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
> +		if (connector_state->crtc != &crtc->base)
> +			continue;
> +
> +		if (crtc_state->pch_pfit.is_pch_required) {
> +			ret = intel_panel_fitting(crtc_state, connector_state);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 8713835e2307..067b123408bf 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1251,6 +1251,7 @@ struct intel_crtc_state {
>   		struct drm_rect dst;
>   		bool enabled;
>   		bool force_thru;
> +		bool is_pch_required;

I think is_required is sufficient here.


>   	} pch_pfit;
>   
>   	/* FDI configuration, only valid if has_pch_encoder is set. */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3903f6ead6e6..d424a328cfca 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2952,10 +2952,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>   		return ret;
>   
>   	if ((intel_dp_is_edp(intel_dp) && fixed_mode) ||
> -	    pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
> -		ret = intel_panel_fitting(pipe_config, conn_state);
> -		if (ret)
> -			return ret;
> +	     pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
> +		pipe_config->pch_pfit.is_pch_required = true;
>   	}
>   
>   	pipe_config->limited_color_range =
> diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
> index 71454ddef20f..69b4c09c634b 100644
> --- a/drivers/gpu/drm/i915/display/intel_panel.c
> +++ b/drivers/gpu/drm/i915/display/intel_panel.c
> @@ -403,8 +403,11 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
>   	case DRM_MODE_SCALE_CENTER:
>   		width = pipe_src_w;
>   		height = pipe_src_h;
> -		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
> -		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
> +		if (crtc_state->joiner_pipes)
> +			x = (adjusted_mode->crtc_hdisplay / 2 - width + 1) / 2;

I think its better to take a variable crtc_hdisplay and set it as per 
joiner_pipes and use that below.

I one patch just use crtc_hdisplay and crtc_vdisplay as variables.

In next patch make crtc_hdisplay half as per joiner pipes. With 
ultrajoiner then it will be easier to change this.


Regards,

Ankit

> +		else
> +			x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
> +		y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
>   		break;
>   
>   	case DRM_MODE_SCALE_ASPECT:
> @@ -412,11 +415,18 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
>   		{
>   			u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
>   			u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
> +			int adjusted_crtc_hdisplay = adjusted_mode->crtc_hdisplay;
> +
> +			if (crtc_state->joiner_pipes) {
> +				scaled_width = adjusted_mode->crtc_hdisplay / 2 * pipe_src_h;
> +				adjusted_crtc_hdisplay = adjusted_mode->crtc_hdisplay / 2;
> +			}
> +
>   			if (scaled_width > scaled_height) { /* pillar */
>   				width = scaled_height / pipe_src_h;
>   				if (width & 1)
>   					width++;
> -				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
> +				x = (adjusted_crtc_hdisplay - width + 1) / 2;
>   				y = 0;
>   				height = adjusted_mode->crtc_vdisplay;
>   			} else if (scaled_width < scaled_height) { /* letter */
> @@ -425,25 +435,35 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
>   				    height++;
>   				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
>   				x = 0;
> -				width = adjusted_mode->crtc_hdisplay;
> +				width = adjusted_crtc_hdisplay;
>   			} else {
>   				x = y = 0;
> -				width = adjusted_mode->crtc_hdisplay;
> +				width = adjusted_crtc_hdisplay;
>   				height = adjusted_mode->crtc_vdisplay;
>   			}
>   		}
>   		break;
>   
>   	case DRM_MODE_SCALE_NONE:
> -		WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
> -		WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
> +		if (crtc_state->joiner_pipes) {
> +			WARN_ON(adjusted_mode->crtc_hdisplay / 2 != pipe_src_w);
> +			WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
> +		} else {
> +			WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
> +			WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
> +		}
>   		fallthrough;
>   	case DRM_MODE_SCALE_FULLSCREEN:
> -		x = y = 0;
> -		width = adjusted_mode->crtc_hdisplay;
> -		height = adjusted_mode->crtc_vdisplay;
> +		if (crtc_state->joiner_pipes) {
> +			x = y = 0;
> +			width = adjusted_mode->crtc_hdisplay / 2;
> +			height = adjusted_mode->crtc_vdisplay;
> +		} else {
> +			x = y = 0;
> +			width = adjusted_mode->crtc_hdisplay;
> +			height = adjusted_mode->crtc_vdisplay;
> +		}
>   		break;
> -
>   	default:
>   		MISSING_CASE(conn_state->scaling_mode);
>   		return -EINVAL;
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index c2c388212e2e..182ffd17a365 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4774,6 +4774,17 @@  intel_modeset_pipe_config(struct intel_atomic_state *state,
 		    crtc->base.base.id, crtc->base.name,
 		    base_bpp, crtc_state->pipe_bpp, crtc_state->dither);
 
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		if (crtc_state->pch_pfit.is_pch_required) {
+			ret = intel_panel_fitting(crtc_state, connector_state);
+			if (ret)
+				return ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 8713835e2307..067b123408bf 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1251,6 +1251,7 @@  struct intel_crtc_state {
 		struct drm_rect dst;
 		bool enabled;
 		bool force_thru;
+		bool is_pch_required;
 	} pch_pfit;
 
 	/* FDI configuration, only valid if has_pch_encoder is set. */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3903f6ead6e6..d424a328cfca 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2952,10 +2952,8 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 		return ret;
 
 	if ((intel_dp_is_edp(intel_dp) && fixed_mode) ||
-	    pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
-		ret = intel_panel_fitting(pipe_config, conn_state);
-		if (ret)
-			return ret;
+	     pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
+		pipe_config->pch_pfit.is_pch_required = true;
 	}
 
 	pipe_config->limited_color_range =
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 71454ddef20f..69b4c09c634b 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -403,8 +403,11 @@  static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
 	case DRM_MODE_SCALE_CENTER:
 		width = pipe_src_w;
 		height = pipe_src_h;
-		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
-		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
+		if (crtc_state->joiner_pipes)
+			x = (adjusted_mode->crtc_hdisplay / 2 - width + 1) / 2;
+		else
+			x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
+		y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
 		break;
 
 	case DRM_MODE_SCALE_ASPECT:
@@ -412,11 +415,18 @@  static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
 		{
 			u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
 			u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
+			int adjusted_crtc_hdisplay = adjusted_mode->crtc_hdisplay;
+
+			if (crtc_state->joiner_pipes) {
+				scaled_width = adjusted_mode->crtc_hdisplay / 2 * pipe_src_h;
+				adjusted_crtc_hdisplay = adjusted_mode->crtc_hdisplay / 2;
+			}
+
 			if (scaled_width > scaled_height) { /* pillar */
 				width = scaled_height / pipe_src_h;
 				if (width & 1)
 					width++;
-				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
+				x = (adjusted_crtc_hdisplay - width + 1) / 2;
 				y = 0;
 				height = adjusted_mode->crtc_vdisplay;
 			} else if (scaled_width < scaled_height) { /* letter */
@@ -425,25 +435,35 @@  static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
 				    height++;
 				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
 				x = 0;
-				width = adjusted_mode->crtc_hdisplay;
+				width = adjusted_crtc_hdisplay;
 			} else {
 				x = y = 0;
-				width = adjusted_mode->crtc_hdisplay;
+				width = adjusted_crtc_hdisplay;
 				height = adjusted_mode->crtc_vdisplay;
 			}
 		}
 		break;
 
 	case DRM_MODE_SCALE_NONE:
-		WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
-		WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
+		if (crtc_state->joiner_pipes) {
+			WARN_ON(adjusted_mode->crtc_hdisplay / 2 != pipe_src_w);
+			WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
+		} else {
+			WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
+			WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
+		}
 		fallthrough;
 	case DRM_MODE_SCALE_FULLSCREEN:
-		x = y = 0;
-		width = adjusted_mode->crtc_hdisplay;
-		height = adjusted_mode->crtc_vdisplay;
+		if (crtc_state->joiner_pipes) {
+			x = y = 0;
+			width = adjusted_mode->crtc_hdisplay / 2;
+			height = adjusted_mode->crtc_vdisplay;
+		} else {
+			x = y = 0;
+			width = adjusted_mode->crtc_hdisplay;
+			height = adjusted_mode->crtc_vdisplay;
+		}
 		break;
-
 	default:
 		MISSING_CASE(conn_state->scaling_mode);
 		return -EINVAL;