Browse Source

disp: msm: dp: separate hdr data into individual packets

Currently a lot of information is packed into the HDR data structure of
the catalog panel making it difficult to individually control the
parameters like colorimetry and other information sent using
VSC SDP packets.

Break up the structure into individual VSC SDP colorimetry, HDR
infoframe and DHDR VSIF packets.

This makes it easier to control each of these parameters independently.
For example, when only the colorspace is changed its sufficient to
update only the VSC SDP colorimetry packets.

Also align these packets with the upstream DP helper header defines.

Change-Id: Ia208f30a480fd203192624fe4f3d99c1c89350dc
Signed-off-by: Abhinav Kumar <[email protected]>
Abhinav Kumar 6 years ago
parent
commit
7f5f73ff41
3 changed files with 118 additions and 98 deletions
  1. 20 34
      msm/dp/dp_catalog.c
  2. 8 27
      msm/dp/dp_catalog.h
  3. 90 37
      msm/dp/dp_panel.c

+ 20 - 34
msm/dp/dp_catalog.c

@@ -6,7 +6,6 @@
 
 #include <linux/delay.h>
 #include <linux/iopoll.h>
-#include <drm/drm_dp_helper.h>
 
 #include "dp_catalog.h"
 #include "dp_reg.h"
@@ -496,11 +495,11 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
 		mst_offset = MMSS_DP1_VSCEXT_0 - MMSS_DP_VSCEXT_0;
 
 	catalog = dp_catalog_get_priv(panel);
-	hdr = &panel->hdr_data.hdr_meta;
+	hdr = &panel->hdr_meta;
 	io_data = catalog->io.dp_link;
 
 	/* HEADER BYTE 1 */
-	header = panel->hdr_data.vscext_header_byte1;
+	header = panel->dhdr_vsif_sdp.HB1;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_1_BIT)
 			| (parity << PARITY_BYTE_1_BIT));
@@ -510,7 +509,7 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
 	off += sizeof(data);
 
 	/* HEADER BYTE 2 */
-	header = panel->hdr_data.vscext_header_byte2;
+	header = panel->dhdr_vsif_sdp.HB2;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_2_BIT)
 			| (parity << PARITY_BYTE_2_BIT));
@@ -518,7 +517,7 @@ static void dp_catalog_panel_setup_vsif_infoframe_sdp(
 			data);
 
 	/* HEADER BYTE 3 */
-	header = panel->hdr_data.vscext_header_byte3;
+	header = panel->dhdr_vsif_sdp.HB3;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_3_BIT)
 			| (parity << PARITY_BYTE_3_BIT));
@@ -541,6 +540,8 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
 	struct dp_io_data *io_data;
 	u32 header, parity, data, mst_offset = 0;
 	u8 buf[SZ_64], off = 0;
+	u32 const version = 0x01;
+	u32 const length = 0x1a;
 
 	if (panel->stream_id >= DP_STREAM_MAX) {
 		DP_ERR("invalid stream_id:%d\n", panel->stream_id);
@@ -551,11 +552,11 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
 		mst_offset = MMSS_DP1_GENERIC2_0 - MMSS_DP_GENERIC2_0;
 
 	catalog = dp_catalog_get_priv(panel);
-	hdr = &panel->hdr_data.hdr_meta;
+	hdr = &panel->hdr_meta;
 	io_data = catalog->io.dp_link;
 
 	/* HEADER BYTE 1 */
-	header = panel->hdr_data.shdr_header_byte1;
+	header = panel->shdr_if_sdp.HB1;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_1_BIT)
 			| (parity << PARITY_BYTE_1_BIT));
@@ -565,7 +566,7 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
 	off += sizeof(data);
 
 	/* HEADER BYTE 2 */
-	header = panel->hdr_data.shdr_header_byte2;
+	header = panel->shdr_if_sdp.HB2;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_2_BIT)
 			| (parity << PARITY_BYTE_2_BIT));
