Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70cea0a9 authored by Andy Gross's avatar Andy Gross Committed by Mark Brown
Browse files

spi: qup: Add support for v1.1.1



This patch adds support for v1.1.1 of the SPI QUP controller.

Signed-off-by: default avatarAndy Gross <agross@codeaurora.org>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 7171511e
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -7,7 +7,11 @@ SPI in master mode supports up to 50MHz, up to four chip selects, programmable
data path from 4 bits to 32 bits and numerous protocol variants.
data path from 4 bits to 32 bits and numerous protocol variants.


Required properties:
Required properties:
- compatible:     Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
- compatible:     Should contain:
		  "qcom,spi-qup-v1.1.1" for 8660, 8960 and 8064.
		  "qcom,spi-qup-v2.1.1" for 8974 and later
		  "qcom,spi-qup-v2.2.1" for 8974 v2 and later.

- reg:            Should contain base register location and length
- reg:            Should contain base register location and length
- interrupts:     Interrupt number used by this controller
- interrupts:     Interrupt number used by this controller


+22 −14
Original line number Original line Diff line number Diff line
@@ -142,6 +142,7 @@ struct spi_qup {
	int			w_size;	/* bytes per SPI word */
	int			w_size;	/* bytes per SPI word */
	int			tx_bytes;
	int			tx_bytes;
	int			rx_bytes;
	int			rx_bytes;
	int			qup_v1;
};
};




@@ -420,6 +421,8 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
	config |= QUP_CONFIG_SPI_MODE;
	config |= QUP_CONFIG_SPI_MODE;
	writel_relaxed(config, controller->base + QUP_CONFIG);
	writel_relaxed(config, controller->base + QUP_CONFIG);


	/* only write to OPERATIONAL_MASK when register is present */
	if (!controller->qup_v1)
		writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
		writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
	return 0;
	return 0;
}
}
@@ -511,7 +514,7 @@ static int spi_qup_probe(struct platform_device *pdev)
	struct resource *res;
	struct resource *res;
	struct device *dev;
	struct device *dev;
	void __iomem *base;
	void __iomem *base;
	u32 data, max_freq, iomode;
	u32 max_freq, iomode;
	int ret, irq, size;
	int ret, irq, size;


	dev = &pdev->dev;
	dev = &pdev->dev;
@@ -554,15 +557,6 @@ static int spi_qup_probe(struct platform_device *pdev)
		return ret;
		return ret;
	}
	}


	data = readl_relaxed(base + QUP_HW_VERSION);

	if (data < QUP_HW_VERSION_2_1_1) {
		clk_disable_unprepare(cclk);
		clk_disable_unprepare(iclk);
		dev_err(dev, "v.%08x is not supported\n", data);
		return -ENXIO;
	}

	master = spi_alloc_master(dev, sizeof(struct spi_qup));
	master = spi_alloc_master(dev, sizeof(struct spi_qup));
	if (!master) {
	if (!master) {
		clk_disable_unprepare(cclk);
		clk_disable_unprepare(cclk);
@@ -591,6 +585,10 @@ static int spi_qup_probe(struct platform_device *pdev)
	controller->cclk = cclk;
	controller->cclk = cclk;
	controller->irq = irq;
	controller->irq = irq;


	/* set v1 flag if device is version 1 */
	if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
		controller->qup_v1 = 1;

	spin_lock_init(&controller->lock);
	spin_lock_init(&controller->lock);
	init_completion(&controller->done);
	init_completion(&controller->done);


@@ -614,8 +612,8 @@ static int spi_qup_probe(struct platform_device *pdev)
	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);


	dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
	dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
		 data, controller->in_blk_sz, controller->in_fifo_sz,
		 controller->in_blk_sz, controller->in_fifo_sz,
		 controller->out_blk_sz, controller->out_fifo_sz);
		 controller->out_blk_sz, controller->out_fifo_sz);


	writel_relaxed(1, base + QUP_SW_RESET);
	writel_relaxed(1, base + QUP_SW_RESET);
@@ -628,10 +626,19 @@ static int spi_qup_probe(struct platform_device *pdev)


	writel_relaxed(0, base + QUP_OPERATIONAL);
	writel_relaxed(0, base + QUP_OPERATIONAL);
	writel_relaxed(0, base + QUP_IO_M_MODES);
	writel_relaxed(0, base + QUP_IO_M_MODES);

	if (!controller->qup_v1)
		writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
		writel_relaxed(0, base + QUP_OPERATIONAL_MASK);

	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
		       base + SPI_ERROR_FLAGS_EN);
		       base + SPI_ERROR_FLAGS_EN);


	/* if earlier version of the QUP, disable INPUT_OVERRUN */
	if (controller->qup_v1)
		writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
			QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
			base + QUP_ERROR_FLAGS_EN);

	writel_relaxed(0, base + SPI_CONFIG);
	writel_relaxed(0, base + SPI_CONFIG);
	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);


@@ -750,6 +757,7 @@ static int spi_qup_remove(struct platform_device *pdev)
}
}


static const struct of_device_id spi_qup_dt_match[] = {
static const struct of_device_id spi_qup_dt_match[] = {
	{ .compatible = "qcom,spi-qup-v1.1.1", },
	{ .compatible = "qcom,spi-qup-v2.1.1", },
	{ .compatible = "qcom,spi-qup-v2.1.1", },
	{ .compatible = "qcom,spi-qup-v2.2.1", },
	{ .compatible = "qcom,spi-qup-v2.2.1", },
	{ }
	{ }