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

Commit 60d59191 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dp: add colorspace property for MSM DP"

parents 42aaee7d 14e02e4b
Loading
Loading
Loading
Loading
+169 −91
Original line number Original line Diff line number Diff line
@@ -6,7 +6,6 @@


#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/iopoll.h>
#include <drm/drm_dp_helper.h>


#include "dp_catalog.h"
#include "dp_catalog.h"
#include "dp_reg.h"
#include "dp_reg.h"
@@ -478,6 +477,29 @@ static u32 dp_catalog_ctrl_read_hdcp_status(struct dp_catalog_ctrl *ctrl)
	return dp_read(catalog->exe_mode, io_data, DP_HDCP_STATUS);
	return dp_read(catalog->exe_mode, io_data, DP_HDCP_STATUS);
}
}


static void dp_catalog_panel_sdp_update(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 sdp_cfg3_off = 0;

	if (panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	if (panel->stream_id == DP_STREAM_1)
		sdp_cfg3_off = MMSS_DP1_SDP_CFG3 - MMSS_DP_SDP_CFG3;

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
			 0x01);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
			 0x00);
}

static void dp_catalog_panel_setup_vsif_infoframe_sdp(
static void dp_catalog_panel_setup_vsif_infoframe_sdp(
		struct dp_catalog_panel *panel)
		struct dp_catalog_panel *panel)
{
{
@@ -496,11 +518,11 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
		mst_offset = MMSS_DP1_VSCEXT_0 - MMSS_DP_VSCEXT_0;
		mst_offset = MMSS_DP1_VSCEXT_0 - MMSS_DP_VSCEXT_0;


	catalog = dp_catalog_get_priv(panel);
	catalog = dp_catalog_get_priv(panel);
	hdr = &panel->hdr_data.hdr_meta;
	hdr = &panel->hdr_meta;
	io_data = catalog->io.dp_link;
	io_data = catalog->io.dp_link;


	/* HEADER BYTE 1 */
	/* HEADER BYTE 1 */
	header = panel->hdr_data.vscext_header_byte1;
	header = panel->dhdr_vsif_sdp.HB1;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_1_BIT)
	data   = ((header << HEADER_BYTE_1_BIT)
			| (parity << PARITY_BYTE_1_BIT));
			| (parity << PARITY_BYTE_1_BIT));
@@ -510,7 +532,7 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
	off += sizeof(data);
	off += sizeof(data);


	/* HEADER BYTE 2 */
	/* HEADER BYTE 2 */
	header = panel->hdr_data.vscext_header_byte2;
	header = panel->dhdr_vsif_sdp.HB2;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_2_BIT)
	data   = ((header << HEADER_BYTE_2_BIT)
			| (parity << PARITY_BYTE_2_BIT));
			| (parity << PARITY_BYTE_2_BIT));
@@ -518,7 +540,7 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
			data);
			data);


	/* HEADER BYTE 3 */
	/* HEADER BYTE 3 */
	header = panel->hdr_data.vscext_header_byte3;
	header = panel->dhdr_vsif_sdp.HB3;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_3_BIT)
	data   = ((header << HEADER_BYTE_3_BIT)
			| (parity << PARITY_BYTE_3_BIT));
			| (parity << PARITY_BYTE_3_BIT));
@@ -541,6 +563,8 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
	struct dp_io_data *io_data;
	struct dp_io_data *io_data;
	u32 header, parity, data, mst_offset = 0;
	u32 header, parity, data, mst_offset = 0;
	u8 buf[SZ_64], off = 0;
	u8 buf[SZ_64], off = 0;
	u32 const version = 0x01;
	u32 const length = 0x1a;


	if (panel->stream_id >= DP_STREAM_MAX) {
	if (panel->stream_id >= DP_STREAM_MAX) {
		DP_ERR("invalid stream_id:%d\n", panel->stream_id);
		DP_ERR("invalid stream_id:%d\n", panel->stream_id);
@@ -551,11 +575,11 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
		mst_offset = MMSS_DP1_GENERIC2_0 - MMSS_DP_GENERIC2_0;
		mst_offset = MMSS_DP1_GENERIC2_0 - MMSS_DP_GENERIC2_0;


	catalog = dp_catalog_get_priv(panel);
	catalog = dp_catalog_get_priv(panel);
	hdr = &panel->hdr_data.hdr_meta;
	hdr = &panel->hdr_meta;
	io_data = catalog->io.dp_link;
	io_data = catalog->io.dp_link;


	/* HEADER BYTE 1 */
	/* HEADER BYTE 1 */
	header = panel->hdr_data.shdr_header_byte1;
	header = panel->shdr_if_sdp.HB1;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_1_BIT)
	data   = ((header << HEADER_BYTE_1_BIT)
			| (parity << PARITY_BYTE_1_BIT));
			| (parity << PARITY_BYTE_1_BIT));
