Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp1900126rwr; Sat, 6 May 2023 00:44:39 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4gfseXVLHNS5LWAgPbGxrJ3IrDxO/ZmbFLabUKFKVgR7ZrAPXVzMPI+NGFQ/PsmKNefzvQ X-Received: by 2002:a05:6a20:e415:b0:f9:431e:a076 with SMTP id nh21-20020a056a20e41500b000f9431ea076mr4302718pzb.27.1683359078687; Sat, 06 May 2023 00:44:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683359078; cv=none; d=google.com; s=arc-20160816; b=meBdUBO6pgw2LBzcVFDEbOICHaboFFwsjEABeth1XZobsdAWzkC0Pr6sMUuMF3FOMv WVXMv4zAYUYMrJWedx1y9Cu2FzJB2mOn9k4y2CPjOiUI5hJtg+tx/VkD6MkZzaq38oVh Ts4tV0TnrNlol/ZiQjoo+7iQgAWlw+/nYN61AyIDfRyHsgM0uPE8sobFFaUBIs8lr6Z+ ZFMgw9QtmUuge+zqf3LBXdCQIcxNwoMmfBbg2eRdd0GPUAmupxtGQgozdt55ohbYy0LT VZgTZ2nJ7K3V5Ru/kM7TM/atbaRqhzRT05XZcETw96LOnYwEVRUIHafstmqpTF98svfL juZA== 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=TFyKS6D3H171iwuZty2TjCeanFkTzGt+OOVglDDX5lY=; b=lTxAB/vARj8WL5NI4Az4N9gBRNH0UrKuqcNJrzdmUrBjGZVo7n72RvHsQmkrdbzNZZ jAXS7lPdNJ8qvnEaVS2NrQ8D2eIzsKFViOji8Kvrk6uTNbMCfrnzKahkFop1xAgvE/T7 8r9zcRDHJirOEyVLlP06IkFr3RaSczQiIcISfIb4POunojb+OkN6EAIDf5xpKYE6DA91 qJpWgBhYNlSP9kwZLO5cTywvLLfiSKBr12EqBszMUJc/4cYGyQ+/WzPaejOsVhOapzYn vFQ1sJ0Tcftbh90VLdG7DepUUxGV2xZ2sxnUus1qNGJhEecHbFkpG8Nx2GhNAJMRZC96 7iaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=Mg5OR+cK; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j22-20020a633c16000000b0051b47fe799fsi3597031pga.557.2023.05.06.00.44.25; Sat, 06 May 2023 00:44:38 -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=@gmail.com header.s=20221208 header.b=Mg5OR+cK; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231343AbjEFHdW (ORCPT + 99 others); Sat, 6 May 2023 03:33:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231286AbjEFHcr (ORCPT ); Sat, 6 May 2023 03:32:47 -0400 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6E028687; Sat, 6 May 2023 00:32:26 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-3075e802738so2162569f8f.1; Sat, 06 May 2023 00:32:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683358342; x=1685950342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TFyKS6D3H171iwuZty2TjCeanFkTzGt+OOVglDDX5lY=; b=Mg5OR+cKNABnP1ZeBsKFUI8l3cCluLuDyl9SSr0zjJQ5CI19lQxOkeGFskpN5Zvryc RufGl3taIclVQ2EALggAzFJQa7gHvdzZL/xvdOgJQSgI7P1/sKSmRX/QQttUzzZMcJTP cdJjhAol6Tgp8a6WtpodlXbSQhfA8R2pg9bMQVVK/s2QYIbDggbifkt54oeWmKPPDw7D b0Gp+lucurerEdp45K+aoMnuZysGZ9QH4hNzfQEF5wn6Vcq38eNQDUwGC5E12ZaNm7r5 5c9UiI1BP96OYmO8kbIqVYVrRSpm9v79XR2LTi8LEt6gGH4dC+RqMZoSkU9GL4f/QZOY 9JLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683358342; x=1685950342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TFyKS6D3H171iwuZty2TjCeanFkTzGt+OOVglDDX5lY=; b=Dud/vAhxcIjpDWybcAbHAYyjqf0MvdTb1dmEhMnVLDxpYpk7eW1z+xQM0ddb2SS688 qKawnTmmB3tNQB2F9srTsrl5Ql6isjwwtydYEPre4gLPw6xZlWlKg6hPDZF/9cyNMDXr 2kUaq6TtHNlpk1DIsUFPMljKm+cBy22HVZZwMrQ4Dzk+YgXdrXNItQ2f4imnMe8v0Ypl OVAbc9mJVvOUtnZ0EmV+6mUHOYs44wWpb3q4g98jp4C3rkUQr7MDmLL0XsdX/Hhy/1xY X59GW9cIVt/mYMWPqjJKeQ1EqlKUqWGcutRxy8lCx1TZgrrzo1vRbH4zRaRMYQr/iIR/ +Fnw== X-Gm-Message-State: AC+VfDxGlETF1M11sMCspEI88A5au1yROIcOfnJTNW5OmV+OU2GZrlbx /VA+MYKRPovNvklOYzyX3Qw= X-Received: by 2002:adf:e943:0:b0:306:2cf5:79dc with SMTP id m3-20020adfe943000000b003062cf579dcmr3428928wrn.35.1683358342158; Sat, 06 May 2023 00:32:22 -0700 (PDT) Received: from localhost.localdomain ([176.221.215.212]) by smtp.gmail.com with ESMTPSA id q14-20020a7bce8e000000b003f182a10106sm10071944wmj.8.2023.05.06.00.32.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 May 2023 00:32:21 -0700 (PDT) From: Maksim Kiselev To: Andre Przywara Cc: Icenowy Zheng , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Cristian Ciocaltea , Heiko Stuebner , Maksim Kiselev , Maxime Ripard , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Subject: [PATCH v2 3/6] spi: sun6i: add quirk for in-controller clock divider Date: Sat, 6 May 2023 10:30:11 +0300 Message-Id: <20230506073018.1411583-4-bigunclemax@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230506073018.1411583-1-bigunclemax@gmail.com> References: <20230506073018.1411583-1-bigunclemax@gmail.com> 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,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,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 From: Icenowy Zheng Previously SPI controllers in Allwinner SoCs has a clock divider inside. However now the clock divider is removed and to set the transfer clock rate it's only needed to set the SPI module clock to the target value. Add a quirk for this kind of SPI controllers. Signed-off-by: Icenowy Zheng --- drivers/spi/spi-sun6i.c | 68 +++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 01a01cd86db5..82523011a3a5 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -87,6 +87,7 @@ struct sun6i_spi_cfg { unsigned long fifo_depth; + bool has_clk_ctl; }; struct sun6i_spi { @@ -260,7 +261,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, struct spi_transfer *tfr) { struct sun6i_spi *sspi = spi_master_get_devdata(master); - unsigned int mclk_rate, div, div_cdr1, div_cdr2, timeout; + unsigned int div, div_cdr1, div_cdr2, timeout; unsigned int start, end, tx_time; unsigned int trig_level; unsigned int tx_len = 0, rx_len = 0; @@ -350,39 +351,44 @@ static int sun6i_spi_transfer_one(struct spi_master *master, sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); - /* Ensure that we have a parent clock fast enough */ - mclk_rate = clk_get_rate(sspi->mclk); - if (mclk_rate < (2 * tfr->speed_hz)) { - clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); - mclk_rate = clk_get_rate(sspi->mclk); - } + if (sspi->cfg->has_clk_ctl) { + unsigned int mclk_rate = clk_get_rate(sspi->mclk); + /* Ensure that we have a parent clock fast enough */ + if (mclk_rate < (2 * tfr->speed_hz)) { + clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); + mclk_rate = clk_get_rate(sspi->mclk); + } - /* - * Setup clock divider. - * - * We have two choices there. Either we can use the clock - * divide rate 1, which is calculated thanks to this formula: - * SPI_CLK = MOD_CLK / (2 ^ cdr) - * Or we can use CDR2, which is calculated with the formula: - * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) - * Wether we use the former or the latter is set through the - * DRS bit. - * - * First try CDR2, and if we can't reach the expected - * frequency, fall back to CDR1. - */ - div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); - div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); - if (div_cdr2 <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { - reg = SUN6I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN6I_CLK_CTL_DRS; - tfr->effective_speed_hz = mclk_rate / (2 * div_cdr2); + /* + * Setup clock divider. + * + * We have two choices there. Either we can use the clock + * divide rate 1, which is calculated thanks to this formula: + * SPI_CLK = MOD_CLK / (2 ^ cdr) + * Or we can use CDR2, which is calculated with the formula: + * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) + * Wether we use the former or the latter is set through the + * DRS bit. + * + * First try CDR2, and if we can't reach the expected + * frequency, fall back to CDR1. + */ + div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); + div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); + if (div_cdr2 <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { + reg = SUN6I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN6I_CLK_CTL_DRS; + tfr->effective_speed_hz = mclk_rate / (2 * div_cdr2); + } else { + div = min(SUN6I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); + reg = SUN6I_CLK_CTL_CDR1(div); + tfr->effective_speed_hz = mclk_rate / (1 << div); + } + + sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); } else { - div = min(SUN6I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); - reg = SUN6I_CLK_CTL_CDR1(div); - tfr->effective_speed_hz = mclk_rate / (1 << div); + clk_set_rate(sspi->mclk, tfr->speed_hz); } - sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); /* Finally enable the bus - doing so before might raise SCK to HIGH */ reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); reg |= SUN6I_GBL_CTL_BUS_ENABLE; @@ -701,10 +707,12 @@ static void sun6i_spi_remove(struct platform_device *pdev) static const struct sun6i_spi_cfg sun6i_a31_spi_cfg = { .fifo_depth = SUN6I_FIFO_DEPTH, + .has_clk_ctl = true, }; static const struct sun6i_spi_cfg sun8i_h3_spi_cfg = { .fifo_depth = SUN8I_FIFO_DEPTH, + .has_clk_ctl = true, }; static const struct of_device_id sun6i_spi_match[] = { -- 2.39.2