aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-03-08 18:22:44 -0500
committerDave Airlie <airlied@redhat.com>2018-03-08 18:22:44 -0500
commitf5732e66a7d04d587514841124cb591856a943dc (patch)
tree24691742a04e5fd1a895fd1cf589398aa38a2bdc
parentaa87d62f7e752ee95b7162cc0373899e97146b15 (diff)
parentfd00c4ee76f0b509ce79ffbc1f5a682fbdd84efd (diff)
Merge tag 'drm-misc-fixes-2018-03-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
sun4i fixes on clk, division by zero and LVDS. * tag 'drm-misc-fixes-2018-03-07' of git://anongit.freedesktop.org/drm/drm-misc: drm/sun4i: crtc: Call drm_crtc_vblank_on / drm_crtc_vblank_off drm/sun4i: rgb: Fix potential division by zero drm/sun4i: tcon: Reduce the scope of the LVDS error a bit drm/sun4i: Release exclusive clock lock when disabling TCON drm/sun4i: Fix dclk_set_phase
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_crtc.c4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_dotclock.c5
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c92
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h1
5 files changed, 60 insertions, 44 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index 5decae0069d0..78cbc3145e44 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -93,6 +93,8 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
93 93
94 DRM_DEBUG_DRIVER("Disabling the CRTC\n"); 94 DRM_DEBUG_DRIVER("Disabling the CRTC\n");
95 95
96 drm_crtc_vblank_off(crtc);
97
96 sun4i_tcon_set_status(scrtc->tcon, encoder, false); 98 sun4i_tcon_set_status(scrtc->tcon, encoder, false);
97 99
98 if (crtc->state->event && !crtc->state->active) { 100 if (crtc->state->event && !crtc->state->active) {
@@ -113,6 +115,8 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
113 DRM_DEBUG_DRIVER("Enabling the CRTC\n"); 115 DRM_DEBUG_DRIVER("Enabling the CRTC\n");
114 116
115 sun4i_tcon_set_status(scrtc->tcon, encoder, true); 117 sun4i_tcon_set_status(scrtc->tcon, encoder, true);
118
119 drm_crtc_vblank_on(crtc);
116} 120}
117 121
118static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) 122static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
index 023f39bda633..e36004fbe453 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
@@ -132,10 +132,13 @@ static int sun4i_dclk_get_phase(struct clk_hw *hw)
132static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees) 132static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
133{ 133{
134 struct sun4i_dclk *dclk = hw_to_dclk(hw); 134 struct sun4i_dclk *dclk = hw_to_dclk(hw);
135 u32 val = degrees / 120;
136
137 val <<= 28;
135 138
136 regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG, 139 regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
137 GENMASK(29, 28), 140 GENMASK(29, 28),
138 degrees / 120); 141 val);
139 142
140 return 0; 143 return 0;
141} 144}
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 832f8f9bc47f..b8da5a50a61d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -92,6 +92,8 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
92 92
93 DRM_DEBUG_DRIVER("Vertical parameters OK\n"); 93 DRM_DEBUG_DRIVER("Vertical parameters OK\n");
94 94
95 tcon->dclk_min_div = 6;
96 tcon->dclk_max_div = 127;
95 rounded_rate = clk_round_rate(tcon->dclk, rate); 97 rounded_rate = clk_round_rate(tcon->dclk, rate);
96 if (rounded_rate < rate) 98 if (rounded_rate < rate)
97 return MODE_CLOCK_LOW; 99 return MODE_CLOCK_LOW;
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index b3960118deb9..2de586b7c98b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -101,10 +101,12 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
101 return; 101 return;
102 } 102 }
103 103
104 if (enabled) 104 if (enabled) {
105 clk_prepare_enable(clk); 105 clk_prepare_enable(clk);
106 else 106 } else {
107 clk_rate_exclusive_put(clk);
107 clk_disable_unprepare(clk); 108 clk_disable_unprepare(clk);
109 }
108} 110}
109 111
110static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon, 112static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
@@ -873,52 +875,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
873 return ret; 875 return ret;
874 } 876 }
875 877
876 /* 878 if (tcon->quirks->supports_lvds) {
877 * This can only be made optional since we've had DT nodes 879 /*
878 * without the LVDS reset properties. 880 * This can only be made optional since we've had DT
879 * 881 * nodes without the LVDS reset properties.
880 * If the property is missing, just disable LVDS, and print a 882 *
881 * warning. 883 * If the property is missing, just disable LVDS, and
882 */ 884 * print a warning.
883 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); 885 */
884 if (IS_ERR(tcon->lvds_rst)) { 886 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
885 dev_err(dev, "Couldn't get our reset line\n"); 887 if (IS_ERR(tcon->lvds_rst)) {
886 return PTR_ERR(tcon->lvds_rst); 888 dev_err(dev, "Couldn't get our reset line\n");
887 } else if (tcon->lvds_rst) { 889 return PTR_ERR(tcon->lvds_rst);
888 has_lvds_rst = true; 890 } else if (tcon->lvds_rst) {
889 reset_control_reset(tcon->lvds_rst); 891 has_lvds_rst = true;
890 } else { 892 reset_control_reset(tcon->lvds_rst);
891 has_lvds_rst = false; 893 } else {
892 } 894 has_lvds_rst = false;
895 }
893 896
894 /* 897 /*
895 * This can only be made optional since we've had DT nodes 898 * This can only be made optional since we've had DT
896 * without the LVDS reset properties. 899 * nodes without the LVDS reset properties.
897 * 900 *
898 * If the property is missing, just disable LVDS, and print a 901 * If the property is missing, just disable LVDS, and
899 * warning. 902 * print a warning.
900 */ 903 */
901 if (tcon->quirks->has_lvds_alt) { 904 if (tcon->quirks->has_lvds_alt) {
902 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); 905 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
903 if (IS_ERR(tcon->lvds_pll)) { 906 if (IS_ERR(tcon->lvds_pll)) {
904 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { 907 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
905 has_lvds_alt = false; 908 has_lvds_alt = false;
909 } else {
910 dev_err(dev, "Couldn't get the LVDS PLL\n");
911 return PTR_ERR(tcon->lvds_pll);
912 }
906 } else { 913 } else {
907 dev_err(dev, "Couldn't get the LVDS PLL\n"); 914 has_lvds_alt = true;
908 return PTR_ERR(tcon->lvds_pll);
909 } 915 }
910 } else {
911 has_lvds_alt = true;
912 } 916 }
913 }
914 917
915 if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { 918 if (!has_lvds_rst ||
916 dev_warn(dev, 919 (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
917 "Missing LVDS properties, Please upgrade your DT\n"); 920 dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
918 dev_warn(dev, "LVDS output disabled\n"); 921 dev_warn(dev, "LVDS output disabled\n");
919 can_lvds = false; 922 can_lvds = false;
923 } else {
924 can_lvds = true;
925 }
920 } else { 926 } else {
921 can_lvds = true; 927 can_lvds = false;
922 } 928 }
923 929
924 ret = sun4i_tcon_init_clocks(dev, tcon); 930 ret = sun4i_tcon_init_clocks(dev, tcon);
@@ -1137,7 +1143,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
1137}; 1143};
1138 1144
1139static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { 1145static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
1140 /* nothing is supported */ 1146 .supports_lvds = true,
1141}; 1147};
1142 1148
1143static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { 1149static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index b761c7b823c5..278700c7bf9f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -175,6 +175,7 @@ struct sun4i_tcon_quirks {
175 bool has_channel_1; /* a33 does not have channel 1 */ 175 bool has_channel_1; /* a33 does not have channel 1 */
176 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */ 176 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
177 bool needs_de_be_mux; /* sun6i needs mux to select backend */ 177 bool needs_de_be_mux; /* sun6i needs mux to select backend */
178 bool supports_lvds; /* Does the TCON support an LVDS output? */
178 179
179 /* callback to handle tcon muxing options */ 180 /* callback to handle tcon muxing options */
180 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); 181 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);