spi: tegra quad: Add Tegra Grace features
authorMark Brown <broonie@kernel.org>
Mon, 13 Jun 2022 17:23:40 +0000 (18:23 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 13 Jun 2022 17:23:40 +0000 (18:23 +0100)
Merge series from Krishna Yarlagadda <kyarlagadda@nvidia.com>:

Add multiple chip select lines supported on Tegra 241

Documentation/devicetree/bindings/spi/nvidia,tegra210-quad-peripheral-props.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
drivers/spi/spi-tegra210-quad.c

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad-peripheral-props.yaml
new file mode 100644 (file)
index 0000000..24e0c21
--- /dev/null
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral properties for Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding <thierry.reding@gmail.com>
+  - Jonathan Hunter <jonathanh@nvidia.com>
+
+properties:
+  nvidia,tx-clk-tap-delay:
+    description:
+      Delays the clock going out to device with this tap value.
+      Tap value varies based on platform design trace lengths from Tegra
+      QSPI to corresponding slave device.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 31
+
+  nvidia,rx-clk-tap-delay:
+    description:
+      Delays the clock coming in from the device with this tap value.
+      Tap value varies based on platform design trace lengths from Tegra
+      QSPI to corresponding slave device.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 255
+
+unevaluatedProperties: true
+
index 0296edd1de22e7b8f190f52f465d5c777adf6a43..6b733e5c116384dd21b2387cab830ba34eee6b44 100644 (file)
@@ -20,6 +20,7 @@ properties:
       - nvidia,tegra186-qspi
       - nvidia,tegra194-qspi
       - nvidia,tegra234-qspi
+      - nvidia,tegra241-qspi
 
   reg:
     maxItems: 1
@@ -57,27 +58,6 @@ patternProperties:
       spi-tx-bus-width:
         enum: [1, 2, 4]
 
-      nvidia,tx-clk-tap-delay:
-        description:
-          Delays the clock going out to device with this tap value.
-          Tap value varies based on platform design trace lengths from Tegra
-          QSPI to corresponding slave device.
-        $ref: /schemas/types.yaml#/definitions/uint32
-        minimum: 0
-        maximum: 31
-
-      nvidia,rx-clk-tap-delay:
-        description:
-          Delays the clock coming in from the device with this tap value.
-          Tap value varies based on platform design trace lengths from Tegra
-          QSPI to corresponding slave device.
-        $ref: /schemas/types.yaml#/definitions/uint32
-        minimum: 0
-        maximum: 255
-
-    required:
-      - reg
-
 required:
   - compatible
   - reg
index 6ffb74352bef72577a90b8de58da6126ab388f72..9d63a58b46a088c79877320be6db580db642254c 100644 (file)
@@ -117,5 +117,6 @@ properties:
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
   - $ref: samsung,spi-peripheral-props.yaml#
+  - $ref: nvidia,tegra210-quad-peripheral-props.yaml#
 
 additionalProperties: true
index 66f647f32876e34ee5fd752642ea02d4ac500a5d..c89592b21ffc5bcc6864e3465550cf4a9232da13 100644 (file)
 #define QSPI_RX_EN                             BIT(12)
 #define QSPI_CS_SW_VAL                         BIT(20)
 #define QSPI_CS_SW_HW                          BIT(21)
+
+#define QSPI_CS_POL_INACTIVE(n)                        (1 << (22 + (n)))
+#define QSPI_CS_POL_INACTIVE_MASK              (0xF << 22)
+#define QSPI_CS_SEL_0                          (0 << 26)
+#define QSPI_CS_SEL_1                          (1 << 26)
+#define QSPI_CS_SEL_2                          (2 << 26)
+#define QSPI_CS_SEL_3                          (3 << 26)
+#define QSPI_CS_SEL_MASK                       (3 << 26)
+#define QSPI_CS_SEL(x)                         (((x) & 0x3) << 26)
+
 #define QSPI_CONTROL_MODE_0                    (0 << 28)
 #define QSPI_CONTROL_MODE_3                    (3 << 28)
 #define QSPI_CONTROL_MODE_MASK                 (3 << 28)
 struct tegra_qspi_soc_data {
        bool has_dma;
        bool cmb_xfer_capable;
+       unsigned int cs_count;
 };
 
 struct tegra_qspi_client_data {
@@ -812,6 +823,7 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran
                tegra_qspi_mask_clear_irq(tqspi);
 
                command1 = tqspi->def_command1_reg;
+               command1 |= QSPI_CS_SEL(spi->chip_select);
                command1 |= QSPI_BIT_LENGTH(bits_per_word - 1);
 
                command1 &= ~QSPI_CONTROL_MODE_MASK;
@@ -941,10 +953,11 @@ static int tegra_qspi_setup(struct spi_device *spi)
 
        /* keep default cs state to inactive */
        val = tqspi->def_command1_reg;
+       val |= QSPI_CS_SEL(spi->chip_select);
        if (spi->mode & SPI_CS_HIGH)
-               val &= ~QSPI_CS_SW_VAL;
+               val &= ~QSPI_CS_POL_INACTIVE(spi->chip_select);
        else
-               val |= QSPI_CS_SW_VAL;
+               val |= QSPI_CS_POL_INACTIVE(spi->chip_select);
 
        tqspi->def_command1_reg = val;
        tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);
@@ -1425,16 +1438,25 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
 static struct tegra_qspi_soc_data tegra210_qspi_soc_data = {
        .has_dma = true,
        .cmb_xfer_capable = false,
+       .cs_count = 1,
 };
 
 static struct tegra_qspi_soc_data tegra186_qspi_soc_data = {
        .has_dma = true,
        .cmb_xfer_capable = true,
+       .cs_count = 1,
 };
 
 static struct tegra_qspi_soc_data tegra234_qspi_soc_data = {
        .has_dma = false,
        .cmb_xfer_capable = true,
+       .cs_count = 1,
+};
+
+static struct tegra_qspi_soc_data tegra241_qspi_soc_data = {
+       .has_dma = false,
+       .cmb_xfer_capable = true,
+       .cs_count = 4,
 };
 
 static const struct of_device_id tegra_qspi_of_match[] = {
@@ -1450,6 +1472,9 @@ static const struct of_device_id tegra_qspi_of_match[] = {
        }, {
                .compatible = "nvidia,tegra234-qspi",
                .data       = &tegra234_qspi_soc_data,
+       }, {
+               .compatible = "nvidia,tegra241-qspi",
+               .data       = &tegra241_qspi_soc_data,
        },
        {}
 };
@@ -1467,6 +1492,9 @@ static const struct acpi_device_id tegra_qspi_acpi_match[] = {
        }, {
                .id = "NVDA1413",
                .driver_data = (kernel_ulong_t)&tegra234_qspi_soc_data,
+       }, {
+               .id = "NVDA1513",
+               .driver_data = (kernel_ulong_t)&tegra241_qspi_soc_data,
        },
        {}
 };
@@ -1506,6 +1534,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
        spin_lock_init(&tqspi->lock);
 
        tqspi->soc_data = device_get_match_data(&pdev->dev);
+       master->num_chipselect = tqspi->soc_data->cs_count;
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        tqspi->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(tqspi->base))