From patchwork Tue Sep 27 15:29:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 77056 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp1784090qgf; Tue, 27 Sep 2016 08:30:13 -0700 (PDT) X-Received: by 10.66.248.229 with SMTP id yp5mr49133542pac.31.1474990213318; Tue, 27 Sep 2016 08:30:13 -0700 (PDT) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id bf12si3125908pac.239.2016.09.27.08.30.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Sep 2016 08:30:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@baylibre-com.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 827256E2DF; Tue, 27 Sep 2016 15:30:12 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x231.google.com (mail-wm0-x231.google.com [IPv6:2a00:1450:400c:c09::231]) by gabe.freedesktop.org (Postfix) with ESMTPS id C32316E2F1 for ; Tue, 27 Sep 2016 15:30:10 +0000 (UTC) Received: by mail-wm0-x231.google.com with SMTP id w84so182330784wmg.1 for ; Tue, 27 Sep 2016 08:30:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=5CkOwes1PbvA7QYspZbbSMM6JhvZFj5UubM49YnWErY=; b=YZXbt+F9hohdFO4zsNa8N4EgYeI3kCmKuzMBhkPFDa3CJvyrhyd6TMhY0wT2+hLvrQ rqeyBR23VTF/lE/Fabwx5rIFx0A346DmdpLCh3gi7Ad2vQnS/AXZmPmQQs7eLMMZTGvW BB8r3SMKNRFhTl0fRFf9IJsQiAP4nIYgsLpuZcKPLdO6BL/khvjnp6awTUzzRj35reRD 85tWmGsA2MBhOojZHM3Q/aFCNJgHZN+vPcV0s7V99n5y71YSb+yOgz2YhtbFF1HNvo57 1Fmf0htcdxxNgvMjgcW7RjquLooGzUxjc/PcpsLlzjvQLB+T07X1sWLTgIQOE1fDN31p yGLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=5CkOwes1PbvA7QYspZbbSMM6JhvZFj5UubM49YnWErY=; b=cBDCzj6uCSJH0ulbMDTB1UCV+vooLCylSDL21BKsjT+AlfG3I3YlHzJvWgL9wf5/uJ bPoKGWpgwZaWucAKGkO6Es6NCeKY1O5PvBXkKbtsF2K7UU7FTdQEkZjmVPzJDIkJ70un xPvoQNtVCN9XKbkMoOUoUTAGmzOADWNxKnGw/y9Qcntp/uDAhEo5bWIg9Mso1S8n+vZQ fBEu+sd6STPXa/VpwqADtOzcxwePcENgI1PlPBlMXes3ir5r/9KBzO0Xp0mMBn3XbjjH 1JzRdeMZkumj0SQmp6NKphX9LVWJ4bDQqcWGsrHPxFPeakVy9IoKLTrMgYuM7f5HpGWZ wsvw== X-Gm-Message-State: AA6/9RkVCBoM/bgl3t2PUfF4+7/qcTAv2Qj46HRO5N2j3UR4/fx2Om3Hn7cGcGVk+sV0oU3d X-Received: by 10.194.106.103 with SMTP id gt7mr23265726wjb.201.1474990209352; Tue, 27 Sep 2016 08:30:09 -0700 (PDT) Received: from bgdev-debian.lan (jua06-1-82-242-157-225.fbx.proxad.net. [82.242.157.225]) by smtp.gmail.com with ESMTPSA id u64sm17317779wmd.20.2016.09.27.08.30.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 27 Sep 2016 08:30:08 -0700 (PDT) From: Bartosz Golaszewski To: Jyri Sarha , Tomi Valkeinen , David Airlie , Kevin Hilman , Michael Turquette Subject: [PATCH] drm: tilcdc: add a workaround for failed clk_set_rate() Date: Tue, 27 Sep 2016 17:29:56 +0200 Message-Id: <1474990196-808-1-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 Cc: Bartosz Golaszewski , LKML , linux-drm X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 . Tested with a da850-lcdk with an LCD display connected over VGA. Signed-off-by: Bartosz Golaszewski --- 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);