@@ -565,7 +589,7 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
	off += sizeof(data);
	off += sizeof(data);


	/* HEADER BYTE 2 */
	/* HEADER BYTE 2 */
	header = panel->hdr_data.shdr_header_byte2;
	header = panel->shdr_if_sdp.HB2;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_2_BIT)
	data   = ((header << HEADER_BYTE_2_BIT)
			| (parity << PARITY_BYTE_2_BIT));
			| (parity << PARITY_BYTE_2_BIT));
@@ -573,7 +597,7 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
			data);
			data);


	/* HEADER BYTE 3 */
	/* HEADER BYTE 3 */
	header = panel->hdr_data.shdr_header_byte3;
	header = panel->shdr_if_sdp.HB3;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_3_BIT)
	data   = ((header << HEADER_BYTE_3_BIT)
			| (parity << PARITY_BYTE_3_BIT));
			| (parity << PARITY_BYTE_3_BIT));
@@ -584,8 +608,8 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
	memcpy(buf + off, &data, sizeof(data));
	memcpy(buf + off, &data, sizeof(data));
	off += sizeof(data);
	off += sizeof(data);


	data = panel->hdr_data.version;
	data = version;
	data |= panel->hdr_data.length << 8;
	data |= length << 8;
	data |= hdr->eotf << 16;
	data |= hdr->eotf << 16;
	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_2 + mst_offset,
	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_2 + mst_offset,
			data);
			data);
@@ -661,7 +685,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
	struct dp_catalog_private *catalog;
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	struct dp_io_data *io_data;
	u32 header, parity, data, mst_offset = 0;
	u32 header, parity, data, mst_offset = 0;
	u8 bpc, off = 0;
	u8 off = 0;
	u8 buf[SZ_128];
	u8 buf[SZ_128];


	if (!panel) {
	if (!panel) {
@@ -681,7 +705,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
	io_data = catalog->io.dp_link;
	io_data = catalog->io.dp_link;


	/* HEADER BYTE 1 */
	/* HEADER BYTE 1 */
	header = panel->hdr_data.vsc_header_byte1;
	header = panel->vsc_colorimetry.header.HB1;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_1_BIT)
	data   = ((header << HEADER_BYTE_1_BIT)
			| (parity << PARITY_BYTE_1_BIT));
			| (parity << PARITY_BYTE_1_BIT));
@@ -691,7 +715,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
	off += sizeof(data);
	off += sizeof(data);


	/* HEADER BYTE 2 */
	/* HEADER BYTE 2 */
	header = panel->hdr_data.vsc_header_byte2;
	header = panel->vsc_colorimetry.header.HB2;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_2_BIT)
	data   = ((header << HEADER_BYTE_2_BIT)
			| (parity << PARITY_BYTE_2_BIT));
			| (parity << PARITY_BYTE_2_BIT));
@@ -699,7 +723,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
			data);
			data);


	/* HEADER BYTE 3 */
	/* HEADER BYTE 3 */
	header = panel->hdr_data.vsc_header_byte3;
	header = panel->vsc_colorimetry.header.HB3;
	parity = dp_header_get_parity(header);
	parity = dp_header_get_parity(header);
	data   = ((header << HEADER_BYTE_3_BIT)
	data   = ((header << HEADER_BYTE_3_BIT)
			| (parity << PARITY_BYTE_3_BIT));
			| (parity << PARITY_BYTE_3_BIT));
