summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2025-07-24 23:06:15 +0100
committerMark Brown <broonie@kernel.org>2025-07-24 23:06:15 +0100
commitf54b69a57a77c301a1013a22257357d9294a1fdc (patch)
treef849167fe7e53018b9c3e24cef1f15d818023953
parentb71cb3461765bcf42f619138f4c90c360369a246 (diff)
parentf6b159431697c903da1418e70c825faa0cddbdae (diff)
spi: sophgo: Add SPI NOR controller for SG2042
Merge series from Zixian Zeng <sycamoremoon376@gmail.com>: Add support SPI NOR flash memory controller for SG2042, using upstreamed SG2044 SPI NOR driver. Tested on SG2042 Pioneer Box, read, write operations. Thanks Chen Wang who provided machine and guidance.
-rw-r--r--Documentation/devicetree/bindings/spi/spi-sg2044-nor.yaml9
-rw-r--r--drivers/spi/spi-sg2044-nor.c29
2 files changed, 29 insertions, 9 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-sg2044-nor.yaml b/Documentation/devicetree/bindings/spi/spi-sg2044-nor.yaml
index 66e54dedab140..0e7ead7637052 100644
--- a/Documentation/devicetree/bindings/spi/spi-sg2044-nor.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-sg2044-nor.yaml
@@ -14,12 +14,9 @@ allOf:
properties:
compatible:
- oneOf:
- - const: sophgo,sg2044-spifmc-nor
- - items:
- - enum:
- - sophgo,sg2042-spifmc-nor
- - const: sophgo,sg2044-spifmc-nor
+ enum:
+ - sophgo,sg2042-spifmc-nor
+ - sophgo,sg2044-spifmc-nor
reg:
maxItems: 1
diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c
index a59aa3fc55d27..af48b1fcda930 100644
--- a/drivers/spi/spi-sg2044-nor.c
+++ b/drivers/spi/spi-sg2044-nor.c
@@ -84,12 +84,18 @@
#define SPIFMC_MAX_READ_SIZE 0x10000
+struct sg204x_spifmc_chip_info {
+ bool has_opt_reg;
+ u32 rd_fifo_int_trigger_level;
+};
+
struct sg2044_spifmc {
struct spi_controller *ctrl;
void __iomem *io_base;
struct device *dev;
struct mutex lock;
struct clk *clk;
+ const struct sg204x_spifmc_chip_info *chip_info;
};
static int sg2044_spifmc_wait_int(struct sg2044_spifmc *spifmc, u8 int_type)
@@ -139,7 +145,7 @@ static ssize_t sg2044_spifmc_read_64k(struct sg2044_spifmc *spifmc,
reg = sg2044_spifmc_init_reg(spifmc);
reg |= (op->addr.nbytes + op->dummy.nbytes) << SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT;
- reg |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_8_BYTE;
+ reg |= spifmc->chip_info->rd_fifo_int_trigger_level;
reg |= SPIFMC_TRAN_CSR_WITH_CMD;
reg |= SPIFMC_TRAN_CSR_TRAN_MODE_RX;
@@ -335,7 +341,8 @@ static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc,
reg |= SPIFMC_TRAN_CSR_TRAN_MODE_RX;
reg |= SPIFMC_TRAN_CSR_TRAN_MODE_TX;
- writel(SPIFMC_OPT_DISABLE_FIFO_FLUSH, spifmc->io_base + SPIFMC_OPT);
+ if (spifmc->chip_info->has_opt_reg)
+ writel(SPIFMC_OPT_DISABLE_FIFO_FLUSH, spifmc->io_base + SPIFMC_OPT);
} else {
/*
* If write values to the Status Register,
@@ -457,6 +464,11 @@ static int sg2044_spifmc_probe(struct platform_device *pdev)
ret = devm_mutex_init(dev, &spifmc->lock);
if (ret)
return ret;
+ spifmc->chip_info = device_get_match_data(&pdev->dev);
+ if (!spifmc->chip_info) {
+ dev_err(&pdev->dev, "Failed to get specific chip info\n");
+ return -EINVAL;
+ }
sg2044_spifmc_init(spifmc);
sg2044_spifmc_init_reg(spifmc);
@@ -468,8 +480,19 @@ static int sg2044_spifmc_probe(struct platform_device *pdev)
return 0;
}
+static const struct sg204x_spifmc_chip_info sg2044_chip_info = {
+ .has_opt_reg = true,
+ .rd_fifo_int_trigger_level = SPIFMC_TRAN_CSR_FIFO_TRG_LVL_8_BYTE,
+};
+
+static const struct sg204x_spifmc_chip_info sg2042_chip_info = {
+ .has_opt_reg = false,
+ .rd_fifo_int_trigger_level = SPIFMC_TRAN_CSR_FIFO_TRG_LVL_1_BYTE,
+};
+
static const struct of_device_id sg2044_spifmc_match[] = {
- { .compatible = "sophgo,sg2044-spifmc-nor" },
+ { .compatible = "sophgo,sg2044-spifmc-nor", .data = &sg2044_chip_info },
+ { .compatible = "sophgo,sg2042-spifmc-nor", .data = &sg2042_chip_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sg2044_spifmc_match);