disp: msm: dp: Support DP display as primary

Changes to support DP display as primary. The connector should
indicate the display type as primary to the drm library.

Change-Id: Ib5f6d9d72e8c42f88d38e06ed504848b8fc52029
Signed-off-by: Xiaowen Wu <wxiaowen@codeaurora.org>
Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad@quicinc.com>
Signed-off-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Signed-off-by: Nilesh Laad <quic_nlaad@quicinc.com>
This commit is contained in:
Nilesh Laad 2023-03-24 16:55:28 +05:30 committed by Gerrit - the friendly Code Review server
parent dfce8892e1
commit 4eb2953032
8 changed files with 121 additions and 0 deletions

View File

@ -3552,6 +3552,46 @@ static void dp_display_wakeup_phy_layer(struct dp_display *dp_display,
hpd->wakeup_phy(hpd, wakeup);
}
static int dp_display_get_display_type(struct dp_display *dp_display,
const char **display_type)
{
struct dp_display_private *dp;
if (!dp_display || !display_type) {
pr_err("invalid input\n");
return -EINVAL;
}
dp = container_of(dp_display, struct dp_display_private, dp_display);
*display_type = dp->parser->display_type;
return 0;
}
static int dp_display_mst_get_fixed_topology_display_type(
struct dp_display *dp_display, u32 strm_id,
const char **display_type)
{
struct dp_display_private *dp;
if (!dp_display || !display_type) {
pr_err("invalid input\n");
return -EINVAL;
}
if (strm_id >= DP_STREAM_MAX) {
pr_err("invalid stream id:%d\n", strm_id);
return -EINVAL;
}
dp = container_of(dp_display, struct dp_display_private, dp_display);
*display_type = dp->parser->mst_fixed_display_type[strm_id];
return 0;
}
static int dp_display_probe(struct platform_device *pdev)
{
int rc = 0;
@ -3629,6 +3669,9 @@ static int dp_display_probe(struct platform_device *pdev)
g_dp_display->set_colorspace = dp_display_setup_colospace;
g_dp_display->get_available_dp_resources =
dp_display_get_available_dp_resources;
g_dp_display->get_display_type = dp_display_get_display_type;
g_dp_display->mst_get_fixed_topology_display_type =
dp_display_mst_get_fixed_topology_display_type;
rc = component_add(&pdev->dev, &dp_display_comp_ops);
if (rc) {

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
@ -132,6 +133,10 @@ struct dp_display {
int (*get_available_dp_resources)(struct dp_display *dp_display,
const struct msm_resource_caps_info *avail_res,
struct msm_resource_caps_info *max_dp_avail_res);
int (*get_display_type)(struct dp_display *dp_display,
const char **display_type);
int (*mst_get_fixed_topology_display_type)(struct dp_display *dp_display,
u32 strm_id, const char **display_type);
};
#if IS_ENABLED(CONFIG_DRM_MSM_DP)

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
@ -594,6 +595,18 @@ int dp_connector_get_modes(struct drm_connector *connector,
return rc;
}
int dp_connector_set_info_blob(struct drm_connector *connector,
void *info, void *display, struct msm_mode_info *mode_info)
{
struct dp_display *dp_display = display;
const char *display_type = NULL;
dp_display->get_display_type(dp_display, &display_type);
sde_kms_info_add_keystr(info, "display type", display_type);
return 0;
}
int dp_drm_bridge_init(void *data, struct drm_encoder *encoder,
u32 max_mixer_count, u32 max_dsc_count)
{

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
@ -136,6 +137,18 @@ void dp_connector_post_open(struct drm_connector *connector, void *display);
* @max_mixer_count: max available mixers for dp display
* @max_dsc_count: max available dsc for dp display
*/
/**
* dp_conn_set_info_blob - callback to perform info blob initialization
* @connector: Pointer to drm connector structure
* @info: Pointer to sde connector info structure
* @display: Pointer to private display handle
* @mode_info: Pointer to mode info structure
* Returns: Zero on success
*/
int dp_connector_set_info_blob(struct drm_connector *connector,
void *info, void *display, struct msm_mode_info *mode_info);
int dp_drm_bridge_init(void *display, struct drm_encoder *encoder,
u32 max_mixer_count, u32 max_dsc_count);
@ -233,6 +246,12 @@ static inline void dp_connector_post_open(struct drm_connector *connector,
{
}
static inline int dp_connector_set_info_blob(struct drm_connector *connector,
void *info, void *display, struct msm_mode_info *mode_info)
{
return 0;
}
static inline int dp_drm_bridge_init(void *display, struct drm_encoder *encoder,
u32 max_mixer_count, u32 max_dsc_count)
{

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
@ -2130,11 +2131,36 @@ static void dp_mst_destroy_fixed_connector(struct drm_dp_mst_topology_mgr *mgr,
dp_mst_destroy_connector(mgr, connector);
}
static int dp_mst_fixed_connector_set_info_blob(
struct drm_connector *connector,
void *info, void *display, struct msm_mode_info *mode_info)
{
struct sde_connector *c_conn = to_sde_connector(connector);
struct dp_display *dp_display = display;
struct dp_mst_private *mst = dp_display->dp_mst_prv_info;
const char *display_type = NULL;
int i;
for (i = 0; i < MAX_DP_MST_DRM_BRIDGES; i++) {
if (mst->mst_bridge[i].base.encoder != c_conn->encoder)
continue;
dp_display->mst_get_fixed_topology_display_type(dp_display,
mst->mst_bridge[i].id, &display_type);
sde_kms_info_add_keystr(info, "display type", display_type);
break;
}
return 0;
}
static struct drm_connector *
dp_mst_drm_fixed_connector_init(struct dp_display *dp_display,
struct drm_encoder *encoder)
{
static const struct sde_connector_ops dp_mst_connector_ops = {
.set_info_blob = dp_mst_fixed_connector_set_info_blob,
.post_init = dp_mst_connector_post_init,
.detect = dp_mst_fixed_connector_detect,
.get_modes = dp_mst_connector_get_modes,

View File

@ -173,6 +173,10 @@ static int dp_parser_misc(struct dp_parser *parser)
&parser->pixel_base_off[i]);
}
parser->display_type = of_get_property(of_node, "qcom,display-type", NULL);
if (!parser->display_type)
parser->display_type = "unknown";
return 0;
}
@ -744,6 +748,12 @@ static int dp_parser_mst(struct dp_parser *parser)
of_property_read_u32_index(dev->of_node,
"qcom,mst-fixed-topology-ports", i,
&parser->mst_fixed_port[i]);
of_property_read_string_index(
dev->of_node,
"qcom,mst-fixed-topology-display-types", i,
&parser->mst_fixed_display_type[i]);
if (!parser->mst_fixed_display_type[i])
parser->mst_fixed_display_type[i] = "unknown";
}
return 0;

View File

@ -224,6 +224,8 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type)
* @get_io: function to be called by client to get io data.
* @get_io_buf: function to be called by client to get io buffers.
* @clear_io_buf: function to be called by client to clear io buffers.
* @mst_fixed_display_type: mst display_type reserved for fixed topology
* @display_type: display type as defined in device tree.
*/
struct dp_parser {
struct platform_device *pdev;
@ -250,6 +252,8 @@ struct dp_parser {
bool lphw_hpd;
u32 mst_fixed_port[MAX_DP_MST_STREAMS];
u32 pixel_base_off[MAX_DP_MST_STREAMS];
const char *mst_fixed_display_type[MAX_DP_MST_STREAMS];
const char *display_type;
int (*parse)(struct dp_parser *parser);
struct dp_io_data *(*get_io)(struct dp_parser *parser, char *name);

View File

@ -1776,6 +1776,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.set_allowed_mode_switch = NULL,
};
static const struct sde_connector_ops dp_ops = {
.set_info_blob = dp_connector_set_info_blob,
.post_init = dp_connector_post_init,
.detect = dp_connector_detect,
.get_modes = dp_connector_get_modes,