aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sun4i/sun4i_tcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_tcon.c')
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c99
1 files changed, 54 insertions, 45 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 3c15cf24b503..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,
@@ -260,7 +262,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
260 const struct drm_display_mode *mode) 262 const struct drm_display_mode *mode)
261{ 263{
262 /* Configure the dot clock */ 264 /* Configure the dot clock */
263 clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); 265 clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000);
264 266
265 /* Set the resolution */ 267 /* Set the resolution */
266 regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, 268 regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
@@ -335,6 +337,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
335 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, 337 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
336 SUN4I_TCON_GCTL_IOMAP_MASK, 338 SUN4I_TCON_GCTL_IOMAP_MASK,
337 SUN4I_TCON_GCTL_IOMAP_TCON0); 339 SUN4I_TCON_GCTL_IOMAP_TCON0);
340
341 /* Enable the output on the pins */
342 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
338} 343}
339 344
340static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, 345static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
@@ -418,7 +423,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
418 WARN_ON(!tcon->quirks->has_channel_1); 423 WARN_ON(!tcon->quirks->has_channel_1);
419 424
420 /* Configure the dot clock */ 425 /* Configure the dot clock */
421 clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); 426 clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000);
422 427
423 /* Adjust clock delay */ 428 /* Adjust clock delay */
424 clk_delay = sun4i_tcon_get_clk_delay(mode, 1); 429 clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
@@ -870,52 +875,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
870 return ret; 875 return ret;
871 } 876 }
872 877
873 /* 878 if (tcon->quirks->supports_lvds) {
874 * This can only be made optional since we've had DT nodes 879 /*
875 * without the LVDS reset properties. 880 * This can only be made optional since we've had DT
876 * 881 * nodes without the LVDS reset properties.
877 * If the property is missing, just disable LVDS, and print a 882 *
878 * warning. 883 * If the property is missing, just disable LVDS, and
879 */ 884 * print a warning.
880 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); 885 */
881 if (IS_ERR(tcon->lvds_rst)) { 886 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
882 dev_err(dev, "Couldn't get our reset line\n"); 887 if (IS_ERR(tcon->lvds_rst)) {
883 return PTR_ERR(tcon->lvds_rst); 888 dev_err(dev, "Couldn't get our reset line\n");
884 } else if (tcon->lvds_rst) { 889 return PTR_ERR(tcon->lvds_rst);
885 has_lvds_rst = true; 890 } else if (tcon->lvds_rst) {
886 reset_control_reset(tcon->lvds_rst); 891 has_lvds_rst = true;
887 } else { 892 reset_control_reset(tcon->lvds_rst);
888 has_lvds_rst = false; 893 } else {
889 } 894 has_lvds_rst = false;
895 }
890 896
891 /* 897 /*
892 * This can only be made optional since we've had DT nodes 898 * This can only be made optional since we've had DT
893 * without the LVDS reset properties. 899 * nodes without the LVDS reset properties.
894 * 900 *
895 * If the property is missing, just disable LVDS, and print a 901 * If the property is missing, just disable LVDS, and
896 * warning. 902 * print a warning.
897 */ 903 */
898 if (tcon->quirks->has_lvds_alt) { 904 if (tcon->quirks->has_lvds_alt) {
899 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); 905 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
900 if (IS_ERR(tcon->lvds_pll)) { 906 if (IS_ERR(tcon->lvds_pll)) {
901 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { 907 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
902 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 }
903 } else { 913 } else {
904 dev_err(dev, "Couldn't get the LVDS PLL\n"); 914 has_lvds_alt = true;
905 return PTR_ERR(tcon->lvds_pll);
906 } 915 }
907 } else {
908 has_lvds_alt = true;
909 } 916 }
910 }
911 917
912 if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { 918 if (!has_lvds_rst ||
913 dev_warn(dev, 919 (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
914 "Missing LVDS properties, Please upgrade your DT\n"); 920 dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
915 dev_warn(dev, "LVDS output disabled\n"); 921 dev_warn(dev, "LVDS output disabled\n");
916 can_lvds = false; 922 can_lvds = false;
923 } else {
924 can_lvds = true;
925 }
917 } else { 926 } else {
918 can_lvds = true; 927 can_lvds = false;
919 } 928 }
920 929
921 ret = sun4i_tcon_init_clocks(dev, tcon); 930 ret = sun4i_tcon_init_clocks(dev, tcon);
@@ -1134,7 +1143,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
1134}; 1143};
1135 1144
1136static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { 1145static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
1137 /* nothing is supported */ 1146 .supports_lvds = true,
1138}; 1147};
1139 1148
1140static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { 1149static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {