Commit 3347b55f authored by Suraj Kandpal's avatar Suraj Kandpal
Browse files

drm/i915/xe3lpd: Prune modes for YUV420



We only support resolution up to 4k for single pipe when using
YUV420 format so we prune these modes and restrict the plane size
at src. This is because pipe scaling will not support YUV420 scaling
for hwidth > 4096.

--v2
-Use output format to check [Ville]
-Add Bspec references
-Modify commit messge to point to why this is needed

--v3
-Use a function skl_scaler_mode_valid which is routed throug
intel_pfit_mode_valid [Ville]
-Combine the check conditons [Jonathan]

--v4
-mode_valid functions should return drm_mode_status [Jani]

--v5
-Use skl_scaler_max_src_size [Ankit]

Bspec: 49247, 50441
Signed-off-by: default avatarSuraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> #v2
Reviewed-by: default avatarAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://lore.kernel.org/r/20250708043328.1086192-2-suraj.kandpal@intel.com
parent f7a9dc79
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -1418,6 +1418,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
	struct intel_display *display = to_intel_display(_connector->dev);
	struct intel_connector *connector = to_intel_connector(_connector);
	struct intel_dp *intel_dp = intel_attached_dp(connector);
	enum intel_output_format sink_format, output_format;
	const struct drm_display_mode *fixed_mode;
	int target_clock = mode->clock;
	int max_rate, mode_rate, max_lanes, max_link_clock;
@@ -1451,6 +1452,13 @@ intel_dp_mode_valid(struct drm_connector *_connector,
						     mode->hdisplay, target_clock);
	max_dotclk *= num_joined_pipes;

	sink_format = intel_dp_sink_format(connector, mode);
	output_format = intel_dp_output_format(connector, sink_format);

	status = intel_pfit_mode_valid(display, mode, output_format, num_joined_pipes);
	if (status != MODE_OK)
		return status;

	if (target_clock > max_dotclk)
		return MODE_CLOCK_HIGH;

@@ -1466,11 +1474,8 @@ intel_dp_mode_valid(struct drm_connector *_connector,
					   intel_dp_mode_min_output_bpp(connector, mode));

	if (intel_dp_has_dsc(connector)) {
		enum intel_output_format sink_format, output_format;
		int pipe_bpp;

		sink_format = intel_dp_sink_format(connector, mode);
		output_format = intel_dp_output_format(connector, sink_format);
		/*
		 * TBD pass the connector BPC,
		 * for now U8_MAX so that max BPC on that platform would be picked
+4 −0
Original line number Diff line number Diff line
@@ -2053,6 +2053,10 @@ intel_hdmi_mode_valid(struct drm_connector *_connector,
	else
		sink_format = INTEL_OUTPUT_FORMAT_RGB;

	status = intel_pfit_mode_valid(display, mode, sink_format, 0);
	if (status != MODE_OK)
		return status;

	status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, sink_format);
	if (status != MODE_OK) {
		if (ycbcr_420_only ||
+11 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "intel_lvds_regs.h"
#include "intel_pfit.h"
#include "intel_pfit_regs.h"
#include "skl_scaler.h"

static int intel_pch_pfit_check_dst_window(const struct intel_crtc_state *crtc_state)
{
@@ -546,6 +547,16 @@ static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
	return intel_gmch_pfit_check_timings(crtc_state);
}

enum drm_mode_status
intel_pfit_mode_valid(struct intel_display *display,
		      const struct drm_display_mode *mode,
		      enum intel_output_format output_format,
		      int num_joined_pipes)
{
	return skl_scaler_mode_valid(display, mode, output_format,
				     num_joined_pipes);
}

int intel_pfit_compute_config(struct intel_crtc_state *crtc_state,
			      const struct drm_connector_state *conn_state)
{
+11 −1
Original line number Diff line number Diff line
@@ -6,8 +6,14 @@
#ifndef __INTEL_PFIT_H__
#define __INTEL_PFIT_H__

#include <linux/types.h>

enum drm_mode_status;
struct drm_display_mode;
struct drm_connector_state;
struct intel_crtc_state;
struct intel_display;
enum intel_output_format;

int intel_pfit_compute_config(struct intel_crtc_state *crtc_state,
			      const struct drm_connector_state *conn_state);
@@ -17,5 +23,9 @@ void ilk_pfit_get_config(struct intel_crtc_state *crtc_state);
void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state);
void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state);
void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state);

enum drm_mode_status
intel_pfit_mode_valid(struct intel_display *display,
		      const struct drm_display_mode *mode,
		      enum intel_output_format output_format,
		      int num_joined_pipes);
#endif /* __INTEL_PFIT_H__ */
+17 −0
Original line number Diff line number Diff line
@@ -132,6 +132,23 @@ static void skl_scaler_max_dst_size(struct intel_crtc *crtc,
	}
}

enum drm_mode_status
skl_scaler_mode_valid(struct intel_display *display,
		      const struct drm_display_mode *mode,
		      enum intel_output_format output_format,
		      int num_joined_pipes)
{
	int max_h, max_w;

	if (num_joined_pipes < 2 && output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
		skl_scaler_max_src_size(display, &max_w, &max_h);
		if (mode->hdisplay > max_h)
			return MODE_NO_420;
	}

	return MODE_OK;
}

static int
skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
		  unsigned int scaler_user, int *scaler_id,
Loading