From patchwork Tue May 30 16:28:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Elwell X-Patchwork-Id: 9754883 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 57A83602B9 for ; Tue, 30 May 2017 16:29:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48C621FFCA for ; Tue, 30 May 2017 16:29:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D783223B2; Tue, 30 May 2017 16:29:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CCFC21FFCA for ; Tue, 30 May 2017 16:29:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751126AbdE3Q2t (ORCPT ); Tue, 30 May 2017 12:28:49 -0400 Received: from mx07-00252a01.pphosted.com ([62.209.51.214]:10643 "EHLO mx07-00252a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751058AbdE3Q2V (ORCPT ); Tue, 30 May 2017 12:28:21 -0400 Received: from pps.filterd (m0102628.ppops.net [127.0.0.1]) by mx07-00252a01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v4UGRvgY020291 for ; Tue, 30 May 2017 17:28:15 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.org; h=to : from : subject : message-id : date : mime-version : content-type : content-transfer-encoding; s=pp; bh=BEHjATF2DAlQ5cGS5AP61nyPTR4GlDSHNPrZM4sSeCQ=; b=wE0K5SIuaLWR1/xrDNCajAissmvUVjf1sQDG41FndNW1ZwOIGA/DIRBmOcHnDKEGFqcn OGTwxTkSlPFJLcWDQ1r84JURMVk7J4IBACJrK8hY6S4HvIAIbsD4ybFwv0YlW6GQ0ykF aPg8oMNhteoAvfXQYxAbyd1+V+m+cTatvQqjoBe173CGRo+VHATwjT+ywkNKtsMCAz6/ 22P0bHSqBuCGvk1lkg8WILLj336HOHrZCzLmHEiN0ozoDyiIFrVSaWBwnUrYUEAg1oG5 HhhpD+fusJCfe6yZKo4kGIdTq+vBEskA/nkdJN6Xp6dyuWHfYTqXhI4BHTT0P/lbPZ4e 1g== Received: from mail-wr0-f199.google.com (mail-wr0-f199.google.com [209.85.128.199]) by mx07-00252a01.pphosted.com with ESMTP id 2apxuy9jx1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK) for ; Tue, 30 May 2017 17:28:15 +0100 Received: by mail-wr0-f199.google.com with SMTP id n104so2622144wrb.0 for ; Tue, 30 May 2017 09:28:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi-org.20150623.gappssmtp.com; s=20150623; h=to:from:subject:message-id:date:user-agent:mime-version :content-language:content-transfer-encoding; bh=BEHjATF2DAlQ5cGS5AP61nyPTR4GlDSHNPrZM4sSeCQ=; b=kKTnPYKOqzHEjRyIdc5HgpNftcbZovy9ZsC5BHKpHPYEHH4GOT/OzYp5R+FEyOW2AD 3unPaRzWa+Pv6SROABjP0MHG4WNHI8/cNhkRkJ+Np8hwjc6593wEL6GL9YQ002+Sva+4 pEQdey6FeNswbo9EYKreApiVy99pW3Q5jgzZxr/Y8RDHi3RmbfG9PhWnFi0HWZ+sSh3V fI5v6X5021MrjYUF0OmGyhqdvQ2GxELVNBToLr0DCqcIickiL/BjnAPx+tw3Bf7D0oOA rrwqVQ87fmeZo59M3H7PCbJnVL/VTTzle1sVfDCcnP/GOJ/TuzTX+ngXpXWHgE+Rprkd LigA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=BEHjATF2DAlQ5cGS5AP61nyPTR4GlDSHNPrZM4sSeCQ=; b=ZOgZzHUI1/rx/8qDDkldqY50rHwpg5efEKz5EEMX+mQDdaYVmmS1j81Rtci5QIpVK5 zcuyS8RkiivzdUkAEVwgg9I7k35R+/2nlkSf/JopecxUZnfvUifGwlWlQ/Nxt9u8z0RA G3Msbk0jQAhXCiIymD+ivVhlKmMuomCKAOV1xwNpYk5cbAXtNYLz1uleyK2FbaFgP0n0 9Go5yXuDaeW1RA0bWu/Psg7ja4cjhzRk8v77Z6LtkScVb2464m9Uglyv768vPBZRL4Iw BKHa8sQBIkgqxhQjHUCujyMICH0oAgQsI5ocQMy9hBuYwjlE1JVVsitSc/Kq/gjhAnG+ jL/A== X-Gm-Message-State: AODbwcCMwhz82XeeubuJ1KcBzJzwb5oU5H44Ec/Uyszjnzj2qlkQw6nT aP3zlKpdzBI9Le4o+uHn2CZluC9SMWABkiooMFT75J3yrmy4CxMU/QNNBao+HE4lF2Qffr6GTCq T6qVoKHO3MXk= X-Received: by 10.223.151.107 with SMTP id r98mr9549024wrb.6.1496161693869; Tue, 30 May 2017 09:28:13 -0700 (PDT) X-Received: by 10.223.151.107 with SMTP id r98mr9549011wrb.6.1496161693705; Tue, 30 May 2017 09:28:13 -0700 (PDT) Received: from ?IPv6:2a00:2381:fdf7:14:79d0:49c2:6e14:f72b? ([2a00:2381:fdf7:14:79d0:49c2:6e14:f72b]) by smtp.gmail.com with ESMTPSA id r6sm11005091wme.27.2017.05.30.09.28.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 May 2017 09:28:13 -0700 (PDT) To: Michael Turquette , Stephen Boyd , Eric Anholt , Stefan Wahren , Florian Fainelli , linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-kernel@vger.kernel.org From: Phil Elwell Subject: [PATCH 2/2] clk: bcm2835: Minimise clock jitter for PCM clock Message-ID: Date: Tue, 30 May 2017 17:28:14 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 Content-Language: en-GB X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-05-30_10:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_spam_notspam policy=outbound_spam score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705300305 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Fractional clock dividers generate accurate average frequencies but with jitter, particularly when the integer divisor is small. Introduce a new metric of clock accuracy to penalise clocks with a good average but worse jitter compared to clocks with an average which is no better but with lower jitter. The metric is the ideal rate minus the worse deviation from that ideal using the nearest integer divisors. Use this metric for parent selection for clocks requiring low jitter (currently just PCM). Signed-off-by: Phil Elwell --- drivers/clk/bcm/clk-bcm2835.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index facc346..e0ce5e7 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -530,6 +530,7 @@ struct bcm2835_clock_data { bool is_vpu_clock; bool is_mash_clock; + bool low_jitter; u32 tcnt_mux; }; @@ -1124,7 +1125,8 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, int parent_idx, unsigned long rate, u32 *div, - unsigned long *prate) + unsigned long *prate, + unsigned long *avgrate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; @@ -1136,11 +1138,33 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, parent = clk_hw_get_parent_by_index(hw, parent_idx); if (!(BIT(parent_idx) & data->set_rate_parent)) { + unsigned long tmp_rate; + *prate = clk_hw_get_rate(parent); *div = bcm2835_clock_choose_div(hw, rate, *prate, true); - return bcm2835_clock_rate_from_divisor(clock, *prate, - *div); + tmp_rate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); + *avgrate = tmp_rate; + + if (data->low_jitter && (*div & CM_DIV_FRAC_MASK)) { + unsigned long high, low; + u32 idiv = *div & ~CM_DIV_FRAC_MASK; + + high = bcm2835_clock_rate_from_divisor(clock, *prate, + idiv); + idiv += CM_DIV_FRAC_MASK + 1; + low = bcm2835_clock_rate_from_divisor(clock, *prate, + idiv); + + /* Return a value which is the maximum deviation + * below the ideal rate, for use as a metric. + */ + if ((tmp_rate - low) < (high - tmp_rate)) + tmp_rate = low; + else + tmp_rate -= high - tmp_rate; + } + return tmp_rate; } if (data->frac_bits) @@ -1167,6 +1191,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, *div = curdiv << CM_DIV_FRAC_BITS; *prate = curdiv * best_rate; + *avgrate = best_rate; return best_rate; } @@ -1178,6 +1203,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, bool current_parent_is_pllc; unsigned long rate, best_rate = 0; unsigned long prate, best_prate = 0; + unsigned long avgrate, best_avgrate = 0; size_t i; u32 div; @@ -1202,11 +1228,13 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, continue; rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, - &div, &prate); + &div, &prate, + &avgrate); if (rate > best_rate && rate <= req->rate) { best_parent = parent; best_prate = prate; best_rate = rate; + best_avgrate = avgrate; } } @@ -1216,7 +1244,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, req->best_parent_hw = best_parent; req->best_parent_rate = best_prate; - req->rate = best_rate; + req->rate = best_avgrate; return 0; } @@ -2010,6 +2038,7 @@ struct bcm2835_clk_desc { .int_bits = 12, .frac_bits = 12, .is_mash_clock = true, + .low_jitter = true, .parents = bcm2835_pcm_per_parents, .tcnt_mux = 23), [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(