* [PATCH v1 0/2] add support for Meson A1 SPI Flash Controller
@ 2023-03-22 15:04 Martin Kurbanov
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
2023-03-22 15:04 ` [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller Martin Kurbanov
0 siblings, 2 replies; 8+ messages in thread
From: Martin Kurbanov @ 2023-03-22 15:04 UTC (permalink / raw)
To: Mark Brown, Rob Herring, Krzysztof Kozlowski, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel, Martin Kurbanov
This patchset introduces DT bindings and driver for the Amlogic Meson A1
SPI flash controller (A113L family).
The existing spi-meson-spifc driver is incompatible with the A1 SPIFC
at all.
The implementation has been tested on the Amlogic A113L SoC based device
connected with ESMT F50L1G41LB spinand flash.
This patchset has dependencies on the A1 clock series which is still
under review [1].
Links:
[1] https://lore.kernel.org/all/20230321193014.26349-1-ddrokosov@sberdevices.ru/
Martin Kurbanov (2):
dt-bindings: spi: add binding for meson-spifc-a1
spi: add support for Meson A1 SPI Flash Controller
.../bindings/spi/amlogic,meson-a1-spifc.yaml | 42 ++
drivers/spi/Kconfig | 7 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-meson-spifc-a1.c | 444 ++++++++++++++++++
4 files changed, 494 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
create mode 100644 drivers/spi/spi-meson-spifc-a1.c
--
2.40.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1
2023-03-22 15:04 [PATCH v1 0/2] add support for Meson A1 SPI Flash Controller Martin Kurbanov
@ 2023-03-22 15:04 ` Martin Kurbanov
2023-03-22 15:55 ` Neil Armstrong
` (2 more replies)
2023-03-22 15:04 ` [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller Martin Kurbanov
1 sibling, 3 replies; 8+ messages in thread
From: Martin Kurbanov @ 2023-03-22 15:04 UTC (permalink / raw)
To: Mark Brown, Rob Herring, Krzysztof Kozlowski, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel, Martin Kurbanov
Add YAML devicetree binding for Amlogic Meson A113L (A1 family)
SPIFC Driver.
Signed-off-by: Martin Kurbanov <mmkurbanov@sberdevices.ru>
---
.../bindings/spi/amlogic,meson-a1-spifc.yaml | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
new file mode 100644
index 000000000000..5f84063b01f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/amlogic,meson-a1-spifc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Meson A113L SPI Flash Controller
+
+maintainers:
+ - Martin Kurbanov <mmkurbanov@sberdevices.ru>
+
+allOf:
+ - $ref: spi-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - amlogic,meson-a1-spifc
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/amlogic,a1-clkc.h>
+ spi@fd000400 {
+ compatible = "amlogic,meson-a1-spifc";
+ reg = <0xfd000400 0x290>;
+ clocks = <&clkc_periphs CLKID_SPIFC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.40.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller
2023-03-22 15:04 [PATCH v1 0/2] add support for Meson A1 SPI Flash Controller Martin Kurbanov
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
@ 2023-03-22 15:04 ` Martin Kurbanov
2023-03-22 16:00 ` Neil Armstrong
2023-03-22 20:50 ` kernel test robot
1 sibling, 2 replies; 8+ messages in thread
From: Martin Kurbanov @ 2023-03-22 15:04 UTC (permalink / raw)
To: Mark Brown, Rob Herring, Krzysztof Kozlowski, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel, Martin Kurbanov
This is a driver for the Amlogic Meson SPI flash controller support
on A113L SoC.
Signed-off-by: Martin Kurbanov <mmkurbanov@sberdevices.ru>
---
drivers/spi/Kconfig | 7 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-meson-spifc-a1.c | 444 +++++++++++++++++++++++++++++++
3 files changed, 452 insertions(+)
create mode 100644 drivers/spi/spi-meson-spifc-a1.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3b1c0878bb85..a12452bd1e0c 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -582,6 +582,13 @@ config SPI_MESON_SPIFC
This enables master mode support for the SPIFC (SPI flash
controller) available in Amlogic Meson SoCs.
+config SPI_MESON_SPIFC_A1
+ tristate "Amlogic Meson A113L SPIFC controller"
+ depends on ARCH_MESON || COMPILE_TEST
+ help
+ This enables master mode support for the SPIFC (SPI flash
+ controller) available in Amlogic Meson A113L (A1 family) SoC.
+
config SPI_MICROCHIP_CORE
tristate "Microchip FPGA SPI controllers"
depends on SPI_MASTER
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index be9ba40ef8d0..702053970967 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o
obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
+obj-$(CONFIG_SPI_MESON_SPIFC_A1) += spi-meson-spifc-a1.o
obj-$(CONFIG_SPI_MICROCHIP_CORE) += spi-microchip-core.o
obj-$(CONFIG_SPI_MICROCHIP_CORE_QSPI) += spi-microchip-core-qspi.o
obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
diff --git a/drivers/spi/spi-meson-spifc-a1.c b/drivers/spi/spi-meson-spifc-a1.c
new file mode 100644
index 000000000000..213c8b692675
--- /dev/null
+++ b/drivers/spi/spi-meson-spifc-a1.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Amlogic Meson A113L SPI flash controller (SPIFC)
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ *
+ * Author: Martin Kurbanov <mmkurbanov@sberdevices.ru>
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+#include <linux/types.h>
+
+#define A1_SPIFC_AHB_CTRL_REG 0x0
+#define A1_SPIFC_AHB_BUS_EN BIT(31)
+
+#define A1_SPIFC_USER_CTRL0_REG 0x200
+#define A1_SPIFC_USER_REQUEST_ENABLE BIT(31)
+#define A1_SPIFC_USER_REQUEST_FINISH BIT(30)
+#define A1_SPIFC_USER_DATA_UPDATED BIT(0)
+
+#define A1_SPIFC_USER_CTRL1_REG 0x204
+#define A1_SPIFC_USER_CMD_ENABLE BIT(30)
+#define A1_SPIFC_USER_CMD_MODE GENMASK(29, 28)
+#define A1_SPIFC_USER_CMD_CODE GENMASK(27, 20)
+#define A1_SPIFC_USER_ADDR_ENABLE BIT(19)
+#define A1_SPIFC_USER_ADDR_MODE GENMASK(18, 17)
+#define A1_SPIFC_USER_ADDR_BYTES GENMASK(16, 15)
+#define A1_SPIFC_USER_DOUT_ENABLE BIT(14)
+#define A1_SPIFC_USER_DOUT_MODE GENMASK(11, 10)
+#define A1_SPIFC_USER_DOUT_BYTES GENMASK(9, 0)
+
+#define A1_SPIFC_USER_CTRL2_REG 0x208
+#define A1_SPIFC_USER_DUMMY_ENABLE BIT(31)
+#define A1_SPIFC_USER_DUMMY_MODE GENMASK(30, 29)
+#define A1_SPIFC_USER_DUMMY_CLK_SYCLES GENMASK(28, 23)
+
+#define A1_SPIFC_USER_CTRL3_REG 0x20c
+#define A1_SPIFC_USER_DIN_ENABLE BIT(31)
+#define A1_SPIFC_USER_DIN_MODE GENMASK(28, 27)
+#define A1_SPIFC_USER_DIN_BYTES GENMASK(25, 16)
+
+#define A1_SPIFC_USER_ADDR_REG 0x210
+
+#define A1_SPIFC_AHB_REQ_CTRL_REG 0x214
+#define A1_SPIFC_AHB_REQ_ENABLE BIT(31)
+
+#define A1_SPIFC_ACTIMING0_REG (0x0088 << 2)
+#define A1_SPIFC_TSLCH GENMASK(31, 30)
+#define A1_SPIFC_TCLSH GENMASK(29, 28)
+#define A1_SPIFC_TSHWL GENMASK(20, 16)
+#define A1_SPIFC_TSHSL2 GENMASK(15, 12)
+#define A1_SPIFC_TSHSL1 GENMASK(11, 8)
+#define A1_SPIFC_TWHSL GENMASK(7, 0)
+
+#define A1_SPIFC_DBUF_CTRL_REG 0x240
+#define A1_SPIFC_DBUF_DIR BIT(31)
+#define A1_SPIFC_DBUF_AUTO_UPDATE_ADDR BIT(30)
+#define A1_SPIFC_DBUF_ADDR GENMASK(7, 0)
+
+#define A1_SPIFC_DBUF_DATA_REG 0x244
+
+#define A1_SPIFC_USER_DBUF_ADDR_REG 0x248
+
+#define A1_SPIFC_BUFFER_SIZE 512
+
+#define A1_SPIFC_MAX_HZ 200000000
+#define A1_SPIFC_MIN_HZ 1000000
+
+#define A1_SPIFC_USER_CMD(op) ( \
+ A1_SPIFC_USER_CMD_ENABLE | \
+ FIELD_PREP(A1_SPIFC_USER_CMD_CODE, (op)->cmd.opcode) | \
+ FIELD_PREP(A1_SPIFC_USER_CMD_MODE, ilog2((op)->cmd.buswidth)))
+
+#define A1_SPIFC_USER_ADDR(op) ( \
+ A1_SPIFC_USER_ADDR_ENABLE | \
+ FIELD_PREP(A1_SPIFC_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \
+ FIELD_PREP(A1_SPIFC_USER_ADDR_BYTES, (op)->addr.nbytes - 1))
+
+#define A1_SPIFC_USER_DUMMY(op) ( \
+ A1_SPIFC_USER_DUMMY_ENABLE | \
+ FIELD_PREP(A1_SPIFC_USER_DUMMY_MODE, ilog2((op)->dummy.buswidth)) | \
+ FIELD_PREP(A1_SPIFC_USER_DUMMY_CLK_SYCLES, (op)->dummy.nbytes << 3))
+
+#define A1_SPIFC_TSLCH_VAL FIELD_PREP(A1_SPIFC_TSLCH, 1)
+#define A1_SPIFC_TCLSH_VAL FIELD_PREP(A1_SPIFC_TCLSH, 1)
+#define A1_SPIFC_TSHWL_VAL FIELD_PREP(A1_SPIFC_TSHWL, 7)
+#define A1_SPIFC_TSHSL2_VAL FIELD_PREP(A1_SPIFC_TSHSL2, 7)
+#define A1_SPIFC_TSHSL1_VAL FIELD_PREP(A1_SPIFC_TSHSL1, 7)
+#define A1_SPIFC_TWHSL_VAL FIELD_PREP(A1_SPIFC_TWHSL, 2)
+#define A1_SPIFC_ACTIMING0_VAL (A1_SPIFC_TSLCH_VAL | A1_SPIFC_TCLSH_VAL | \
+ A1_SPIFC_TSHWL_VAL | A1_SPIFC_TSHSL2_VAL | \
+ A1_SPIFC_TSHSL1_VAL | A1_SPIFC_TWHSL_VAL)
+
+struct a1_spifc {
+ struct spi_controller *ctrl;
+ struct clk *clk;
+ struct device *dev;
+ void __iomem *base;
+};
+
+static int a1_spifc_request(struct a1_spifc *spifc, bool read)
+{
+ u32 mask = A1_SPIFC_USER_REQUEST_FINISH |
+ (read ? A1_SPIFC_USER_DATA_UPDATED : 0);
+ u32 val;
+
+ writel(A1_SPIFC_USER_REQUEST_ENABLE,
+ spifc->base + A1_SPIFC_USER_CTRL0_REG);
+
+ return readl_poll_timeout(spifc->base + A1_SPIFC_USER_CTRL0_REG,
+ val, (val & mask) == mask, 0,
+ 200 * USEC_PER_MSEC);
+}
+
+static void a1_spifc_drain_buffer(struct a1_spifc *spifc, char *buf, u32 len)
+{
+ u32 data;
+ const u32 count = len / sizeof(data);
+ const u32 pad = len % sizeof(data);
+
+ writel(A1_SPIFC_DBUF_AUTO_UPDATE_ADDR,
+ spifc->base + A1_SPIFC_DBUF_CTRL_REG);
+ ioread32_rep(spifc->base + A1_SPIFC_DBUF_DATA_REG, buf, count);
+
+ if (pad) {
+ data = readl(spifc->base + A1_SPIFC_DBUF_DATA_REG);
+ memcpy(buf + len - pad, &data, pad);
+ }
+}
+
+static void a1_spifc_fill_buffer(struct a1_spifc *spifc,
+ const char *buf, u32 len)
+{
+ u32 data;
+ const u32 count = len / sizeof(data);
+ const u32 pad = len % sizeof(data);
+
+ writel(A1_SPIFC_DBUF_DIR | A1_SPIFC_DBUF_AUTO_UPDATE_ADDR,
+ spifc->base + A1_SPIFC_DBUF_CTRL_REG);
+ iowrite32_rep(spifc->base + A1_SPIFC_DBUF_DATA_REG, buf, count);
+
+ if (pad) {
+ memcpy(&data, buf + len - pad, pad);
+ writel(data, spifc->base + A1_SPIFC_DBUF_DATA_REG);
+ }
+}
+
+static void a1_spifc_user_init(struct a1_spifc *spifc)
+{
+ writel(0, spifc->base + A1_SPIFC_USER_CTRL0_REG);
+ writel(0, spifc->base + A1_SPIFC_USER_CTRL1_REG);
+ writel(0, spifc->base + A1_SPIFC_USER_CTRL2_REG);
+ writel(0, spifc->base + A1_SPIFC_USER_CTRL3_REG);
+}
+
+static void a1_spifc_set_cmd(struct a1_spifc *spifc, u32 cmd_cfg)
+{
+ u32 val;
+
+ val = readl(spifc->base + A1_SPIFC_USER_CTRL1_REG);
+ val &= ~(A1_SPIFC_USER_CMD_MODE | A1_SPIFC_USER_CMD_CODE);
+ val |= cmd_cfg;
+ writel(val, spifc->base + A1_SPIFC_USER_CTRL1_REG);
+}
+
+static void a1_spifc_set_addr(struct a1_spifc *spifc, u32 addr, u32 addr_cfg)
+{
+ u32 val;
+
+ writel(addr, spifc->base + A1_SPIFC_USER_ADDR_REG);
+
+ val = readl(spifc->base + A1_SPIFC_USER_CTRL1_REG);
+ val &= ~(A1_SPIFC_USER_ADDR_MODE | A1_SPIFC_USER_ADDR_BYTES);
+ val |= addr_cfg;
+ writel(val, spifc->base + A1_SPIFC_USER_CTRL1_REG);
+}
+
+static void a1_spifc_set_dummy(struct a1_spifc *spifc, u32 dummy_cfg)
+{
+ u32 val = readl(spifc->base + A1_SPIFC_USER_CTRL2_REG);
+
+ val &= ~(A1_SPIFC_USER_DUMMY_MODE | A1_SPIFC_USER_DUMMY_CLK_SYCLES);
+ val |= dummy_cfg;
+ writel(val, spifc->base + A1_SPIFC_USER_CTRL2_REG);
+}
+
+static int a1_spifc_read(struct a1_spifc *spifc, void *buf, u32 size, u32 mode)
+{
+ u32 val = readl(spifc->base + A1_SPIFC_USER_CTRL3_REG);
+ int ret;
+
+ val &= ~(A1_SPIFC_USER_DIN_MODE | A1_SPIFC_USER_DIN_BYTES);
+ val |= A1_SPIFC_USER_DIN_ENABLE;
+ val |= FIELD_PREP(A1_SPIFC_USER_DIN_MODE, mode);
+ val |= FIELD_PREP(A1_SPIFC_USER_DIN_BYTES, size);
+ writel(val, spifc->base + A1_SPIFC_USER_CTRL3_REG);
+
+ ret = a1_spifc_request(spifc, true);
+ if (!ret)
+ a1_spifc_drain_buffer(spifc, buf, size);
+
+ return ret;
+}
+
+static int a1_spifc_write(struct a1_spifc *spifc,
+ const void *buf, u32 size, u32 mode)
+{
+ u32 val;
+
+ a1_spifc_fill_buffer(spifc, buf, size);
+
+ val = readl(spifc->base + A1_SPIFC_USER_CTRL1_REG);
+ val &= ~(A1_SPIFC_USER_DOUT_MODE | A1_SPIFC_USER_DOUT_BYTES);
+ val |= FIELD_PREP(A1_SPIFC_USER_DOUT_MODE, mode);
+ val |= FIELD_PREP(A1_SPIFC_USER_DOUT_BYTES, size);
+ val |= A1_SPIFC_USER_DOUT_ENABLE;
+ writel(val, spifc->base + A1_SPIFC_USER_CTRL1_REG);
+
+ return a1_spifc_request(spifc, false);
+}
+
+static int a1_spifc_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+ struct a1_spifc *spifc = spi_controller_get_devdata(mem->spi->controller);
+ size_t off, nbytes = op->data.nbytes;
+ u32 cmd_cfg, addr_cfg, dummy_cfg, dmode;
+ int ret;
+
+ a1_spifc_user_init(spifc);
+
+ cmd_cfg = A1_SPIFC_USER_CMD(op);
+ a1_spifc_set_cmd(spifc, cmd_cfg);
+
+ if (op->addr.nbytes) {
+ addr_cfg = A1_SPIFC_USER_ADDR(op);
+ a1_spifc_set_addr(spifc, op->addr.val, addr_cfg);
+ }
+
+ if (op->dummy.nbytes) {
+ dummy_cfg = A1_SPIFC_USER_DUMMY(op);
+ a1_spifc_set_dummy(spifc, dummy_cfg);
+ }
+
+ if (!op->data.nbytes)
+ return a1_spifc_request(spifc, false);
+
+ dmode = ilog2(op->data.buswidth);
+ off = 0;
+
+ do {
+ size_t block_size = min_t(size_t, nbytes, A1_SPIFC_BUFFER_SIZE);
+
+ a1_spifc_set_cmd(spifc, cmd_cfg);
+
+ if (op->addr.nbytes)
+ a1_spifc_set_addr(spifc, op->addr.val + off, addr_cfg);
+
+ if (op->dummy.nbytes)
+ a1_spifc_set_dummy(spifc, dummy_cfg);
+
+ writel(0, spifc->base + A1_SPIFC_USER_DBUF_ADDR_REG);
+
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ ret = a1_spifc_read(spifc, op->data.buf.in + off,
+ block_size, dmode);
+ else
+ ret = a1_spifc_write(spifc, op->data.buf.out + off,
+ block_size, dmode);
+
+ nbytes -= block_size;
+ off += block_size;
+ } while (nbytes != 0 && !ret);
+
+ return ret;
+}
+
+static void a1_spifc_hw_init(struct a1_spifc *spifc)
+{
+ u32 regv;
+
+ regv = readl(spifc->base + A1_SPIFC_AHB_REQ_CTRL_REG);
+ regv &= ~(A1_SPIFC_AHB_REQ_ENABLE);
+ writel(regv, spifc->base + A1_SPIFC_AHB_REQ_CTRL_REG);
+
+ regv = readl(spifc->base + A1_SPIFC_AHB_CTRL_REG);
+ regv &= ~(A1_SPIFC_AHB_BUS_EN);
+ writel(regv, spifc->base + A1_SPIFC_AHB_CTRL_REG);
+
+ writel(A1_SPIFC_ACTIMING0_VAL, spifc->base + A1_SPIFC_ACTIMING0_REG);
+
+ writel(0, spifc->base + A1_SPIFC_USER_DBUF_ADDR_REG);
+}
+
+static const struct spi_controller_mem_ops a1_spifc_mem_ops = {
+ .exec_op = a1_spifc_exec_op,
+};
+
+static int a1_spifc_probe(struct platform_device *pdev)
+{
+ struct spi_controller *ctrl;
+ struct a1_spifc *spifc;
+ int ret;
+
+ ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*spifc));
+ if (!ctrl)
+ return -ENOMEM;
+
+ spifc = spi_controller_get_devdata(ctrl);
+ platform_set_drvdata(pdev, spifc);
+
+ spifc->dev = &pdev->dev;
+ spifc->ctrl = ctrl;
+
+ spifc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(spifc->base))
+ return PTR_ERR(spifc->base);
+
+ spifc->clk = devm_clk_get_enabled(spifc->dev, NULL);
+ if (IS_ERR(spifc->clk))
+ return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk),
+ "unable to get clock\n");
+
+ a1_spifc_hw_init(spifc);
+
+ pm_runtime_set_autosuspend_delay(spifc->dev, 500);
+ pm_runtime_use_autosuspend(spifc->dev);
+ devm_pm_runtime_enable(spifc->dev);
+
+ ctrl->num_chipselect = 1;
+ ctrl->dev.of_node = pdev->dev.of_node;
+ ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
+ ctrl->auto_runtime_pm = true;
+ ctrl->mem_ops = &a1_spifc_mem_ops;
+ ctrl->min_speed_hz = A1_SPIFC_MIN_HZ;
+ ctrl->max_speed_hz = A1_SPIFC_MAX_HZ;
+ ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL |
+ SPI_RX_QUAD | SPI_TX_QUAD);
+
+ ret = devm_spi_register_controller(spifc->dev, ctrl);
+ if (ret)
+ return dev_err_probe(spifc->dev, ret,
+ "failed to register spi controller\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int a1_spifc_suspend(struct device *dev)
+{
+ struct a1_spifc *spifc = dev_get_drvdata(dev);
+ int ret;
+
+ ret = spi_controller_suspend(spifc->ctrl);
+ if (ret)
+ return ret;
+
+ if (!pm_runtime_suspended(dev))
+ clk_disable_unprepare(spifc->clk);
+
+ return 0;
+}
+
+static int a1_spifc_resume(struct device *dev)
+{
+ struct a1_spifc *spifc = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (!pm_runtime_suspended(dev)) {
+ ret = clk_prepare_enable(spifc->clk);
+ if (ret)
+ return ret;
+ }
+
+ a1_spifc_hw_init(spifc);
+
+ ret = spi_controller_resume(spifc->ctrl);
+ if (ret)
+ clk_disable_unprepare(spifc->clk);
+
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int a1_spifc_runtime_suspend(struct device *dev)
+{
+ struct a1_spifc *spifc = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(spifc->clk);
+
+ return 0;
+}
+
+static int a1_spifc_runtime_resume(struct device *dev)
+{
+ struct a1_spifc *spifc = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(spifc->clk);
+ if (!ret)
+ a1_spifc_hw_init(spifc);
+
+ return ret;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops a1_spifc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(a1_spifc_suspend, a1_spifc_resume)
+ SET_RUNTIME_PM_OPS(a1_spifc_runtime_suspend,
+ a1_spifc_runtime_resume,
+ NULL)
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id a1_spifc_dt_match[] = {
+ { .compatible = "amlogic,meson-a1-spifc", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, a1_spifc_dt_match);
+#endif /* CONFIG_OF */
+
+static struct platform_driver a1_spifc_driver = {
+ .probe = a1_spifc_probe,
+ .driver = {
+ .name = "meson-spifc-a1",
+ .of_match_table = of_match_ptr(a1_spifc_dt_match),
+ .pm = &a1_spifc_pm_ops,
+ },
+};
+module_platform_driver(a1_spifc_driver);
+
+MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>");
+MODULE_DESCRIPTION("Amlogic Meson A113L SPIFC driver");
+MODULE_LICENSE("GPL");
--
2.40.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
@ 2023-03-22 15:55 ` Neil Armstrong
2023-03-22 16:25 ` Krzysztof Kozlowski
2023-03-22 16:59 ` Rob Herring
2 siblings, 0 replies; 8+ messages in thread
From: Neil Armstrong @ 2023-03-22 15:55 UTC (permalink / raw)
To: Martin Kurbanov, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel
Hi,
On 22/03/2023 16:04, Martin Kurbanov wrote:
> Add YAML devicetree binding for Amlogic Meson A113L (A1 family)
> SPIFC Driver.
>
> Signed-off-by: Martin Kurbanov <mmkurbanov@sberdevices.ru>
> ---
> .../bindings/spi/amlogic,meson-a1-spifc.yaml | 42 +++++++++++++++++++
> 1 file changed, 42 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
>
> diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
> new file mode 100644
> index 000000000000..5f84063b01f8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
> @@ -0,0 +1,42 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/amlogic,meson-a1-spifc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic Meson A113L SPI Flash Controller
I think it should be "A1 SPI Flash Controller" to be more coherent
Neil
> +
> +maintainers:
> + - Martin Kurbanov <mmkurbanov@sberdevices.ru>
> +
> +allOf:
> + - $ref: spi-controller.yaml#
> +
> +properties:
> + compatible:
> + enum:
> + - amlogic,meson-a1-spifc
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/amlogic,a1-clkc.h>
> + spi@fd000400 {
> + compatible = "amlogic,meson-a1-spifc";
> + reg = <0xfd000400 0x290>;
> + clocks = <&clkc_periphs CLKID_SPIFC>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller
2023-03-22 15:04 ` [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller Martin Kurbanov
@ 2023-03-22 16:00 ` Neil Armstrong
2023-03-22 20:50 ` kernel test robot
1 sibling, 0 replies; 8+ messages in thread
From: Neil Armstrong @ 2023-03-22 16:00 UTC (permalink / raw)
To: Martin Kurbanov, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel
Hi,
On 22/03/2023 16:04, Martin Kurbanov wrote:
> This is a driver for the Amlogic Meson SPI flash controller support
> on A113L SoC.
>
> Signed-off-by: Martin Kurbanov <mmkurbanov@sberdevices.ru>
> ---
> drivers/spi/Kconfig | 7 +
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-meson-spifc-a1.c | 444 +++++++++++++++++++++++++++++++
> 3 files changed, 452 insertions(+)
> create mode 100644 drivers/spi/spi-meson-spifc-a1.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 3b1c0878bb85..a12452bd1e0c 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -582,6 +582,13 @@ config SPI_MESON_SPIFC
> This enables master mode support for the SPIFC (SPI flash
> controller) available in Amlogic Meson SoCs.
>
> +config SPI_MESON_SPIFC_A1
> + tristate "Amlogic Meson A113L SPIFC controller"
The title should be "Amlogic Meson A1 SPIFC controller" for coherency.
> + depends on ARCH_MESON || COMPILE_TEST
> + help
> + This enables master mode support for the SPIFC (SPI flash
> + controller) available in Amlogic Meson A113L (A1 family) SoC.
You should write the reverse: available in Amlogic Meson A1 Family (A113L SoC).
> +
> config SPI_MICROCHIP_CORE
> tristate "Microchip FPGA SPI controllers"
> depends on SPI_MASTER
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index be9ba40ef8d0..702053970967 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -72,6 +72,7 @@ obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
> obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
> obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o
> obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
> +obj-$(CONFIG_SPI_MESON_SPIFC_A1) += spi-meson-spifc-a1.o
> obj-$(CONFIG_SPI_MICROCHIP_CORE) += spi-microchip-core.o
> obj-$(CONFIG_SPI_MICROCHIP_CORE_QSPI) += spi-microchip-core-qspi.o
> obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
> diff --git a/drivers/spi/spi-meson-spifc-a1.c b/drivers/spi/spi-meson-spifc-a1.c
> new file mode 100644
> index 000000000000..213c8b692675
> --- /dev/null
> +++ b/drivers/spi/spi-meson-spifc-a1.c
> @@ -0,0 +1,444 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Amlogic Meson A113L SPI flash controller (SPIFC)
Same here
> + *
> + * Copyright (c) 2023, SberDevices. All Rights Reserved.
> + *
> + * Author: Martin Kurbanov <mmkurbanov@sberdevices.ru>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/spi/spi.h>
> +#include <linux/spi/spi-mem.h>
> +#include <linux/types.h>
> +
> +#define A1_SPIFC_AHB_CTRL_REG 0x0
> +#define A1_SPIFC_AHB_BUS_EN BIT(31)
I find the "A1_SPIFC" hard to read, I think you should reverse
it in all the file into :
#define SPIFC_A1_...
and
static XXX meson_spifc_a1_request to be coherent with the legacy spifc
driver and spicc driver.
<snip>
> +
> +MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>");
> +MODULE_DESCRIPTION("Amlogic Meson A113L SPIFC driver");
Same here "Meson A1 SPIFC driver"
> +MODULE_LICENSE("GPL");
Thanks,
Neil
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
2023-03-22 15:55 ` Neil Armstrong
@ 2023-03-22 16:25 ` Krzysztof Kozlowski
2023-03-22 16:59 ` Rob Herring
2 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-22 16:25 UTC (permalink / raw)
To: Martin Kurbanov, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: linux-spi, devicetree, linux-arm-kernel, linux-amlogic,
linux-kernel, kernel
On 22/03/2023 16:04, Martin Kurbanov wrote:
> Add YAML devicetree binding for Amlogic Meson A113L (A1 family)
> SPIFC Driver.
Subject: drop second/last, redundant "binding for". The "dt-bindings"
prefix is already stating that these are bindings.
> +examples:
> + - |
> + #include <dt-bindings/clock/amlogic,a1-clkc.h>
> + spi@fd000400 {
> + compatible = "amlogic,meson-a1-spifc";
Use 4 spaces for example indentation.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
2023-03-22 15:55 ` Neil Armstrong
2023-03-22 16:25 ` Krzysztof Kozlowski
@ 2023-03-22 16:59 ` Rob Herring
2 siblings, 0 replies; 8+ messages in thread
From: Rob Herring @ 2023-03-22 16:59 UTC (permalink / raw)
To: Martin Kurbanov
Cc: Mark Brown, kernel, Neil Armstrong, Rob Herring, Jerome Brunet,
linux-arm-kernel, Krzysztof Kozlowski, Kevin Hilman, linux-spi,
linux-kernel, devicetree, Martin Blumenstingl, linux-amlogic
On Wed, 22 Mar 2023 18:04:57 +0300, Martin Kurbanov wrote:
> Add YAML devicetree binding for Amlogic Meson A113L (A1 family)
> SPIFC Driver.
>
> Signed-off-by: Martin Kurbanov <mmkurbanov@sberdevices.ru>
> ---
> .../bindings/spi/amlogic,meson-a1-spifc.yaml | 42 +++++++++++++++++++
> 1 file changed, 42 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.example.dts:18:18: fatal error: dt-bindings/clock/amlogic,a1-clkc.h: No such file or directory
18 | #include <dt-bindings/clock/amlogic,a1-clkc.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/spi/amlogic,meson-a1-spifc.example.dtb] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1512: dt_binding_check] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230322150458.783901-2-mmkurbanov@sberdevices.ru
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller
2023-03-22 15:04 ` [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller Martin Kurbanov
2023-03-22 16:00 ` Neil Armstrong
@ 2023-03-22 20:50 ` kernel test robot
1 sibling, 0 replies; 8+ messages in thread
From: kernel test robot @ 2023-03-22 20:50 UTC (permalink / raw)
To: Martin Kurbanov, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
Cc: oe-kbuild-all, linux-spi, devicetree, linux-arm-kernel,
linux-amlogic, linux-kernel, kernel, Martin Kurbanov
Hi Martin,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on robh/for-next krzk-dt/for-next linus/master v6.3-rc3 next-20230322]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Martin-Kurbanov/dt-bindings-spi-add-binding-for-meson-spifc-a1/20230322-230744
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link: https://lore.kernel.org/r/20230322150458.783901-3-mmkurbanov%40sberdevices.ru
patch subject: [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230323/202303230442.lGIrV8PZ-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/7d8d54cc0b563efb979caf17507b29c0bb3efde0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Martin-Kurbanov/dt-bindings-spi-add-binding-for-meson-spifc-a1/20230322-230744
git checkout 7d8d54cc0b563efb979caf17507b29c0bb3efde0
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303230442.lGIrV8PZ-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/spi/spi-meson-spifc-a1.c: In function 'a1_spifc_read':
>> drivers/spi/spi-meson-spifc-a1.c:204:16: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
204 | val |= FIELD_PREP(A1_SPIFC_USER_DIN_MODE, mode);
| ^~~~~~~~~~
cc1: some warnings being treated as errors
vim +/FIELD_PREP +204 drivers/spi/spi-meson-spifc-a1.c
196
197 static int a1_spifc_read(struct a1_spifc *spifc, void *buf, u32 size, u32 mode)
198 {
199 u32 val = readl(spifc->base + A1_SPIFC_USER_CTRL3_REG);
200 int ret;
201
202 val &= ~(A1_SPIFC_USER_DIN_MODE | A1_SPIFC_USER_DIN_BYTES);
203 val |= A1_SPIFC_USER_DIN_ENABLE;
> 204 val |= FIELD_PREP(A1_SPIFC_USER_DIN_MODE, mode);
205 val |= FIELD_PREP(A1_SPIFC_USER_DIN_BYTES, size);
206 writel(val, spifc->base + A1_SPIFC_USER_CTRL3_REG);
207
208 ret = a1_spifc_request(spifc, true);
209 if (!ret)
210 a1_spifc_drain_buffer(spifc, buf, size);
211
212 return ret;
213 }
214
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-03-22 20:52 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-22 15:04 [PATCH v1 0/2] add support for Meson A1 SPI Flash Controller Martin Kurbanov
2023-03-22 15:04 ` [PATCH v1 1/2] dt-bindings: spi: add binding for meson-spifc-a1 Martin Kurbanov
2023-03-22 15:55 ` Neil Armstrong
2023-03-22 16:25 ` Krzysztof Kozlowski
2023-03-22 16:59 ` Rob Herring
2023-03-22 15:04 ` [PATCH v1 2/2] spi: add support for Meson A1 SPI Flash Controller Martin Kurbanov
2023-03-22 16:00 ` Neil Armstrong
2023-03-22 20:50 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).