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 <quic_rsubbia@quicinc.com>
This commit is contained in:
@@ -44,6 +44,8 @@
|
|||||||
(DP_INTR_MST_DP0_VCPF_SENT | DP_INTR_MST_DP1_VCPF_SENT)
|
(DP_INTR_MST_DP0_VCPF_SENT | DP_INTR_MST_DP1_VCPF_SENT)
|
||||||
|
|
||||||
#define DP_INTR_MASK5 (DP_INTERRUPT_STATUS5 << 2)
|
#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) { \
|
#define dp_catalog_fill_io(x) { \
|
||||||
catalog->io.x = parser->get_io(parser, #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();
|
wmb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel,
|
static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel, u32 pattern)
|
||||||
bool enable)
|
|
||||||
{
|
{
|
||||||
struct dp_catalog_private *catalog;
|
struct dp_catalog_private *catalog;
|
||||||
struct dp_io_data *io_data;
|
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)
|
else if (panel->stream_id == DP_STREAM_1)
|
||||||
io_data = catalog->io.dp_p1;
|
io_data = catalog->io.dp_p1;
|
||||||
|
|
||||||
if (!enable) {
|
if (!pattern) {
|
||||||
dp_write(MMSS_DP_TPG_MAIN_CONTROL, 0x0);
|
dp_write(MMSS_DP_TPG_MAIN_CONTROL, 0x0);
|
||||||
dp_write(MMSS_DP_BIST_ENABLE, 0x0);
|
dp_write(MMSS_DP_BIST_ENABLE, 0x0);
|
||||||
reg = dp_read(MMSS_DP_TIMING_ENGINE_EN);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pattern > DP_TPG_PATTERN_MAX)
|
||||||
|
pattern = DP_TPG_PATTERN_DEFAULT;
|
||||||
|
|
||||||
dp_write(MMSS_DP_INTF_HSYNC_CTL,
|
dp_write(MMSS_DP_INTF_HSYNC_CTL,
|
||||||
panel->hsync_ctl);
|
panel->hsync_ctl);
|
||||||
dp_write(MMSS_DP_INTF_VSYNC_PERIOD_F0,
|
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);
|
dp_write(MMSS_DP_INTF_POLARITY_CTL, 0);
|
||||||
wmb(); /* ensure TPG registers are programmed */
|
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);
|
dp_write(MMSS_DP_TPG_VIDEO_CONFIG, 0x5);
|
||||||
wmb(); /* ensure TPG config is programmed */
|
wmb(); /* ensure TPG config is programmed */
|
||||||
dp_write(MMSS_DP_BIST_ENABLE, 0x1);
|
dp_write(MMSS_DP_BIST_ENABLE, 0x1);
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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.
|
* 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);
|
void (*config_sdp)(struct dp_catalog_panel *panel, bool en);
|
||||||
int (*set_colorspace)(struct dp_catalog_panel *panel,
|
int (*set_colorspace)(struct dp_catalog_panel *panel,
|
||||||
bool vsc_supported);
|
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_spd)(struct dp_catalog_panel *panel);
|
||||||
void (*config_misc)(struct dp_catalog_panel *panel);
|
void (*config_misc)(struct dp_catalog_panel *panel);
|
||||||
void (*config_msa)(struct dp_catalog_panel *panel,
|
void (*config_msa)(struct dp_catalog_panel *panel,
|
||||||
|
@@ -893,7 +893,7 @@ static ssize_t dp_debug_tpg_write(struct file *file,
|
|||||||
struct dp_debug_private *debug = file->private_data;
|
struct dp_debug_private *debug = file->private_data;
|
||||||
char buf[SZ_8];
|
char buf[SZ_8];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
u32 tpg_state = 0;
|
u32 tpg_pattern = 0;
|
||||||
|
|
||||||
if (!debug)
|
if (!debug)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -908,19 +908,18 @@ static ssize_t dp_debug_tpg_write(struct file *file,
|
|||||||
|
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
|
||||||
if (kstrtoint(buf, 10, &tpg_state) != 0)
|
if (kstrtoint(buf, 10, &tpg_pattern) != 0)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
tpg_state &= 0x1;
|
DP_DEBUG("tpg_pattern: %d\n", tpg_pattern);
|
||||||
DP_DEBUG("tpg_state: %d\n", tpg_state);
|
|
||||||
|
|
||||||
if (tpg_state == debug->dp_debug.tpg_state)
|
if (tpg_pattern == debug->dp_debug.tpg_pattern)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (debug->panel)
|
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:
|
bail:
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@@ -1386,7 +1385,7 @@ static ssize_t dp_debug_tpg_read(struct file *file,
|
|||||||
if (*ppos)
|
if (*ppos)
|
||||||
return 0;
|
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);
|
len = min_t(size_t, count, len);
|
||||||
if (copy_to_user(user_buff, buf, len))
|
if (copy_to_user(user_buff, buf, len))
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@
|
|||||||
* @psm_enabled: specifies whether psm enabled
|
* @psm_enabled: specifies whether psm enabled
|
||||||
* @hdcp_disabled: specifies if hdcp is disabled
|
* @hdcp_disabled: specifies if hdcp is disabled
|
||||||
* @hdcp_wait_sink_sync: used to wait for sink synchronization before HDCP auth
|
* @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
|
* @max_pclk_khz: max pclk supported
|
||||||
* @force_encryption: enable/disable forced encryption for HDCP 2.2
|
* @force_encryption: enable/disable forced encryption for HDCP 2.2
|
||||||
* @skip_uevent: skip hotplug uevent to the user space
|
* @skip_uevent: skip hotplug uevent to the user space
|
||||||
@@ -70,7 +71,7 @@ struct dp_debug {
|
|||||||
bool psm_enabled;
|
bool psm_enabled;
|
||||||
bool hdcp_disabled;
|
bool hdcp_disabled;
|
||||||
bool hdcp_wait_sink_sync;
|
bool hdcp_wait_sink_sync;
|
||||||
bool tpg_state;
|
u32 tpg_pattern;
|
||||||
u32 max_pclk_khz;
|
u32 max_pclk_khz;
|
||||||
bool force_encryption;
|
bool force_encryption;
|
||||||
bool skip_uevent;
|
bool skip_uevent;
|
||||||
|
@@ -1695,8 +1695,8 @@ static int dp_display_stream_enable(struct dp_display_private *dp,
|
|||||||
|
|
||||||
rc = dp->ctrl->stream_on(dp->ctrl, dp_panel);
|
rc = dp->ctrl->stream_on(dp->ctrl, dp_panel);
|
||||||
|
|
||||||
if (dp->debug->tpg_state)
|
if (dp->debug->tpg_pattern)
|
||||||
dp_panel->tpg_config(dp_panel, true);
|
dp_panel->tpg_config(dp_panel, dp->debug->tpg_pattern);
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
dp->active_panels[dp_panel->stream_id] = dp_panel;
|
dp->active_panels[dp_panel->stream_id] = dp_panel;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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.
|
* 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;
|
u32 hsync_start_x, hsync_end_x, hactive;
|
||||||
struct dp_catalog_panel *catalog;
|
struct dp_catalog_panel *catalog;
|
||||||
@@ -2100,8 +2101,8 @@ static void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enable) {
|
if (!pattern) {
|
||||||
panel->catalog->tpg_config(catalog, false);
|
panel->catalog->tpg_config(catalog, pattern);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2132,7 +2133,7 @@ static void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable)
|
|||||||
pinfo->h_sync_width;
|
pinfo->h_sync_width;
|
||||||
catalog->display_hctl = (hsync_end_x << 16) | hsync_start_x;
|
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)
|
static int dp_panel_config_timing(struct dp_panel *dp_panel)
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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.
|
* 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);
|
bool dhdr_update, u64 core_clk_rate, bool flush);
|
||||||
int (*set_colorspace)(struct dp_panel *dp_panel,
|
int (*set_colorspace)(struct dp_panel *dp_panel,
|
||||||
u32 colorspace);
|
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);
|
int (*spd_config)(struct dp_panel *dp_panel);
|
||||||
bool (*hdr_supported)(struct dp_panel *dp_panel);
|
bool (*hdr_supported)(struct dp_panel *dp_panel);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user