@@ -731,24 +755,9 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
	memcpy(buf + off, &data, sizeof(data));
	memcpy(buf + off, &data, sizeof(data));
	off += sizeof(data);
	off += sizeof(data);


	switch (panel->hdr_data.bpc) {
	data = (panel->vsc_colorimetry.data[16] & 0xFF) |
	default:
		((panel->vsc_colorimetry.data[17] & 0xFF) << 8) |
	case 10:
		((panel->vsc_colorimetry.data[18] & 0x7) << 16);
		bpc = BIT(1);
		break;
	case 8:
		bpc = BIT(0);
		break;
	case 6:
		bpc = 0;
		break;
	}

	data = (panel->hdr_data.colorimetry & 0xF) |
		((panel->hdr_data.pixel_encoding & 0xF) << 4) |
		(bpc << 8) |
		((panel->hdr_data.dynamic_range & 0x1) << 15) |
		((panel->hdr_data.content_type & 0x7) << 16);


	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC0_6 + mst_offset,
	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC0_6 + mst_offset,
			data);
			data);
@@ -775,15 +784,125 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
			DUMP_PREFIX_NONE, 16, 4, buf, off, false);
			DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
}


static void dp_catalog_panel_config_sdp(struct dp_catalog_panel *panel,
	bool en)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 cfg, cfg2;
	u32 sdp_cfg_off = 0;
	u32 sdp_cfg2_off = 0;

	if (panel->stream_id >= DP_STREAM_MAX) {
		DP_ERR("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	if (panel->stream_id == DP_STREAM_1) {
		sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
		sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
	}

	cfg = dp_read(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG + sdp_cfg_off);
	cfg2 = dp_read(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG2 + sdp_cfg2_off);

	if (en) {
		/* GEN0_SDP_EN */
		cfg |= BIT(17);
		dp_write(catalog->exe_mode, io_data,
				 MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);

		/* GENERIC0_SDPSIZE */
		cfg2 |= BIT(16);
		dp_write(catalog->exe_mode, io_data,
				 MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);

		/* setup the GENERIC0 in case of en = true */
		dp_catalog_panel_setup_vsc_sdp(panel);

	} else {
		/* GEN0_SDP_EN */
		cfg &= ~BIT(17);
		dp_write(catalog->exe_mode, io_data,
				 MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);

		/* GENERIC0_SDPSIZE */
		cfg2 &= ~BIT(16);
		dp_write(catalog->exe_mode, io_data,
				 MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);
	}

	dp_catalog_panel_sdp_update(panel);
}

static void dp_catalog_panel_config_misc(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 reg_offset = 0;

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

	if (panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	if (panel->stream_id == DP_STREAM_1)
		reg_offset = DP1_MISC1_MISC0 - DP_MISC1_MISC0;

	DP_DEBUG("misc settings = 0x%x\n", panel->misc_val);
	dp_write(catalog->exe_mode, io_data, DP_MISC1_MISC0 + reg_offset,
			panel->misc_val);
}

static int dp_catalog_panel_set_colorspace(struct dp_catalog_panel *panel,
bool vsc_supported)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!panel) {
		pr_err("invalid input\n");
		return -EINVAL;
	}

	if (panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream_id:%d\n", panel->stream_id);
		return -EINVAL;
	}

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	if (vsc_supported) {
		dp_catalog_panel_setup_vsc_sdp(panel);
		dp_catalog_panel_sdp_update(panel);
	} else
		dp_catalog_panel_config_misc(panel);

	return 0;
}

