diff options
author | Mark Brown <broonie@kernel.org> | 2025-07-24 23:06:15 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2025-07-24 23:06:15 +0100 |
commit | f54b69a57a77c301a1013a22257357d9294a1fdc (patch) | |
tree | f849167fe7e53018b9c3e24cef1f15d818023953 | |
parent | b71cb3461765bcf42f619138f4c90c360369a246 (diff) | |
parent | f6b159431697c903da1418e70c825faa0cddbdae (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.yaml | 9 | ||||
-rw-r--r-- | drivers/spi/spi-sg2044-nor.c | 29 |
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); |