Received: by 2002:a05:6358:1087:b0:cb:c9d3:cd90 with SMTP id j7csp168370rwi; Wed, 12 Oct 2022 18:01:00 -0700 (PDT) X-Google-Smtp-Source: AMsMyM40ZMUJB1JENaVqDt2TDdaiMIRemqwO6Evlg4aW2UfBDIFaZ9LTeiv26dsxq0q9crQXmvDQ X-Received: by 2002:a17:902:db0f:b0:176:e70f:6277 with SMTP id m15-20020a170902db0f00b00176e70f6277mr32661156plx.13.1665622860731; Wed, 12 Oct 2022 18:01:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665622860; cv=none; d=google.com; s=arc-20160816; b=byq2vggfzaDg+S03LMAoPe1GtsCuWE+AJH4Y3alHtsKJmut9UIG4hPMwd7cfQ2PFdR BLS/cJ426oGIhzwiORkM/kbd/7SSSWKIZsvpQl/kOZiOyDSOPj6WazBIcfIW1zAfPuev mGjIN82dWbbbacaX3Lit6VGeUOqcusNZr+soKcgZzJRXVfkWjttNlCphdi4e9laY8sUd kKeMchQ2FKDyN27NOaSPhcHbKWm+g2PltOpBpKmQqaP7uRczjKPV29YGHy1SWTwLZDup xoPbqHGYpU7gaQsKZOp0BRoPo/FnMq+A1OmTIg70+tByLoi5oyE9p7TUGwkkSf6BAYZZ BQrA== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=DFCiKvY61xXHmVbUOQuxExYRWwxePgvWwtD82a5SViI=; b=EvR4LNotOzk23uAlekUmsGbKN8o/JScoY3FS+FCKgmKpaLR/cR+mcFC/T4r0q1lI/U cv/W5Ek5nYxhQV4QX0WCv20OlKdFOpi56P0a+bDrCHEOp3oyxjHxztunegWtMEzkTS8J TxyfqzLMdIpU02Gwcgly91/zinCRZt5JOEcpZz2N73DJC45NZzXWIV7vlZ2uFR3FTBT6 YKfuTnrAF32yqPrOerLrlLMbbsEdc67rj5WM3A4aDOgUYEDTRYNdKutqgFF+Dz7sO59E Rr2DMHLz7ecla3rASMTxklSu2TqUyaxWASQ+qHbPUXt8BV71TP7ePzfG6vsho73HlbnI Xf7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=m+gzeRu6; 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=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mw18-20020a17090b4d1200b001fe30008cd0si4265810pjb.166.2022.10.12.18.00.48; Wed, 12 Oct 2022 18:01:00 -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=@kernel.org header.s=k20201202 header.b=m+gzeRu6; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230246AbiJMAXO (ORCPT + 99 others); Wed, 12 Oct 2022 20:23:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229965AbiJMAWs (ORCPT ); Wed, 12 Oct 2022 20:22:48 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A910DCAEB; Wed, 12 Oct 2022 17:19:27 -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 dfw.source.kernel.org (Postfix) with ESMTPS id B58F4616D1; Thu, 13 Oct 2022 00:18:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4553C433D6; Thu, 13 Oct 2022 00:18:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1665620316; bh=IAIz3auuKzMB24HYDVw7FfWvbqNMcbnafFAOA3nTfwo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m+gzeRu6/BYlIicagaAxD7i+KAijP3VZFgOi5dG0uS9snys2xKeObsBRaoZz4vRxP Qlm8L+yRZX1DDxSIoPjJt55aOjCz67FSl79bnbCQ/VGCfXG4CjYaXhZ86Kx8RbMSma 0CLtJL0ivMEDvUgLFXdSWP0yZg2rSnZiYjQ6oMDrF46i2cswZZKk9UE7wO+CPDAzkJ lPu3AXO1VfoW8o8SOlEB9/H+l68JgVvQYpNnl5G4lUbwBZ3aica/ZGqDZje4+V95zA ecswWnU29lEYe7zSv3p0NlUIAyGZxjEBHgLsop8rxJPArOpqF5vdVPotSbHriI7KDc Dt4zPWKvxUZ6g== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: "Ivan T. Ivanov" , Phil Elwell , Stefan Wahren , Stephen Boyd , Sasha Levin , mturquette@baylibre.com, f.fainelli@gmail.com, rjui@broadcom.com, sbranden@broadcom.com, maxime@cerno.tech, linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH AUTOSEL 6.0 67/67] clk: bcm2835: Round UART input clock up Date: Wed, 12 Oct 2022 20:15:48 -0400 Message-Id: <20221013001554.1892206-67-sashal@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221013001554.1892206-1-sashal@kernel.org> References: <20221013001554.1892206-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 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 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 19de0e83b65d..3f2ce20d27ec 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 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( -- 2.35.1