Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce2aa517 authored by Chirag Khurana's avatar Chirag Khurana Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm: change CSC matrix selection logic for CDM block



CDM block is always using a limited quantization range
matrix.

This can be overridden to use a full range matrix if
the sink supports override capability or the mode is a
non-CEA mode.

Adjust the matrix selection logic to accommodate full
range quantization as well.

Change-Id: I708412a923fb0d47e798f35ebe14b4c2f1a72fc9
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: default avatarChirag Khurana <ckhurana@codeaurora.org>
parent d4921e03
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -50,4 +50,5 @@ struct dp_display {

int dp_display_get_num_of_displays(void);
int dp_display_get_displays(void **displays, int count);
bool dp_connector_mode_needs_full_range(void *display);
#endif /* _DP_DISPLAY_H_ */
+29 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -356,6 +356,34 @@ int dp_connector_get_info(struct msm_display_info *info, void *data)
	return 0;
}

bool dp_connector_mode_needs_full_range(void *data)
{
	struct dp_display *display = data;
	struct dp_bridge *bridge;
	struct dp_display_mode *mode;
	struct dp_panel_info *timing;

	if (!display) {
		pr_err("invalid input\n");
		return false;
	}

	bridge = display->bridge;
	if (!bridge) {
		pr_err("invalid bridge data\n");
		return false;
	}

	mode = &bridge->dp_mode;
	timing = &mode->timing;

	if (timing->h_active == 640 &&
	    timing->v_active == 480)
		return true;

	return false;
}

enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
		bool force,
		void *display)
+22 −0
Original line number Diff line number Diff line
@@ -724,6 +724,28 @@ int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable)
	return rc;
}

bool sde_connector_mode_needs_full_range(struct drm_connector *connector)
{
	struct sde_connector *c_conn;

	if (!connector) {
		SDE_ERROR("invalid argument\n");
		return false;
	}

	c_conn = to_sde_connector(connector);

	if (!c_conn->display) {
		SDE_ERROR("invalid argument\n");
		return false;
	}

	if (!c_conn->ops.mode_needs_full_range)
		return false;

	return c_conn->ops.mode_needs_full_range(c_conn->display);
}

static void sde_connector_destroy(struct drm_connector *connector)
{
	struct sde_connector *c_conn;
+17 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -183,6 +183,14 @@ struct sde_connector_ops {
			void *display,
			struct msm_display_kickoff_params *params);

	/**
	 * mode_needs_full_range - does the mode need full range
	 * quantization
	 * @display: Pointer to private display structure
	 * Returns: true or false based on whether full range is needed
	 */
	bool (*mode_needs_full_range)(void *display);

	/**
	 * clk_ctrl - perform clk enable/disable on the connector
	 * @handle: Pointer to clk handle
@@ -702,6 +710,14 @@ static inline bool sde_connector_needs_offset(struct drm_connector *connector)
	return (c_conn->connector_type != DRM_MODE_CONNECTOR_VIRTUAL);
}

/**
 * sde_connector_mode_needs_full_range - query quantization type
 * for the connector mode
 * @connector: Pointer to drm connector object
 * Returns: true OR false based on connector mode
 */
bool sde_connector_mode_needs_full_range(struct drm_connector *connector);

/**
 * sde_connector_get_dither_cfg - get dither property data
 * @conn: Pointer to drm_connector struct
+20 −3
Original line number Diff line number Diff line
@@ -5171,6 +5171,7 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
	struct sde_encoder_virt *sde_enc = NULL;
	struct sde_hw_cdm *hw_cdm = phys_enc->hw_cdm;
	struct sde_hw_cdm_cfg *cdm_cfg = &phys_enc->cdm_cfg;
	struct drm_connector *connector = phys_enc->connector;
	int ret;
	u32 csc_type = 0;

@@ -5230,10 +5231,26 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
			cdm_cfg->h_cdwn_type,
			cdm_cfg->v_cdwn_type);

	if (output_type == CDM_CDWN_OUTPUT_HDMI)
	/**
	 * Choose CSC matrix based on following rules:
	 * 1. If connector supports quantization select,
	 *	  pick Full-Range for better quality.
	 * 2. If non-CEA mode, then pick Full-Range as per CEA spec
	 * 3. Otherwise, pick Limited-Range as all other CEA modes
	 *    need a limited range
	 */

	if (output_type == CDM_CDWN_OUTPUT_HDMI) {
		if (connector && connector->yuv_qs)
			csc_type = SDE_CSC_RGB2YUV_601FR;
		else if (connector &&
			sde_connector_mode_needs_full_range(connector))
			csc_type = SDE_CSC_RGB2YUV_601FR;
	else if (output_type == CDM_CDWN_OUTPUT_WB)
		else
			csc_type = SDE_CSC_RGB2YUV_601L;
	} else if (output_type == CDM_CDWN_OUTPUT_WB) {
		csc_type = SDE_CSC_RGB2YUV_601L;
	}

	if (hw_cdm && hw_cdm->ops.setup_csc_data) {
		ret = hw_cdm->ops.setup_csc_data(hw_cdm,
Loading