mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
drm/msm/dp: add support to multiple dp instances
Add support to multiple dp isntances. Clean up dp-mst global state. Change-Id: Iaa88ab8c339fa0e247656024b289faa087ea0fbd Signed-off-by: Xiaowen Wu <wxiaowen@codeaurora.org> Signed-off-by: Soutrik Mukhopadhyay <quic_mukhopad@quicinc.com>
This commit is contained in:
parent
4e9b8a8eda
commit
cfaa8dfa20
6 changed files with 241 additions and 147 deletions
|
|
@ -32,6 +32,8 @@ struct dp_debug_private {
|
|||
char exe_mode[SZ_32];
|
||||
char reg_dump[SZ_32];
|
||||
|
||||
const char *name;
|
||||
|
||||
struct dp_hpd *hpd;
|
||||
struct dp_link *link;
|
||||
struct dp_panel *panel;
|
||||
|
|
@ -1899,7 +1901,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs create mst_con_id failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1908,7 +1910,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs create mst_conn_info failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1917,7 +1919,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DRM_ERROR("[%s] debugfs create mst_con_add failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1926,7 +1928,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DRM_ERROR("[%s] debugfs create mst_con_remove failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1935,7 +1937,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs mst_mode failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1944,7 +1946,7 @@ static int dp_debug_init_mst(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs mst_sideband_mode failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1962,7 +1964,7 @@ static int dp_debug_init_link(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs max_bw_code failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1971,7 +1973,7 @@ static int dp_debug_init_link(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs max_pclk_khz failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1998,7 +2000,7 @@ static int dp_debug_init_link(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs link_bw_code failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2016,7 +2018,7 @@ static int dp_debug_init_hdcp(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs hdcp_wait_sink_sync failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2025,7 +2027,7 @@ static int dp_debug_init_hdcp(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs force_encryption failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2043,7 +2045,7 @@ static int dp_debug_init_sink_caps(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs create edid_modes failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2052,7 +2054,7 @@ static int dp_debug_init_sink_caps(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs create edid_modes_mst failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2061,7 +2063,7 @@ static int dp_debug_init_sink_caps(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs edid failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2070,7 +2072,7 @@ static int dp_debug_init_sink_caps(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs dpcd failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2088,7 +2090,7 @@ static int dp_debug_init_status(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs create file failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2097,7 +2099,7 @@ static int dp_debug_init_status(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs connected failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2105,7 +2107,7 @@ static int dp_debug_init_status(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs hdr failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2113,7 +2115,7 @@ static int dp_debug_init_status(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs hdr_mst failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2121,7 +2123,7 @@ static int dp_debug_init_status(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs hdcp failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2137,7 +2139,7 @@ static int dp_debug_init_sim(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs hpd failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2145,7 +2147,7 @@ static int dp_debug_init_sim(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs sim failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2154,7 +2156,7 @@ static int dp_debug_init_sim(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs attention failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2163,7 +2165,7 @@ static int dp_debug_init_sim(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs skip_uevent failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2172,7 +2174,7 @@ static int dp_debug_init_sim(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs force_multi_func failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2190,7 +2192,7 @@ static int dp_debug_init_dsc_fec(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs dsc_feature failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2199,7 +2201,7 @@ static int dp_debug_init_dsc_fec(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs fec_feature_enable failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2216,7 +2218,7 @@ static int dp_debug_init_tpg(struct dp_debug_private *debug, struct dentry *dir)
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs tpg failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2234,7 +2236,7 @@ static int dp_debug_init_reg_dump(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs register failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2243,7 +2245,7 @@ static int dp_debug_init_reg_dump(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs dump failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2261,7 +2263,7 @@ static int dp_debug_init_feature_toggle(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs ssc_enable failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2270,7 +2272,7 @@ static int dp_debug_init_feature_toggle(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs widebus_mode failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2288,7 +2290,7 @@ static int dp_debug_init_configs(struct dp_debug_private *debug,
|
|||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs connect_notification_delay_ms failed, rc=%d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
return rc;
|
||||
}
|
||||
debug->dp_debug.connect_notification_delay_ms =
|
||||
|
|
@ -2321,14 +2323,18 @@ static int dp_debug_init(struct dp_debug *dp_debug)
|
|||
return 0;
|
||||
}
|
||||
|
||||
dir = debugfs_create_dir(DEBUG_NAME, NULL);
|
||||
debug->name = of_get_property(debug->dev->of_node, "label", NULL);
|
||||
if (!debug->name)
|
||||
debug->name = DEBUG_NAME;
|
||||
|
||||
dir = debugfs_create_dir(debug->name, NULL);
|
||||
if (IS_ERR_OR_NULL(dir)) {
|
||||
if (!dir)
|
||||
rc = -EINVAL;
|
||||
else
|
||||
rc = PTR_ERR(dir);
|
||||
DP_ERR("[%s] debugfs create dir failed, rc = %d\n",
|
||||
DEBUG_NAME, rc);
|
||||
debug->name, rc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ static char *dp_display_state_name(enum dp_display_states state)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static struct dp_display *g_dp_display;
|
||||
static struct dp_display *g_dp_display[MAX_DP_ACTIVE_DISPLAY];
|
||||
#define HPD_STRING_SIZE 30
|
||||
|
||||
struct dp_hdcp_dev {
|
||||
|
|
@ -206,6 +206,11 @@ struct dp_display_private {
|
|||
bool process_hpd_connect;
|
||||
|
||||
struct notifier_block usb_nb;
|
||||
|
||||
u32 cell_idx;
|
||||
u32 intf_idx[DP_STREAM_MAX];
|
||||
u32 phy_idx;
|
||||
u32 stream_cnt;
|
||||
};
|
||||
|
||||
static const struct dp_display_type_info dp_info = {
|
||||
|
|
@ -758,6 +763,32 @@ static int dp_display_post_hw_acquire(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dp_display_get_cell_info(struct dp_display_private *dp)
|
||||
{
|
||||
struct device_node *of_node = dp->pdev->dev.of_node;
|
||||
int i, rc;
|
||||
|
||||
of_property_read_u32(of_node,
|
||||
"cell-index", &dp->cell_idx);
|
||||
|
||||
if (of_property_read_bool(of_node, "qcom,mst-enable"))
|
||||
dp->stream_cnt = DP_STREAM_MAX;
|
||||
|
||||
of_property_read_u32_index(of_node,
|
||||
"qcom,intf-index", 0, &dp->intf_idx[0]);
|
||||
|
||||
for (i = 1; i < dp->stream_cnt; i++) {
|
||||
rc = of_property_read_u32_index(of_node,
|
||||
"qcom,intf-index", i, &dp->intf_idx[i]);
|
||||
if (rc)
|
||||
dp->intf_idx[i] = dp->intf_idx[0] + i;
|
||||
}
|
||||
|
||||
of_property_read_u32(of_node,
|
||||
"qcom,phy-index", &dp->phy_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dp_display_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
|
|
@ -1994,8 +2025,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
|||
goto error_catalog;
|
||||
}
|
||||
|
||||
g_dp_display->is_mst_supported = dp->parser->has_mst;
|
||||
g_dp_display->dsc_cont_pps = dp->parser->dsc_continuous_pps;
|
||||
dp->dp_display.is_mst_supported = dp->parser->has_mst;
|
||||
dp->dp_display.dsc_cont_pps = dp->parser->dsc_continuous_pps;
|
||||
|
||||
dp->catalog = dp_catalog_get(dev, dp->parser);
|
||||
if (IS_ERR(dp->catalog)) {
|
||||
|
|
@ -3788,6 +3819,8 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
struct dp_display_private *dp;
|
||||
const struct of_device_id *id;
|
||||
const struct dp_display_type_info *info;
|
||||
struct dp_display *dp_display;
|
||||
int index;
|
||||
|
||||
if (!pdev || !pdev->dev.of_node) {
|
||||
DP_ERR("pdev not found\n");
|
||||
|
|
@ -3801,6 +3834,13 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
|
||||
info = id->data;
|
||||
|
||||
index = dp_display_get_num_of_displays();
|
||||
if (index >= MAX_DP_ACTIVE_DISPLAY) {
|
||||
pr_err("exceeds max dp count\n");
|
||||
rc = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
|
||||
if (!dp) {
|
||||
rc = -ENOMEM;
|
||||
|
|
@ -3815,6 +3855,10 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
|
||||
memset(&dp->mst, 0, sizeof(dp->mst));
|
||||
|
||||
rc = dp_display_get_cell_info(dp);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = dp_display_create_workqueue(dp);
|
||||
if (rc) {
|
||||
DP_ERR("Failed to create workqueue\n");
|
||||
|
|
@ -3823,50 +3867,51 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, dp);
|
||||
|
||||
g_dp_display = &dp->dp_display;
|
||||
dp_display = &dp->dp_display;
|
||||
g_dp_display[index] = dp_display;
|
||||
|
||||
g_dp_display->enable = dp_display_enable;
|
||||
g_dp_display->post_enable = dp_display_post_enable;
|
||||
g_dp_display->pre_disable = dp_display_pre_disable;
|
||||
g_dp_display->disable = dp_display_disable;
|
||||
g_dp_display->set_mode = dp_display_set_mode;
|
||||
g_dp_display->validate_mode = dp_display_validate_mode;
|
||||
g_dp_display->get_modes = dp_display_get_modes;
|
||||
g_dp_display->prepare = dp_display_prepare;
|
||||
g_dp_display->unprepare = dp_display_unprepare;
|
||||
g_dp_display->request_irq = dp_request_irq;
|
||||
g_dp_display->get_debug = dp_get_debug;
|
||||
g_dp_display->post_open = NULL;
|
||||
g_dp_display->post_init = dp_display_post_init;
|
||||
g_dp_display->config_hdr = dp_display_config_hdr;
|
||||
g_dp_display->mst_install = dp_display_mst_install;
|
||||
g_dp_display->mst_uninstall = dp_display_mst_uninstall;
|
||||
g_dp_display->mst_connector_install = dp_display_mst_connector_install;
|
||||
g_dp_display->mst_connector_uninstall =
|
||||
dp_display->enable = dp_display_enable;
|
||||
dp_display->post_enable = dp_display_post_enable;
|
||||
dp_display->pre_disable = dp_display_pre_disable;
|
||||
dp_display->disable = dp_display_disable;
|
||||
dp_display->set_mode = dp_display_set_mode;
|
||||
dp_display->validate_mode = dp_display_validate_mode;
|
||||
dp_display->get_modes = dp_display_get_modes;
|
||||
dp_display->prepare = dp_display_prepare;
|
||||
dp_display->unprepare = dp_display_unprepare;
|
||||
dp_display->request_irq = dp_request_irq;
|
||||
dp_display->get_debug = dp_get_debug;
|
||||
dp_display->post_open = NULL;
|
||||
dp_display->post_init = dp_display_post_init;
|
||||
dp_display->config_hdr = dp_display_config_hdr;
|
||||
dp_display->mst_install = dp_display_mst_install;
|
||||
dp_display->mst_uninstall = dp_display_mst_uninstall;
|
||||
dp_display->mst_connector_install = dp_display_mst_connector_install;
|
||||
dp_display->mst_connector_uninstall =
|
||||
dp_display_mst_connector_uninstall;
|
||||
g_dp_display->mst_connector_update_edid =
|
||||
dp_display->mst_connector_update_edid =
|
||||
dp_display_mst_connector_update_edid;
|
||||
g_dp_display->mst_connector_update_link_info =
|
||||
dp_display->mst_connector_update_link_info =
|
||||
dp_display_mst_connector_update_link_info;
|
||||
g_dp_display->get_mst_caps = dp_display_get_mst_caps;
|
||||
g_dp_display->set_stream_info = dp_display_set_stream_info;
|
||||
g_dp_display->update_pps = dp_display_update_pps;
|
||||
g_dp_display->convert_to_dp_mode = dp_display_convert_to_dp_mode;
|
||||
g_dp_display->mst_get_connector_info =
|
||||
dp_display->get_mst_caps = dp_display_get_mst_caps;
|
||||
dp_display->set_stream_info = dp_display_set_stream_info;
|
||||
dp_display->update_pps = dp_display_update_pps;
|
||||
dp_display->convert_to_dp_mode = dp_display_convert_to_dp_mode;
|
||||
dp_display->mst_get_connector_info =
|
||||
dp_display_mst_get_connector_info;
|
||||
g_dp_display->mst_get_fixed_topology_port =
|
||||
dp_display->mst_get_fixed_topology_port =
|
||||
dp_display_mst_get_fixed_topology_port;
|
||||
g_dp_display->wakeup_phy_layer =
|
||||
dp_display->wakeup_phy_layer =
|
||||
dp_display_wakeup_phy_layer;
|
||||
g_dp_display->set_colorspace = dp_display_setup_colospace;
|
||||
g_dp_display->get_available_dp_resources =
|
||||
dp_display->set_colorspace = dp_display_setup_colospace;
|
||||
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->get_display_type = dp_display_get_display_type;
|
||||
dp_display->mst_get_fixed_topology_display_type =
|
||||
dp_display_mst_get_fixed_topology_display_type;
|
||||
|
||||
g_dp_display->is_edp = (info->display_type == DRM_MODE_CONNECTOR_eDP) ? true : false;
|
||||
g_dp_display->edp_detect = dp_display_edp_detect;
|
||||
dp_display->is_edp = (info->display_type == DRM_MODE_CONNECTOR_eDP) ? true : false;
|
||||
dp_display->edp_detect = dp_display_edp_detect;
|
||||
|
||||
rc = component_add(&pdev->dev, &dp_display_comp_ops);
|
||||
if (rc) {
|
||||
|
|
@ -3883,31 +3928,71 @@ bail:
|
|||
|
||||
int dp_display_get_displays(void **displays, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!displays) {
|
||||
DP_ERR("invalid data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count != 1) {
|
||||
DP_ERR("invalid number of displays\n");
|
||||
return -EINVAL;
|
||||
for (i = 0; i < MAX_DP_ACTIVE_DISPLAY && i < count; i++) {
|
||||
if (!g_dp_display[i])
|
||||
break;
|
||||
|
||||
displays[i] = g_dp_display[i];
|
||||
}
|
||||
|
||||
displays[0] = g_dp_display;
|
||||
return count;
|
||||
return i;
|
||||
}
|
||||
|
||||
int dp_display_get_num_of_displays(void)
|
||||
{
|
||||
if (!g_dp_display)
|
||||
return 0;
|
||||
int i;
|
||||
|
||||
return 1;
|
||||
for (i = 0; i < MAX_DP_ACTIVE_DISPLAY; i++)
|
||||
if (!g_dp_display[i])
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int dp_display_get_num_of_streams(void)
|
||||
{
|
||||
return DP_STREAM_MAX;
|
||||
struct dp_display_private *dp;
|
||||
int i, count = 0;
|
||||
|
||||
for (i = 0; i < MAX_DP_ACTIVE_DISPLAY; i++) {
|
||||
if (!g_dp_display[i])
|
||||
break;
|
||||
|
||||
dp = container_of(g_dp_display[i], struct dp_display_private, dp_display);
|
||||
|
||||
count += dp->stream_cnt;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int dp_display_get_info(void *dp_display, struct dp_display_info *dp_info)
|
||||
{
|
||||
struct dp_display_private *dp;
|
||||
int i;
|
||||
|
||||
if (!dp_display) {
|
||||
DP_DEBUG("dp display not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
|
||||
dp_info->cell_idx = dp->cell_idx;
|
||||
dp_info->intf_idx[0] = dp->intf_idx[0];
|
||||
for (i = 1; i < dp->stream_cnt; i++)
|
||||
dp_info->intf_idx[i] = dp->intf_idx[i];
|
||||
dp_info->phy_idx = dp->phy_idx;
|
||||
dp_info->stream_cnt = dp->stream_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dp_display_set_mst_state(void *dp_display,
|
||||
|
|
@ -3915,16 +4000,11 @@ static void dp_display_set_mst_state(void *dp_display,
|
|||
{
|
||||
struct dp_display_private *dp;
|
||||
|
||||
if (!g_dp_display) {
|
||||
DP_DEBUG("dp display not initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dp = container_of(g_dp_display, struct dp_display_private, dp_display);
|
||||
dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
SDE_EVT32_EXTERNAL(mst_state, dp->mst.mst_active);
|
||||
|
||||
if (dp->mst.mst_active && dp->mst.cbs.set_drv_state)
|
||||
dp->mst.cbs.set_drv_state(g_dp_display, mst_state);
|
||||
dp->mst.cbs.set_drv_state(dp_display, mst_state);
|
||||
}
|
||||
|
||||
static int dp_display_remove(struct platform_device *pdev)
|
||||
|
|
@ -3949,12 +4029,16 @@ static int dp_display_remove(struct platform_device *pdev)
|
|||
|
||||
static int dp_pm_prepare(struct device *dev)
|
||||
{
|
||||
struct dp_display_private *dp = container_of(g_dp_display,
|
||||
struct dp_display_private, dp_display);
|
||||
struct dp_display_private *dp;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
dp = dev_get_drvdata(dev);
|
||||
|
||||
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY);
|
||||
mutex_lock(&dp->session_lock);
|
||||
dp_display_set_mst_state(g_dp_display, PM_SUSPEND);
|
||||
dp_display_set_mst_state(&dp->dp_display, PM_SUSPEND);
|
||||
|
||||
/*
|
||||
* There are a few instances where the DP is hotplugged when the device
|
||||
|
|
@ -3979,12 +4063,16 @@ static int dp_pm_prepare(struct device *dev)
|
|||
|
||||
static void dp_pm_complete(struct device *dev)
|
||||
{
|
||||
struct dp_display_private *dp = container_of(g_dp_display,
|
||||
struct dp_display_private, dp_display);
|
||||
struct dp_display_private *dp;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
dp = dev_get_drvdata(dev);
|
||||
|
||||
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY);
|
||||
mutex_lock(&dp->session_lock);
|
||||
dp_display_set_mst_state(g_dp_display, PM_DEFAULT);
|
||||
dp_display_set_mst_state(&dp->dp_display, PM_DEFAULT);
|
||||
|
||||
/*
|
||||
* There are multiple PM suspend entry and exits observed before
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "dp_parser.h"
|
||||
|
||||
#define DP_MST_SIM_MAX_PORTS 8
|
||||
#define MAX_DP_ACTIVE_DISPLAY 8
|
||||
|
||||
enum dp_drv_state {
|
||||
PM_DEFAULT,
|
||||
|
|
@ -31,6 +32,13 @@ struct dp_mst_hpd_info {
|
|||
int mst_sim_remove_con_id;
|
||||
};
|
||||
|
||||
struct dp_display_info {
|
||||
u32 cell_idx;
|
||||
u32 intf_idx[DP_STREAM_MAX];
|
||||
u32 phy_idx;
|
||||
u32 stream_cnt;
|
||||
};
|
||||
|
||||
struct dp_mst_drm_cbs {
|
||||
void (*hpd)(void *display, bool hpd_status);
|
||||
void (*hpd_irq)(void *display, struct dp_mst_hpd_info *info);
|
||||
|
|
@ -146,6 +154,7 @@ struct dp_display {
|
|||
int dp_display_get_num_of_displays(void);
|
||||
int dp_display_get_displays(void **displays, int count);
|
||||
int dp_display_get_num_of_streams(void);
|
||||
int dp_display_get_info(void *dp_display, struct dp_display_info *dp_info);
|
||||
#else
|
||||
static inline int dp_display_get_num_of_displays(void)
|
||||
{
|
||||
|
|
@ -159,6 +168,10 @@ static inline int dp_display_get_num_of_streams(void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int dp_display_get_info(void *dp_display, struct dp_display_info *dp_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int dp_connector_update_pps(struct drm_connector *connector,
|
||||
char *pps_cmd, void *display)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,11 +159,6 @@ struct dp_mst_private {
|
|||
bool mst_session_state;
|
||||
};
|
||||
|
||||
struct dp_mst_encoder_info_cache {
|
||||
u8 cnt;
|
||||
struct drm_encoder *mst_enc[MAX_DP_MST_DRM_BRIDGES];
|
||||
};
|
||||
|
||||
#define to_dp_mst_bridge(x) container_of((x), struct dp_mst_bridge, base)
|
||||
#define to_dp_mst_bridge_priv(x) \
|
||||
container_of((x), struct dp_mst_bridge, obj)
|
||||
|
|
@ -172,9 +167,6 @@ struct dp_mst_encoder_info_cache {
|
|||
#define to_dp_mst_bridge_state(x) \
|
||||
to_dp_mst_bridge_priv_state((x)->obj.state)
|
||||
|
||||
struct dp_mst_private dp_mst;
|
||||
struct dp_mst_encoder_info_cache dp_mst_enc_cache;
|
||||
|
||||
static void dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
struct dp_mst_private *mst = container_of(mgr, struct dp_mst_private,
|
||||
|
|
@ -299,7 +291,7 @@ static void dp_mst_sim_add_port(struct dp_mst_private *mst,
|
|||
port->parent = mstb;
|
||||
port->port_num = port_msg->port_number;
|
||||
port->mgr = mstb->mgr;
|
||||
port->aux.name = dp_mst.caps.drm_aux->name;
|
||||
port->aux.name = mst->caps.drm_aux->name;
|
||||
port->aux.dev = mst->dp_display->drm_dev->dev;
|
||||
|
||||
/*
|
||||
|
|
@ -1259,19 +1251,6 @@ int dp_mst_drm_bridge_init(void *data, struct drm_encoder *encoder)
|
|||
struct dp_mst_private *mst = display->dp_mst_prv_info;
|
||||
int i;
|
||||
|
||||
if (!mst || !mst->mst_initialized) {
|
||||
if (dp_mst_enc_cache.cnt >= MAX_DP_MST_DRM_BRIDGES) {
|
||||
DP_MST_INFO("exceeding max bridge cnt %d\n",
|
||||
dp_mst_enc_cache.cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dp_mst_enc_cache.mst_enc[dp_mst_enc_cache.cnt] = encoder;
|
||||
dp_mst_enc_cache.cnt++;
|
||||
DP_MST_INFO("mst not initialized. cache encoder information\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DP_MST_DRM_BRIDGES; i++) {
|
||||
if (!mst->mst_bridge[i].in_use) {
|
||||
bridge = &mst->mst_bridge[i];
|
||||
|
|
@ -2415,10 +2394,9 @@ int dp_mst_init(struct dp_display *dp_display)
|
|||
{
|
||||
struct drm_device *dev;
|
||||
int conn_base_id = 0;
|
||||
int ret, i;
|
||||
int ret;
|
||||
struct dp_mst_drm_install_info install_info;
|
||||
|
||||
memset(&dp_mst, 0, sizeof(dp_mst));
|
||||
struct dp_mst_private *dp_mst;
|
||||
|
||||
if (!dp_display) {
|
||||
DP_ERR("invalid params\n");
|
||||
|
|
@ -2427,60 +2405,57 @@ int dp_mst_init(struct dp_display *dp_display)
|
|||
|
||||
dev = dp_display->drm_dev;
|
||||
|
||||
dp_mst = devm_kzalloc(dev->dev, sizeof(*dp_mst), GFP_KERNEL);
|
||||
if (!dp_mst)
|
||||
return -ENOMEM;
|
||||
|
||||
/* register with DP driver */
|
||||
install_info.dp_mst_prv_info = &dp_mst;
|
||||
install_info.dp_mst_prv_info = dp_mst;
|
||||
install_info.cbs = &dp_mst_display_cbs;
|
||||
dp_display->mst_install(dp_display, &install_info);
|
||||
|
||||
dp_display->get_mst_caps(dp_display, &dp_mst.caps);
|
||||
dp_display->get_mst_caps(dp_display, &dp_mst->caps);
|
||||
|
||||
if (!dp_mst.caps.has_mst) {
|
||||
if (!dp_mst->caps.has_mst) {
|
||||
DP_MST_DEBUG("mst not supported\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dp_mst.mst_fw_cbs = &drm_dp_mst_fw_helper_ops;
|
||||
dp_mst->mst_fw_cbs = &drm_dp_mst_fw_helper_ops;
|
||||
|
||||
memset(&dp_mst.mst_mgr, 0, sizeof(dp_mst.mst_mgr));
|
||||
dp_mst.mst_mgr.cbs = &dp_mst_drm_cbs;
|
||||
memset(&dp_mst->mst_mgr, 0, sizeof(dp_mst->mst_mgr));
|
||||
dp_mst->mst_mgr.cbs = &dp_mst_drm_cbs;
|
||||
conn_base_id = dp_display->base_connector->base.id;
|
||||
dp_mst.dp_display = dp_display;
|
||||
dp_mst->dp_display = dp_display;
|
||||
|
||||
mutex_init(&dp_mst.mst_lock);
|
||||
mutex_init(&dp_mst.edid_lock);
|
||||
mutex_init(&dp_mst->mst_lock);
|
||||
mutex_init(&dp_mst->edid_lock);
|
||||
|
||||
ret = drm_dp_mst_topology_mgr_init(&dp_mst.mst_mgr, dev,
|
||||
dp_mst.caps.drm_aux,
|
||||
dp_mst.caps.max_dpcd_transaction_bytes,
|
||||
dp_mst.caps.max_streams_supported,
|
||||
ret = drm_dp_mst_topology_mgr_init(&dp_mst->mst_mgr, dev,
|
||||
dp_mst->caps.drm_aux,
|
||||
dp_mst->caps.max_dpcd_transaction_bytes,
|
||||
dp_mst->caps.max_streams_supported,
|
||||
conn_base_id);
|
||||
if (ret) {
|
||||
DP_ERR("dp drm mst topology manager init failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
dp_mst_sim_init(&dp_mst);
|
||||
dp_mst_sim_init(dp_mst);
|
||||
|
||||
dp_mst.mst_initialized = true;
|
||||
|
||||
/* create drm_bridges for cached mst encoders and clear cache */
|
||||
for (i = 0; i < dp_mst_enc_cache.cnt; i++) {
|
||||
ret = dp_mst_drm_bridge_init(dp_display,
|
||||
dp_mst_enc_cache.mst_enc[i]);
|
||||
}
|
||||
memset(&dp_mst_enc_cache, 0, sizeof(dp_mst_enc_cache));
|
||||
dp_mst->mst_initialized = true;
|
||||
|
||||
/* choose fixed callback function if fixed topology is found */
|
||||
if (!dp_display->mst_get_fixed_topology_port(dp_display, 0, NULL))
|
||||
dp_mst.mst_mgr.cbs = &dp_mst_fixed_drm_cbs;
|
||||
dp_mst->mst_mgr.cbs = &dp_mst_fixed_drm_cbs;
|
||||
|
||||
DP_MST_INFO("dp drm mst topology manager init completed\n");
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
mutex_destroy(&dp_mst.mst_lock);
|
||||
mutex_destroy(&dp_mst.edid_lock);
|
||||
mutex_destroy(&dp_mst->mst_lock);
|
||||
mutex_destroy(&dp_mst->edid_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -2502,7 +2477,7 @@ void dp_mst_deinit(struct dp_display *dp_display)
|
|||
|
||||
drm_dp_mst_topology_mgr_destroy(&mst->mst_mgr);
|
||||
|
||||
dp_mst.mst_initialized = false;
|
||||
mst->mst_initialized = false;
|
||||
|
||||
mutex_destroy(&mst->mst_lock);
|
||||
mutex_destroy(&mst->edid_lock);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,10 @@ struct dp_pll *dp_pll_get(struct dp_pll_in *in)
|
|||
goto error;
|
||||
}
|
||||
|
||||
pll->name = of_get_property(pdev->dev.of_node, "label", NULL);
|
||||
if (!pll->name)
|
||||
pll->name = "dp0";
|
||||
|
||||
pll->ssc_en = of_property_read_bool(pdev->dev.of_node,
|
||||
"qcom,ssc-feature-enable");
|
||||
pll->bonding_en = of_property_read_bool(pdev->dev.of_node,
|
||||
|
|
|
|||
|
|
@ -1926,6 +1926,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
for (i = 0; i < sde_kms->dp_display_count &&
|
||||
priv->num_encoders < max_encoders; ++i) {
|
||||
int idx;
|
||||
struct dp_display_info dp_info = {0};
|
||||
|
||||
display = sde_kms->dp_displays[i];
|
||||
encoder = NULL;
|
||||
|
|
@ -1937,6 +1938,13 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
continue;
|
||||
}
|
||||
|
||||
rc = dp_display_get_info(display, &dp_info);
|
||||
if (rc) {
|
||||
SDE_ERROR("failed to read dp info, %d\n", rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
info.h_tile_instance[0] = dp_info.intf_idx[0];
|
||||
encoder = sde_encoder_init(dev, &info);
|
||||
if (IS_ERR_OR_NULL(encoder)) {
|
||||
SDE_ERROR("dp encoder init failed %d\n", i);
|
||||
|
|
@ -1970,9 +1978,9 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
|||
/* update display cap to MST_MODE for DP MST encoders */
|
||||
info.capabilities |= MSM_DISPLAY_CAP_MST_MODE;
|
||||
|
||||
for (idx = 0; idx < sde_kms->dp_stream_count &&
|
||||
for (idx = 0; idx < dp_info.stream_cnt &&
|
||||
priv->num_encoders < max_encoders; idx++) {
|
||||
info.h_tile_instance[0] = idx;
|
||||
info.h_tile_instance[0] = dp_info.intf_idx[idx];
|
||||
encoder = sde_encoder_init(dev, &info);
|
||||
if (IS_ERR_OR_NULL(encoder)) {
|
||||
SDE_ERROR("dp mst encoder init failed %d\n", i);
|
||||
|
|
|
|||
Loading…
Reference in a new issue