From f3e5feeb92a163c935659b7222a32965276c1c23 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 1 Mar 2018 22:34:32 +0100 Subject: drm/sun4i: Release exclusive clock lock when disabling TCON Currently exclusive TCON clock lock is never released, which, for example, prevents changing resolution on HDMI. In order to fix that, release clock when disabling TCON. TCON is always disabled first before new mode is set. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180301213442.16677-7-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun4i_tcon.c') diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index b3960118deb9..ade197b1a9ac 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, return; } - if (enabled) + if (enabled) { clk_prepare_enable(clk); - else + } else { + clk_rate_exclusive_put(clk); clk_disable_unprepare(clk); + } } static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon, -- cgit v1.2.1 From e742a17cd360fbd64425a3c861c59062ec837f23 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 21 Feb 2018 13:57:01 +0100 Subject: drm/sun4i: tcon: Reduce the scope of the LVDS error a bit The current logic to deal with old DT missing the LVDS properties doesn't take into account whether the LVDS output is supported in the first place, resulting in spurious error messages on SoCs where it doesn't even matter. Introduce a new TCON flag to list if LVDS is supported at all to prevent this from happening. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180221125703.4595-1-maxime.ripard@bootlin.com --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 86 ++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 41 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun4i_tcon.c') diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index ade197b1a9ac..2de586b7c98b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -875,52 +875,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, return ret; } - /* - * This can only be made optional since we've had DT nodes - * without the LVDS reset properties. - * - * If the property is missing, just disable LVDS, and print a - * warning. - */ - tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); - if (IS_ERR(tcon->lvds_rst)) { - dev_err(dev, "Couldn't get our reset line\n"); - return PTR_ERR(tcon->lvds_rst); - } else if (tcon->lvds_rst) { - has_lvds_rst = true; - reset_control_reset(tcon->lvds_rst); - } else { - has_lvds_rst = false; - } + if (tcon->quirks->supports_lvds) { + /* + * This can only be made optional since we've had DT + * nodes without the LVDS reset properties. + * + * If the property is missing, just disable LVDS, and + * print a warning. + */ + tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); + if (IS_ERR(tcon->lvds_rst)) { + dev_err(dev, "Couldn't get our reset line\n"); + return PTR_ERR(tcon->lvds_rst); + } else if (tcon->lvds_rst) { + has_lvds_rst = true; + reset_control_reset(tcon->lvds_rst); + } else { + has_lvds_rst = false; + } - /* - * This can only be made optional since we've had DT nodes - * without the LVDS reset properties. - * - * If the property is missing, just disable LVDS, and print a - * warning. - */ - if (tcon->quirks->has_lvds_alt) { - tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); - if (IS_ERR(tcon->lvds_pll)) { - if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { - has_lvds_alt = false; + /* + * This can only be made optional since we've had DT + * nodes without the LVDS reset properties. + * + * If the property is missing, just disable LVDS, and + * print a warning. + */ + if (tcon->quirks->has_lvds_alt) { + tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); + if (IS_ERR(tcon->lvds_pll)) { + if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { + has_lvds_alt = false; + } else { + dev_err(dev, "Couldn't get the LVDS PLL\n"); + return PTR_ERR(tcon->lvds_pll); + } } else { - dev_err(dev, "Couldn't get the LVDS PLL\n"); - return PTR_ERR(tcon->lvds_pll); + has_lvds_alt = true; } - } else { - has_lvds_alt = true; } - } - if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { - dev_warn(dev, - "Missing LVDS properties, Please upgrade your DT\n"); - dev_warn(dev, "LVDS output disabled\n"); - can_lvds = false; + if (!has_lvds_rst || + (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { + dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n"); + dev_warn(dev, "LVDS output disabled\n"); + can_lvds = false; + } else { + can_lvds = true; + } } else { - can_lvds = true; + can_lvds = false; } ret = sun4i_tcon_init_clocks(dev, tcon); @@ -1139,7 +1143,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = { }; static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { - /* nothing is supported */ + .supports_lvds = true, }; static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { -- cgit v1.2.1 From 7035046d6d02d455325c5d0328bcc8a0b5dd96b0 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Sat, 10 Mar 2018 12:05:11 +0100 Subject: drm/sun4i: Fix exclusivity of the TCON clocks Currently the exclusivity is enabled when the rate is set by the mode setting functions. These functions are called by mode_set_nofb callback of drm_crc_helper. Then exclusivity is disabled when tcon is disabled by atomic_disable callback. What happens is that mode_set_nofb can be called once when mode changes, and afterwards the system can call atomic_enable and atomic_disable multiple times without further calls to mode_set_nofb. This happens: mode_set_nofb - clk exclusivity is enabled atomic_enable atomic_disable - clk exclusivity is disabled atomic_enable atomic_disable - clk exclusivity is already disabled, leading to WARN in clk_rate_exclusive_put Solution is to enable exclusivity in sun4i_tcon_channel_set_status. Signed-off-by: Ondrej Jirman Cc: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180310110511.14697-1-megous@megous.com --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun4i_tcon.c') diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 2de586b7c98b..a818ca491605 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -103,6 +103,7 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel, if (enabled) { clk_prepare_enable(clk); + clk_rate_exclusive_get(clk); } else { clk_rate_exclusive_put(clk); clk_disable_unprepare(clk); @@ -262,7 +263,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, const struct drm_display_mode *mode) { /* Configure the dot clock */ - clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000); + clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); /* Set the resolution */ regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, @@ -423,7 +424,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, WARN_ON(!tcon->quirks->has_channel_1); /* Configure the dot clock */ - clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000); + clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 1); -- cgit v1.2.1