static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
		u32 dhdr_max_pkts)
	u32 dhdr_max_pkts, bool flush)
{
{
	struct dp_catalog_private *catalog;
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	struct dp_io_data *io_data;
	u32 cfg, cfg2, cfg4, misc;
	u32 cfg, cfg2, cfg4, misc;
	u32 sdp_cfg_off = 0;
	u32 sdp_cfg_off = 0;
	u32 sdp_cfg2_off = 0;
	u32 sdp_cfg2_off = 0;
	u32 sdp_cfg3_off = 0;
	u32 sdp_cfg4_off = 0;
	u32 sdp_cfg4_off = 0;
	u32 misc1_misc0_off = 0;
	u32 misc1_misc0_off = 0;


@@ -803,7 +922,6 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
	if (panel->stream_id == DP_STREAM_1) {
	if (panel->stream_id == DP_STREAM_1) {
		sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
		sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
		sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
		sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
		sdp_cfg3_off = MMSS_DP1_SDP_CFG3 - MMSS_DP_SDP_CFG3;
		sdp_cfg4_off = MMSS_DP1_SDP_CFG4 - MMSS_DP_SDP_CFG4;
		sdp_cfg4_off = MMSS_DP1_SDP_CFG4 - MMSS_DP_SDP_CFG4;
		misc1_misc0_off = DP1_MISC1_MISC0 - DP_MISC1_MISC0;
		misc1_misc0_off = DP1_MISC1_MISC0 - DP_MISC1_MISC0;
	}
	}
@@ -826,34 +944,30 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
			dp_catalog_panel_setup_vsif_infoframe_sdp(panel);
			dp_catalog_panel_setup_vsif_infoframe_sdp(panel);
		}
		}


		/* GEN0_SDP_EN, GEN2_SDP_EN */
		/* GEN2_SDP_EN */
		cfg |= BIT(17) | BIT(19);
		cfg |= BIT(19);
		dp_write(catalog->exe_mode, io_data,
		dp_write(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);
				MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);


		/* GENERIC0_SDPSIZE GENERIC2_SDPSIZE */
		/* GENERIC2_SDPSIZE */
		cfg2 |= BIT(16) | BIT(20);
		cfg2 |= BIT(20);
		dp_write(catalog->exe_mode, io_data,
		dp_write(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);
				MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);


		dp_catalog_panel_setup_vsc_sdp(panel);
		dp_catalog_panel_setup_hdr_infoframe_sdp(panel);
		dp_catalog_panel_setup_hdr_infoframe_sdp(panel);


		/* indicates presence of VSC (BIT(6) of MISC1) */
		if (panel->hdr_meta.eotf)
		misc |= BIT(14);

		if (panel->hdr_data.hdr_meta.eotf)
			DP_DEBUG("Enabled\n");
			DP_DEBUG("Enabled\n");
		else
		else
			DP_DEBUG("Reset\n");
			DP_DEBUG("Reset\n");
	} else {
	} else {
		/* VSCEXT_SDP_EN, GEN0_SDP_EN */
		/* VSCEXT_SDP_ENG */
		cfg &= ~BIT(16) & ~BIT(17) & ~BIT(19);
		cfg &= ~BIT(16) & ~BIT(19);
		dp_write(catalog->exe_mode, io_data,
		dp_write(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);
				MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);


		/* GENERIC0_SDPSIZE GENERIC2_SDPSIZE */
		/* GENERIC0_SDPSIZE GENERIC2_SDPSIZE */
		cfg2 &= ~BIT(16) & ~BIT(20);
		cfg2 &= ~BIT(20);
		dp_write(catalog->exe_mode, io_data,
		dp_write(catalog->exe_mode, io_data,
				MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);
				MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);


@@ -862,19 +976,13 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
		dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG4
		dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG4
				+ sdp_cfg4_off, cfg4);
				+ sdp_cfg4_off, cfg4);


		/* switch back to MSA */
		misc &= ~BIT(14);

		DP_DEBUG("Disabled\n");
		DP_DEBUG("Disabled\n");
	}
	}


	dp_write(catalog->exe_mode, io_data, DP_MISC1_MISC0 + misc1_misc0_off,
	if (flush) {
			misc);
		DP_DEBUG("flushing HDR metadata\n");

		dp_catalog_panel_sdp_update(panel);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
	}
			0x01);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
			0x00);
}
}


static void dp_catalog_panel_update_transfer_unit(
static void dp_catalog_panel_update_transfer_unit(
@@ -1109,33 +1217,6 @@ static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl,
	}
	}
}
}


static void dp_catalog_panel_config_misc(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 reg_offset = 0;

	if (!panel) {
		DP_ERR("invalid input\n");
		return;
	}

	if (panel->stream_id >= DP_STREAM_MAX) {
		DP_ERR("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	if (panel->stream_id == DP_STREAM_1)
		reg_offset = DP1_MISC1_MISC0 - DP_MISC1_MISC0;

	DP_DEBUG("misc settings = 0x%x\n", panel->misc_val);
	dp_write(catalog->exe_mode, io_data, DP_MISC1_MISC0 + reg_offset,
			panel->misc_val);
}

static void dp_catalog_panel_config_msa(struct dp_catalog_panel *panel,
static void dp_catalog_panel_config_msa(struct dp_catalog_panel *panel,
					u32 rate, u32 stream_rate_khz)
					u32 rate, u32 stream_rate_khz)
{
{
@@ -2494,7 +2575,6 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel)
	u32 offset = 0;
	u32 offset = 0;
	u32 sdp_cfg_off = 0;
	u32 sdp_cfg_off = 0;
	u32 sdp_cfg2_off = 0;
	u32 sdp_cfg2_off = 0;
	u32 sdp_cfg3_off = 0;


	/*
	/*
	 * Source Device Information
	 * Source Device Information
@@ -2567,7 +2647,6 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel)
	if (panel->stream_id == DP_STREAM_1) {
	if (panel->stream_id == DP_STREAM_1) {
		sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
		sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
		sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
		sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
		sdp_cfg3_off = MMSS_DP1_SDP_CFG3 - MMSS_DP_SDP_CFG3;
	}
	}


	spd_cfg = dp_read(catalog->exe_mode, io_data,
	spd_cfg = dp_read(catalog->exe_mode, io_data,
@@ -2584,10 +2663,7 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel)
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg2_off,
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg2_off,
			spd_cfg2);
			spd_cfg2);


	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
	dp_catalog_panel_sdp_update(panel);
				0x1);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG3 + sdp_cfg3_off,
				0x0);
}
}


static void dp_catalog_get_io_buf(struct dp_catalog_private *catalog)
static void dp_catalog_get_io_buf(struct dp_catalog_private *catalog)
@@ -2745,9 +2821,11 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
	struct dp_catalog_panel panel = {
	struct dp_catalog_panel panel = {
		.timing_cfg = dp_catalog_panel_timing_cfg,
		.timing_cfg = dp_catalog_panel_timing_cfg,
		.config_hdr = dp_catalog_panel_config_hdr,
		.config_hdr = dp_catalog_panel_config_hdr,
		.config_sdp = dp_catalog_panel_config_sdp,
		.tpg_config = dp_catalog_panel_tpg_cfg,
		.tpg_config = dp_catalog_panel_tpg_cfg,
		.config_spd = dp_catalog_panel_config_spd,
		.config_spd = dp_catalog_panel_config_spd,
		.config_misc = dp_catalog_panel_config_misc,
		.config_misc = dp_catalog_panel_config_misc,
		.set_colorspace = dp_catalog_panel_set_colorspace,
		.config_msa = dp_catalog_panel_config_msa,
		.config_msa = dp_catalog_panel_config_msa,
		.update_transfer_unit = dp_catalog_panel_update_transfer_unit,
		.update_transfer_unit = dp_catalog_panel_update_transfer_unit,
		.config_ctrl = dp_catalog_panel_config_ctrl,
		.config_ctrl = dp_catalog_panel_config_ctrl,
+12 −28
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@
#ifndef _DP_CATALOG_H_
#ifndef _DP_CATALOG_H_
#define _DP_CATALOG_H_
#define _DP_CATALOG_H_


#include <drm/drm_dp_helper.h>
#include <drm/msm_drm.h>
#include <drm/msm_drm.h>


#include "dp_parser.h"
#include "dp_parser.h"
@@ -39,32 +40,9 @@ enum dp_stream_id {
	DP_STREAM_MAX,
	DP_STREAM_MAX,
};
};


struct dp_catalog_hdr_data {
struct dp_catalog_vsc_sdp_colorimetry {
	u32 vsc_header_byte0;
	struct dp_sdp_header header;
	u32 vsc_header_byte1;
	u8 data[32];
	u32 vsc_header_byte2;
	u32 vsc_header_byte3;

	u32 vscext_header_byte0;
	u32 vscext_header_byte1;
	u32 vscext_header_byte2;
	u32 vscext_header_byte3;

	u32 shdr_header_byte0;
	u32 shdr_header_byte1;
	u32 shdr_header_byte2;
	u32 shdr_header_byte3;

	u32 bpc;

	u32 version;
	u32 length;
	u32 pixel_encoding;
	u32 colorimetry;
	u32 dynamic_range;
	u32 content_type;

	struct drm_msm_ext_hdr_metadata hdr_meta;
};
};


struct dp_catalog_aux {
struct dp_catalog_aux {
@@ -197,7 +175,10 @@ struct dp_catalog_panel {
	u8 *spd_vendor_name;
	u8 *spd_vendor_name;
	u8 *spd_product_description;
	u8 *spd_product_description;


	struct dp_catalog_hdr_data hdr_data;
	struct dp_catalog_vsc_sdp_colorimetry vsc_colorimetry;
	struct dp_sdp_header dhdr_vsif_sdp;
	struct dp_sdp_header shdr_if_sdp;
	struct drm_msm_ext_hdr_metadata hdr_meta;


	/* TPG */
	/* TPG */
	u32 hsync_period;
	u32 hsync_period;
@@ -222,7 +203,10 @@ struct dp_catalog_panel {


	int (*timing_cfg)(struct dp_catalog_panel *panel);
	int (*timing_cfg)(struct dp_catalog_panel *panel);
	void (*config_hdr)(struct dp_catalog_panel *panel, bool en,
	void (*config_hdr)(struct dp_catalog_panel *panel, bool en,
			u32 dhdr_max_pkts);
		u32 dhdr_max_pkts, bool flush);
	void (*config_sdp)(struct dp_catalog_panel *panel, bool en);
	int (*set_colorspace)(struct dp_catalog_panel *panel,
		 bool vsc_supported);
	void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);
	void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);
	void (*config_spd)(struct dp_catalog_panel *panel);
	void (*config_spd)(struct dp_catalog_panel *panel);
	void (*config_misc)(struct dp_catalog_panel *panel);
	void (*config_misc)(struct dp_catalog_panel *panel);
+45 −2
Original line number Original line Diff line number Diff line
@@ -1627,7 +1627,7 @@ static void dp_display_stream_post_enable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
			struct dp_panel *dp_panel)
{
{
	dp_panel->spd_config(dp_panel);
	dp_panel->spd_config(dp_panel);
	dp_panel->setup_hdr(dp_panel, NULL, false, 0);
	dp_panel->setup_hdr(dp_panel, NULL, false, 0, true);
}
}


static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
@@ -1676,6 +1676,14 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
	return 0;
	return 0;
}
}


