spi: qup: Add support for v1.1.1
authorAndy Gross <agross@codeaurora.org>
Thu, 12 Jun 2014 19:34:12 +0000 (14:34 -0500)
committerMark Brown <broonie@linaro.org>
Sat, 21 Jun 2014 10:13:19 +0000 (11:13 +0100)
This patch adds support for v1.1.1 of the SPI QUP controller.

Signed-off-by: Andy Gross <agross@codeaurora.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
drivers/spi/spi-qup.c

index b82a268f1bd4639b350a94075d2d935a6c5e1282..775a2d86f502af523f2f2a539393e2b83d527076 100644 (file)
@@ -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.
 
 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
 - interrupts:     Interrupt number used by this controller
 
index fc1de86d3c8a18a1a9e24c3967955204687b5b85..f5b646e35cc4d1b57e67b9ed29eb3cb8abff2513 100644 (file)
@@ -142,6 +142,7 @@ struct spi_qup {
        int                     w_size; /* bytes per SPI word */
        int                     tx_bytes;
        int                     rx_bytes;
+       int                     qup_v1;
 };
 
 
@@ -420,7 +421,9 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
        config |= QUP_CONFIG_SPI_MODE;
        writel_relaxed(config, controller->base + QUP_CONFIG);
 
-       writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
+       /* only write to OPERATIONAL_MASK when register is present */
+       if (!controller->qup_v1)
+               writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
        return 0;
 }
 
@@ -511,7 +514,7 @@ static int spi_qup_probe(struct platform_device *pdev)
        struct resource *res;
        struct device *dev;
        void __iomem *base;
-       u32 data, max_freq, iomode;
+       u32 max_freq, iomode;
        int ret, irq, size;
 
        dev = &pdev->dev;
@@ -554,15 +557,6 @@ static int spi_qup_probe(struct platform_device *pdev)
                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));
        if (!master) {
                clk_disable_unprepare(cclk);
@@ -591,6 +585,10 @@ static int spi_qup_probe(struct platform_device *pdev)
        controller->cclk = cclk;
        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);
        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);
        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",
-                data, controller->in_blk_sz, controller->in_fifo_sz,
+       dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
+                controller->in_blk_sz, controller->in_fifo_sz,
                 controller->out_blk_sz, controller->out_fifo_sz);
 
        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_IO_M_MODES);
-       writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
+
+       if (!controller->qup_v1)
+               writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
+
        writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
                       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(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[] = {
+       { .compatible = "qcom,spi-qup-v1.1.1", },
        { .compatible = "qcom,spi-qup-v2.1.1", },
        { .compatible = "qcom,spi-qup-v2.2.1", },
        { }