From patchwork Sat Oct 22 07:29:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 7729 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4242:0:0:0:0:0 with SMTP id s2csp1110125wrr; Sat, 22 Oct 2022 01:51:27 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5qyjYLCIhm7B2PXjuXltIaCwjjjBrEDoEHOis4VeL2oOTetx1FZGRGssYT67sf6amb7xHn X-Received: by 2002:a17:907:3da2:b0:78d:51c4:5b80 with SMTP id he34-20020a1709073da200b0078d51c45b80mr18890825ejc.716.1666428687077; Sat, 22 Oct 2022 01:51:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666428687; cv=none; d=google.com; s=arc-20160816; b=GEluvoEYwtKC1nHC8rNOGUyOHzkIdfA588M1L0xDQiQkwBucA7GvE9Qa6bxW1o1cly 8lWE69yOv1GpCDTn47sjhp13lm3qDgsXZf5Jzl6eK5Tq/Y05DnQyvTlpXe7jWFz/BZLI mP0rzaCySNXA3ioy/lDT5SnBFruUnqau7882E3KHmM29wsoNF6UHdapvJiuF3WZkLtYC hChQdxqeJJjy6i9IzAECFPps5Ez+6heZOAQzZX7EmDIaOOgGkrf/eA8uN1AGa8p2gc7G LT7/tBlxOVtMDOiOuTCDRWjmAo+Rf76Jt19sPe22mgk6fJyGNk1dMJQ5Mrx/w1IZKRcH JKmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=n9+3I6df9kyNB+5t+tXn/pRdnRxOnJ5haWzAoO44kfk=; b=NN8NOQTHtljaNdmTjc0E5YshtDkYmYgmeNBvps6o0NbvsH7cnVcn92s+prpeZqMZf8 IUlrly94kF5KI4hVN3lhGx9M5/8tOXPQfWPi5AMUcvf9e0W6X6kLKhS0F0Ucdzntn88P TORR3pM+6FDM2/IhSQ5kdwRfPaeJthAuRfzayk5la8/s0QO4Pc47OwL4pFd61AoXD+9b qY/Vg92J0++vT1f+xRCYaMX/wykU9zpHjDc/kiOC0Bv4RbU9yNbyM4e2TZKyQL2AdCZJ 8eDl3sfaZk04/hCsxbBOpVuVKKywku1FLRju4vAJRbi/2PkGWkfUmOsO+QvF+RPQSNsO F3RA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KLNden24; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x23-20020a170906135700b007470b52f94esi18669699ejb.199.2022.10.22.01.51.02; Sat, 22 Oct 2022 01:51:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KLNden24; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234802AbiJVIuP (ORCPT + 99 others); Sat, 22 Oct 2022 04:50:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234857AbiJVIsK (ORCPT ); Sat, 22 Oct 2022 04:48:10 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A309E9F36B; Sat, 22 Oct 2022 01:10:09 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 92E69B82E09; Sat, 22 Oct 2022 08:07:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E054BC433D6; Sat, 22 Oct 2022 08:07:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666426027; bh=5aitl3GEqiPMweqkIwJxZlH7zJawy7W/BWV5r8LclIQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KLNden249oiRfzhEgmAeeTfPfoig12h+TZIatSIXTtJGPGO4gzHTRoSE5JUytETj9 GJFcgEYh7XHNgC7f8IAy24dmH5L8AlFMEMi335G/FFYN10RcIYEG8hjdlN3zXo3kTB MBbyDzI+x9dXgR/Ft+E5HxP+dEVa+7QHup9vR4Tk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Phil Elwell , "Ivan T. Ivanov" , Stefan Wahren , Stephen Boyd , Sasha Levin Subject: [PATCH 5.19 695/717] clk: bcm2835: Round UART input clock up Date: Sat, 22 Oct 2022 09:29:34 +0200 Message-Id: <20221022072529.205233985@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221022072415.034382448@linuxfoundation.org> References: <20221022072415.034382448@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747377126784890905?= X-GMAIL-MSGID: =?utf-8?q?1747377126784890905?= From: Ivan T. Ivanov [ Upstream commit f690a4d7a8f66430662975511c86819dc9965bcc ] It was reported that RPi3[1] and RPi Zero 2W boards have issues with the Bluetooth. It turns out that when switching from initial to operation speed host and device no longer can talk each other because host uses incorrect UART baud rate. The UART driver used in this case is amba-pl011. Original fix, see below Github link[2], was inside pl011 module, but somehow it didn't look as the right place to fix. Beside that this original rounding function is not exactly perfect for all possible clock values. So I deiced to move the hack to the platform which actually need it. The UART clock is initialised to be as close to the requested frequency as possible without exceeding it. Now that there is a clock manager that returns the actual frequencies, an expected 48MHz clock is reported as 47999625. If the requested baud rate == requested clock/16, there is no headroom and the slight reduction in actual clock rate results in failure. If increasing a clock by less than 0.1% changes it from ..999.. to ..000.., round it up. [1] https://bugzilla.suse.com/show_bug.cgi?id=1188238 [2] https://github.com/raspberrypi/linux/commit/ab3f1b39537f6d3825b8873006fbe2fc5ff057b7 Cc: Phil Elwell Signed-off-by: Ivan T. Ivanov Reviewed-by: Stefan Wahren Link: https://lore.kernel.org/r/20220912081306.24662-1-iivanov@suse.de Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/bcm/clk-bcm2835.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index f1102b4c7e88..e74fe6219d14 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -502,6 +503,8 @@ struct bcm2835_clock_data { bool low_jitter; u32 tcnt_mux; + + bool round_up; }; struct bcm2835_gate_data { @@ -993,12 +996,34 @@ static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock return temp; } +static unsigned long bcm2835_round_rate(unsigned long rate) +{ + unsigned long scaler; + unsigned long limit; + + limit = rate / 100000; + + scaler = 1; + while (scaler < limit) + scaler *= 10; + + /* + * If increasing a clock by less than 0.1% changes it + * from ..999.. to ..000.., round up. + */ + if ((rate + scaler - 1) / scaler % 1000 == 0) + rate = roundup(rate, scaler); + + return rate; +} + static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, unsigned long parent_rate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; + unsigned long rate; u32 div; if (data->int_bits == 0 && data->frac_bits == 0) @@ -1006,7 +1031,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, div = cprman_read(cprman, data->div_reg); - return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + + if (data->round_up) + rate = bcm2835_round_rate(rate); + + return rate; } static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) @@ -2143,7 +2173,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_UARTDIV, .int_bits = 10, .frac_bits = 12, - .tcnt_mux = 28), + .tcnt_mux = 28, + .round_up = true), /* TV encoder clock. Only operating frequency is 108Mhz. */ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(