From patchwork Thu Jun 1 14:14:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Elwell X-Patchwork-Id: 9759643 X-Patchwork-Delegate: sboyd@codeaurora.org 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 1876E602BC for ; Thu, 1 Jun 2017 14:14:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 055A92849A for ; Thu, 1 Jun 2017 14:14:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ED4C1284BF; Thu, 1 Jun 2017 14:14:27 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham 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 6F8B52849A for ; Thu, 1 Jun 2017 14:14:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751155AbdFAOO0 (ORCPT ); Thu, 1 Jun 2017 10:14:26 -0400 Received: from mx08-00252a01.pphosted.com ([91.207.212.211]:37174 "EHLO mx08-00252a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751209AbdFAOOY (ORCPT ); Thu, 1 Jun 2017 10:14:24 -0400 Received: from pps.filterd (m0102629.ppops.net [127.0.0.1]) by mx08-00252a01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v51E9l8X015686 for ; Thu, 1 Jun 2017 15:14:23 +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=CnxhMNrpUyDovqbj7U78fLwt4JOrDXVXxNJcFHhTULw=; b=UfE8nkFdmJ3lpskUPyYzefjoLCUbNs7qg0cDJBy/6H2JSkhPSz9nGXuN6Emvm4g5mYDR NGtoSTvFJ/6HDqe4cQgB0pnJfrPFqmmS+z3wNoL8JLedujoHFOSRLrwSfgMtA1iNWHbd Rt1xdB2Z+EVCBQsbD9JVXTsunYmTOlYC/PBxDHM66lsfbL8CWSY9N3yoOnac7FdSzlwV TQbm0ZHkCnZfNF/4Ouzq3fBwbMGOi+sMoWfDpRG04Fh52j9SSItSOIHDqG1bqvFK6mJp 58+18S/DJWhd94SbiEp0rdYzGpGvfzxz4N+XtC2M9WQGVpphZphl9cW19rfuGMcfqcr4 yw== Received: from mail-wm0-f72.google.com (mail-wm0-f72.google.com [74.125.82.72]) by mx08-00252a01.pphosted.com with ESMTP id 2apwxetgay-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK) for ; Thu, 01 Jun 2017 15:14:22 +0100 Received: by mail-wm0-f72.google.com with SMTP id a77so10430155wma.12 for ; Thu, 01 Jun 2017 07:14:22 -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=CnxhMNrpUyDovqbj7U78fLwt4JOrDXVXxNJcFHhTULw=; b=DUPonTXhTQvRCuXepIsaLphNO206BBTHy0IOqHtbLmnjXmykkGJRHpxzBSIiwFetug y2nq7G3HFtNx3STyCh3SU6NmFb64CigjkDHM+IL8HbDDFLtJNWKsno8s3C+hE5veSJg7 YmfcQt8mBscfnBiFvWWJL8MYkag7VLVbIJ/IhmgnYeZHFVNZid+f4NMTKUUkxZB7eCD7 q2X7z1JGY8XQ62R7DhF73Sf8R1bmV8ishD+14+pWZvtoT+hc4yirPakyOFDXNAk/45ie ncOt6dYYLcoZf848phHGQaSaI7/pvVXrYfVk5fu7qGysJTt0BBg7D7fljlciyyYktnwi QGtw== 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=CnxhMNrpUyDovqbj7U78fLwt4JOrDXVXxNJcFHhTULw=; b=F64u2JEOzFI+xPYwQwN5op1q97opUI057ptqyQ/ILw8k871QPOLtCHAcRRVt9YvIS9 VyyTZfbLKaCLvJLu4ddSh+WWKi4txJ+tJ6qHTz3VezBXQwvVXEFLgD6FY1kVQAfoEXTA dP2Tvrfy3gckA/MMUhsBWbKVc44KInF6ts5TD9vre/bncYdKPn4RxM6TQwnZ5W/a+iz4 vnzosIYyIds2xCy5/lCSxyRH0IiQoOePCqZMMuFR5qHE/WuFBKa9O9plEJLYLTeR8Xv5 aHENUVoMAOJNzPxSLiS5Qr2ehWRPiO82o2kw8IkH8/zsfsK8guCaCbuOvfg35PshvyWI JtFA== X-Gm-Message-State: AODbwcB9Y8NqWcKiCfa2rdP/VDgQnmpdz/lBEYxrEpbieGtQi9Cnu1lJ PARPt/hH/Y6qtcyrYjzCjywaHz2HuQ7GHihEud7ywTQNA+2GNWGM9JjF85bFgmP60j3H35PvORf I8dwfO1P8uEE= X-Received: by 10.223.156.26 with SMTP id f26mr1455382wrc.187.1496326461791; Thu, 01 Jun 2017 07:14:21 -0700 (PDT) X-Received: by 10.223.156.26 with SMTP id f26mr1455368wrc.187.1496326461592; Thu, 01 Jun 2017 07:14:21 -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 w18sm14240137wra.34.2017.06.01.07.14.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 01 Jun 2017 07:14:21 -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 v4 2/2] clk: bcm2835: Minimise clock jitter for PCM clock Message-ID: <9989244b-ca4d-9081-95d9-b24f51099222@raspberrypi.org> Date: Thu, 1 Jun 2017 15:14:22 +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-06-01_03:, , 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-1706010262 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 Reviewed-by: Eric Anholt Acked-by: Stefan Wahren --- drivers/clk/bcm/clk-bcm2835.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 49867d2..0bc56a0 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; @@ -1139,8 +1141,25 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, *prate = clk_hw_get_rate(parent); *div = bcm2835_clock_choose_div(hw, rate, *prate, true); - return bcm2835_clock_rate_from_divisor(clock, *prate, - *div); + *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); + + if (data->low_jitter && (*div & CM_DIV_FRAC_MASK)) { + unsigned long high, low; + u32 int_div = *div & ~CM_DIV_FRAC_MASK; + + high = bcm2835_clock_rate_from_divisor(clock, *prate, + int_div); + int_div += CM_DIV_FRAC_MASK + 1; + low = bcm2835_clock_rate_from_divisor(clock, *prate, + int_div); + + /* + * Return a value which is the maximum deviation + * below the ideal rate, for use as a metric. + */ + return *avgrate - max(*avgrate - low, high - *avgrate); + } + return *avgrate; } if (data->frac_bits) @@ -1167,6 +1186,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 +1198,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 +1223,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 +1239,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; } @@ -2025,6 +2048,7 @@ struct bcm2835_clk_desc { .int_bits = 12, .frac_bits = 12, .is_mash_clock = true, + .low_jitter = true, .tcnt_mux = 23), [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( .name = "pwm",