Unverified Commit f54b69a5 authored by Mark Brown's avatar Mark Brown
Browse files

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.
parents b71cb346 f6b15943
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -14,12 +14,9 @@ allOf:

properties:
  compatible:
    oneOf:
      - const: sophgo,sg2044-spifmc-nor
      - items:
          - enum:
    enum:
      - sophgo,sg2042-spifmc-nor
          - const: sophgo,sg2044-spifmc-nor
      - sophgo,sg2044-spifmc-nor

  reg:
    maxItems: 1
+26 −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,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);