Merge "drm/msm/dp: add support for HDR state machine"
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index c237a23..cfb4436 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -338,6 +338,7 @@
struct drm_msm_ext_hdr_metadata *hdr;
void __iomem *base;
u32 header, parity, data;
+ u8 buf[SZ_128], off = 0;
if (!panel) {
pr_err("invalid input\n");
@@ -354,8 +355,8 @@
data = ((header << HEADER_BYTE_1_BIT)
| (parity << PARITY_BYTE_1_BIT));
dp_write(base + MMSS_DP_VSCEXT_0, data);
- pr_debug("Header#1: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_VSCEXT_0: 0x%x\n", data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
/* HEADER BYTE 2 */
header = panel->hdr_data.vscext_header_byte2;
@@ -363,8 +364,6 @@
data = ((header << HEADER_BYTE_2_BIT)
| (parity << PARITY_BYTE_2_BIT));
dp_write(base + MMSS_DP_VSCEXT_1, data);
- pr_debug("Header#2: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_VSCEXT_1: 0x%x\n", data);
/* HEADER BYTE 3 */
header = panel->hdr_data.vscext_header_byte3;
@@ -373,65 +372,80 @@
| (parity << PARITY_BYTE_3_BIT));
data |= dp_read(base + MMSS_DP_VSCEXT_1);
dp_write(base + MMSS_DP_VSCEXT_1, data);
- pr_debug("Header#3: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_VSCEXT_1: 0x%x\n", data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = panel->hdr_data.version;
data |= panel->hdr_data.length << 8;
data |= hdr->eotf << 16;
- pr_debug("DP_VSCEXT_2: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_2, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->display_primaries_x[0]) |
(DP_GET_MSB(hdr->display_primaries_x[0]) << 8) |
(DP_GET_LSB(hdr->display_primaries_y[0]) << 16) |
(DP_GET_MSB(hdr->display_primaries_y[0]) << 24));
- pr_debug("DP_VSCEXT_3: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_3, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->display_primaries_x[1]) |
(DP_GET_MSB(hdr->display_primaries_x[1]) << 8) |
(DP_GET_LSB(hdr->display_primaries_y[1]) << 16) |
(DP_GET_MSB(hdr->display_primaries_y[1]) << 24));
- pr_debug("DP_VSCEXT_4: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_4, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->display_primaries_x[2]) |
(DP_GET_MSB(hdr->display_primaries_x[2]) << 8) |
(DP_GET_LSB(hdr->display_primaries_y[2]) << 16) |
(DP_GET_MSB(hdr->display_primaries_y[2]) << 24));
- pr_debug("DP_VSCEXT_5: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_5, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->white_point_x) |
(DP_GET_MSB(hdr->white_point_x) << 8) |
(DP_GET_LSB(hdr->white_point_y) << 16) |
(DP_GET_MSB(hdr->white_point_y) << 24));
- pr_debug("DP_VSCEXT_6: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_6, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->max_luminance) |
(DP_GET_MSB(hdr->max_luminance) << 8) |
(DP_GET_LSB(hdr->min_luminance) << 16) |
(DP_GET_MSB(hdr->min_luminance) << 24));
- pr_debug("DP_VSCEXT_7: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_7, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
data = (DP_GET_LSB(hdr->max_content_light_level) |
(DP_GET_MSB(hdr->max_content_light_level) << 8) |
(DP_GET_LSB(hdr->max_average_light_level) << 16) |
(DP_GET_MSB(hdr->max_average_light_level) << 24));
- pr_debug("DP_VSCEXT_8: 0x%x\n", data);
dp_write(base + MMSS_DP_VSCEXT_8, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
- dp_write(base + MMSS_DP_VSCEXT_9, 0x00);
+ data = 0;
+ dp_write(base + MMSS_DP_VSCEXT_9, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ print_hex_dump(KERN_DEBUG, "[drm-dp] VSCEXT: ",
+ DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
-static void dp_catalog_panel_setup_ext_sdp(struct dp_catalog_panel *panel)
+static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
{
struct dp_catalog_private *catalog;
void __iomem *base;
u32 header, parity, data;
+ u8 bpc, off = 0;
+ u8 buf[SZ_128];
if (!panel) {
pr_err("invalid input\n");
@@ -442,57 +456,13 @@
base = catalog->io->dp_link.base;
/* HEADER BYTE 1 */
- header = panel->hdr_data.ext_header_byte1;
- parity = dp_header_get_parity(header);
- data = ((header << HEADER_BYTE_1_BIT)
- | (parity << PARITY_BYTE_1_BIT));
- dp_write(base + MMSS_DP_EXTENSION_0, data);
- pr_debug("Header#1: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_EXTENSION_0: 0x%x\n", data);
-
- /* HEADER BYTE 2 */
- header = panel->hdr_data.ext_header_byte2;
- parity = dp_header_get_parity(header);
- data = ((header << HEADER_BYTE_2_BIT)
- | (parity << PARITY_BYTE_2_BIT));
- dp_write(base + MMSS_DP_EXTENSION_1, data);
- pr_debug("Header#2: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_EXTENSION_1: 0x%x\n", data);
-
- dp_write(base + MMSS_DP_EXTENSION_1, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_2, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_3, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_4, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_5, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_6, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_7, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_8, 0x5AA55AA5);
- dp_write(base + MMSS_DP_EXTENSION_9, 0x5AA55AA5);
-}
-
-static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
-{
- struct dp_catalog_private *catalog;
- void __iomem *base;
- u32 header, parity, data;
- u8 bpc;
-
- if (!panel) {
- pr_err("invalid input\n");
- return;
- }
-
- dp_catalog_get_priv(panel);
- base = catalog->io->ctrl_io.base;
-
- /* HEADER BYTE 1 */
header = panel->hdr_data.vsc_header_byte1;
parity = dp_header_get_parity(header);
data = ((header << HEADER_BYTE_1_BIT)
| (parity << PARITY_BYTE_1_BIT));
dp_write(base + MMSS_DP_GENERIC0_0, data);
- pr_debug("Header#1: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_GENERIC0_0: 0x%x\n", data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
/* HEADER BYTE 2 */
header = panel->hdr_data.vsc_header_byte2;
@@ -500,8 +470,6 @@
data = ((header << HEADER_BYTE_2_BIT)
| (parity << PARITY_BYTE_2_BIT));
dp_write(base + MMSS_DP_GENERIC0_1, data);
- pr_debug("Header#2: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_GENERIC0_1: 0x%x\n", data);
/* HEADER BYTE 3 */
header = panel->hdr_data.vsc_header_byte3;
@@ -510,14 +478,25 @@
| (parity << PARITY_BYTE_3_BIT));
data |= dp_read(base + MMSS_DP_GENERIC0_1);
dp_write(base + MMSS_DP_GENERIC0_1, data);
- pr_debug("Header#3: 0x%x, parity = 0x%x\n", header, parity);
- pr_debug("DP_GENERIC0_1: 0x%x\n", data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
- dp_write(base + MMSS_DP_GENERIC0_2, 0x00);
- dp_write(base + MMSS_DP_GENERIC0_3, 0x00);
- dp_write(base + MMSS_DP_GENERIC0_4, 0x00);
- dp_write(base + MMSS_DP_GENERIC0_5, 0x00);
+ data = 0;
+ dp_write(base + MMSS_DP_GENERIC0_2, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+ dp_write(base + MMSS_DP_GENERIC0_3, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(base + MMSS_DP_GENERIC0_4, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(base + MMSS_DP_GENERIC0_5, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
switch (panel->hdr_data.bpc) {
default:
@@ -538,18 +517,32 @@
((panel->hdr_data.dynamic_range & 0x1) << 15) |
((panel->hdr_data.content_type & 0x7) << 16);
- pr_debug("DP_GENERIC0_6: 0x%x\n", data);
dp_write(base + MMSS_DP_GENERIC0_6, data);
- dp_write(base + MMSS_DP_GENERIC0_7, 0x00);
- dp_write(base + MMSS_DP_GENERIC0_8, 0x00);
- dp_write(base + MMSS_DP_GENERIC0_9, 0x00);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ data = 0;
+ dp_write(base + MMSS_DP_GENERIC0_7, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(base + MMSS_DP_GENERIC0_8, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(base + MMSS_DP_GENERIC0_9, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ print_hex_dump(KERN_DEBUG, "[drm-dp] VSC: ",
+ DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
-static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel)
+static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en)
{
struct dp_catalog_private *catalog;
void __iomem *base;
- u32 cfg, cfg2;
+ u32 cfg, cfg2, misc;
if (!panel) {
pr_err("invalid input\n");
@@ -560,39 +553,44 @@
base = catalog->io->dp_link.base;
cfg = dp_read(base + MMSS_DP_SDP_CFG);
- /* EXTENSION_SDP_EN */
- cfg |= BIT(4);
-
- /* VSCEXT_SDP_EN */
- cfg |= BIT(16);
-
- /* GEN0_SDP_EN */
- cfg |= BIT(17);
-
- /* GEN1_SDP_EN */
- cfg |= BIT(18);
- dp_write(base + MMSS_DP_SDP_CFG, cfg);
-
cfg2 = dp_read(base + MMSS_DP_SDP_CFG2);
- /* EXTN_SDPSIZE */
- cfg2 |= BIT(15);
+ misc = dp_read(base + DP_MISC1_MISC0);
- /* GENERIC0_SDPSIZE */
- cfg |= BIT(16);
+ if (en) {
+ /* VSCEXT_SDP_EN, GEN0_SDP_EN */
+ cfg |= BIT(16) | BIT(17);
+ dp_write(base + MMSS_DP_SDP_CFG, cfg);
- /* GENERIC1_SDPSIZE */
- cfg |= BIT(17);
- dp_write(base + MMSS_DP_SDP_CFG2, cfg2);
+ /* EXTN_SDPSIZE GENERIC0_SDPSIZE */
+ cfg2 |= BIT(15) | BIT(16);
+ dp_write(base + MMSS_DP_SDP_CFG2, cfg2);
- dp_catalog_panel_setup_ext_sdp(panel);
- dp_catalog_panel_setup_vsc_sdp(panel);
- dp_catalog_panel_setup_infoframe_sdp(panel);
+ dp_catalog_panel_setup_vsc_sdp(panel);
+ dp_catalog_panel_setup_infoframe_sdp(panel);
- cfg = dp_read(base + DP_MISC1_MISC0);
- /* Indicates presence of VSC */
- cfg |= BIT(6) << 8;
+ /* indicates presence of VSC (BIT(6) of MISC1) */
+ misc |= BIT(14);
- dp_write(base + DP_MISC1_MISC0, cfg);
+ if (panel->hdr_data.hdr_meta.eotf)
+ pr_debug("Enabled\n");
+ else
+ pr_debug("Reset\n");
+ } else {
+ /* VSCEXT_SDP_EN, GEN0_SDP_EN */
+ cfg &= ~BIT(16) & ~BIT(17);
+ dp_write(base + MMSS_DP_SDP_CFG, cfg);
+
+ /* EXTN_SDPSIZE GENERIC0_SDPSIZE */
+ cfg2 &= ~BIT(15) & ~BIT(16);
+ dp_write(base + MMSS_DP_SDP_CFG2, cfg2);
+
+ /* switch back to MSA */
+ misc &= ~BIT(14);
+
+ pr_debug("Disabled\n");
+ }
+
+ dp_write(base + DP_MISC1_MISC0, misc);
dp_write(base + MMSS_DP_SDP_CFG3, 0x01);
dp_write(base + MMSS_DP_SDP_CFG3, 0x00);
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index b270545..d03be6a 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -171,7 +171,7 @@
u32 display_hctl;
int (*timing_cfg)(struct dp_catalog_panel *panel);
- void (*config_hdr)(struct dp_catalog_panel *panel);
+ void (*config_hdr)(struct dp_catalog_panel *panel, bool en);
void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);
void (*config_spd)(struct dp_catalog_panel *panel);
};
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c
index d00f159..6342fef 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -23,6 +23,7 @@
#include "dp_ctrl.h"
#include "dp_debug.h"
#include "drm_connector.h"
+#include "sde_connector.h"
#include "dp_display.h"
#define DEBUG_NAME "drm_dp"
@@ -618,6 +619,201 @@
return len;
}
+static ssize_t dp_debug_write_hdr(struct file *file,
+ const char __user *user_buff, size_t count, loff_t *ppos)
+{
+ struct drm_connector *connector;
+ struct sde_connector *c_conn;
+ struct sde_connector_state *c_state;
+ struct dp_debug_private *debug = file->private_data;
+ char buf[SZ_1K];
+ size_t len = 0;
+
+ if (!debug)
+ return -ENODEV;
+
+ if (*ppos)
+ return 0;
+
+ connector = *debug->connector;
+ c_conn = to_sde_connector(connector);
+ c_state = to_sde_connector_state(connector->state);
+
+ /* Leave room for termination char */
+ len = min_t(size_t, count, SZ_1K - 1);
+ if (copy_from_user(buf, user_buff, len))
+ goto end;
+
+ buf[len] = '\0';
+
+ if (sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
+ &c_state->hdr_meta.hdr_supported,
+ &c_state->hdr_meta.hdr_state,
+ &c_state->hdr_meta.eotf,
+ &c_state->hdr_meta.display_primaries_x[0],
+ &c_state->hdr_meta.display_primaries_x[1],
+ &c_state->hdr_meta.display_primaries_x[2],
+ &c_state->hdr_meta.display_primaries_y[0],
+ &c_state->hdr_meta.display_primaries_y[1],
+ &c_state->hdr_meta.display_primaries_y[2],
+ &c_state->hdr_meta.white_point_x,
+ &c_state->hdr_meta.white_point_y,
+ &c_state->hdr_meta.max_luminance,
+ &c_state->hdr_meta.min_luminance,
+ &c_state->hdr_meta.max_content_light_level,
+ &c_state->hdr_meta.max_average_light_level) != 15) {
+ pr_err("invalid input\n");
+ len = -EINVAL;
+ }
+end:
+ return len;
+}
+
+static ssize_t dp_debug_read_hdr(struct file *file,
+ char __user *user_buff, size_t count, loff_t *ppos)
+{
+ struct dp_debug_private *debug = file->private_data;
+ char *buf;
+ u32 len = 0, i;
+ u32 max_size = SZ_4K;
+ int rc = 0;
+ struct drm_connector *connector;
+ struct sde_connector *c_conn;
+ struct sde_connector_state *c_state;
+ struct drm_msm_ext_hdr_metadata *hdr;
+
+ if (!debug) {
+ pr_err("invalid data\n");
+ rc = -ENODEV;
+ goto error;
+ }
+
+ connector = *debug->connector;
+
+ if (!connector) {
+ pr_err("connector is NULL\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ if (*ppos)
+ goto error;
+
+ buf = kzalloc(SZ_4K, GFP_KERNEL);
+ if (!buf) {
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ c_conn = to_sde_connector(connector);
+ c_state = to_sde_connector_state(connector->state);
+
+ hdr = &c_state->hdr_meta;
+
+ rc = snprintf(buf + len, max_size,
+ "============SINK HDR PARAMETERS===========\n");
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "eotf = %d\n",
+ connector->hdr_eotf);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "type_one = %d\n",
+ connector->hdr_metadata_type_one);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
+ connector->hdr_max_luminance);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "avg_luminance = %d\n",
+ connector->hdr_avg_luminance);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
+ connector->hdr_min_luminance);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size,
+ "============VIDEO HDR PARAMETERS===========\n");
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "hdr_state = %d\n", hdr->hdr_state);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "hdr_supported = %d\n",
+ hdr->hdr_supported);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "eotf = %d\n", hdr->eotf);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "white_point_x = %d\n",
+ hdr->white_point_x);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "white_point_y = %d\n",
+ hdr->white_point_y);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
+ hdr->max_luminance);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
+ hdr->min_luminance);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "max_content_light_level = %d\n",
+ hdr->max_content_light_level);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "min_content_light_level = %d\n",
+ hdr->max_average_light_level);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ for (i = 0; i < HDR_PRIMARIES_COUNT; i++) {
+ rc = snprintf(buf + len, max_size, "primaries_x[%d] = %d\n",
+ i, hdr->display_primaries_x[i]);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+
+ rc = snprintf(buf + len, max_size, "primaries_y[%d] = %d\n",
+ i, hdr->display_primaries_y[i]);
+ if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
+ goto error;
+ }
+
+ if (copy_to_user(user_buff, buf, len)) {
+ kfree(buf);
+ rc = -EFAULT;
+ goto error;
+ }
+
+ *ppos += len;
+ kfree(buf);
+
+ return len;
+error:
+ return rc;
+}
+
static const struct file_operations dp_debug_fops = {
.open = simple_open,
.read = dp_debug_read_info,
@@ -661,6 +857,12 @@
.write = dp_debug_tpg_write,
};
+static const struct file_operations hdr_fops = {
+ .open = simple_open,
+ .write = dp_debug_write_hdr,
+ .read = dp_debug_read_hdr,
+};
+
static int dp_debug_init(struct dp_debug *dp_debug)
{
int rc = 0;
@@ -753,6 +955,16 @@
goto error_remove_dir;
}
+ file = debugfs_create_file("hdr", 0644, dir,
+ debug, &hdr_fops);
+
+ if (IS_ERR_OR_NULL(file)) {
+ rc = PTR_ERR(file);
+ pr_err("[%s] debugfs hdr failed, rc=%d\n",
+ DEBUG_NAME, rc);
+ goto error_remove_dir;
+ }
+
return 0;
error_remove_dir:
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 9bb3753..884dd68 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1196,6 +1196,7 @@
static int dp_display_pre_kickoff(struct dp_display *dp_display,
struct drm_msm_ext_hdr_metadata *hdr)
{
+ int rc = 0;
struct dp_display_private *dp;
if (!dp_display) {
@@ -1205,7 +1206,10 @@
dp = container_of(dp_display, struct dp_display_private, dp_display);
- return dp->panel->setup_hdr(dp->panel, hdr);
+ if (hdr->hdr_supported)
+ rc = dp->panel->setup_hdr(dp->panel, hdr);
+
+ return rc;
}
static int dp_display_create_workqueue(struct dp_display_private *dp)
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 96f9d3a..02edafb 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -19,8 +19,41 @@
#define DP_PANEL_DEFAULT_BPP 24
#define DP_MAX_DS_PORT_COUNT 1
-enum {
- DP_LINK_RATE_MULTIPLIER = 27000000,
+enum dp_panel_hdr_pixel_encoding {
+ RGB,
+ YCbCr444,
+ YCbCr422,
+ YCbCr420,
+ YONLY,
+ RAW,
+};
+
+enum dp_panel_hdr_rgb_colorimetry {
+ sRGB,
+ RGB_WIDE_GAMUT_FIXED_POINT,
+ RGB_WIDE_GAMUT_FLOATING_POINT,
+ ADOBERGB,
+ DCI_P3,
+ CUSTOM_COLOR_PROFILE,
+ ITU_R_BT_2020_RGB,
+};
+
+enum dp_panel_hdr_dynamic_range {
+ VESA,
+ CEA,
+};
+
+enum dp_panel_hdr_content_type {
+ NOT_DEFINED,
+ GRAPHICS,
+ PHOTO,
+ VIDEO,
+ GAME,
+};
+
+enum dp_panel_hdr_state {
+ HDR_DISABLED,
+ HDR_ENABLED,
};
struct dp_panel_private {
@@ -32,6 +65,7 @@
bool custom_edid;
bool custom_dpcd;
bool panel_on;
+ enum dp_panel_hdr_state hdr_state;
u8 spd_vendor_name[8];
u8 spd_product_description[16];
};
@@ -621,37 +655,29 @@
return min_link_rate_khz;
}
-enum dp_panel_hdr_pixel_encoding {
- RGB,
- YCbCr444,
- YCbCr422,
- YCbCr420,
- YONLY,
- RAW,
-};
+static bool dp_panel_is_validate_hdr_state(struct dp_panel_private *panel,
+ struct drm_msm_ext_hdr_metadata *hdr_meta)
+{
+ struct drm_msm_ext_hdr_metadata *panel_hdr_meta =
+ &panel->catalog->hdr_data.hdr_meta;
-enum dp_panel_hdr_rgb_colorimetry {
- sRGB,
- RGB_WIDE_GAMUT_FIXED_POINT,
- RGB_WIDE_GAMUT_FLOATING_POINT,
- ADOBERGB,
- DCI_P3,
- CUSTOM_COLOR_PROFILE,
- ITU_R_BT_2020_RGB,
-};
+ if (!hdr_meta)
+ goto end;
-enum dp_panel_hdr_dynamic_range {
- VESA,
- CEA,
-};
+ /* bail out if HDR not active */
+ if (hdr_meta->hdr_state == HDR_DISABLED &&
+ panel->hdr_state == HDR_DISABLED)
+ goto end;
-enum dp_panel_hdr_content_type {
- NOT_DEFINED,
- GRAPHICS,
- PHOTO,
- VIDEO,
- GAME,
-};
+ /* bail out if same meta data is received */
+ if (hdr_meta->hdr_state == HDR_ENABLED &&
+ panel_hdr_meta->eotf == hdr_meta->eotf)
+ goto end;
+
+ return true;
+end:
+ return false;
+}
static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
struct drm_msm_ext_hdr_metadata *hdr_meta)
@@ -660,9 +686,6 @@
struct dp_panel_private *panel;
struct dp_catalog_hdr_data *hdr;
- if (!hdr_meta || !hdr_meta->hdr_state)
- goto end;
-
if (!dp_panel) {
pr_err("invalid input\n");
rc = -EINVAL;
@@ -670,6 +693,12 @@
}
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+ if (!dp_panel_is_validate_hdr_state(panel, hdr_meta))
+ goto end;
+
+ panel->hdr_state = hdr_meta->hdr_state;
+
hdr = &panel->catalog->hdr_data;
hdr->ext_header_byte0 = 0x00;
@@ -682,6 +711,11 @@
hdr->vsc_header_byte2 = 0x05;
hdr->vsc_header_byte3 = 0x13;
+ hdr->vscext_header_byte0 = 0x00;
+ hdr->vscext_header_byte1 = 0x87;
+ hdr->vscext_header_byte2 = 0x1D;
+ hdr->vscext_header_byte3 = 0x13 << 2;
+
/* VSC SDP Payload for DB16 */
hdr->pixel_encoding = RGB;
hdr->colorimetry = ITU_R_BT_2020_RGB;
@@ -694,17 +728,12 @@
hdr->bpc = dp_panel->pinfo.bpp / 3;
- hdr->vscext_header_byte0 = 0x00;
- hdr->vscext_header_byte1 = 0x87;
- hdr->vscext_header_byte2 = 0x1D;
- hdr->vscext_header_byte3 = 0x13 << 2;
-
hdr->version = 0x01;
hdr->length = 0x1A;
memcpy(&hdr->hdr_meta, hdr_meta, sizeof(hdr->hdr_meta));
- panel->catalog->config_hdr(panel->catalog);
+ panel->catalog->config_hdr(panel->catalog, panel->hdr_state);
end:
return rc;
}