summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/dp/dp_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_display.c')
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c77
1 files changed, 36 insertions, 41 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 76f139540..4f89c9939 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -88,7 +88,6 @@ struct dp_display_private {
bool audio_supported;
struct drm_device *drm_dev;
- struct platform_device *pdev;
struct dentry *root;
struct dp_parser *parser;
@@ -171,6 +170,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = {
{}
};
+static const struct msm_dp_desc sm8650_dp_descs[] = {
+ { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ {}
+};
+
static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
@@ -181,6 +185,7 @@ static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
{ .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
{ .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
+ { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },
{}
};
@@ -341,21 +346,6 @@ static const struct component_ops dp_display_comp_ops = {
.unbind = dp_display_unbind,
};
-static bool dp_display_is_ds_bridge(struct dp_panel *panel)
-{
- return (panel->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
- DP_DWN_STRM_PORT_PRESENT);
-}
-
-static bool dp_display_is_sink_count_zero(struct dp_display_private *dp)
-{
- drm_dbg_dp(dp->drm_dev, "present=%#x sink_count=%d\n",
- dp->panel->dpcd[DP_DOWNSTREAMPORT_PRESENT],
- dp->link->sink_count);
- return dp_display_is_ds_bridge(dp->panel) &&
- (dp->link->sink_count == 0);
-}
-
static void dp_display_send_hpd_event(struct msm_dp *dp_display)
{
struct dp_display_private *dp;
@@ -379,8 +369,14 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp,
}
/* reset video pattern flag on disconnect */
- if (!hpd)
+ if (!hpd) {
dp->panel->video_test = false;
+ if (!dp->dp_display.is_edp)
+ drm_dp_set_subconnector_property(dp->dp_display.connector,
+ connector_status_disconnected,
+ dp->panel->dpcd,
+ dp->panel->downstream_ports);
+ }
dp->dp_display.is_connected = hpd;
@@ -408,6 +404,12 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
dp_link_process_request(dp->link);
+ if (!dp->dp_display.is_edp)
+ drm_dp_set_subconnector_property(dp->dp_display.connector,
+ connector_status_connected,
+ dp->panel->dpcd,
+ dp->panel->downstream_ports);
+
edid = dp->panel->edid;
dp->dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
@@ -514,7 +516,7 @@ static int dp_display_handle_port_ststus_changed(struct dp_display_private *dp)
{
int rc = 0;
- if (dp_display_is_sink_count_zero(dp)) {
+ if (drm_dp_is_branch(dp->panel->dpcd) && dp->link->sink_count == 0) {
drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
if (dp->hpd_state != ST_DISCONNECTED) {
dp->hpd_state = ST_DISCONNECT_PENDING;
@@ -603,7 +605,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
return 0;
}
- ret = dp_display_usbpd_configure_cb(&dp->pdev->dev);
+ ret = dp_display_usbpd_configure_cb(&dp->dp_display.pdev->dev);
if (ret) { /* link train failed */
dp->hpd_state = ST_DISCONNECTED;
} else {
@@ -651,7 +653,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
if (dp->link->sink_count == 0) {
dp_display_host_phy_exit(dp);
}
- dp_display_notify_disconnect(&dp->pdev->dev);
+ dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
mutex_unlock(&dp->event_mutex);
return 0;
} else if (state == ST_DISCONNECT_PENDING) {
@@ -661,7 +663,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
dp_ctrl_off_link(dp->ctrl);
dp_display_host_phy_exit(dp);
dp->hpd_state = ST_DISCONNECTED;
- dp_display_notify_disconnect(&dp->pdev->dev);
+ dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
mutex_unlock(&dp->event_mutex);
return 0;
}
@@ -670,7 +672,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
* We don't need separate work for disconnect as
* connect/attention interrupts are disabled
*/
- dp_display_notify_disconnect(&dp->pdev->dev);
+ dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
if (state == ST_DISPLAY_OFF) {
dp->hpd_state = ST_DISCONNECTED;
@@ -712,7 +714,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
return 0;
}
- dp_display_usbpd_attention_cb(&dp->pdev->dev);
+ dp_display_usbpd_attention_cb(&dp->dp_display.pdev->dev);
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state);
@@ -733,12 +735,12 @@ static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
static int dp_init_sub_modules(struct dp_display_private *dp)
{
int rc = 0;
- struct device *dev = &dp->pdev->dev;
+ struct device *dev = &dp->dp_display.pdev->dev;
struct dp_panel_in panel_in = {
.dev = dev,
};
- dp->parser = dp_parser_get(dp->pdev);
+ dp->parser = dp_parser_get(dp->dp_display.pdev);
if (IS_ERR(dp->parser)) {
rc = PTR_ERR(dp->parser);
DRM_ERROR("failed to initialize parser, rc = %d\n", rc);
@@ -799,7 +801,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
goto error_ctrl;
}
- dp->audio = dp_audio_get(dp->pdev, dp->panel, dp->catalog);
+ dp->audio = dp_audio_get(dp->dp_display.pdev, dp->panel, dp->catalog);
if (IS_ERR(dp->audio)) {
rc = PTR_ERR(dp->audio);
pr_err("failed to initialize audio, rc = %d\n", rc);
@@ -1205,7 +1207,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
dp = container_of(dp_display, struct dp_display_private, dp_display);
- dp->irq = irq_of_parse_and_map(dp->pdev->dev.of_node, 0);
+ dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0);
if (!dp->irq) {
DRM_ERROR("failed to get irq\n");
return -EINVAL;
@@ -1261,7 +1263,7 @@ static int dp_display_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
- dp->pdev = pdev;
+ dp->dp_display.pdev = pdev;
dp->name = "drm_dp";
dp->id = desc->id;
dp->dp_display.connector_type = desc->connector_type;
@@ -1296,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
return rc;
}
-static int dp_display_remove(struct platform_device *pdev)
+static void dp_display_remove(struct platform_device *pdev)
{
struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
@@ -1304,8 +1306,6 @@ static int dp_display_remove(struct platform_device *pdev)
dp_display_deinit_sub_modules(dp);
platform_set_drvdata(pdev, NULL);
-
- return 0;
}
static int dp_pm_resume(struct device *dev)
@@ -1415,7 +1415,7 @@ static const struct dev_pm_ops dp_pm_ops = {
static struct platform_driver dp_display_driver = {
.probe = dp_display_probe,
- .remove = dp_display_remove,
+ .remove_new = dp_display_remove,
.driver = {
.name = "msm-dp-display",
.of_match_table = dp_dt_match,
@@ -1469,7 +1469,7 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
int rc;
dp = container_of(dp_display, struct dp_display_private, dp_display);
- dev = &dp->pdev->dev;
+ dev = &dp->dp_display.pdev->dev;
dp->debug = dp_debug_get(dev, dp->panel,
dp->link, dp->dp_display.connector,
@@ -1489,7 +1489,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
struct device *dev;
dp_priv = container_of(dp, struct dp_display_private, dp_display);
- dev = &dp_priv->pdev->dev;
+ dev = &dp_priv->dp_display.pdev->dev;
aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
if (aux_bus && dp->is_edp) {
@@ -1541,7 +1541,6 @@ error:
int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
struct drm_encoder *encoder)
{
- struct msm_drm_private *priv = dev->dev_private;
struct dp_display_private *dp_priv;
int ret;
@@ -1559,17 +1558,13 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
if (ret)
return ret;
- dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
- if (IS_ERR(dp_display->bridge)) {
- ret = PTR_ERR(dp_display->bridge);
+ ret = dp_bridge_init(dp_display, dev, encoder);
+ if (ret) {
DRM_DEV_ERROR(dev->dev,
"failed to create dp bridge: %d\n", ret);
- dp_display->bridge = NULL;
return ret;
}
- priv->bridges[priv->num_bridges++] = dp_display->bridge;
-
dp_display->connector = dp_drm_connector_init(dp_display, encoder);
if (IS_ERR(dp_display->connector)) {
ret = PTR_ERR(dp_display->connector);