static void dp_display_clear_colorspaces(struct dp_display *dp_display)
{
	struct drm_connector *connector;

	connector = dp_display->base_connector;
	connector->color_enc_fmt = 0;
}

static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
{
{
	struct dp_display_private *dp;
	struct dp_display_private *dp;
@@ -1732,6 +1740,8 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
		}
		}
	}
	}


	dp_display_clear_colorspaces(dp_display);

clean:
clean:
	if (dp_panel->audio_supported)
	if (dp_panel->audio_supported)
		dp_panel->audio->off(dp_panel->audio);
		dp_panel->audio->off(dp_panel->audio);
@@ -2082,8 +2092,10 @@ static int dp_display_config_hdr(struct dp_display *dp_display, void *panel,
			struct drm_msm_ext_hdr_metadata *hdr, bool dhdr_update)
			struct drm_msm_ext_hdr_metadata *hdr, bool dhdr_update)
{
{
	struct dp_panel *dp_panel;
	struct dp_panel *dp_panel;
	struct sde_connector *sde_conn;
	struct dp_display_private *dp;
	struct dp_display_private *dp;
	u64 core_clk_rate;
	u64 core_clk_rate;
	bool flush_hdr;


	if (!dp_display || !panel) {
	if (!dp_display || !panel) {
		DP_ERR("invalid input\n");
		DP_ERR("invalid input\n");
@@ -2092,6 +2104,7 @@ static int dp_display_config_hdr(struct dp_display *dp_display, void *panel,


	dp_panel = panel;
	dp_panel = panel;
	dp = container_of(dp_display, struct dp_display_private, dp_display);
	dp = container_of(dp_display, struct dp_display_private, dp_display);
	sde_conn =  to_sde_connector(dp_panel->connector);


	core_clk_rate = dp->power->clk_get_rate(dp->power, "core_clk");
	core_clk_rate = dp->power->clk_get_rate(dp->power, "core_clk");
	if (!core_clk_rate) {
	if (!core_clk_rate) {
@@ -2099,7 +2112,36 @@ static int dp_display_config_hdr(struct dp_display *dp_display, void *panel,
		return -EINVAL;
		return -EINVAL;
	}
	}


	return dp_panel->setup_hdr(dp_panel, hdr, dhdr_update, core_clk_rate);
	/*
	 * In rare cases where HDR metadata is updated independently
	 * flush the HDR metadata immediately instead of relying on
	 * the colorspace
	 */
	flush_hdr = !sde_conn->colorspace_updated;

	if (flush_hdr)
		DP_DEBUG("flushing the HDR metadata\n");
	else
		DP_DEBUG("piggy-backing with colorspace\n");

	return dp_panel->setup_hdr(dp_panel, hdr, dhdr_update,
		core_clk_rate, flush_hdr);
}

static int dp_display_setup_colospace(struct dp_display *dp_display,
		void *panel,
		u32 colorspace)
{
	struct dp_panel *dp_panel;

	if (!dp_display || !panel) {
		pr_err("invalid input\n");
		return -EINVAL;
	}

	dp_panel = panel;

	return dp_panel->set_colorspace(dp_panel, colorspace);
}
}


static int dp_display_create_workqueue(struct dp_display_private *dp)
static int dp_display_create_workqueue(struct dp_display_private *dp)
@@ -2623,6 +2665,7 @@ static int dp_display_probe(struct platform_device *pdev)
					dp_display_mst_get_fixed_topology_port;
					dp_display_mst_get_fixed_topology_port;
	g_dp_display->wakeup_phy_layer =
	g_dp_display->wakeup_phy_layer =
					dp_display_wakeup_phy_layer;
					dp_display_wakeup_phy_layer;
	g_dp_display->set_colorspace = dp_display_setup_colospace;


	rc = component_add(&pdev->dev, &dp_display_comp_ops);
	rc = component_add(&pdev->dev, &dp_display_comp_ops);
	if (rc) {
	if (rc) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -93,6 +93,8 @@ struct dp_display {
	int (*config_hdr)(struct dp_display *dp_display, void *panel,
	int (*config_hdr)(struct dp_display *dp_display, void *panel,
				struct drm_msm_ext_hdr_metadata *hdr_meta,
				struct drm_msm_ext_hdr_metadata *hdr_meta,
				bool dhdr_update);
				bool dhdr_update);
	int (*set_colorspace)(struct dp_display *dp_display, void *panel,
				u32 colorspace);
	int (*post_init)(struct dp_display *dp_display);
	int (*post_init)(struct dp_display *dp_display);
	int (*mst_install)(struct dp_display *dp_display,
	int (*mst_install)(struct dp_display *dp_display,
			struct dp_mst_drm_install_info *mst_install_info);
			struct dp_mst_drm_install_info *mst_install_info);
+45 −0
Original line number Original line Diff line number Diff line
@@ -326,6 +326,25 @@ int dp_connector_config_hdr(struct drm_connector *connector, void *display,
			c_state->dyn_hdr_meta.dynamic_hdr_update);
			c_state->dyn_hdr_meta.dynamic_hdr_update);
}
}


int dp_connector_set_colorspace(struct drm_connector *connector,
	void *display)
{
	struct dp_display *dp_display = display;
	struct sde_connector *sde_conn;

	if (!dp_display || !connector)
		return -EINVAL;

	sde_conn = to_sde_connector(connector);
	if (!sde_conn->drv_panel) {
		pr_err("invalid dp panel\n");
		return -EINVAL;
	}

	return dp_display->set_colorspace(dp_display,
		sde_conn->drv_panel, connector->state->colorspace);
}

int dp_connector_post_init(struct drm_connector *connector, void *display)
int dp_connector_post_init(struct drm_connector *connector, void *display)
{
{
	int rc;
	int rc;
@@ -469,6 +488,32 @@ void dp_connector_post_open(struct drm_connector *connector, void *display)
		dp->post_open(dp);
		dp->post_open(dp);
}
}


int dp_connector_atomic_check(struct drm_connector *connector,
	void *display,
	struct drm_connector_state *c_state)
{
	struct sde_connector *sde_conn;
	struct drm_connector_state *old_state =
		drm_atomic_get_old_connector_state(c_state->state, connector);

	if (!connector || !display)
		return -EINVAL;

	sde_conn = to_sde_connector(connector);

	/*
	 * Marking the colorspace has been changed
	 * the flag shall be checked in the pre_kickoff
	 * to configure the new colorspace in HW
	 */
	if (c_state->colorspace != old_state->colorspace) {
		DP_DEBUG("colorspace has been updated\n");
		sde_conn->colorspace_updated = true;
	}

	return 0;
}

int dp_connector_get_modes(struct drm_connector *connector,
int dp_connector_get_modes(struct drm_connector *connector,
		void *display, const struct msm_resource_caps_info *avail_res)
		void *display, const struct msm_resource_caps_info *avail_res)
{
{
Loading