aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-01-10 15:32:37 -0500
committerDave Airlie <airlied@redhat.com>2019-01-10 15:32:44 -0500
commitbd86c9e66c8385fb437c5ad506243304a8814b65 (patch)
treedcfa342e7ee31a1450b4101f7b10c483d32ae97e
parentbfeffd155283772bbe78c6a05dec7c0128ee500c (diff)
parentf8c15790e4d8bdf2d21a5e9d43b5f97983af1222 (diff)
Merge tag 'drm-misc-fixes-2019-01-10' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
Pull request for drm-misc-fixes for v5.0-rc2: - Fixes for the tc358767 bridge to work correctly with tc358867 using a DP connector. - Make resume work on amdgpu when a DP-MST display is unplugged. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/1c47722d-c416-184d-4340-0dc6a614d685@linux.intel.com
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c37
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c48
-rw-r--r--include/drm/drm_dp_mst_helper.h3
3 files changed, 65 insertions, 23 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a9a28dbc3e24..34f35e9a3c46 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -699,22 +699,36 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
699{ 699{
700 struct amdgpu_dm_connector *aconnector; 700 struct amdgpu_dm_connector *aconnector;
701 struct drm_connector *connector; 701 struct drm_connector *connector;
702 struct drm_dp_mst_topology_mgr *mgr;
703 int ret;
704 bool need_hotplug = false;
702 705
703 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 706 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
704 707
705 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 708 list_for_each_entry(connector, &dev->mode_config.connector_list,
706 aconnector = to_amdgpu_dm_connector(connector); 709 head) {
707 if (aconnector->dc_link->type == dc_connection_mst_branch && 710 aconnector = to_amdgpu_dm_connector(connector);
708 !aconnector->mst_port) { 711 if (aconnector->dc_link->type != dc_connection_mst_branch ||
712 aconnector->mst_port)
713 continue;
709 714
710 if (suspend) 715 mgr = &aconnector->mst_mgr;
711 drm_dp_mst_topology_mgr_suspend(&aconnector->mst_mgr); 716
712 else 717 if (suspend) {
713 drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr); 718 drm_dp_mst_topology_mgr_suspend(mgr);
714 } 719 } else {
720 ret = drm_dp_mst_topology_mgr_resume(mgr);
721 if (ret < 0) {
722 drm_dp_mst_topology_mgr_set_mst(mgr, false);
723 need_hotplug = true;
724 }
725 }
715 } 726 }
716 727
717 drm_modeset_unlock(&dev->mode_config.connection_mutex); 728 drm_modeset_unlock(&dev->mode_config.connection_mutex);
729
730 if (need_hotplug)
731 drm_kms_helper_hotplug_event(dev);
718} 732}
719 733
720/** 734/**
@@ -898,7 +912,6 @@ static int dm_resume(void *handle)
898 struct drm_plane_state *new_plane_state; 912 struct drm_plane_state *new_plane_state;
899 struct dm_plane_state *dm_new_plane_state; 913 struct dm_plane_state *dm_new_plane_state;
900 enum dc_connection_type new_connection_type = dc_connection_none; 914 enum dc_connection_type new_connection_type = dc_connection_none;
901 int ret;
902 int i; 915 int i;
903 916
904 /* power on hardware */ 917 /* power on hardware */
@@ -971,13 +984,13 @@ static int dm_resume(void *handle)
971 } 984 }
972 } 985 }
973 986
974 ret = drm_atomic_helper_resume(ddev, dm->cached_state); 987 drm_atomic_helper_resume(ddev, dm->cached_state);
975 988
976 dm->cached_state = NULL; 989 dm->cached_state = NULL;
977 990
978 amdgpu_dm_irq_resume_late(adev); 991 amdgpu_dm_irq_resume_late(adev);
979 992
980 return ret; 993 return 0;
981} 994}
982 995
983/** 996/**
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 8e28e738cb52..e6403b9549f1 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -98,6 +98,8 @@
98#define DP0_STARTVAL 0x064c 98#define DP0_STARTVAL 0x064c
99#define DP0_ACTIVEVAL 0x0650 99#define DP0_ACTIVEVAL 0x0650
100#define DP0_SYNCVAL 0x0654 100#define DP0_SYNCVAL 0x0654
101#define SYNCVAL_HS_POL_ACTIVE_LOW (1 << 15)
102#define SYNCVAL_VS_POL_ACTIVE_LOW (1 << 31)
101#define DP0_MISC 0x0658 103#define DP0_MISC 0x0658
102#define TU_SIZE_RECOMMENDED (63) /* LSCLK cycles per TU */ 104#define TU_SIZE_RECOMMENDED (63) /* LSCLK cycles per TU */
103#define BPC_6 (0 << 5) 105#define BPC_6 (0 << 5)
@@ -142,6 +144,8 @@
142#define DP0_LTLOOPCTRL 0x06d8 144#define DP0_LTLOOPCTRL 0x06d8
143#define DP0_SNKLTCTRL 0x06e4 145#define DP0_SNKLTCTRL 0x06e4
144 146
147#define DP1_SRCCTRL 0x07a0
148
145/* PHY */ 149/* PHY */
146#define DP_PHY_CTRL 0x0800 150#define DP_PHY_CTRL 0x0800
147#define DP_PHY_RST BIT(28) /* DP PHY Global Soft Reset */ 151#define DP_PHY_RST BIT(28) /* DP PHY Global Soft Reset */
@@ -150,6 +154,7 @@
150#define PHY_M1_RST BIT(12) /* Reset PHY1 Main Channel */ 154#define PHY_M1_RST BIT(12) /* Reset PHY1 Main Channel */
151#define PHY_RDY BIT(16) /* PHY Main Channels Ready */ 155#define PHY_RDY BIT(16) /* PHY Main Channels Ready */
152#define PHY_M0_RST BIT(8) /* Reset PHY0 Main Channel */ 156#define PHY_M0_RST BIT(8) /* Reset PHY0 Main Channel */
157#define PHY_2LANE BIT(2) /* PHY Enable 2 lanes */
153#define PHY_A0_EN BIT(1) /* PHY Aux Channel0 Enable */ 158#define PHY_A0_EN BIT(1) /* PHY Aux Channel0 Enable */
154#define PHY_M0_EN BIT(0) /* PHY Main Channel0 Enable */ 159#define PHY_M0_EN BIT(0) /* PHY Main Channel0 Enable */
155 160
@@ -540,6 +545,7 @@ static int tc_aux_link_setup(struct tc_data *tc)
540 unsigned long rate; 545 unsigned long rate;
541 u32 value; 546 u32 value;
542 int ret; 547 int ret;
548 u32 dp_phy_ctrl;
543 549
544 rate = clk_get_rate(tc->refclk); 550 rate = clk_get_rate(tc->refclk);
545 switch (rate) { 551 switch (rate) {
@@ -564,7 +570,10 @@ static int tc_aux_link_setup(struct tc_data *tc)
564 value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2; 570 value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2;
565 tc_write(SYS_PLLPARAM, value); 571 tc_write(SYS_PLLPARAM, value);
566 572
567 tc_write(DP_PHY_CTRL, BGREN | PWR_SW_EN | BIT(2) | PHY_A0_EN); 573 dp_phy_ctrl = BGREN | PWR_SW_EN | PHY_A0_EN;
574 if (tc->link.base.num_lanes == 2)
575 dp_phy_ctrl |= PHY_2LANE;
576 tc_write(DP_PHY_CTRL, dp_phy_ctrl);
568 577
569 /* 578 /*
570 * Initially PLLs are in bypass. Force PLL parameter update, 579 * Initially PLLs are in bypass. Force PLL parameter update,
@@ -719,7 +728,9 @@ static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode)
719 728
720 tc_write(DP0_ACTIVEVAL, (mode->vdisplay << 16) | (mode->hdisplay)); 729 tc_write(DP0_ACTIVEVAL, (mode->vdisplay << 16) | (mode->hdisplay));
721 730
722 tc_write(DP0_SYNCVAL, (vsync_len << 16) | (hsync_len << 0)); 731 tc_write(DP0_SYNCVAL, (vsync_len << 16) | (hsync_len << 0) |
732 ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? SYNCVAL_HS_POL_ACTIVE_LOW : 0) |
733 ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? SYNCVAL_VS_POL_ACTIVE_LOW : 0));
723 734
724 tc_write(DPIPXLFMT, VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW | 735 tc_write(DPIPXLFMT, VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW |
725 DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888); 736 DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888);
@@ -829,12 +840,11 @@ static int tc_main_link_setup(struct tc_data *tc)
829 if (!tc->mode) 840 if (!tc->mode)
830 return -EINVAL; 841 return -EINVAL;
831 842
832 /* from excel file - DP0_SrcCtrl */ 843 tc_write(DP0_SRCCTRL, tc_srcctrl(tc));
833 tc_write(DP0_SRCCTRL, DP0_SRCCTRL_SCRMBLDIS | DP0_SRCCTRL_EN810B | 844 /* SSCG and BW27 on DP1 must be set to the same as on DP0 */
834 DP0_SRCCTRL_LANESKEW | DP0_SRCCTRL_LANES_2 | 845 tc_write(DP1_SRCCTRL,
835 DP0_SRCCTRL_BW27 | DP0_SRCCTRL_AUTOCORRECT); 846 (tc->link.spread ? DP0_SRCCTRL_SSCG : 0) |
836 /* from excel file - DP1_SrcCtrl */ 847 ((tc->link.base.rate != 162000) ? DP0_SRCCTRL_BW27 : 0));
837 tc_write(0x07a0, 0x00003083);
838 848
839 rate = clk_get_rate(tc->refclk); 849 rate = clk_get_rate(tc->refclk);
840 switch (rate) { 850 switch (rate) {
@@ -855,8 +865,11 @@ static int tc_main_link_setup(struct tc_data *tc)
855 } 865 }
856 value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2; 866 value |= SYSCLK_SEL_LSCLK | LSCLK_DIV_2;
857 tc_write(SYS_PLLPARAM, value); 867 tc_write(SYS_PLLPARAM, value);
868
858 /* Setup Main Link */ 869 /* Setup Main Link */
859 dp_phy_ctrl = BGREN | PWR_SW_EN | BIT(2) | PHY_A0_EN | PHY_M0_EN; 870 dp_phy_ctrl = BGREN | PWR_SW_EN | PHY_A0_EN | PHY_M0_EN;
871 if (tc->link.base.num_lanes == 2)
872 dp_phy_ctrl |= PHY_2LANE;
860 tc_write(DP_PHY_CTRL, dp_phy_ctrl); 873 tc_write(DP_PHY_CTRL, dp_phy_ctrl);
861 msleep(100); 874 msleep(100);
862 875
@@ -1105,10 +1118,20 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
1105static enum drm_mode_status tc_connector_mode_valid(struct drm_connector *connector, 1118static enum drm_mode_status tc_connector_mode_valid(struct drm_connector *connector,
1106 struct drm_display_mode *mode) 1119 struct drm_display_mode *mode)
1107{ 1120{
1121 struct tc_data *tc = connector_to_tc(connector);
1122 u32 req, avail;
1123 u32 bits_per_pixel = 24;
1124
1108 /* DPI interface clock limitation: upto 154 MHz */ 1125 /* DPI interface clock limitation: upto 154 MHz */
1109 if (mode->clock > 154000) 1126 if (mode->clock > 154000)
1110 return MODE_CLOCK_HIGH; 1127 return MODE_CLOCK_HIGH;
1111 1128
1129 req = mode->clock * bits_per_pixel / 8;
1130 avail = tc->link.base.num_lanes * tc->link.base.rate;
1131
1132 if (req > avail)
1133 return MODE_BAD;
1134
1112 return MODE_OK; 1135 return MODE_OK;
1113} 1136}
1114 1137
@@ -1186,7 +1209,8 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
1186 /* Create eDP connector */ 1209 /* Create eDP connector */
1187 drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs); 1210 drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);
1188 ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs, 1211 ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs,
1189 DRM_MODE_CONNECTOR_eDP); 1212 tc->panel ? DRM_MODE_CONNECTOR_eDP :
1213 DRM_MODE_CONNECTOR_DisplayPort);
1190 if (ret) 1214 if (ret)
1191 return ret; 1215 return ret;
1192 1216
@@ -1195,6 +1219,10 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
1195 1219
1196 drm_display_info_set_bus_formats(&tc->connector.display_info, 1220 drm_display_info_set_bus_formats(&tc->connector.display_info,
1197 &bus_format, 1); 1221 &bus_format, 1);
1222 tc->connector.display_info.bus_flags =
1223 DRM_BUS_FLAG_DE_HIGH |
1224 DRM_BUS_FLAG_PIXDATA_NEGEDGE |
1225 DRM_BUS_FLAG_SYNC_NEGEDGE;
1198 drm_connector_attach_encoder(&tc->connector, tc->bridge.encoder); 1226 drm_connector_attach_encoder(&tc->connector, tc->bridge.encoder);
1199 1227
1200 return 0; 1228 return 0;
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 59f005b419cf..727af08e5ea6 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -616,7 +616,8 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
616 struct drm_dp_mst_topology_mgr *mgr); 616 struct drm_dp_mst_topology_mgr *mgr);
617 617
618void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr); 618void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
619int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); 619int __must_check
620drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
620struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, 621struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
621 struct drm_dp_mst_topology_mgr *mgr); 622 struct drm_dp_mst_topology_mgr *mgr);
622int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, 623int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,