From bbd8a4b5ab28da7dab0cf2bfd678a28887be796b Mon Sep 17 00:00:00 2001 From: Rajkumar Subbiah Date: Fri, 8 Apr 2022 12:07:39 -0400 Subject: [PATCH] disp: msm: dp: add ability to select pattern for tpg Currently the tpg_ctrl node takes a boolean flag to enable or disable test pattern output on DP controller. It always sets the pattern type to a default pattern. This change updates this interface to accept an integer value so the user can select different patterns supported by the controller. Change-Id: I399091a57f353b2fb8d29a48a8390898ca9afb55 Signed-off-by: Rajkumar Subbiah --- msm/dp/dp_catalog.c | 12 ++++++++---- msm/dp/dp_catalog.h | 3 ++- msm/dp/dp_debug.c | 15 +++++++-------- msm/dp/dp_debug.h | 5 +++-- msm/dp/dp_display.c | 4 ++-- msm/dp/dp_panel.c | 9 +++++---- msm/dp/dp_panel.h | 3 ++- 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/msm/dp/dp_catalog.c b/msm/dp/dp_catalog.c index ec3611034c..e6dfae0a48 100644 --- a/msm/dp/dp_catalog.c +++ b/msm/dp/dp_catalog.c @@ -44,6 +44,8 @@ (DP_INTR_MST_DP0_VCPF_SENT | DP_INTR_MST_DP1_VCPF_SENT) #define DP_INTR_MASK5 (DP_INTERRUPT_STATUS5 << 2) +#define DP_TPG_PATTERN_MAX 9 +#define DP_TPG_PATTERN_DEFAULT 8 #define dp_catalog_fill_io(x) { \ catalog->io.x = parser->get_io(parser, #x); \ @@ -1417,8 +1419,7 @@ static void dp_catalog_ctrl_usb_reset(struct dp_catalog_ctrl *ctrl, bool flip) wmb(); } -static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, - bool enable) +static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, u32 pattern) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; @@ -1441,7 +1442,7 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, else if (panel->stream_id == DP_STREAM_1) io_data = catalog->io.dp_p1; - if (!enable) { + if (!pattern) { dp_write(MMSS_DP_TPG_MAIN_CONTROL, 0x0); dp_write(MMSS_DP_BIST_ENABLE, 0x0); reg = dp_read(MMSS_DP_TIMING_ENGINE_EN); @@ -1451,6 +1452,9 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, return; } + if (pattern > DP_TPG_PATTERN_MAX) + pattern = DP_TPG_PATTERN_DEFAULT; + dp_write(MMSS_DP_INTF_HSYNC_CTL, panel->hsync_ctl); dp_write(MMSS_DP_INTF_VSYNC_PERIOD_F0, @@ -1472,7 +1476,7 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, dp_write(MMSS_DP_INTF_POLARITY_CTL, 0); wmb(); /* ensure TPG registers are programmed */ - dp_write(MMSS_DP_TPG_MAIN_CONTROL, 0x100); + dp_write(MMSS_DP_TPG_MAIN_CONTROL, (1 << pattern)); dp_write(MMSS_DP_TPG_VIDEO_CONFIG, 0x5); wmb(); /* ensure TPG config is programmed */ dp_write(MMSS_DP_BIST_ENABLE, 0x1); diff --git a/msm/dp/dp_catalog.h b/msm/dp/dp_catalog.h index 829a2e8a7f..fea2365883 100644 --- a/msm/dp/dp_catalog.h +++ b/msm/dp/dp_catalog.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ @@ -208,7 +209,7 @@ struct dp_catalog_panel { 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, u32 pattern); void (*config_spd)(struct dp_catalog_panel *panel); void (*config_misc)(struct dp_catalog_panel *panel); void (*config_msa)(struct dp_catalog_panel *panel, diff --git a/msm/dp/dp_debug.c b/msm/dp/dp_debug.c index ed621f6156..c71a468ee2 100644 --- a/msm/dp/dp_debug.c +++ b/msm/dp/dp_debug.c @@ -893,7 +893,7 @@ static ssize_t dp_debug_tpg_write(struct file *file, struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; - u32 tpg_state = 0; + u32 tpg_pattern = 0; if (!debug) return -ENODEV; @@ -908,19 +908,18 @@ static ssize_t dp_debug_tpg_write(struct file *file, buf[len] = '\0'; - if (kstrtoint(buf, 10, &tpg_state) != 0) + if (kstrtoint(buf, 10, &tpg_pattern) != 0) goto bail; - tpg_state &= 0x1; - DP_DEBUG("tpg_state: %d\n", tpg_state); + DP_DEBUG("tpg_pattern: %d\n", tpg_pattern); - if (tpg_state == debug->dp_debug.tpg_state) + if (tpg_pattern == debug->dp_debug.tpg_pattern) goto bail; if (debug->panel) - debug->panel->tpg_config(debug->panel, tpg_state); + debug->panel->tpg_config(debug->panel, tpg_pattern); - debug->dp_debug.tpg_state = tpg_state; + debug->dp_debug.tpg_pattern = tpg_pattern; bail: return len; } @@ -1386,7 +1385,7 @@ static ssize_t dp_debug_tpg_read(struct file *file, if (*ppos) return 0; - len += snprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_state); + len += scnprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_pattern); len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) diff --git a/msm/dp/dp_debug.h b/msm/dp/dp_debug.h index 5f7311828b..43fb7b08a1 100644 --- a/msm/dp/dp_debug.h +++ b/msm/dp/dp_debug.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ @@ -52,7 +53,7 @@ * @psm_enabled: specifies whether psm enabled * @hdcp_disabled: specifies if hdcp is disabled * @hdcp_wait_sink_sync: used to wait for sink synchronization before HDCP auth - * @tpg_state: specifies whether tpg feature is enabled + * @tpg_pattern: selects tpg pattern on the controller * @max_pclk_khz: max pclk supported * @force_encryption: enable/disable forced encryption for HDCP 2.2 * @skip_uevent: skip hotplug uevent to the user space @@ -70,7 +71,7 @@ struct dp_debug { bool psm_enabled; bool hdcp_disabled; bool hdcp_wait_sink_sync; - bool tpg_state; + u32 tpg_pattern; u32 max_pclk_khz; bool force_encryption; bool skip_uevent; diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index a3f5943231..4159eca2ec 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -1695,8 +1695,8 @@ static int dp_display_stream_enable(struct dp_display_private *dp, rc = dp->ctrl->stream_on(dp->ctrl, dp_panel); - if (dp->debug->tpg_state) - dp_panel->tpg_config(dp_panel, true); + if (dp->debug->tpg_pattern) + dp_panel->tpg_config(dp_panel, dp->debug->tpg_pattern); if (!rc) { dp->active_panels[dp_panel->stream_id] = dp_panel; diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index 6ea8c96804..ef8f45e8fa 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ @@ -2074,7 +2075,7 @@ static void dp_panel_handle_sink_request(struct dp_panel *dp_panel) } } -static void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable) +static void dp_panel_tpg_config(struct dp_panel *dp_panel, u32 pattern) { u32 hsync_start_x, hsync_end_x, hactive; struct dp_catalog_panel *catalog; @@ -2100,8 +2101,8 @@ static void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable) return; } - if (!enable) { - panel->catalog->tpg_config(catalog, false); + if (!pattern) { + panel->catalog->tpg_config(catalog, pattern); return; } @@ -2132,7 +2133,7 @@ static void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable) pinfo->h_sync_width; catalog->display_hctl = (hsync_end_x << 16) | hsync_start_x; - panel->catalog->tpg_config(catalog, true); + panel->catalog->tpg_config(catalog, pattern); } static int dp_panel_config_timing(struct dp_panel *dp_panel) diff --git a/msm/dp/dp_panel.h b/msm/dp/dp_panel.h index eceaf1605c..fa47bfb319 100644 --- a/msm/dp/dp_panel.h +++ b/msm/dp/dp_panel.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ @@ -176,7 +177,7 @@ struct dp_panel { bool dhdr_update, u64 core_clk_rate, bool flush); int (*set_colorspace)(struct dp_panel *dp_panel, u32 colorspace); - void (*tpg_config)(struct dp_panel *dp_panel, bool enable); + void (*tpg_config)(struct dp_panel *dp_panel, u32 pattern); int (*spd_config)(struct dp_panel *dp_panel); bool (*hdr_supported)(struct dp_panel *dp_panel);