Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp4205176imm; Mon, 30 Jul 2018 10:22:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpets0Pg4e4fthWgMYD0VEjtG12HB1dbeOthcOK5V8fq6lAwXakM7eFNc42hUpVd9N6JIDU2 X-Received: by 2002:a63:6441:: with SMTP id y62-v6mr16988036pgb.240.1532971366362; Mon, 30 Jul 2018 10:22:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532971366; cv=none; d=google.com; s=arc-20160816; b=io0PMti8QLh8tDLjZzT5zLVIwlBGbQgJ+QhSjib5n/vUKqj7gJEO25tcNWAx8xZ9w7 RVN+xfX7DLBXb4QssaOiLzQuBe12xjdYM9s9sWNtmugqUfjXFQzwI26qg51g5AsVswAB O7Cz6RQE1wyHJ52p3dTz0HAdpW2xq7LTKGcmtQWF4ZsX2IGjgFkNXT+4nt8wNP1ZXxSB Al6yEoUybrJ10UkbnsGuS76jdro8B03rowD+egz+l6PbHLj76kZn9pBIonIps07fDMpX 86mLun8cro3oo/E8WNuRd3ApY9p5P7+bl3IQLionMEkR1cRBLS7PfWtwQJJ2CYXkfd77 zpdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=h/kkEUsxrdcynvIjcYI+oZ4x8a3XWYDD3skfv2W+ERM=; b=qfNCUYbMW5uyv109sZ24lisjK1THZuiZZ72giQW/Iu1sWJ0OOYGv4LXvlk6FOtWXZN CK87MYshVuS/t9URT79F3UCUcmVHsAdH4gi9Cl8EYXp+hLtMEcAghkrxtbctiCPo3asn IBvYiZTMPs/udUUAHH/IOCEkPNv/ywqwMyQnmeWOrolqzUUo25jxK7S6EFHXwyyJ1lsd 9FZa3SIbtLKqFx9vNuNmJ9kPBrJYDHVeavgcI1crwHCGv4FYzgD/KZ2bK1599LlXFcus FrPqL7dtoYlh4clsseTIKKWZD57sdDbQOujHSogE9/TXKjtvugw4rdYZEyTAHCuwtxws tYhA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u2-v6si10590683pge.585.2018.07.30.10.22.31; Mon, 30 Jul 2018 10:22:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728768AbeG3S4a (ORCPT + 99 others); Mon, 30 Jul 2018 14:56:30 -0400 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:32793 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726752AbeG3S43 (ORCPT ); Mon, 30 Jul 2018 14:56:29 -0400 X-Originating-IP: 2.224.242.101 Received: from w540.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id C727EE0004; Mon, 30 Jul 2018 17:20:27 +0000 (UTC) From: Jacopo Mondi To: Laurent Pinchart , David Airlie Cc: Jacopo Mondi , dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR RENESAS), linux-renesas-soc@vger.kernel.org (open list:DRM DRIVERS FOR RENESAS), linux-kernel@vger.kernel.org (open list), Laurent Pinchart Subject: [PATCH 1/3] drm: rcar-du: Rework clock configuration based on hardware limits Date: Mon, 30 Jul 2018 19:20:12 +0200 Message-Id: <1532971214-17962-2-git-send-email-jacopo@jmondi.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532971214-17962-1-git-send-email-jacopo@jmondi.org> References: <1532971214-17962-1-git-send-email-jacopo@jmondi.org> X-Spam-Level: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Laurent Pinchart The DU channels that have a display PLL (DPLL) can only use external clock sources, and don't have an internal clock divider (with the exception of H3 ES1.x where the post-divider is present and needs to be used as a workaround for a DPLL silicon issue). Rework the clock configuration to take this into account, avoiding selection of non-existing clock sources or usage of a missing post-divider. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 122 ++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index b52b3e8..6d55cec 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -208,78 +208,90 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode; struct rcar_du_device *rcdu = rcrtc->group->dev; unsigned long mode_clock = mode->clock * 1000; - unsigned long clk; u32 value; u32 escr; - u32 div; - /* - * Compute the clock divisor and select the internal or external dot - * clock based on the requested frequency. - */ - clk = clk_get_rate(rcrtc->clock); - div = DIV_ROUND_CLOSEST(clk, mode_clock); - div = clamp(div, 1U, 64U) - 1; - escr = div | ESCR_DCLKSEL_CLKS; - - if (rcrtc->extclock) { + if (rcdu->info->dpll_ch & (1 << rcrtc->index)) { + unsigned long target = mode_clock; struct dpll_info dpll = { 0 }; unsigned long extclk; - unsigned long extrate; - unsigned long rate; - u32 extdiv; + u32 dpllcr; + u32 div = 0; - extclk = clk_get_rate(rcrtc->extclock); - if (rcdu->info->dpll_ch & (1 << rcrtc->index)) { - unsigned long target = mode_clock; + /* + * DU channels that have a display PLL can't use the internal + * system clock, and have no internal clock divider. + */ - /* - * The H3 ES1.x exhibits dot clock duty cycle stability - * issues. We can work around them by configuring the - * DPLL to twice the desired frequency, coupled with a - * /2 post-divider. This isn't needed on other SoCs and - * breaks HDMI output on M3-W for a currently unknown - * reason, so restrict the workaround to H3 ES1.x. - */ - if (soc_device_match(rcar_du_r8a7795_es1)) - target *= 2; + if (WARN_ON(!rcrtc->extclock)) + return; - rcar_du_dpll_divider(rcrtc, &dpll, extclk, target); - extclk = dpll.output; + /* + * The H3 ES1.x exhibits dot clock duty cycle stability issues. + * We can work around them by configuring the DPLL to twice the + * desired frequency, coupled with a /2 post-divider. Restrict + * the workaround to H3 ES1.x as ES2.0 and all other SoCs have + * no post-divider when a display PLL is present (as shown by + * the workaround breaking HDMI output on M3-W during testing). + */ + if (soc_device_match(rcar_du_r8a7795_es1)) { + target *= 2; + div = 1; } - extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock); - extdiv = clamp(extdiv, 1U, 64U) - 1; + extclk = clk_get_rate(rcrtc->extclock); + rcar_du_dpll_divider(rcrtc, &dpll, extclk, target); - rate = clk / (div + 1); - extrate = extclk / (extdiv + 1); + dpllcr = DPLLCR_CODE | DPLLCR_CLKE + | DPLLCR_FDPLL(dpll.fdpll) + | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m) + | DPLLCR_STBY; - if (abs((long)extrate - (long)mode_clock) < - abs((long)rate - (long)mode_clock)) { + if (rcrtc->index == 1) + dpllcr |= DPLLCR_PLCS1 + | DPLLCR_INCS_DOTCLKIN1; + else + dpllcr |= DPLLCR_PLCS0 + | DPLLCR_INCS_DOTCLKIN0; - if (rcdu->info->dpll_ch & (1 << rcrtc->index)) { - u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE - | DPLLCR_FDPLL(dpll.fdpll) - | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m) - | DPLLCR_STBY; + rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr); - if (rcrtc->index == 1) - dpllcr |= DPLLCR_PLCS1 - | DPLLCR_INCS_DOTCLKIN1; - else - dpllcr |= DPLLCR_PLCS0 - | DPLLCR_INCS_DOTCLKIN0; + escr = ESCR_DCLKSEL_DCLKIN | div; + } else { + unsigned long clk; + u32 div; - rcar_du_group_write(rcrtc->group, DPLLCR, - dpllcr); - } + /* + * Compute the clock divisor and select the internal or external + * dot clock based on the requested frequency. + */ + clk = clk_get_rate(rcrtc->clock); + div = DIV_ROUND_CLOSEST(clk, mode_clock); + div = clamp(div, 1U, 64U) - 1; - escr = ESCR_DCLKSEL_DCLKIN | extdiv; - } + escr = ESCR_DCLKSEL_CLKS | div; - dev_dbg(rcrtc->group->dev->dev, - "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n", - mode_clock, extrate, rate, escr); + if (rcrtc->extclock) { + unsigned long extclk; + unsigned long extrate; + unsigned long rate; + u32 extdiv; + + extclk = clk_get_rate(rcrtc->extclock); + extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock); + extdiv = clamp(extdiv, 1U, 64U) - 1; + + extrate = extclk / (extdiv + 1); + rate = clk / (div + 1); + + if (abs((long)extrate - (long)mode_clock) < + abs((long)rate - (long)mode_clock)) + escr = ESCR_DCLKSEL_DCLKIN | extdiv; + + dev_dbg(rcrtc->group->dev->dev, + "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n", + mode_clock, extrate, rate, escr); + } } rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, -- 2.7.4