Received: by 2002:a05:6358:45e:b0:b5:b6eb:e1f9 with SMTP id 30csp3192305rwe; Mon, 29 Aug 2022 07:22:15 -0700 (PDT) X-Google-Smtp-Source: AA6agR4xlGAhDAo/hCie4gCuM9icAja+XZIqk3O+C3ktDt8+CZk4+1NK+ZXDeRKOLh/ghWDxAg7O X-Received: by 2002:a17:907:7b95:b0:72f:9c64:4061 with SMTP id ne21-20020a1709077b9500b0072f9c644061mr13723977ejc.351.1661782934992; Mon, 29 Aug 2022 07:22:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661782934; cv=none; d=google.com; s=arc-20160816; b=sMrmsx1+EOwZw+juZ0AHSYvOA1ntZj+7cZ9fedW/1QBs/p0uZw6dDkse2H811T0gFx 1k57Ffb2o0tEx5XB4RrCwP3ai2hPRuyC2XramnxbgwIMHgjnoIj9VCJ1NVzx9V/FwEIJ TWET6v1zIM0bGNjZwY50lcFxrTbsfooXGoFNVzUKup8xvRE3isAgapRxvVrg/0Sm1lIo 01ektFTq7AgZHtvhjFhHaJPsjmvYRa83XJ7B8w/9xxwH3lnaWpmc8n9tgg5B8nVYZgWs 0U7/bOYirioeq/J4vVZikBd9655LTqnxlxMjkF0ovM4v62+SOs+A8miP211kWrXtrT2K TUyA== 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 :message-id:date:subject:cc:to:from:dkim-signature:dkim-signature; bh=z8v8hIBgOnjJ8xhoD9EZ4lTuLGuumwo0j80Jmrs/kH4=; b=WIeVKtKcrbktl9JnUqV8lqa39jP3Bq1oEYMxlU70Ljud9mLoYIuvDNJkPcDBPTr6uD vg6Pz8wg4XENZJS02UO4h3cLm7PUDbC3E4eihxeSU940UHm44rIypbllIdI22bHW/9V2 Y4NG2wMI+pGIIuoHo07YDm01Ismj0/vZMWv6N1FCmsU41teYgRBb7aDi0bOeCbJtrnZw WAdRB+Vz9WUaCCKsoxNHr9DCjHfdEeAzss6fibtroJvMZz92TTKvSfKmMVcQFK64BUgT gYUbmpngo8+Lk8yMjRAHEG+p5C92r4UK4TA6LEdobuF8aYhZdr2fwiOcc0sB+wlGLlQv UuaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=EPsfEpnQ; dkim=neutral (no key) header.i=@suse.de; 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=suse.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oz44-20020a1709077dac00b0073117e47fe5si210411ejc.997.2022.08.29.07.21.44; Mon, 29 Aug 2022 07:22:14 -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=@suse.de header.s=susede2_rsa header.b=EPsfEpnQ; dkim=neutral (no key) header.i=@suse.de; 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=suse.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229908AbiH2NsD (ORCPT + 99 others); Mon, 29 Aug 2022 09:48:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229561AbiH2NsB (ORCPT ); Mon, 29 Aug 2022 09:48:01 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D1FE90827; Mon, 29 Aug 2022 06:48:00 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id BE0571F8BA; Mon, 29 Aug 2022 13:47:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1661780878; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=z8v8hIBgOnjJ8xhoD9EZ4lTuLGuumwo0j80Jmrs/kH4=; b=EPsfEpnQA/yt9w/uzZ4FSOlGTAlV1iEwXHSgwP2Gnebj+GpayeHwGcxfavOpmhKAYOwiuS dGBf6vLkrCQ1JguiTWnd8SPi+ItCnIyZXLceX7h+/fDW8on84c9nDEFt8m1S0W0Jo75+ur qShPfRDCBna5QtE6En8xANO4bq+ErtU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1661780878; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=z8v8hIBgOnjJ8xhoD9EZ4lTuLGuumwo0j80Jmrs/kH4=; b=QTJ+O6zePsWlRUsqsSSb39Cfna5YelOVy6xpC6fcEa4U0kXGcAiLL0tfvkQHnpOmD2Stm7 T4jdxCK4wyIUXmDQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8857C1352A; Mon, 29 Aug 2022 13:47:58 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Xne7II7DDGOJWgAAMHmgww (envelope-from ); Mon, 29 Aug 2022 13:47:58 +0000 From: "Ivan T. Ivanov" To: Michael Turquette , Stephen Boyd , Florian Fainelli , Ray Jui , Scott Branden , Broadcom internal kernel review list , Paul Walmsley , Palmer Dabbelt , Albert Ou , Maxime Ripard , Nicolas Saenz Julienne , "Ivan T. Ivanov" , Stefan Wahren Cc: Phil Elwell , kernel test robot , linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Subject: [PATCH v4] clk: bcm2835: Round UART input clock up Date: Mon, 29 Aug 2022 16:29:40 +0300 Message-Id: <20220829132943.144608-1-iivanov@suse.de> X-Mailer: git-send-email 2.35.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE 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 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 --- Changes since v3 * Rework 'scaler' calculation to avoid overflow * Update Phil Elwell email address Changes since v2 * Added more information in commit message * Changed hand crafted round function with the one form math.h Changes since v1 Make bcm2835_clock_round() static to fix following warning when compiling for riscv: drivers/clk/bcm/clk-bcm2835.c:997:15: warning: no previous prototype for 'bcm2835_clock_round' [-Wmissing-prototypes] Reported-by: kernel test robot 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 48a1eb9f2d55..26a5c9a0dd34 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_clock_round(unsigned long clk) +{ + unsigned long scaler; + unsigned long limit;; + + limit = clk / 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 ((clk + scaler - 1) / scaler % 1000 == 0) + clk = roundup(clk, scaler); + + return clk; +} + 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_clock_round(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.3