Unverified Commit 33f1ef6d authored by William Qiu's avatar William Qiu Committed by Mark Brown
Browse files

spi: cadence-quadspi: Add clock configuration for StarFive JH7110 QSPI

parent 0d2b6a1b
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
@@ -46,6 +46,12 @@

#define CQSPI_OP_WIDTH(part) ((part).nbytes ? ilog2((part).buswidth) : 0)

enum {
	CLK_QSPI_APB = 0,
	CLK_QSPI_AHB,
	CLK_QSPI_NUM,
};

struct cqspi_st;

struct cqspi_flash_pdata {
@@ -63,6 +69,7 @@ struct cqspi_st {
	struct platform_device	*pdev;
	struct spi_master	*master;
	struct clk		*clk;
	struct clk		*clks[CLK_QSPI_NUM];
	unsigned int		sclk;

	void __iomem		*iobase;
@@ -91,6 +98,8 @@ struct cqspi_st {
	bool			wr_completion;
	bool			slow_sram;
	bool			apb_ahb_hazard;

	bool			is_jh7110; /* Flag for StarFive JH7110 SoC */
};

struct cqspi_driver_platdata {
@@ -99,6 +108,8 @@ struct cqspi_driver_platdata {
	int (*indirect_read_dma)(struct cqspi_flash_pdata *f_pdata,
				 u_char *rxbuf, loff_t from_addr, size_t n_rx);
	u32 (*get_dma_status)(struct cqspi_st *cqspi);
	int (*jh7110_clk_init)(struct platform_device *pdev,
			       struct cqspi_st *cqspi);
};

/* Operation timeout value */
@@ -1629,6 +1640,51 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi)
	return 0;
}

static int cqspi_jh7110_clk_init(struct platform_device *pdev, struct cqspi_st *cqspi)
{
	static struct clk_bulk_data qspiclk[] = {
		{ .id = "apb" },
		{ .id = "ahb" },
	};

	int ret = 0;

	ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(qspiclk), qspiclk);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to get qspi clocks\n", __func__);
		return ret;
	}

	cqspi->clks[CLK_QSPI_APB] = qspiclk[0].clk;
	cqspi->clks[CLK_QSPI_AHB] = qspiclk[1].clk;

	ret = clk_prepare_enable(cqspi->clks[CLK_QSPI_APB]);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to enable CLK_QSPI_APB\n", __func__);
		return ret;
	}

	ret = clk_prepare_enable(cqspi->clks[CLK_QSPI_AHB]);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to enable CLK_QSPI_AHB\n", __func__);
		goto disable_apb_clk;
	}

	cqspi->is_jh7110 = true;

	return 0;

disable_apb_clk:
	clk_disable_unprepare(cqspi->clks[CLK_QSPI_APB]);

	return ret;
}

static void cqspi_jh7110_disable_clk(struct platform_device *pdev, struct cqspi_st *cqspi)
{
	clk_disable_unprepare(cqspi->clks[CLK_QSPI_AHB]);
	clk_disable_unprepare(cqspi->clks[CLK_QSPI_APB]);
}
static int cqspi_probe(struct platform_device *pdev)
{
	const struct cqspi_driver_platdata *ddata;
@@ -1654,6 +1710,7 @@ static int cqspi_probe(struct platform_device *pdev)

	cqspi->pdev = pdev;
	cqspi->master = master;
	cqspi->is_jh7110 = false;
	platform_set_drvdata(pdev, cqspi);

	/* Obtain configuration from OF. */
@@ -1765,6 +1822,12 @@ static int cqspi_probe(struct platform_device *pdev)
		if (ddata->quirks & CQSPI_NEEDS_APB_AHB_HAZARD_WAR)
			cqspi->apb_ahb_hazard = true;

		if (ddata->jh7110_clk_init) {
			ret = cqspi_jh7110_clk_init(pdev, cqspi);
			if (ret)
				goto probe_clk_failed;
		}

		if (of_device_is_compatible(pdev->dev.of_node,
					    "xlnx,versal-ospi-1.0")) {
			ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
@@ -1829,6 +1892,9 @@ static void cqspi_remove(struct platform_device *pdev)

	clk_disable_unprepare(cqspi->clk);

	if (cqspi->is_jh7110)
		cqspi_jh7110_disable_clk(pdev, cqspi);

	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
}
@@ -1896,6 +1962,7 @@ static const struct cqspi_driver_platdata versal_ospi = {

static const struct cqspi_driver_platdata jh7110_qspi = {
	.quirks = CQSPI_DISABLE_DAC_MODE,
	.jh7110_clk_init = cqspi_jh7110_clk_init,
};

static const struct cqspi_driver_platdata pensando_cdns_qspi = {