From patchwork Thu Jun 1 09:10:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Elwell X-Patchwork-Id: 9758913 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 9ADEF60360 for ; Thu, 1 Jun 2017 09:10:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 921F628517 for ; Thu, 1 Jun 2017 09:10:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8694F28515; Thu, 1 Jun 2017 09:10:58 +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 D32C228508 for ; Thu, 1 Jun 2017 09:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751589AbdFAJKv (ORCPT ); Thu, 1 Jun 2017 05:10:51 -0400 Received: from mx08-00252a01.pphosted.com ([91.207.212.211]:58844 "EHLO mx08-00252a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751587AbdFAJKu (ORCPT ); Thu, 1 Jun 2017 05:10:50 -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 v5199Vx0009819 for ; Thu, 1 Jun 2017 10:10:49 +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=8TxH0MLVHkToh8lInkFPcqAww0mqxCJmTY0XLj9XFRg=; b=oget47G8KBBHawRlw8eTwpLYN5I0WlQhM28HLHpC8dE+6q+rF4/sL4g1dZxAS6KZJkfM 3oJR5JH0zyukc8p9yQ74WzI16tjFIPsm6W2BDeZyWwF+spqAOSTAFgDP9cIzUqBOkl3F CTy5cuROrgVfbn/PcHJV2+B/+FmFB0kD4EcjucI5eAqVBPbR7fOUdAzBbg+qvjsmFjYx RxnwvaJSIQDlHVWg04Klx+JzIy2ta7q7pVie/aBB3wIFHz7OA+lbnsh5DVYioopNUa0g Hu+7CzRppr3LSC/O1bqb4tjRl62OIxXeSg5jLaeGzOWeNelBFPaEUhGSOGf9O8aLaJVi BQ== Received: from mail-wm0-f72.google.com (mail-wm0-f72.google.com [74.125.82.72]) by mx08-00252a01.pphosted.com with ESMTP id 2apwxetcsu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK) for ; Thu, 01 Jun 2017 10:10:48 +0100 Received: by mail-wm0-f72.google.com with SMTP id g13so8557341wmd.9 for ; Thu, 01 Jun 2017 02:10:48 -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=8TxH0MLVHkToh8lInkFPcqAww0mqxCJmTY0XLj9XFRg=; b=Cw0WM+AMj+7noeoLzLkxmqgeiny3V+OsRYVcdK8+b2jYx3njK6a/Uh1by1k2myIX/g NI9g6RZlfcoRLe7K3zkCTYdquJ52bXGfPqGnVS8kVGSwg1IyXH+E+L7TrgnnZLy7OmVm JmKD/DZUXN7oPMedi4musompTDovoapS3NC1AJx2cfiYK2jiHfA1pujT4BKSgd6EcbKD p16VUWoJRaczJ4gbt9LFogkYA0v4iEfHB+X56TztVdIpprWrpjGLr40Ddysuh4YGfrbw WOJ2TLyiAXwlvkXzfAUqc34VvUWLj3jbX6XR+Dltx5bI1V835zLALuWF18VTiuM2QTl3 /U7g== 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=8TxH0MLVHkToh8lInkFPcqAww0mqxCJmTY0XLj9XFRg=; b=KUtm88n62zXQNp1AaWbJnEhArrAGzD2H/58UCAKR9w9znCQR2ZBU8I7sD/3Us58B9a /ZNSqfWWg2JIp+OJDwXUTVphYnOaFlPa6JpLdzutqMtrzO7YTzGyKZhDf/oPqL1kO9x7 MZDilh9KjoQ+wK/rojvAS5oavTarYl0pJ/Vd7j5z2akQddeGPz9aGn5OQnXz2tajm6Op 95tDOoL6Zf8S273e5z8azzzvBj24JvDG2sOaFZovy43Jn+Wtu14knKhQr7MXdMcczyvl tYjs6XjLsT+22QrMGfGKhoOGY3g//lB0w22QWE/PstXd+HLhDOGlRUJ3bNaXul1GXF04 DtIA== X-Gm-Message-State: AODbwcBWXbuCD/uKLhMyEeIDmxVBOqbyrTvQVxbxlPccrLbsdsLpiwd/ pnG+cBCVh+M5l4NFYKUGr7fNWh0MUyVC6rq4F5M9chF80gpRql7dGG43uC4nq8ayOAXEZXcJ0aJ tDQm7axdEkqg= X-Received: by 10.28.175.136 with SMTP id y130mr921255wme.112.1496308247755; Thu, 01 Jun 2017 02:10:47 -0700 (PDT) X-Received: by 10.28.175.136 with SMTP id y130mr921238wme.112.1496308247574; Thu, 01 Jun 2017 02:10:47 -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 53sm27217773wrt.36.2017.06.01.02.10.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 01 Jun 2017 02:10:47 -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 v3 2/2] clk: bcm2835: Minimise clock jitter for PCM clock Message-ID: Date: Thu, 1 Jun 2017 10:10:48 +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_02:, , 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-1706010168 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 --- 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 81ecd4c..5f4ce44 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",