lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Mon, 1 Aug 2022 08:21:48 +0200
From:   Birger Koblitz <mail@...ger-koblitz.de>
To:     Martin Blumenstingl <martin.blumenstingl@...glemail.com>
Cc:     linux-spi@...r.kernel.org, linux-kernel@...r.kernel.org,
        bert@...t.com, sander@...nheule.net
Subject: [PATCH 6/7] spi: realtek-rtl: add support to configure bus speed

The available datasheets for the RTL8381M and RTL9301 state
that the SPI frequency is 50MHz. Set this maximum spi frequency
unless specified otherwise in the device node.

The SPI device on the RTL83xx and RTL93xx SoCs is also accessed
independently by dedicated SPI-NOR (RTL83xx/RTL93xx) and
SPI-NAND (RTL93xx) hardware, which can perform DMA transfers via
the SPI device.
While these devices can set chip selects, they cannot configure
the SPI frequency for a transfer. The clock divider is therefore
configured once during device probe and not changed for individual
transfers as the SPI frequency is a bus property on this platform.

The clock divider setting can take values 0-7, the actual divider
then is:
clock_divider = 2 * (divider_setting + 1)
allowing for clock dividers with values 2-16. The clock used to
derive the SPI clock on the Realtek SoCs is the Lexra bus clock.
When a clock is provided in the SPI device node, we set a clock
divider corresponding to the maximum spi frequency.

Signed-off-by: Birger Koblitz <mail@...ger-koblitz.de>
---
  drivers/spi/spi-realtek-rtl.c | 28 +++++++++++++++++++++++++++-
  1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-realtek-rtl.c b/drivers/spi/spi-realtek-rtl.c
index 21c0dc16c8cc..91aa7a0348a2 100644
--- a/drivers/spi/spi-realtek-rtl.c
+++ b/drivers/spi/spi-realtek-rtl.c
@@ -5,15 +5,21 @@
  #include <linux/mod_devicetable.h>
  #include <linux/spi/spi.h>
  #include <linux/property.h>
+#include <linux/of.h>
+#include <linux/clk.h>

  struct rtspi {
  	void __iomem *base;
  	u32 dev_flags;
  	u32 cs_all;
+	struct clk *clk;
+	int frequency_div;
  };

  /* SPI Flash Configuration Register */
  #define RTL_SPI_SFCR			0x00
+#define RTL_SPI_SFCR_CLK_DIV_BIT	29
+#define RTL_SPI_SFCR_CLK_DIV_MASK	~(0x7 << RTL_SPI_SFCR_CLK_DIV_BIT)
  #define RTL_SPI_SFCR_RBO		BIT(28)
  #define RTL_SPI_SFCR_WBO		BIT(27)

@@ -208,9 +214,14 @@ static void init_hw(struct rtspi *rtspi)
  {
  	u32 value;

-	/* Turn on big-endian byte ordering */
+	/* Turn on big-endian byte ordering and set clock divider */
  	value = readl(REG(RTL_SPI_SFCR));
  	value |= RTL_SPI_SFCR_RBO | RTL_SPI_SFCR_WBO;
+	if (rtspi->frequency_div >= 0) {
+		value &= RTL_SPI_SFCR_CLK_DIV_MASK;
+		value |= rtspi->frequency_div << RTL_SPI_SFCR_CLK_DIV_BIT;
+	}
+
  	writel(value, REG(RTL_SPI_SFCR));

  	/* Disable CS0-CS3, enable CS */
@@ -222,6 +233,7 @@ static int realtek_rtl_spi_probe(struct platform_device *pdev)
  {
  	struct spi_controller *ctrl;
  	struct rtspi *rtspi;
+	u32 spi_clk;
  	int err;

  	ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*rtspi));
@@ -239,6 +251,20 @@ static int realtek_rtl_spi_probe(struct platform_device *pdev)
  		return -ENOMEM;
  	}

+	if (of_property_read_u32(pdev->dev.of_node, "spi-max-frequency",
+				 &ctrl->max_speed_hz))
+		ctrl->max_speed_hz = 50000000; /* 50MHz */
+
+	rtspi->frequency_div = -1;
+	rtspi->clk = devm_clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(rtspi->clk)) {
+		spi_clk = clk_get_rate(rtspi->clk);
+		rtspi->frequency_div = DIV_ROUND_UP(spi_clk, ctrl->max_speed_hz);
+		rtspi->frequency_div = (rtspi->frequency_div / 2) - 1;
+		if (rtspi->frequency_div > 0x7)
+			rtspi->frequency_div = 0x7;
+	}
+
  	init_hw(rtspi);

  	ctrl->dev.of_node = pdev->dev.of_node;
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