Commit 5653b4f8 authored by Zixian Zeng's avatar Zixian Zeng Committed by Mark Brown
Browse files

spi: spi-sg2044-nor: Add configurable chip_info

SG2044 and SG2042 have similar SPI-NOR flash controller design,
but have incompatibility which causes existing driver
not working on SG2042:
1. SPI-NOR flash controller on SG2042 have no OPT register.
2. FIFO trigger level on SG2042 should be strictly less than 8.

So introduce a new configurable chip_info structure to hold the
different configuration.

Link: https://github.com/sophgo/sophgo-doc/blob/main/SG2042/TRM/source/SPI-flash.rst


Signed-off-by: default avatarZixian Zeng <sycamoremoon376@gmail.com>
Reviewed-by: Chen Wang <unicorn_wang@outlook.com> & Tested-by: Chen Wang
Link: https://patch.msgid.link/20250720-sfg-spifmc-v4-2-033188ad801e@gmail.com


Reviewed-by: Chen Wang <unicorn_wang@outlook.com> & Tested-by: Chen Wang 
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7438379c
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -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,6 +341,7 @@ 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;

		if (spifmc->chip_info->has_opt_reg)
			writel(SPIFMC_OPT_DISABLE_FIFO_FLUSH, spifmc->io_base + SPIFMC_OPT);
	} else {
		/*
@@ -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,13 @@ 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 of_device_id sg2044_spifmc_match[] = {
	{ .compatible = "sophgo,sg2044-spifmc-nor" },
	{ .compatible = "sophgo,sg2044-spifmc-nor", .data = &sg2044_chip_info },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sg2044_spifmc_match);