mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
To: Jyri Sarha <jsarha@ti.com>,
	Tomi Valkeinen <tomi.valkeinen@ti.com>,
	David Airlie <airlied@linux.ie>,
	Kevin Hilman <khilman@baylibre.com>,
	Michael Turquette <mturquette@baylibre.com>
Cc: linux-drm <dri-devel@lists.freedesktop.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>
Subject: [PATCH] drm: tilcdc: add a workaround for failed clk_set_rate()
Date: Tue, 27 Sep 2016 17:29:56 +0200	[thread overview]
Message-ID: <1474990196-808-1-git-send-email-bgolaszewski@baylibre.com> (raw)

Some architectures don't use the common clock framework and don't
implement all the clk interfaces for every clock. This is the case
for da850-lcdk where clk_set_rate() only works for PLL0 and PLL1.

Trying to set the clock rate for the LCDC clock results in -EINVAL
being returned.

As a workaround for that: if the call to clk_set_rate() fails, fall
back to adjusting the clock divider instead. Proper divider value is
calculated by dividing the current clock rate by the required pixel
clock rate in HZ.

This code is based on a hack initially developed internally for
baylibre by Karl Beldan <kbeldan@baylibre.com>.

Tested with a da850-lcdk with an LCD display connected over VGA.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 2087689..f2ff3b1 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -636,22 +636,40 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct tilcdc_drm_private *priv = dev->dev_private;
 	unsigned long lcd_clk;
-	const unsigned clkdiv = 2; /* using a fixed divider of 2 */
+	unsigned int clkdiv;
 	int ret;
 
 	pm_runtime_get_sync(dev->dev);
 
 	tilcdc_crtc_disable(crtc);
 
+	clkdiv = 2; /* first try using a standard divider of 2 */
+
 	/* mode.clock is in KHz, set_rate wants parameter in Hz */
 	ret = clk_set_rate(priv->clk, crtc->mode.clock * 1000 * clkdiv);
+	lcd_clk = clk_get_rate(priv->clk);
 	if (ret < 0) {
-		dev_err(dev->dev, "failed to set display clock rate to: %d\n",
-				crtc->mode.clock);
-		goto out;
-	}
+		/*
+		 * If we fail to set the clock rate (some architectures don't
+		 * use the common clock framework yet and may not implement
+		 * all the clk API calls for every clock), try the next best
+		 * thing: adjusting the clock divider, unless clk_get_rate()
+		 * failed as well.
+		 */
+		dev_err(dev->dev,
+			"failed to set display clock rate to: %d\n",
+			crtc->mode.clock);
+		if (!lcd_clk) {
+			/* Nothing more we can do. Just bail out. */
+			dev_err(dev->dev,
+				"failed to read the display clock rate\n");
+			goto out;
+		}
 
-	lcd_clk = clk_get_rate(priv->clk);
+		dev_info(dev->dev,
+			 "falling back to adjusting the clock divisor\n");
+		clkdiv = DIV_ROUND_CLOSEST(lcd_clk, (crtc->mode.clock * 1000));
+	}
 
 	DBG("lcd_clk=%lu, mode clock=%d, div=%u",
 		lcd_clk, crtc->mode.clock, clkdiv);
@@ -664,7 +682,6 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
 		tilcdc_set(dev, LCDC_CLK_ENABLE_REG,
 				LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN |
 				LCDC_V2_CORE_CLK_EN);
-
 	if (tilcdc_crtc_is_on(crtc))
 		tilcdc_crtc_enable(crtc);
 
-- 
2.7.4

             reply	other threads:[~2016-09-27 15:30 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-27 15:29 Bartosz Golaszewski [this message]
2016-09-28 10:57 ` Jyri Sarha
2016-09-28 11:19 ` Tomi Valkeinen
2016-09-28 11:43   ` Bartosz Golaszewski
2016-09-28 11:55     ` Tomi Valkeinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474990196-808-1-git-send-email-bgolaszewski@baylibre.com \
    --to=bgolaszewski@baylibre.com \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jsarha@ti.com \
    --cc=khilman@baylibre.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=tomi.valkeinen@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®