@@ -573,7 +574,7 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
 			data);
 
 	/* HEADER BYTE 3 */
-	header = panel->hdr_data.shdr_header_byte3;
+	header = panel->shdr_if_sdp.HB3;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_3_BIT)
 			| (parity << PARITY_BYTE_3_BIT));
@@ -584,8 +585,8 @@ static void dp_catalog_panel_setup_hdr_infoframe_sdp(
 	memcpy(buf + off, &data, sizeof(data));
 	off += sizeof(data);
 
-	data = panel->hdr_data.version;
-	data |= panel->hdr_data.length << 8;
+	data = version;
+	data |= length << 8;
 	data |= hdr->eotf << 16;
 	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_2 + mst_offset,
 			data);
@@ -661,7 +662,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
 	struct dp_catalog_private *catalog;
 	struct dp_io_data *io_data;
 	u32 header, parity, data, mst_offset = 0;
-	u8 bpc, off = 0;
+	u8 off = 0;
 	u8 buf[SZ_128];
 
 	if (!panel) {
@@ -681,7 +682,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
 	io_data = catalog->io.dp_link;
 
 	/* HEADER BYTE 1 */
-	header = panel->hdr_data.vsc_header_byte1;
+	header = panel->vsc_colorimetry.header.HB1;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_1_BIT)
 			| (parity << PARITY_BYTE_1_BIT));
@@ -691,7 +692,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
 	off += sizeof(data);
 
 	/* HEADER BYTE 2 */
-	header = panel->hdr_data.vsc_header_byte2;
+	header = panel->vsc_colorimetry.header.HB2;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_2_BIT)
 			| (parity << PARITY_BYTE_2_BIT));
@@ -699,7 +700,7 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
 			data);
 
 	/* HEADER BYTE 3 */
-	header = panel->hdr_data.vsc_header_byte3;
+	header = panel->vsc_colorimetry.header.HB3;
 	parity = dp_header_get_parity(header);
 	data   = ((header << HEADER_BYTE_3_BIT)
 			| (parity << PARITY_BYTE_3_BIT));
@@ -731,24 +732,9 @@ static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
 	memcpy(buf + off, &data, sizeof(data));
 	off += sizeof(data);
 
-	switch (panel->hdr_data.bpc) {
-	default:
-	case 10:
-		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);
+	data = (panel->vsc_colorimetry.data[16] & 0xFF) |
+		((panel->vsc_colorimetry.data[17] & 0xFF) << 8) |
+		((panel->vsc_colorimetry.data[18] & 0x7) << 16);
 
 	dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC0_6 + mst_offset,
 			data);
@@ -842,7 +828,7 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
 		/* indicates presence of VSC (BIT(6) of MISC1) */
 		misc |= BIT(14);
 
-		if (panel->hdr_data.hdr_meta.eotf)
+		if (panel->hdr_meta.eotf)
 			DP_DEBUG("Enabled\n");
 		else
 			DP_DEBUG("Reset\n");

+ 8 - 27
msm/dp/dp_catalog.h

@@ -6,6 +6,7 @@
 #ifndef _DP_CATALOG_H_
 #define _DP_CATALOG_H_
 
+#include <drm/drm_dp_helper.h>
 #include <drm/msm_drm.h>
 
 #include "dp_parser.h"
@@ -39,32 +40,9 @@ enum dp_stream_id {
 	DP_STREAM_MAX,
 };
 
-struct dp_catalog_hdr_data {
-	u32 vsc_header_byte0;
-	u32 vsc_header_byte1;
-	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_vsc_sdp_colorimetry {
+	struct dp_sdp_header header;
+	u8 data[32];
 };
 
 struct dp_catalog_aux {
@@ -197,7 +175,10 @@ struct dp_catalog_panel {
 	u8 *spd_vendor_name;
 	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 */
 	u32 hsync_period;

+ 90 - 37
msm/dp/dp_panel.c

@@ -2480,7 +2480,10 @@ static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel, u32 flags)
 {
 	int rc = 0;
 	struct dp_panel_private *panel;
-	struct dp_catalog_hdr_data *hdr;
+	struct drm_msm_ext_hdr_metadata *hdr_meta;
+	struct dp_sdp_header *dhdr_vsif_sdp;
+	struct dp_sdp_header *shdr_if_sdp;
+	struct dp_catalog_vsc_sdp_colorimetry *vsc_colorimetry;
 	struct drm_connector *connector;
 	struct sde_connector_state *c_state;
 
@@ -2495,14 +2498,22 @@ static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel, u32 flags)
 	}
 
 	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
-	hdr = &panel->catalog->hdr_data;
+	hdr_meta = &panel->catalog->hdr_meta;
+	dhdr_vsif_sdp = &panel->catalog->dhdr_vsif_sdp;
+	shdr_if_sdp = &panel->catalog->shdr_if_sdp;
+	vsc_colorimetry = &panel->catalog->vsc_colorimetry;
 
 	if (!panel->custom_edid && dp_panel->edid_ctrl->edid)
 		sde_free_edid((void **)&dp_panel->edid_ctrl);
 
 	dp_panel_set_stream_info(dp_panel, DP_STREAM_MAX, 0, 0, 0, 0);
 	memset(&dp_panel->pinfo, 0, sizeof(dp_panel->pinfo));
-	memset(&hdr->hdr_meta, 0, sizeof(hdr->hdr_meta));
+	memset(hdr_meta, 0, sizeof(struct drm_msm_ext_hdr_metadata));
+	memset(dhdr_vsif_sdp, 0, sizeof(struct dp_sdp_header));
+	memset(shdr_if_sdp, 0, sizeof(struct dp_sdp_header));
+	memset(vsc_colorimetry, 0,
+		sizeof(struct dp_catalog_vsc_sdp_colorimetry));
+
 	panel->panel_on = false;
 
 	connector = dp_panel->connector;
@@ -2646,14 +2657,76 @@ static u32 dp_panel_calc_dhdr_pkt_limit(struct dp_panel *dp_panel,
 	return calc_pkt_limit;
 }
 
+static void dp_panel_setup_colorimetry_sdp(struct dp_panel *dp_panel)
+{
+	struct dp_panel_private *panel;
+	struct dp_catalog_vsc_sdp_colorimetry *hdr_colorimetry;
+	u8 bpc;
+
+	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	hdr_colorimetry = &panel->catalog->vsc_colorimetry;
+
+	hdr_colorimetry->header.HB0 = 0x00;
+	hdr_colorimetry->header.HB1 = 0x07;
+	hdr_colorimetry->header.HB2 = 0x05;
+	hdr_colorimetry->header.HB3 = 0x13;
+
+	/* VSC SDP Payload for DB16 */
+	hdr_colorimetry->data[16] = (RGB << 4) | ITU_R_BT_2020_RGB;
+
+	/* VSC SDP Payload for DB17 */
+	hdr_colorimetry->data[17] = (CEA << 7);
+	bpc = (dp_panel->pinfo.bpp / 3);
+
+	switch (bpc) {
+	default:
+	case 10:
+		hdr_colorimetry->data[17] |= BIT(1);
+		break;
+	case 8:
+		hdr_colorimetry->data[17] |= BIT(0);
+		break;
+	case 6:
+		hdr_colorimetry->data[17] |= 0;
+		break;
+	}
+
+	/* VSC SDP Payload for DB18 */
+	hdr_colorimetry->data[18] = GRAPHICS;
+}
+
+static void dp_panel_setup_hdr_if(struct dp_panel_private *panel)
+{
+	struct dp_sdp_header *shdr_if;
+
+	shdr_if = &panel->catalog->shdr_if_sdp;
+
+	shdr_if->HB0 = 0x00;
+	shdr_if->HB1 = 0x87;
+	shdr_if->HB2 = 0x1D;
+	shdr_if->HB3 = 0x13 << 2;
+}
+
+static void dp_panel_setup_dhdr_vsif(struct dp_panel_private *panel)
+{
+	struct dp_sdp_header *dhdr_vsif;
+
+	dhdr_vsif = &panel->catalog->dhdr_vsif_sdp;
+
+	dhdr_vsif->HB0 = 0x00;
+	dhdr_vsif->HB1 = 0x81;
+	dhdr_vsif->HB2 = 0x1D;
+	dhdr_vsif->HB3 = 0x13 << 2;
+}
+
 static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
 		struct drm_msm_ext_hdr_metadata *hdr_meta,
 		bool dhdr_update, u64 core_clk_rate)
 {
 	int rc = 0, max_pkts = 0;
 	struct dp_panel_private *panel;
-	struct dp_catalog_hdr_data *hdr;
 	struct dp_dhdr_maxpkt_calc_input input;
+	struct drm_msm_ext_hdr_metadata *catalog_hdr_meta;
 
 	if (!dp_panel) {
 		DP_ERR("invalid input\n");
@@ -2662,11 +2735,12 @@ static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
 	}
 
 	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
-	hdr = &panel->catalog->hdr_data;
+
+	catalog_hdr_meta = &panel->catalog->hdr_meta;
 
 	/* use cached meta data in case meta data not provided */
 	if (!hdr_meta) {
-		if (hdr->hdr_meta.hdr_state)
+		if (catalog_hdr_meta->hdr_state)
 			goto cached;
 		else
 			goto end;
@@ -2674,41 +2748,20 @@ static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
 
 	panel->hdr_state = hdr_meta->hdr_state;
 
-	hdr->vsc_header_byte0 = 0x00;
-	hdr->vsc_header_byte1 = 0x07;
-	hdr->vsc_header_byte2 = 0x05;
-	hdr->vsc_header_byte3 = 0x13;
+	dp_panel_setup_colorimetry_sdp(dp_panel);
 
-	hdr->shdr_header_byte0 = 0x00;
-	hdr->shdr_header_byte1 = 0x87;
-	hdr->shdr_header_byte2 = 0x1D;
-	hdr->shdr_header_byte3 = 0x13 << 2;
+	dp_panel_setup_hdr_if(panel);
 
-	/* VSC SDP Payload for DB16 */
-	hdr->pixel_encoding = RGB;
-	hdr->colorimetry = ITU_R_BT_2020_RGB;
-
-	/* VSC SDP Payload for DB17 */
-	hdr->dynamic_range = CEA;
-
-	/* VSC SDP Payload for DB18 */
-	hdr->content_type = GRAPHICS;
-
-	hdr->bpc = dp_panel->pinfo.bpp / 3;
-
-	hdr->version = 0x01;
-	hdr->length = 0x1A;
-
-	if (panel->hdr_state)
-		memcpy(&hdr->hdr_meta, hdr_meta, sizeof(hdr->hdr_meta));
-	else
-		memset(&hdr->hdr_meta, 0, sizeof(hdr->hdr_meta));
+	if (panel->hdr_state) {
+		memcpy(catalog_hdr_meta, hdr_meta,
+			   sizeof(struct drm_msm_ext_hdr_metadata));
+	} else {
+		memset(catalog_hdr_meta, 0,
+			sizeof(struct drm_msm_ext_hdr_metadata));
+	}
 cached:
 	if (dhdr_update) {
-		hdr->vscext_header_byte0 = 0x00;
-		hdr->vscext_header_byte1 = 0x81;
-		hdr->vscext_header_byte2 = 0x1D;
-		hdr->vscext_header_byte3 = 0x13 << 2;
+		dp_panel_setup_dhdr_vsif(panel);
 
 		input.mdp_clk = core_clk_rate;
 		input.lclk = dp_panel->link_info.rate;