From patchwork Wed May 31 09:18:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Elwell X-Patchwork-Id: 9756351 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 3B33860360 for ; Wed, 31 May 2017 09:18:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3212F27F54 for ; Wed, 31 May 2017 09:18:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2657C28405; Wed, 31 May 2017 09:18:52 +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 B3E2327F54 for ; Wed, 31 May 2017 09:18:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751200AbdEaJSk (ORCPT ); Wed, 31 May 2017 05:18:40 -0400 Received: from mx08-00252a01.pphosted.com ([91.207.212.211]:60548 "EHLO mx08-00252a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751169AbdEaJSf (ORCPT ); Wed, 31 May 2017 05:18:35 -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 v4V9IKRT024439 for ; Wed, 31 May 2017 10:18:34 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.org; h=subject : from : to : references : message-id : date : mime-version : in-reply-to : content-type : content-transfer-encoding; s=pp; bh=PAYnuJ3gQKTZZHKa7Wg8ZHc/wW/UIm1S4qgp32tyrdU=; b=7htrwKaMifDJOxmhkLLIra3nXJflUG+g5PL0M3bZlEm2rA7YmUVi967N3qD1mVFDZvf0 GGzr96G0urXIFKnEN5FEhlXF7OzelB/KXYoBEeHGibX+Z76q0ZctxSW4n47/hPsI9N9b +A7kHaZAPEB8sxIqIFF3WFCfJGCTI2wxegL40kB/SPil0yAh/2LkoJIzT2EL3CwFtt8p N06nU8oXfGa6ianqE8x1ICTN5SeM/QjUa0hdWFf0nb91QhbhdWoigXOT2RoCT+zNqYac d0RqiKlsqgUOCwrr7vrB0wELeWY0hZSCbd2WN3z3q72+1h3QxCdRObSKhHD5691ab92I Sw== Received: from mail-wr0-f200.google.com (mail-wr0-f200.google.com [209.85.128.200]) by mx08-00252a01.pphosted.com with ESMTP id 2apwxeswxm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK) for ; Wed, 31 May 2017 10:18:34 +0100 Received: by mail-wr0-f200.google.com with SMTP id g36so1423339wrg.4 for ; Wed, 31 May 2017 02:18:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi-org.20150623.gappssmtp.com; s=20150623; h=subject:from:to:references:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=PAYnuJ3gQKTZZHKa7Wg8ZHc/wW/UIm1S4qgp32tyrdU=; b=MnhEjv7fYgxOOnKAhWX3qWi9sGs0vxs59drKKurGSS7xCchbrO1cl2VWEj4W+2yYl5 FeJmoeNG6RYtgZ37rjZMpC5w8QVwaKGyRAW+40bRwNY/RXvBdN/rt40EjcCSrNk/E3JB aTxlcB6VX3m9+TeLwXyGMjZnGipXDlxdztc5xBCYLYZlcwszfQPOhDeKtY9TwmZuKLbV 44730d6chuaePajpv2oEjh+Gz42k9RXNylybgJnRTp+hbyRscAZ5HbxRVi5KHcnB3ol4 1s3nR1IEIoAwv55ExzNSVFnWCkOilksfkaNIVGrWNfvRiKRdbAhdFAbu8rrkSGaDnFSn PMjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=PAYnuJ3gQKTZZHKa7Wg8ZHc/wW/UIm1S4qgp32tyrdU=; b=efGgp/k7Lor1Q/iJnHnjy4I7dvLKDXWJlFeak9+P8qjgDvaojWJvEt0jWWYY39bDDP R+RclxO86Llct/sNTv1uJtn2gDw7x6WoYrSebZCqQdriRD2pz6MFHgKC/m7kwwkKPybI 9H1w7wMF1k74pATiK0k5O1005+DxCbZmi4S59pY/IoWDW94LUjVrBjAyeSx2lTOBai7d 0tUeDNe3mvOipz5afKqvVhQZIAZ5LPQYLM28gPwc1oJVI+ViVs/YiXDCzm1tnSTJBMx1 zLeV7hjrfZLZ2BU4HHVTvNIYo/bMaq4pgeiIk2Fc0nvj32oDTmp64VayJHHsVveu4o5C 0E0g== X-Gm-Message-State: AODbwcAa8G78yPP+m5QetO/BGZmzkXK6CEzwNRcXDnQ/CXuUgIQ+Fgn5 vR4Ry2oGEWsSVCWCY43/7bTiclXbKQB5iUhwLamQbyPdbW955+6Hp9iBWMON4VwjdkreQUGUFoX zbsbK4jXh6BM= X-Received: by 10.28.107.131 with SMTP id a3mr1422817wmi.55.1496222313179; Wed, 31 May 2017 02:18:33 -0700 (PDT) X-Received: by 10.28.107.131 with SMTP id a3mr1422808wmi.55.1496222312987; Wed, 31 May 2017 02:18:32 -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 b81sm21799362wmf.7.2017.05.31.02.18.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 May 2017 02:18:32 -0700 (PDT) Subject: [PATCH v2 2/2] clk: bcm2835: Minimise clock jitter for PCM clock From: Phil Elwell 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 References: Message-ID: Date: Wed, 31 May 2017 10:18:33 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 In-Reply-To: Content-Language: en-GB X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-05-31_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-1705310174 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 | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 81ecd4c..c7ee951 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,34 @@ 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 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. + */ + 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 +1192,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 +1204,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 +1229,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 +1245,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 +2054,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",