Re: linux-next: Signed-off-by missing for commit in the block tree

2021-04-11 Thread Sowjanya Komatineni



On 4/11/21 7:14 PM, Jens Axboe wrote:

On 4/11/21 4:34 PM, Stephen Rothwell wrote:

Hi all,

Commit

   6fa6517fe62e ("ata: ahci_tegra: call tegra_powergate_power_off only when PM 
domain is not present")

is missing a Signed-off-by from its author.

Sowjana, please reply that you're OK with me adding your Signed-off-by to that
patch.


Sorry I should have checked that. Thanks Jens. Sure I am OK with it.

Thank you

Sowjanya



[PATCH v2] ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is not present

2021-04-08 Thread Sowjanya Komatineni
This patch adds check to call legacy power domain API
tegra_powergate_power_off() only when PM domain is not present.

This is a follow-up patch to Tegra186 AHCI support patch series.
---
 drivers/ata/ahci_tegra.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 56612af..4fb94db 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -268,7 +268,8 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
 disable_power:
clk_disable_unprepare(tegra->sata_clk);
 
-   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+   if (!tegra->pdev->dev.pm_domain)
+   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
 
 disable_regulators:
regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
@@ -287,7 +288,8 @@ static void tegra_ahci_power_off(struct ahci_host_priv 
*hpriv)
reset_control_assert(tegra->sata_cold_rst);
 
clk_disable_unprepare(tegra->sata_clk);
-   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+   if (!tegra->pdev->dev.pm_domain)
+   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
 
regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
 }
-- 
2.7.4



[PATCH v2] Follow up patch to Tegra186 AHCI support patch series

2021-04-08 Thread Sowjanya Komatineni
This includes a follow up patch to Tegra186 AHCI support patch series
https://lore.kernel.org/patchwork/cover/1408752/

Delta between patch versions:
[v2]:   v1 has missing PM domain check in error path. Fixed in v2.


Sowjanya Komatineni (1):
  ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is
not present

 drivers/ata/ahci_tegra.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.7.4



Re: [PATCH v1] ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is not present

2021-04-08 Thread Sowjanya Komatineni



On 4/8/21 12:58 PM, Dmitry Osipenko wrote:

08.04.2021 19:40, Sowjanya Komatineni пишет:

This patch adds a check on present of PM domain and calls legacy power
domain API tegra_powergate_power_off() only when PM domain is not present.

This is a follow-up patch to Tegra186 AHCI support patch series
https://lore.kernel.org/patchwork/cover/1408752/

Signed-off-by: Sowjanya Komatineni 

---
  drivers/ata/ahci_tegra.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 56612af..bd484dd 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -287,7 +287,8 @@ static void tegra_ahci_power_off(struct ahci_host_priv 
*hpriv)
reset_control_assert(tegra->sata_cold_rst);
  
  	clk_disable_unprepare(tegra->sata_clk);

-   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+   if (!tegra->pdev->dev.pm_domain)
+   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
  
  	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);

  }


There are two instances of tegra_powergate_power_off() in the driver.

Thanks Dmitry. Sorry missed it. Will fix


[PATCH v1] ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is not present

2021-04-08 Thread Sowjanya Komatineni
This patch adds a check on present of PM domain and calls legacy power
domain API tegra_powergate_power_off() only when PM domain is not present.

This is a follow-up patch to Tegra186 AHCI support patch series
https://lore.kernel.org/patchwork/cover/1408752/

Signed-off-by: Sowjanya Komatineni 

---
 drivers/ata/ahci_tegra.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 56612af..bd484dd 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -287,7 +287,8 @@ static void tegra_ahci_power_off(struct ahci_host_priv 
*hpriv)
reset_control_assert(tegra->sata_cold_rst);
 
clk_disable_unprepare(tegra->sata_clk);
-   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+   if (!tegra->pdev->dev.pm_domain)
+   tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
 
regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
 }
-- 
2.7.4



[PATCH v1] Follow up patch to Tegra186 AHCI support patch series

2021-04-08 Thread Sowjanya Komatineni
This includes a follow up patch to Tegra186 AHCI support patch series
https://lore.kernel.org/patchwork/cover/1408752/


Sowjanya Komatineni (1):
  ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is
not present

 drivers/ata/ahci_tegra.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

-- 
2.7.4



Re: [PATCH v4 3/3] ata: ahci_tegra: Add AHCI support for Tegra186

2021-04-07 Thread Sowjanya Komatineni



On 4/7/21 3:57 PM, Sowjanya Komatineni wrote:


On 4/7/21 2:36 PM, Dmitry Osipenko wrote:

07.04.2021 04:25, Sowjanya Komatineni пишет:

+    if (!tegra->pdev->dev.pm_domain) {
+    ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
+    tegra->sata_clk,
+    tegra->sata_rst);
+    if (ret)
+    goto disable_regulators;
+    }

Hi,

Why you haven't added condition for tegra_powergate_power_off()? I think
it should break GENPD and legacy PD API isn't not supported by T186 
at all.


I'm also not sure whether the power up/down sequence is correct using 
GENPD.


Moreover the driver doesn't support runtime PM, so GENPD should be
always off?


This driver already using legacy PD API's so thought its supported and 
added power domain device check during powergate_sequence_power_up and 
yes same should apply for powergate_power_off as well. But if legacy 
PD is not supported by T186 then not sure why original driver even 
using these API's.



Sorry just took a look and driver supports T210 and prior tegra as well. 
T210 and prior supports legacy PD and this check is applicable for 
those. So we should add power domain device check for power off as well.


But for T186, we should have GENPD working once we add runtime PM 
support to driver.


Preetham/Thierry, Can you confirm where SATA is un powergated prior to 
kernel?



But as RPM is not implemented yet for this driver, GENPD will be OFF 
but SATA is not in power-gate by the time kernel starts and 
functionally works.


But with RPM implementation, I guess we can do proper power gate on/off.



Re: [PATCH v4 3/3] ata: ahci_tegra: Add AHCI support for Tegra186

2021-04-07 Thread Sowjanya Komatineni



On 4/7/21 2:36 PM, Dmitry Osipenko wrote:

07.04.2021 04:25, Sowjanya Komatineni пишет:

+   if (!tegra->pdev->dev.pm_domain) {
+   ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
+   tegra->sata_clk,
+   tegra->sata_rst);
+   if (ret)
+   goto disable_regulators;
+   }
  

Hi,

Why you haven't added condition for tegra_powergate_power_off()? I think
it should break GENPD and legacy PD API isn't not supported by T186 at all.

I'm also not sure whether the power up/down sequence is correct using GENPD.

Moreover the driver doesn't support runtime PM, so GENPD should be
always off?


This driver already using legacy PD API's so thought its supported and 
added power domain device check during powergate_sequence_power_up and 
yes same should apply for powergate_power_off as well. But if legacy PD 
is not supported by T186 then not sure why original driver even using 
these API's.


Preetham/Thierry, Can you please comment ?

But as RPM is not implemented yet for this driver, GENPD will be OFF but 
SATA is not in power-gate by the time kernel starts and functionally works.


But with RPM implementation, I guess we can do proper power gate on/off.



[PATCH v4 1/3] dt-bindings: ata: tegra: Convert binding documentation to YAML

2021-04-06 Thread Sowjanya Komatineni
This patch converts text based dt-binding document to YAML based
dt-binding document.

Reviewed-by: Rob Herring 
Signed-off-by: Sowjanya Komatineni 
---
 .../devicetree/bindings/ata/nvidia,tegra-ahci.yaml | 138 +
 .../bindings/ata/nvidia,tegra124-ahci.txt  |  44 ---
 2 files changed, 138 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
 delete mode 100644 
Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt

diff --git a/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml 
b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
new file mode 100644
index 000..3c15aea
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ata/nvidia,tegra-ahci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra AHCI SATA Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra124-ahci
+  - nvidia,tegra132-ahci
+  - nvidia,tegra210-ahci
+
+  reg:
+minItems: 2
+maxItems: 3
+items:
+  - description: AHCI registers
+  - description: SATA configuration and IPFS registers
+  - description: SATA AUX registers
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: sata
+  - const: sata-oob
+
+  clocks:
+maxItems: 2
+
+  reset-names:
+items:
+  - const: sata
+  - const: sata-cold
+  - const: sata-oob
+
+  resets:
+maxItems: 3
+
+  phy-names:
+items:
+  - const: sata-0
+
+  phys:
+maxItems: 1
+
+  hvdd-supply:
+description: SATA HVDD regulator supply.
+
+  vddio-supply:
+description: SATA VDDIO regulator supply.
+
+  avdd-supply:
+description: SATA AVDD regulator supply.
+
+  target-5v-supply:
+description: SATA 5V power regulator supply.
+
+  target-12v-supply:
+description: SATA 12V power regulator supply.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clock-names
+  - clocks
+  - reset-names
+  - resets
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - nvidia,tegra124-ahci
+  - nvidia,tegra132-ahci
+then:
+  properties:
+reg:
+  maxItems: 2
+reset-names:
+  minItems: 3
+resets:
+  minItems: 3
+  required:
+- phys
+- phy-names
+- hvdd-supply
+- vddio-supply
+- avdd-supply
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - nvidia,tegra210-ahci
+then:
+  properties:
+reg:
+  minItems: 3
+reset-names:
+  minItems: 3
+resets:
+  minItems: 3
+
+additionalProperties: true
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+sata@7002 {
+compatible = "nvidia,tegra210-ahci";
+reg = <0x70027000 0x2000>, /* AHCI */
+  <0x7002 0x7000>, /* SATA */
+  <0x70001100 0x0001>; /* SATA AUX */
+interrupts = ;
+clocks = <_car TEGRA210_CLK_SATA>,
+ <_car TEGRA210_CLK_SATA_OOB>;
+clock-names = "sata", "sata-oob";
+resets = <_car 124>,
+ <_car 129>,
+ <_car 123>;
+reset-names = "sata", "sata-cold", "sata-oob";
+};
diff --git a/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt 
b/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt
deleted file mode 100644
index 12ab2f7..000
--- a/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Tegra SoC SATA AHCI controller
-
-Required properties :
-- compatible : Must be one of:
-  - Tegra124 : "nvidia,tegra124-ahci"
-  - Tegra132 : "nvidia,tegra132-ahci", "nvidia,tegra124-ahci"
-  - Tegra210 : "nvidia,tegra210-ahci"
-- reg : Should contain 2 entries:
-  - AHCI register set (SATA BAR5)
-  - SATA register set
-- interrupts : Defines the interrupt used by SATA
-- clocks : Must contain an entry for each entry in clock-names.
-  See ../clocks/clock-bindings.txt for details.
-- clock-names : Must include the following entries:
-  - sata
-  - sata-oob
-- resets : Must contain an entry for each entry in reset-names.
-  See ../reset/reset.txt for details.
-- reset-names : Must include the following entries:
-  - sata
-  - sata-oob
-  - sata-cold
-- phys : Must contain an entry for each entry in phy-names.
-  See ../phy/phy-bindings.txt for details.
-- phy-names : Must include the following entries:
-  - For Tegra

[PATCH v4 2/3] dt-binding: ata: tegra: Add dt-binding documentation for Tegra186

2021-04-06 Thread Sowjanya Komatineni
This patch adds dt-bindings documentation for Tegra186 AHCI
controller.

Reviewed-by: Rob Herring 
Signed-off-by: Sowjanya Komatineni 
---
 .../devicetree/bindings/ata/nvidia,tegra-ahci.yaml | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml 
b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
index 3c15aea..a75e9a8 100644
--- a/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
+++ b/Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
@@ -16,6 +16,7 @@ properties:
   - nvidia,tegra124-ahci
   - nvidia,tegra132-ahci
   - nvidia,tegra210-ahci
+  - nvidia,tegra186-ahci
 
   reg:
 minItems: 2
@@ -37,14 +38,31 @@ properties:
 maxItems: 2
 
   reset-names:
+minItems: 2
 items:
   - const: sata
   - const: sata-cold
   - const: sata-oob
 
   resets:
+minItems: 2
 maxItems: 3
 
+  iommus:
+maxItems: 1
+
+  interconnect-names:
+items:
+  - const: dma-mem
+  - const: write
+
+  interconnects:
+maxItems: 2
+
+  power-domains:
+items:
+  - description: SAX power-domain
+
   phy-names:
 items:
   - const: sata-0
@@ -114,6 +132,26 @@ allOf:
 resets:
   minItems: 3
 
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - nvidia,tegra186-ahci
+then:
+  properties:
+reg:
+  minItems: 3
+reset-names:
+  maxItems: 2
+resets:
+  maxItems: 2
+  required:
+- iommus
+- interconnect-names
+- interconnects
+- power-domains
+
 additionalProperties: true
 
 examples:
-- 
2.7.4



[PATCH v4 3/3] ata: ahci_tegra: Add AHCI support for Tegra186

2021-04-06 Thread Sowjanya Komatineni
This patch adds support for AHCI-compliant Serial ATA controller
on Tegra186 SoC.

Tegra186 does not have sata-oob reset.
Tegra186 SATA_NVOOB register filed COMMA_CNT position and width are
different compared to Tegra210 and prior.

So, this patch adds a flag has_sata_oob_rst and tegra_ahci_regs to
SoC specific strcuture tegra_ahci_soc and updated their implementation
accordingly.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/ata/ahci_tegra.c | 60 +---
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index cb55ebc1..56612af 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -59,8 +59,6 @@
 #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN  BIT(22)
 
 #define T_SATA0_NVOOB   0x114
-#define T_SATA0_NVOOB_COMMA_CNT_MASK(0xff << 16)
-#define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16)
 #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK  (0x3 << 24)
 #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE   (0x1 << 24)
 #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK(0x3 << 26)
@@ -154,11 +152,18 @@ struct tegra_ahci_ops {
int (*init)(struct ahci_host_priv *hpriv);
 };
 
+struct tegra_ahci_regs {
+   unsigned int nvoob_comma_cnt_mask;
+   unsigned int nvoob_comma_cnt_val;
+};
+
 struct tegra_ahci_soc {
const char *const   *supply_names;
u32 num_supplies;
boolsupports_devslp;
+   boolhas_sata_oob_rst;
const struct tegra_ahci_ops *ops;
+   const struct tegra_ahci_regs*regs;
 };
 
 struct tegra_ahci_priv {
@@ -240,11 +245,13 @@ static int tegra_ahci_power_on(struct ahci_host_priv 
*hpriv)
if (ret)
return ret;
 
-   ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
-   tegra->sata_clk,
-   tegra->sata_rst);
-   if (ret)
-   goto disable_regulators;
+   if (!tegra->pdev->dev.pm_domain) {
+   ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
+   tegra->sata_clk,
+   tegra->sata_rst);
+   if (ret)
+   goto disable_regulators;
+   }
 
reset_control_assert(tegra->sata_oob_rst);
reset_control_assert(tegra->sata_cold_rst);
@@ -330,10 +337,10 @@ static int tegra_ahci_controller_init(struct 
ahci_host_priv *hpriv)
writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
 
val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
-   val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
+   val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask |
 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
-   val |= (T_SATA0_NVOOB_COMMA_CNT |
+   val |= (tegra->soc->regs->nvoob_comma_cnt_val |
T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
@@ -449,15 +456,35 @@ static const struct tegra_ahci_ops tegra124_ahci_ops = {
.init = tegra124_ahci_init,
 };
 
+static const struct tegra_ahci_regs tegra124_ahci_regs = {
+   .nvoob_comma_cnt_mask = GENMASK(30, 28),
+   .nvoob_comma_cnt_val = (7 << 28),
+};
+
 static const struct tegra_ahci_soc tegra124_ahci_soc = {
.supply_names = tegra124_supply_names,
.num_supplies = ARRAY_SIZE(tegra124_supply_names),
.supports_devslp = false,
+   .has_sata_oob_rst = true,
.ops = _ahci_ops,
+   .regs = _ahci_regs,
 };
 
 static const struct tegra_ahci_soc tegra210_ahci_soc = {
.supports_devslp = false,
+   .has_sata_oob_rst = true,
+   .regs = _ahci_regs,
+};
+
+static const struct tegra_ahci_regs tegra186_ahci_regs = {
+   .nvoob_comma_cnt_mask = GENMASK(23, 16),
+   .nvoob_comma_cnt_val = (7 << 16),
+};
+
+static const struct tegra_ahci_soc tegra186_ahci_soc = {
+   .supports_devslp = false,
+   .has_sata_oob_rst = false,
+   .regs = _ahci_regs,
 };
 
 static const struct of_device_id tegra_ahci_of_match[] = {
@@ -469,6 +496,10 @@ static const struct of_device_id tegra_ahci_of_match[] = {
.compatible = "nvidia,tegra210-ahci",
.data = _ahci_soc
},
+   {
+   .compatible = "nvidia,tegra186-ahci",
+   .data = _ahci_soc
+   },
{}
 };
 MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
@@ -518,10 +549,13 @@ static int 

[PATCH v4 0/3] Add AHCI support for Tegra186

2021-04-06 Thread Sowjanya Komatineni
Re-sending dt-binding and ahci_tegra driver patches as v4 as device
tree patches from v3 are merged but not the AHCI Tegra driver.

Missed to add Jens Axboe to mailing list in v3. Adding for v4.

This series adds support for AHCI-compliant SATA to Tegra186 SoC.

This series includes patches for
- Converting text based dt-binding document to YAML.
- Adding dt-bindings for Tegra186.
- Adding Tegra186 support to Tegra AHCI driver.

Delta between patch versions:
[v4]:   Same as v3 except removed device tree patches as they are
merged.
[v3]:   fixed yaml example to pass dt_binding_check
[v2]:   v1 feedback related to yaml dt-binding.
Removed conditional reset order in yaml and updated dts files
to maintain same order for commonly available resets across
Tegra124 thru Tegra186.


Sowjanya Komatineni (3):
  dt-bindings: ata: tegra: Convert binding documentation to YAML
  dt-binding: ata: tegra: Add dt-binding documentation for Tegra186
  ata: ahci_tegra: Add AHCI support for Tegra186

 .../devicetree/bindings/ata/nvidia,tegra-ahci.yaml | 176 +
 .../bindings/ata/nvidia,tegra124-ahci.txt  |  44 --
 drivers/ata/ahci_tegra.c   |  60 +--
 3 files changed, 223 insertions(+), 57 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ata/nvidia,tegra-ahci.yaml
 delete mode 100644 
Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt

-- 
2.7.4



Re: [PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-16 Thread Sowjanya Komatineni



On 3/16/21 12:18 AM, Sudeep Holla wrote:

On Mon, Mar 15, 2021 at 11:13:24AM -0700, Sowjanya Komatineni wrote:

Hi Sudeep,

I see you are one of the maintainer of PSCI driver. Please add any other
right persons if you think should also agree/comment.

Can you please comment on below 2 items based on your feedback?

1. Can you please suggest on proper way of generalizing to pass state
residency time run-time along with state during state enter?

Not sure if any other drivers need this but for Tegra as MCE firmware is
in-charge of states enter and decisions, passing run-time state residency
from kernel to ATF is required and agree on not using power_state value for
this which is against PSCI spec.


Yes, I prefer you need to get this added in the PSCI specification.
I have passed this thread to the author of the specification.

Thanks Sudeep.



2. Regarding state thresholds, although state thresholds are policy related
in Tegra cpu idle perspective these thresholds are platform specific based
on use case and mainly for MCE firmware usage to decide on state transitions
for core and core clusters as well.


 From previous emails, I gather these can be moved to firmware and need not be
there in DT ?


Yes we can move state thresholds programming from kernel driver to ATF 
but we still need to use DT properties for this to allow users to tweak 
for their use-cases.


With DT access in ATF this can be done. But checking internally on 
having DTB access in ATF as currently we don't support that.





As these are Tegra platform specific, Please comment if any other concerns
in having this configured by Tegra CPU Idle kernel driver.


I prefer not to have Tegra specific idle driver if we can get the necessary
changes in PSCI spec. We must then have just one PSCI idle driver in the
kernel.


Agree by adding state residency run-time propagation along with power 
state to PSCI specification and moving state thresholds update to MCE 
from kernel driver to AT looks like we can use same PSCI cpu idle driver 
although we will be using state thresholds additional DT properties 
under cpu nodes which will be used by ATF firmware once we decide on no 
concerns to allow DTB access in ATF.




Based on my understanding only above issue-1 is PSCI compliant related.
Please confirm.


Correct.

--
Regards,
Sudeep


Re: [PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-15 Thread Sowjanya Komatineni

Re-sending as it went out as HTML instead of plain text.


On 3/15/21 11:13 AM, Sowjanya Komatineni wrote:


Hi Sudeep,

I see you are one of the maintainer of PSCI driver. Please add any 
other right persons if you think should also agree/comment.


Can you please comment on below 2 items based on your feedback?

1. Can you please suggest on proper way of generalizing to pass state 
residency time run-time along with state during state enter?


Not sure if any other drivers need this but for Tegra as MCE firmware 
is in-charge of states enter and decisions, passing run-time state 
residency from kernel to ATF is required and agree on not using 
power_state value for this which is against PSCI spec.


2. Regarding state thresholds, although state thresholds are policy 
related in Tegra cpu idle perspective these thresholds are platform 
specific based on use case and mainly for MCE firmware usage to decide 
on state transitions for core and core clusters as well.


As these are Tegra platform specific, Please comment if any other 
concerns in having this configured by Tegra CPU Idle kernel driver.


Based on my understanding only above issue-1 is PSCI compliant 
related. Please confirm.


Thanks

Sowjanya


On 3/12/21 2:27 PM, Sowjanya Komatineni wrote:


Hi Sudeep,

To make our driver PSCI compliant below are few updates to be done

1. Standardize passing residency time run-time thru PSCI to ATF.

    From PSCI specification I only see PSCI_STAT_RESIDENCY and 
PSCI_STAT_COUNT optional functions for PSCI1.0/PSCI1.1


   Can you please help add right people to explore on possible ways 
to add PSCI function for passing corresponding state residency time 
to ATF?


2. Tegra CPU Idle support definitely need to pass deepest cluster 
state and threshold to MCE firmware from DT and looks like we can 
move this implementation to ATF


 With both of the above implementation changes Tegra194 driver 
will be PSCI compliant.


Thanks

Sowjanya


On 3/11/21 1:11 PM, Sowjanya Komatineni wrote:


On 3/10/21 6:52 PM, Sudeep Holla wrote:

On Mon, Mar 08, 2021 at 10:32:17AM -0800, Sowjanya Komatineni wrote:

On 3/7/21 8:37 PM, Sudeep Holla wrote:

On Wed, Mar 03, 2021 at 10:08:10PM -0800, Sowjanya Komatineni wrote:

This patch adds cpu-idle-states and corresponding state nodes to
Tegra194 CPU in dt-binding document

I see that this platform has PSCI support. Can you care to 
explain why
you need additional DT bindings and driver for PSCI based CPU 
suspend.
Until the reasons are convincing, consider NACK from my side for 
this
driver and DT bindings. You should be really using those bindings 
and

the driver may be with minor changes there.

MCE firmware is in charge of state transition for Tegra194 carmel 
CPUs.


Sure, but I assume only TF-A talks to MCE and not any OSPM/Linux 
kernel.
No. Tegra194 CPU idle driver works with MCE firmware running in 
background so cpuidle kernel driver also talks to MCE firmware 
directly on state information.


For run-time state transitions, need to provide state request 
along with its

residency time to MCE firmware which is running in the background.


Sounds similar to x86 mwait, perhaps we need to extend PSCI if we need
to make this firmware PSCI compliant or just say it is not and 
implement
completely independent implementation. I am not saying that is 
acceptable

ATM but I prefer not to mix some implementation to make it look like
PSCI compliant.

State min residency is updated into power_state value along with 
state id

that is passed to psci_cpu_suspend_enter

Sounds like a hack/workaround. I would prefer to standardise that. 
IIUC

the power_state is more static and derived from DT. I don't like to
overload that TBH. Need to check with authors of that binding.


Passing state idle time to ATF along with state to enter is Tegra 
specific as ATF firmware updates idle time to Tegra MCE firmware 
which will be used for deciding on state transition along with other 
information and background load.


Not sure if this need to be standardized but will try to find 
alternate way to update idle time without misusing power-state value.


Will discuss on this internally and get back.



Also states cross-over idle times need to be provided to MCE 
firmware.



New requirements if this has to be PSCI compliant.


Updating cross-over idle times from DT to MCE firmware directly from 
cpuidle kernel driver with corresponding MCE ARI commands is again 
Tegra specific.




MCE firmware decides on state transition based on these inputs 
along with

its background work load.

So, Tegra specific CPU idle driver is required mainly to provide 
cross-over
thresholds from DT and run time idle state information to MCE 
firmware

through Tegra MCE communication APIs.


I am worried if different vendors will come up with different custom
solution for this. We need to either standardise this is Linux/DT or
in PSCI.

Allowing cross-over threshold through DT allows users to vary idle 
time

Re: [PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-11 Thread Sowjanya Komatineni



On 3/10/21 6:52 PM, Sudeep Holla wrote:

On Mon, Mar 08, 2021 at 10:32:17AM -0800, Sowjanya Komatineni wrote:

On 3/7/21 8:37 PM, Sudeep Holla wrote:

On Wed, Mar 03, 2021 at 10:08:10PM -0800, Sowjanya Komatineni wrote:

This patch adds cpu-idle-states and corresponding state nodes to
Tegra194 CPU in dt-binding document


I see that this platform has PSCI support. Can you care to explain why
you need additional DT bindings and driver for PSCI based CPU suspend.
Until the reasons are convincing, consider NACK from my side for this
driver and DT bindings. You should be really using those bindings and
the driver may be with minor changes there.


MCE firmware is in charge of state transition for Tegra194 carmel CPUs.


Sure, but I assume only TF-A talks to MCE and not any OSPM/Linux kernel.
No. Tegra194 CPU idle driver works with MCE firmware running in 
background so cpuidle kernel driver also talks to MCE firmware directly 
on state information.



For run-time state transitions, need to provide state request along with its
residency time to MCE firmware which is running in the background.


Sounds similar to x86 mwait, perhaps we need to extend PSCI if we need
to make this firmware PSCI compliant or just say it is not and implement
completely independent implementation. I am not saying that is acceptable
ATM but I prefer not to mix some implementation to make it look like
PSCI compliant.


State min residency is updated into power_state value along with state id
that is passed to psci_cpu_suspend_enter


Sounds like a hack/workaround. I would prefer to standardise that. IIUC
the power_state is more static and derived from DT. I don't like to
overload that TBH. Need to check with authors of that binding.


Passing state idle time to ATF along with state to enter is Tegra 
specific as ATF firmware updates idle time to Tegra MCE firmware which 
will be used for deciding on state transition along with other 
information and background load.


Not sure if this need to be standardized but will try to find alternate 
way to update idle time without misusing power-state value.


Will discuss on this internally and get back.




Also states cross-over idle times need to be provided to MCE firmware.


New requirements if this has to be PSCI compliant.


Updating cross-over idle times from DT to MCE firmware directly from 
cpuidle kernel driver with corresponding MCE ARI commands is again Tegra 
specific.





MCE firmware decides on state transition based on these inputs along with
its background work load.

So, Tegra specific CPU idle driver is required mainly to provide cross-over
thresholds from DT and run time idle state information to MCE firmware
through Tegra MCE communication APIs.


I am worried if different vendors will come up with different custom
solution for this. We need to either standardise this is Linux/DT or
in PSCI.


Allowing cross-over threshold through DT allows users to vary idle time
thresholds for state transitions based on different use-cases.


Sounds like policy and not platform specific to be in DT, but I will leave
that to DT maintainers.


cross-over idle times are based on supported CPU core and cluster states 
and updating these from DT to Tegra MCE firmware running in the 
background is Tegra specific.




--
Regards,
Sudeep


Re: [PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-10 Thread Sowjanya Komatineni



On 3/8/21 10:32 AM, Sowjanya Komatineni wrote:


On 3/7/21 8:37 PM, Sudeep Holla wrote:

On Wed, Mar 03, 2021 at 10:08:10PM -0800, Sowjanya Komatineni wrote:

This patch adds cpu-idle-states and corresponding state nodes to
Tegra194 CPU in dt-binding document


I see that this platform has PSCI support. Can you care to explain why
you need additional DT bindings and driver for PSCI based CPU suspend.
Until the reasons are convincing, consider NACK from my side for this
driver and DT bindings. You should be really using those bindings and
the driver may be with minor changes there.


MCE firmware is in charge of state transition for Tegra194 carmel CPUs.

For run-time state transitions, need to provide state request along 
with its residency time to MCE firmware which is running in the 
background.


State min residency is updated into power_state value along with state 
id that is passed to psci_cpu_suspend_enter


Also states cross-over idle times need to be provided to MCE firmware.

MCE firmware decides on state transition based on these inputs along 
with its background work load.


So, Tegra specific CPU idle driver is required mainly to provide 
cross-over thresholds from DT and run time idle state information to 
MCE firmware through Tegra MCE communication APIs.


Allowing cross-over threshold through DT allows users to vary idle 
time thresholds for state transitions based on different use-cases.



Hi Sudeep,

Can you please let me know if you have any more concerns for having this 
Tegra specific cpuidle driver?


Thanks

Sowjanya



Re: [PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-08 Thread Sowjanya Komatineni



On 3/7/21 8:37 PM, Sudeep Holla wrote:

On Wed, Mar 03, 2021 at 10:08:10PM -0800, Sowjanya Komatineni wrote:

This patch adds cpu-idle-states and corresponding state nodes to
Tegra194 CPU in dt-binding document


I see that this platform has PSCI support. Can you care to explain why
you need additional DT bindings and driver for PSCI based CPU suspend.
Until the reasons are convincing, consider NACK from my side for this
driver and DT bindings. You should be really using those bindings and
the driver may be with minor changes there.


MCE firmware is in charge of state transition for Tegra194 carmel CPUs.

For run-time state transitions, need to provide state request along with 
its residency time to MCE firmware which is running in the background.


State min residency is updated into power_state value along with state 
id that is passed to psci_cpu_suspend_enter


Also states cross-over idle times need to be provided to MCE firmware.

MCE firmware decides on state transition based on these inputs along 
with its background work load.


So, Tegra specific CPU idle driver is required mainly to provide 
cross-over thresholds from DT and run time idle state information to MCE 
firmware through Tegra MCE communication APIs.


Allowing cross-over threshold through DT allows users to vary idle time 
thresholds for state transitions based on different use-cases.




[PATCH v1 1/5] MAINTAINERS: Add Tegra CPUIDLE driver section

2021-03-03 Thread Sowjanya Komatineni
Add Tegra CPUIDLE driver section with maintainers and mailing list
entries.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 12 
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index cac8429..277fcfd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4679,6 +4679,18 @@ S:   Supported
 F: drivers/cpuidle/cpuidle-psci.h
 F: drivers/cpuidle/cpuidle-psci-domain.c
 
+CPUIDLE DRIVER - TEGRA194
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Krishna Sitaraman 
+M: Sanjay Chandrashekara 
+M: Sowjanya Komatineni 
+L: linux...@vger.kernel.org
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/arm/nvidia,tegra194-ccplex.yaml
+F: drivers/cpuidle/cpuidle-tegra194.c
+
 CRAMFS FILESYSTEM
 M: Nicolas Pitre 
 S: Maintained
-- 
2.7.4



[PATCH v1 5/5] arm64: dts: tegra194: Add CPU idle states

2021-03-03 Thread Sowjanya Komatineni
This patch adds CPU core and cluster idle states to Tegra194
device tree

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 9449156..f9c2731 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -2155,12 +2155,14 @@
nvidia,bpmp = <>;
#address-cells = <1>;
#size-cells = <0>;
+   cluster-deepest-power-state = <0x6>;
 
cpu0_0: cpu@0 {
compatible = "nvidia,tegra194-carmel";
device_type = "cpu";
reg = <0x000>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2175,6 +2177,7 @@
device_type = "cpu";
reg = <0x001>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2189,6 +2192,7 @@
device_type = "cpu";
reg = <0x100>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2203,6 +2207,7 @@
device_type = "cpu";
reg = <0x101>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2217,6 +,7 @@
device_type = "cpu";
reg = <0x200>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2231,6 +2237,7 @@
device_type = "cpu";
reg = <0x201>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2245,6 +2252,7 @@
device_type = "cpu";
reg = <0x300>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2259,6 +2267,7 @@
device_type = "cpu";
reg = <0x301>;
enable-method = "psci";
+   cpu-idle-states = <>;
i-cache-size = <131072>;
i-cache-line-size = <64>;
i-cache-sets = <512>;
@@ -2343,12 +2352,31 @@
cache-line-size = <64>;
cache-sets = <4096>;
};
+
+   cpu_core_power_states {
+   C6: c6 {
+   compatible = "nvidia,tegra194-cpuidle-core";
+   idle-state-name = "CPU powergated, state 
retained";
+   wakeup-latency-us = <2000>;
+   min-residency-us = <3>;
+   arm,psci-suspend-param = <0x6>;
+   status = "okay";
+   };
+   };
+
+   cpu_crossover_thresholds {
+   thresholds {
+   crossover_c1_c6 = <3>;
+   crossover_cc1_cc6 = <8>;
+   };
+   };
};
 
psci {
compatible = "arm,psci-1.0";
status = "okay";
method = "smc";
+   cpu_suspend = <0xC401>;
};
 
sound {
-- 
2.7.4



[PATCH v1 4/5] cpuidle: Add Tegra194 cpuidle driver

2021-03-03 Thread Sowjanya Komatineni
This patch adds cpuidle driver for Tegra194.

Tegra194 Carmel CPU supports two core idle state C1 (clock gated)
and C6 (power gated with state restoration) and one cluster idle
state CC6 (power gated).

MCE firmware makes decision on core/cluster power state transition
based on its background tasks and states information provided by
CPU idle driver.

CPU idle driver provides deepest cluster power state, core power
state transition request, estimated time of next wake-up and states
crossover thresholds to MCE firmware through Tegra mce driver.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/cpuidle/Kconfig.arm|  10 ++
 drivers/cpuidle/Makefile   |   1 +
 drivers/cpuidle/cpuidle-tegra194.c | 319 +
 3 files changed, 330 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-tegra194.c

diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 0844fad..e9adad1 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -105,6 +105,16 @@ config ARM_TEGRA_CPUIDLE
help
  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
 
+config ARM_TEGRA194_CPUIDLE
+   tristate "CPU Idle Driver for NVIDIA Tegra194 SoC"
+   depends on ARCH_TEGRA_194_SOC
+   select ARM_CPU_SUSPEND
+   select DT_IDLE_STATES
+   select TEGRA_MCE
+   default y
+   help
+ Select this to enable cpuidle for NVIDIA Tegra194 SoC.
+
 config ARM_QCOM_SPM_CPUIDLE
bool "CPU Idle Driver for Qualcomm Subsystem Power Manager (SPM)"
depends on (ARCH_QCOM || COMPILE_TEST) && !ARM64
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 26bbc5e..4d89578 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
 obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
 obj-$(CONFIG_ARM_PSCI_CPUIDLE_DOMAIN)  += cpuidle-psci-domain.o
 obj-$(CONFIG_ARM_TEGRA_CPUIDLE)+= cpuidle-tegra.o
+obj-$(CONFIG_ARM_TEGRA194_CPUIDLE)  += cpuidle-tegra194.o
 obj-$(CONFIG_ARM_QCOM_SPM_CPUIDLE) += cpuidle-qcom-spm.o
 
 ###
diff --git a/drivers/cpuidle/cpuidle-tegra194.c 
b/drivers/cpuidle/cpuidle-tegra194.c
new file mode 100644
index 000..4ae67ce
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-tegra194.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CPU idle driver for Tegra194 CPUs
+ *
+ * Copyright (c) 2020-2021, NVIDIA Corporation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "cpuidle-psci.h"
+#include "dt_idle_states.h"
+
+#define T194_NVG_CROSSOVER_C6  
TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND
+#define T194_NVG_CROSSOVER_CC6 
TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND
+
+#define PSCI_PSTATE_ID_MASK0xf
+#define PSCI_PSTATE_WKTIM_MASK 0x0ff0
+#define PSCI_PSTATE_WKTIM_SHIFT4
+
+/*
+ * BG_TIME is margin added to target_residency so that actual HW has better
+ * chance entering deep idle state instead of getting back to shallower one.
+ * Units in us.
+ */
+#define BG_TIME2000
+
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
+static struct cpuidle_driver t194_cpu_idle_driver;
+static enum cpuhp_state hp_state;
+static u32 deepest_cc_state;
+static u32 tsc_per_usec;
+
+static bool check_mce_version(void)
+{
+   u32 mce_version_major, mce_version_minor;
+   int err;
+
+   err = tegra_mce_read_versions(_version_major, _version_minor);
+   if (!err && mce_version_major >= TEGRA_NVG_VERSION_MAJOR)
+   return true;
+   else
+   return false;
+}
+
+static int
+t194_cpu_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, 
int index)
+{
+   u32 *state = __this_cpu_read(psci_power_state);
+   u32 power_state = state[index];
+   u32 wake_time;
+   int ret;
+
+   /*
+* MCE firmware does the state transition based on requested idle state,
+* state crossover thresholds and target residency time along with its
+* background work.
+* Pass the state target_residency time along with state ID to MCE
+* firmware through PSCI power-state value.
+*
+* LSB 8 bits of wake time is lost and only 24 MSB bits of wake time 
can fit
+* into additional bits of state value.
+*/
+   wake_time = (drv->states[index].target_residency + BG_TIME) * 
tsc_per_usec;
+   power_state |= ((wake_time >> PSCI_PSTATE_WKTIM_SHIFT) & 
PSCI_PSTATE_WKTIM_MASK);
+
+   if ((power_state & PSCI_PSTATE_ID_MASK) == TEGRA_NVG_CORE_C6)
+ 

[PATCH v1 3/5] dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes

2021-03-03 Thread Sowjanya Komatineni
This patch adds cpu-idle-states and corresponding state nodes to
Tegra194 CPU in dt-binding document

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/arm/nvidia,tegra194-ccplex.yaml   | 53 ++
 1 file changed, 53 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/nvidia,tegra194-ccplex.yaml 
b/Documentation/devicetree/bindings/arm/nvidia,tegra194-ccplex.yaml
index c9675c4..e1a5005 100644
--- a/Documentation/devicetree/bindings/arm/nvidia,tegra194-ccplex.yaml
+++ b/Documentation/devicetree/bindings/arm/nvidia,tegra194-ccplex.yaml
@@ -30,6 +30,36 @@ properties:
   Specifies the bpmp node that needs to be queried to get
   operating point data for all CPUs.
 
+  cluster-deepest-power-state:
+$ref: /schemas/types.yaml#/definitions/uint32
+description: CPU cluster deepest power state ID.
+
+patternProperties:
+  "^[a-z0-9]+$":
+type: object
+description: |
+  CPU core idle state nodes.
+  Refer to Documentation/devicetree/bindings/arm/idle-states.yaml
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra194-cpuidle-core
+
+  cpu_crossover_thresholds:
+type: object
+description: CPU idle states crossover threshold time in uSec.
+
+patternProperties:
+  "^[a-z0-9]+$":
+type: object
+
+properties:
+  crossover_c1_c6:
+$ref: /schemas/types.yaml#/definitions/uint32
+  crossover_cc1_cc6:
+$ref: /schemas/types.yaml#/definitions/uint32
+
 additionalProperties: true
 
 examples:
@@ -39,12 +69,14 @@ examples:
   nvidia,bpmp = <>;
   #address-cells = <1>;
   #size-cells = <0>;
+  cluster-deepest-power-state = <0x6>;
 
   cpu0_0: cpu@0 {
 compatible = "nvidia,tegra194-carmel";
 device_type = "cpu";
 reg = <0x0>;
 enable-method = "psci";
+cpu-idle-states = <>;
   };
 
   cpu0_1: cpu@1 {
@@ -52,6 +84,7 @@ examples:
 device_type = "cpu";
 reg = <0x001>;
 enable-method = "psci";
+cpu-idle-states = <>;
   };
 
   cpu1_0: cpu@100 {
@@ -59,6 +92,7 @@ examples:
 device_type = "cpu";
 reg = <0x100>;
 enable-method = "psci";
+cpu-idle-states = <>;
   };
 
   cpu1_1: cpu@101 {
@@ -66,6 +100,25 @@ examples:
 device_type = "cpu";
 reg = <0x101>;
 enable-method = "psci";
+cpu-idle-states = <>;
+  };
+
+  cpu_core_power_states {
+   C6: c6 {
+ compatible = "nvidia,tegra194-cpuidle-core";
+ idle-state-name = "CPU powergated, state retained";
+ wakeup-latency-us = <2000>;
+ min-residency-us = <3>;
+ arm,psci-suspend-param = <0x6>;
+ status = "okay";
+   };
+ };
+
+ cpu_crossover_thresholds {
+  thresholds {
+crossover_c1_c6 = <3>;
+crossover_cc1_cc6   = <8>;
   };
+ };
 };
 ...
-- 
2.7.4



[PATCH v1 2/5] firmware: tegra: Add Tegra194 MCE ARI driver

2021-03-03 Thread Sowjanya Komatineni
Tegra MCE Abstract Request Interface (ARI) driver manages all NVG
requests to MCE firmware running in the background.

This patch adds Tegra194 MCE interface driver for communicating with
MCE firmware on CPU state configurations and state transition requests
from the CPU idle driver.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/firmware/tegra/Kconfig|  11 +++
 drivers/firmware/tegra/Makefile   |   4 +
 drivers/firmware/tegra/mce-tegra194.c | 155 ++
 drivers/firmware/tegra/mce.c  |  88 +++
 include/soc/tegra/mce.h   |  32 +++
 include/soc/tegra/t194_nvg.h  |  56 
 6 files changed, 346 insertions(+)
 create mode 100644 drivers/firmware/tegra/mce-tegra194.c
 create mode 100644 drivers/firmware/tegra/mce.c
 create mode 100644 include/soc/tegra/mce.h
 create mode 100644 include/soc/tegra/t194_nvg.h

diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
index 1c8ba1f..a14ef1c 100644
--- a/drivers/firmware/tegra/Kconfig
+++ b/drivers/firmware/tegra/Kconfig
@@ -23,4 +23,15 @@ config TEGRA_BPMP
  This driver manages the IPC interface between host CPU and the
  firmware running on BPMP.
 
+config TEGRA_MCE
+   bool "Tegra MCE driver"
+   depends on ARCH_TEGRA_194_SOC
+   help
+ MCE (Micro Codec Engine) firmware is in charge of CPUs power state
+ transitions.
+
+ Tegra MCE driver is an interface driver to communicate with MCE
+ firmware for all the CPU power state change requests from CPU idle
+ driver.
+
 endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
index 49c87e0..2c0417e 100644
--- a/drivers/firmware/tegra/Makefile
+++ b/drivers/firmware/tegra/Makefile
@@ -6,3 +6,7 @@ tegra-bpmp-$(CONFIG_ARCH_TEGRA_194_SOC) += bpmp-tegra186.o
 tegra-bpmp-$(CONFIG_DEBUG_FS)  += bpmp-debugfs.o
 obj-$(CONFIG_TEGRA_BPMP)   += tegra-bpmp.o
 obj-$(CONFIG_TEGRA_IVC)+= ivc.o
+
+tegra-mce-y= mce.o
+tegra-mce-$(CONFIG_ARCH_TEGRA_194_SOC) += mce-tegra194.o
+obj-$(CONFIG_TEGRA_MCE)+= tegra-mce.o
diff --git a/drivers/firmware/tegra/mce-tegra194.c 
b/drivers/firmware/tegra/mce-tegra194.c
new file mode 100644
index 000..5cec761d
--- /dev/null
+++ b/drivers/firmware/tegra/mce-tegra194.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, NVIDIA CORPORATION.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+/* Issue a NVG request with data */
+static noinline notrace void nvg_send_req_data(u64 req, u64 data)
+{
+   asm volatile ("msr s3_0_c15_c1_2, %0\n"
+ "msr s3_0_c15_c1_3, %1\n"
+ :: "r" (req), "r" (data));
+}
+
+/* Issue a NVG request with no data */
+static noinline notrace void nvg_send_req(u64 req)
+{
+   asm volatile ("msr s3_0_c15_c1_2, %0\n" :: "r" (req));
+}
+
+/* Issue a NVG request to read the command response */
+static noinline notrace u64 nvg_get_response(void)
+{
+   u64 ret;
+
+   asm volatile ("mrs %0, s3_0_c15_c1_3" : "=r" (ret));
+
+   return ret;
+}
+
+static int tegra194_mce_update_cstate_info(u32 cluster, u32 ccplex, u32 system,
+  u8 force, u32 wake_mask, bool valid)
+{
+   nvg_cstate_info_channel_t cstate_info = { 0 };
+
+   /* disable preemption */
+   preempt_disable();
+
+   /* update CLUSTER_CSTATE? */
+   if (cluster) {
+   cstate_info.bits.cluster_state = cluster;
+   cstate_info.bits.update_cluster = 1;
+   }
+
+   /* update CCPLEX_CSTATE? */
+   if (ccplex) {
+   cstate_info.bits.cg_cstate = ccplex;
+   cstate_info.bits.update_cg = 1;
+   }
+
+   /* update SYSTEM_CSTATE? */
+   if (system) {
+   cstate_info.bits.system_cstate = system;
+   cstate_info.bits.update_system = 1;
+   }
+
+   /* update wake mask value? */
+   if (valid)
+   cstate_info.bits.update_wake_mask = 1;
+
+   /* set the wake mask */
+   cstate_info.bits.wake_mask = wake_mask;
+
+   /* set the updated cstate info */
+   nvg_send_req_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, cstate_info.flat);
+
+   /* enable preemption */
+   preempt_enable();
+
+   return 0;
+}
+
+static int tegra194_mce_update_crossover_time(u32 type, u32 time)
+{
+   if (type != TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND &&
+   type != TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND &&
+   type != TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND) {
+   pr_err("%s: unknown crossover type (%d)\n", __func__, type);
+   return -EINVAL;
+   }
+
+   /* disable pre-emption*/
+   preempt_disable();
+
+   nvg_send_req_

[PATCH v1 0/5] Add cpuidle support for Tegra194

2021-03-03 Thread Sowjanya Komatineni
This series adds cpuidle support for Tegra194 carmel CPUs.

MCE firmware is responsible for deciding on CPU idle power state
based on state information and MCE firmware background work.

Tegra MCE ARI driver is the interface driver to communicate with
MCE firmware from the kernel.

CPU idle driver passes idle state information to MCE through Tegra
MCE driver and requests idle state transition to MCE happens through
PSCI CPU suspend.

This series includes below patches
- Add CPUIDLE section to MAINTAINERS
- Add Tegra MCE ARI driver to communicate with MCE firmware from kernel
- Add dt-bindings for Tegra194 cpu idle states
- Add cpuidle driver to support Tegra194 CPUs idle state management
- Update Tegra194 device tree with cpuidle support to Tegra194 CPUs.


Sowjanya Komatineni (5):
  MAINTAINERS: Add Tegra CPUIDLE driver section
  firmware: tegra: Add Tegra194 MCE ARI driver
  dt-bindings: arm: Add cpu-idle-states to Tegra194 CPU nodes
  cpuidle: Add Tegra194 cpuidle driver
  arm64: dts: tegra194: Add CPU idle states

 .../bindings/arm/nvidia,tegra194-ccplex.yaml   |  53 
 MAINTAINERS|  12 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi   |  28 ++
 drivers/cpuidle/Kconfig.arm|  10 +
 drivers/cpuidle/Makefile   |   1 +
 drivers/cpuidle/cpuidle-tegra194.c | 319 +
 drivers/firmware/tegra/Kconfig |  11 +
 drivers/firmware/tegra/Makefile|   4 +
 drivers/firmware/tegra/mce-tegra194.c  | 155 ++
 drivers/firmware/tegra/mce.c   |  88 ++
 include/soc/tegra/mce.h|  32 +++
 include/soc/tegra/t194_nvg.h   |  56 
 12 files changed, 769 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-tegra194.c
 create mode 100644 drivers/firmware/tegra/mce-tegra194.c
 create mode 100644 drivers/firmware/tegra/mce.c
 create mode 100644 include/soc/tegra/mce.h
 create mode 100644 include/soc/tegra/t194_nvg.h

-- 
2.7.4



[PATCH v3] i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO

2021-01-12 Thread Sowjanya Komatineni
VI I2C controller has known hardware bug where immediate multiple
writes to TX_FIFO register gets stuck.

Recommended software work around is to read I2C register after
each write to TX_FIFO register to flush out the data.

This patch implements this work around for VI I2C controller.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/i2c/busses/i2c-tegra.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c..4a27782 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 
val, unsigned int reg)
/* read back register to make sure that register writes completed */
if (reg != I2C_TX_FIFO)
readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+   else if (i2c_dev->is_vi)
+   readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, 
I2C_INT_STATUS));
 }
 
 static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, 
void *data,
writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
 
+static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
+  unsigned int reg, unsigned int len)
+{
+   u32 *data32 = data;
+
+   /*
+* VI I2C controller has known hardware bug where writes get stuck
+* when immediate multiple writes happen to TX_FIFO register.
+* Recommended software work around is to read I2C register after
+* each write to TX_FIFO register to flush out the data.
+*/
+   while (len--)
+   i2c_writel(i2c_dev, *data32++, reg);
+}
+
 static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
   unsigned int reg, unsigned int len)
 {
@@ -811,7 +828,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev 
*i2c_dev)
i2c_dev->msg_buf_remaining = buf_remaining;
i2c_dev->msg_buf = buf + words_to_transfer * 
BYTES_PER_FIFO_WORD;
 
-   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+   if (i2c_dev->is_vi)
+   i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
+   else
+   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
 
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
}
-- 
2.7.4



[PATCH v3] Create i2c_writesl_vi() to use with VI I2C

2021-01-12 Thread Sowjanya Komatineni
Patch in this series is to fix known hardware bug with VI I2C
controller where immediate multiple writes to TX_FIFO gets stuck
resulting in VI I2C controller to be in bad state.

Delta between patch versions:
[v3]:   Includes v2 feedback 
- uses relaxed writel and readl
- avoids type casting on data buffer during i2c_writesl_vi()
- updated comment to clearly mention this as workaround to
  known hardware bug with VI I2C.

[v2]:   Creates i2c_writesl_vi() for vi i2c based on v1 feedback.

[v1]:   Updates i2c_writesl() to use writel() followed by i2c_readl().

Sowjanya Komatineni (1):
  i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX
FIFO

 drivers/i2c/busses/i2c-tegra.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

-- 
2.7.4



Re: [PATCH v2] i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO

2021-01-12 Thread Sowjanya Komatineni



On 1/11/21 9:56 PM, Dmitry Osipenko wrote:

12.01.2021 07:06, Sowjanya Komatineni пишет:

VI I2C don't have DMA support and uses PIO mode all the time.

Current driver uses writesl() to fill TX FIFO based on available
empty slots and with this seeing strange silent hang during any I2C
register access after filling TX FIFO with 8 words.

Using writel() followed by i2c_readl() in a loop to write all words
to TX FIFO instead of using writesl() helps for large transfers in
PIO mode.

So, this patch creates i2c_writesl_vi() API to use with VI I2C for
filling TX FIFO.

Signed-off-by: Sowjanya Komatineni 
---
  drivers/i2c/busses/i2c-tegra.c | 20 +++-
  1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c..e2b7503 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -339,6 +339,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, 
void *data,
writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
  }
  
+static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, u32 *data,

+  unsigned int reg, unsigned int len)
+{
+   /*
+* Using writesl() to fill VI I2C TX FIFO for transfers more than
+* 6 words is causing a silent hang on any VI I2C register access
+* after TX FIFO writes.
+* So using writel() followed by i2c_readl().
+*/
+   while (len--) {
+   writel(*data++, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, 
reg));
+   i2c_readl(i2c_dev, I2C_INT_STATUS);
+   }
+}
+
  static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
   unsigned int reg, unsigned int len)
  {
@@ -811,7 +826,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev 
*i2c_dev)
i2c_dev->msg_buf_remaining = buf_remaining;
i2c_dev->msg_buf = buf + words_to_transfer * 
BYTES_PER_FIFO_WORD;
  
-		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);

+   if (i2c_dev->is_vi)
+   i2c_writesl_vi(i2c_dev, (u32 *)buf, I2C_TX_FIFO, 
words_to_transfer);
+   else
+   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
  
  		buf += words_to_transfer * BYTES_PER_FIFO_WORD;

}


Looks almost good, could we please use a relaxed writel and avoid the casting 
in the code?

Like this:

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c3238d..4f843b423d83 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 
val, unsigned int reg)
/* read back register to make sure that register writes completed */
if (reg != I2C_TX_FIFO)
readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+   else
+   readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, 
I2C_INT_STATUS));
  }
  
  static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)

@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, 
void *data,
writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
  }
  
+static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,

+  unsigned int reg, unsigned int len)
+{
+   u32 *data32 = data;
+
+   /*
+* Using writesl() to fill VI I2C TX FIFO for transfers more than
+* 6 words is causing a silent hang on any VI I2C register access
+* after TX FIFO writes. Each write to FIFO should follow by a read
+* of any I2C register in order to work around the problem.
+*/
+   while (len--)
+   i2c_writel(i2c_dev, *data32++, reg);
+}
+
  static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
   unsigned int reg, unsigned int len)
  {
@@ -811,7 +828,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev 
*i2c_dev)
i2c_dev->msg_buf_remaining = buf_remaining;
i2c_dev->msg_buf = buf + words_to_transfer * 
BYTES_PER_FIFO_WORD;
  
-		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);

+   if (i2c_dev->is_vi)
+   i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
+   else
+   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
  
  		buf += words_to_transfer * BYTES_PER_FIFO_WORD;

}



Will have v3.



Re: [PATCH v1] i2c: tegra: Fix i2c_writesl() to use writel() instead of writesl()

2021-01-12 Thread Sowjanya Komatineni



On 1/12/21 1:32 AM, David Laight wrote:

From: Sowjanya Komatineni

Sent: 11 January 2021 17:38

...

Using writesl() for filling TX_FIFO causing silent hang immediate on any
i2c register access after filling FIFO with 8 words and some times with
6 words as well.

So couldn't INTERRUPT_STATUS registers to check for TX FIFO Overflows
when this silent hang happens.

Tried to read thru back-door (JTAG path) but could not connect to JTAG
either. Looks like Tegra chip is in some weird state.

But using writel() followed by i2c_readl helps. Not sure if any thing
related to register access delay or some other issue.

How much does the i2c_read() slow down the transfer?
If the device is PCIe it is probably significant.

If the underlying problem is that the Tegra chip can't handle
back to back writes to the tx fifo maybe there are other solutions!
1) Send it back and ask for a working chip :-)
2) Maybe an interleaved write will slow things down enough?

It may be worth testing back to back writes to other registers
to see if it is a problem that is specific to the tx fifo.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)


This is a known hardware bug with VI I2C controller which is under 
host1x where immediate multiple writes to TX FIFO register gets stuck 
and reading from a register allows them to be flushed out.


VI I2C is dedicated for camera sensors or HDMI2CSI bridge.



[PATCH v2] i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO

2021-01-11 Thread Sowjanya Komatineni
VI I2C don't have DMA support and uses PIO mode all the time.

Current driver uses writesl() to fill TX FIFO based on available
empty slots and with this seeing strange silent hang during any I2C
register access after filling TX FIFO with 8 words.

Using writel() followed by i2c_readl() in a loop to write all words
to TX FIFO instead of using writesl() helps for large transfers in
PIO mode.

So, this patch creates i2c_writesl_vi() API to use with VI I2C for
filling TX FIFO.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/i2c/busses/i2c-tegra.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c..e2b7503 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -339,6 +339,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, 
void *data,
writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
 
+static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, u32 *data,
+  unsigned int reg, unsigned int len)
+{
+   /*
+* Using writesl() to fill VI I2C TX FIFO for transfers more than
+* 6 words is causing a silent hang on any VI I2C register access
+* after TX FIFO writes.
+* So using writel() followed by i2c_readl().
+*/
+   while (len--) {
+   writel(*data++, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, 
reg));
+   i2c_readl(i2c_dev, I2C_INT_STATUS);
+   }
+}
+
 static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
   unsigned int reg, unsigned int len)
 {
@@ -811,7 +826,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev 
*i2c_dev)
i2c_dev->msg_buf_remaining = buf_remaining;
i2c_dev->msg_buf = buf + words_to_transfer * 
BYTES_PER_FIFO_WORD;
 
-   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+   if (i2c_dev->is_vi)
+   i2c_writesl_vi(i2c_dev, (u32 *)buf, I2C_TX_FIFO, 
words_to_transfer);
+   else
+   i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, 
words_to_transfer);
 
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
}
-- 
2.7.4



[PATCH v2] Create i2c_writesl_vi() to use with VI I2C

2021-01-11 Thread Sowjanya Komatineni
Patch in this series is to fix silent hang seen when using writesl()
for filling VI I2C TX FIFO.

Delta between patch versions:
[v2]:   Creates i2c_writesl_vi() for vi i2c based on v1 feedback.

[v1]:   Updates i2c_writesl() to use writel() followed by i2c_readl().


Sowjanya Komatineni (1):
  i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX
FIFO

 drivers/i2c/busses/i2c-tegra.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

-- 
2.7.4



Re: [PATCH v1] i2c: tegra: Fix i2c_writesl() to use writel() instead of writesl()

2021-01-11 Thread Sowjanya Komatineni



On 1/11/21 11:29 AM, Dmitry Osipenko wrote:

11.01.2021 20:38, Sowjanya Komatineni пишет:

On 1/11/21 4:09 AM, Dmitry Osipenko wrote:

11.01.2021 14:50, Dmitry Osipenko пишет:

20.10.2020 19:37, Sowjanya Komatineni пишет:

On 10/20/20 12:48 AM, Thierry Reding wrote:

On Mon, Oct 19, 2020 at 09:03:54PM -0700, Sowjanya Komatineni wrote:

VI I2C don't have DMA support and uses PIO mode all the time.

Current driver uses writesl() to fill TX FIFO based on available
empty slots and with this seeing strange silent hang during any I2C
register access after filling TX FIFO with 8 words.

Using writel() followed by i2c_readl() in a loop to write all words
to TX FIFO instead of using writesl() helps for large transfers in
PIO mode.

So, this patch updates i2c_writesl() API to use writel() in a loop
instead of writesl().

Signed-off-by: Sowjanya Komatineni 
---
    drivers/i2c/busses/i2c-tegra.c | 9 ++---
    1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c
b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c..274bf3a 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -333,10 +333,13 @@ static u32 i2c_readl(struct tegra_i2c_dev
*i2c_dev, unsigned int reg)
    return readl_relaxed(i2c_dev->base +
tegra_i2c_reg_addr(i2c_dev, reg));
    }
    -static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void
*data,
+static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, u32 *data,
    unsigned int reg, unsigned int len)
    {
-    writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data,
len);
+    while (len--) {
+    writel(*data++, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev,
reg));
+    i2c_readl(i2c_dev, I2C_INT_STATUS);
+    }
    }
      static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void
*data,
@@ -811,7 +814,7 @@ static int tegra_i2c_fill_tx_fifo(struct
tegra_i2c_dev *i2c_dev)
    i2c_dev->msg_buf_remaining = buf_remaining;
    i2c_dev->msg_buf = buf + words_to_transfer *
BYTES_PER_FIFO_WORD;
    -    i2c_writesl(i2c_dev, buf, I2C_TX_FIFO,
words_to_transfer);
+    i2c_writesl(i2c_dev, (u32 *)buf, I2C_TX_FIFO,
words_to_transfer);

I've thought a bit more about this and I wonder if we're simply
reading
out the wrong value for tx_fifo_avail and therefore end up overflowing
the TX FIFO. Have you checked what the value is for tx_fifo_avail when
this silent hang occurs? Given that this is specific to the VI I2C I'm
wondering if this is perhaps a hardware bug where we read the wrong TX
FIFO available count.

Thierry

Yes FIFO status shows all 8 slots available.

Please explain how you checked that 8 slots are available, provide
example code.


Have you checked the FIFO overflow interrupt?

This is seen with VI I2C (which is under host1x) as we use PIO mode
always even for large transfers.
HW wise VI I2C is similar to other I2C and FIFO depth is also 8 words.

tegra_i2c_fill_tx_fifo() reads I2C_FIFO_STATUS register field
TX_FIFO_EMPTY_CNT which tells empty slots available in TX_FIFO that can
be filled.
Added debug message to print empty count and, during beginning of
transfer when it executes tegra_i2c_fill_tx_fifo(), empty slots are 8


Using writesl() for filling TX_FIFO causing silent hang immediate on any
i2c register access after filling FIFO with 8 words and some times with
6 words as well.

So couldn't INTERRUPT_STATUS registers to check for TX FIFO Overflows
when this silent hang happens.

Tried to read thru back-door (JTAG path) but could not connect to JTAG
either. Looks like Tegra chip is in some weird state.

But using writel() followed by i2c_readl helps. Not sure if any thing
related to register access delay or some other issue.



Does downstream kernel have this problem?

If there is really no good alternative right now, then perhaps should be
a bit cleaner to add i2c_writesl_vi(), which should contain explanatory
comment telling why it's needed and then it should be used only for the
VI I2C controller.


Yes downstream also has same issue when using writesl() and downstream 
vi i2c driver uses writel() followed by i2c_readl()


OK. Will create separate i2c_writesl_vi() to use with vi i2c and will 
add comment in the code.




Re: [PATCH v1] i2c: tegra: Fix i2c_writesl() to use writel() instead of writesl()

2021-01-11 Thread Sowjanya Komatineni



On 1/11/21 4:09 AM, Dmitry Osipenko wrote:

11.01.2021 14:50, Dmitry Osipenko пишет:

20.10.2020 19:37, Sowjanya Komatineni пишет:

On 10/20/20 12:48 AM, Thierry Reding wrote:

On Mon, Oct 19, 2020 at 09:03:54PM -0700, Sowjanya Komatineni wrote:

VI I2C don't have DMA support and uses PIO mode all the time.

Current driver uses writesl() to fill TX FIFO based on available
empty slots and with this seeing strange silent hang during any I2C
register access after filling TX FIFO with 8 words.

Using writel() followed by i2c_readl() in a loop to write all words
to TX FIFO instead of using writesl() helps for large transfers in
PIO mode.

So, this patch updates i2c_writesl() API to use writel() in a loop
instead of writesl().

Signed-off-by: Sowjanya Komatineni 
---
   drivers/i2c/busses/i2c-tegra.c | 9 ++---
   1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c
b/drivers/i2c/busses/i2c-tegra.c
index 6f08c0c..274bf3a 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -333,10 +333,13 @@ static u32 i2c_readl(struct tegra_i2c_dev
*i2c_dev, unsigned int reg)
   return readl_relaxed(i2c_dev->base +
tegra_i2c_reg_addr(i2c_dev, reg));
   }
   -static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
+static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, u32 *data,
   unsigned int reg, unsigned int len)
   {
-    writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data,
len);
+    while (len--) {
+    writel(*data++, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev,
reg));
+    i2c_readl(i2c_dev, I2C_INT_STATUS);
+    }
   }
     static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
@@ -811,7 +814,7 @@ static int tegra_i2c_fill_tx_fifo(struct
tegra_i2c_dev *i2c_dev)
   i2c_dev->msg_buf_remaining = buf_remaining;
   i2c_dev->msg_buf = buf + words_to_transfer *
BYTES_PER_FIFO_WORD;
   -    i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+    i2c_writesl(i2c_dev, (u32 *)buf, I2C_TX_FIFO,
words_to_transfer);

I've thought a bit more about this and I wonder if we're simply reading
out the wrong value for tx_fifo_avail and therefore end up overflowing
the TX FIFO. Have you checked what the value is for tx_fifo_avail when
this silent hang occurs? Given that this is specific to the VI I2C I'm
wondering if this is perhaps a hardware bug where we read the wrong TX
FIFO available count.

Thierry

Yes FIFO status shows all 8 slots available.

Please explain how you checked that 8 slots are available, provide
example code.


Have you checked the FIFO overflow interrupt?


This is seen with VI I2C (which is under host1x) as we use PIO mode 
always even for large transfers.

HW wise VI I2C is similar to other I2C and FIFO depth is also 8 words.

tegra_i2c_fill_tx_fifo() reads I2C_FIFO_STATUS register field 
TX_FIFO_EMPTY_CNT which tells empty slots available in TX_FIFO that can 
be filled.
Added debug message to print empty count and, during beginning of 
transfer when it executes tegra_i2c_fill_tx_fifo(), empty slots are 8



Using writesl() for filling TX_FIFO causing silent hang immediate on any 
i2c register access after filling FIFO with 8 words and some times with 
6 words as well.


So couldn't INTERRUPT_STATUS registers to check for TX FIFO Overflows 
when this silent hang happens.


Tried to read thru back-door (JTAG path) but could not connect to JTAG 
either. Looks like Tegra chip is in some weird state.


But using writel() followed by i2c_readl helps. Not sure if any thing 
related to register access delay or some other issue.





Re: [PATCH v5 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2021-01-04 Thread Sowjanya Komatineni



On 12/31/20 10:33 AM, Rob Herring wrote:

On Mon, 21 Dec 2020 13:17:32 -0800, Sowjanya Komatineni wrote:

This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
  .../bindings/spi/nvidia,tegra210-quad.yaml | 117 +
  1 file changed, 117 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml



Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.


Sorry Rob. Missed to add tag from v4 to v5.

Regards,

Sowjanya



[PATCH v5 9/9] arm64: tegra: Enable QSPI on Jetson Xavier NX

2020-12-21 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Xavier NX.

Signed-off-by: Sowjanya Komatineni 
---
 .../arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts 
b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
index 7f97b34..f1053e7 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
@@ -100,6 +100,18 @@
phy-names = "usb2-1", "usb2-2", "usb3-2";
};
 
+   spi@327 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10200>;
+   spi-tx-bus-width = <4>;
+   spi-rx-bus-width = <4>;
+   };
+   };
+
pwm@32d {
status = "okay";
};
-- 
2.7.4



[PATCH v5 7/9] arm64: tegra: Enable QSPI on Jetson Nano

2020-12-21 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Nano.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts | 12 
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |  5 +++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts 
b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
index 6a877de..a1b4603 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
@@ -638,6 +638,18 @@
};
};
 
+   spi@7041 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10400>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+   };
+
clk32k_in: clock@0 {
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 4fbf8c1..998fa81 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1536,8 +1536,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
-   clocks = <_car TEGRA210_CLK_QSPI>;
-   clock-names = "qspi";
+   clocks = <_car TEGRA210_CLK_QSPI>,
+<_car TEGRA210_CLK_QSPI_PM>;
+   clock-names = "qspi", "qspi_out";
resets = <_car 211>;
reset-names = "qspi";
dmas = < 5>, < 5>;
-- 
2.7.4



[PATCH v5 8/9] arm64: tegra: Add QSPI nodes on Tegra194

2020-12-21 Thread Sowjanya Komatineni
Tegra194 has 2 QSPI controllers.

This patch adds DT node for these 2 QSPI controllers.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 25f36d6..852980f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -609,6 +609,34 @@
status = "disabled";
};
 
+   spi@327 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x327 0x1000>;
+   interrupts = ;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   clocks = < TEGRA194_CLK_QSPI0>,
+< TEGRA194_CLK_QSPI0_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI0>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
+   spi@330 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x330 0x1000>;
+   interrupts = ;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   clocks = < TEGRA194_CLK_QSPI1>,
+< TEGRA194_CLK_QSPI1_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI1>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
pwm1: pwm@328 {
compatible = "nvidia,tegra194-pwm",
 "nvidia,tegra186-pwm";
-- 
2.7.4



[PATCH v5 6/9] spi: tegra210-quad: Add support for hardware dummy cycles transfer

2020-12-21 Thread Sowjanya Komatineni
Tegra Quad SPI controller hardware supports sending dummy bytes based
on programmed dummy clock cycles after the actual transfer bytes.

This patch adds this support of hardware dummy bytes transfer and
skips transfer of dummy bytes from the software.

For dummy cycles more than Tegra Quad SPI hardware maximum dummy
cycles limit, driver transfers dummy bytes from the software.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-tegra210-quad.c | 34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index e7bee8d..2f806f4 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -117,6 +117,7 @@
 
 #define QSPI_MISC_REG   0x194
 #define QSPI_NUM_DUMMY_CYCLE(x)(((x) & 0xff) << 0)
+#define QSPI_DUMMY_CYCLES_MAX  0xff
 
 #define DATA_DIR_TXBIT(0)
 #define DATA_DIR_RXBIT(1)
@@ -170,6 +171,7 @@ struct tegra_qspi {
u32 def_command2_reg;
u32 spi_cs_timing1;
u32 spi_cs_timing2;
+   u8  dummy_cycles;
 
struct completion   xfer_completion;
struct spi_transfer *curr_xfer;
@@ -856,6 +858,8 @@ static int tegra_qspi_start_transfer_one(struct spi_device 
*spi,
 
tqspi->command1_reg = command1;
 
+   tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
QSPI_MISC_REG);
+
ret = tegra_qspi_flush_fifos(tqspi, false);
if (ret < 0)
return ret;
@@ -974,7 +978,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
 {
struct tegra_qspi *tqspi = spi_master_get_devdata(master);
struct spi_device *spi = msg->spi;
-   struct spi_transfer *xfer;
+   struct spi_transfer *transfer;
bool is_first_msg = true;
int ret;
 
@@ -983,9 +987,33 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
tqspi->tx_status = 0;
tqspi->rx_status = 0;
 
-   list_for_each_entry(xfer, >transfers, transfer_list) {
+   list_for_each_entry(transfer, >transfers, transfer_list) {
+   struct spi_transfer *xfer = transfer;
+   u8 dummy_bytes = 0;
u32 cmd1;
 
+   tqspi->dummy_cycles = 0;
+   /*
+* Tegra QSPI hardware supports dummy bytes transfer after 
actual transfer
+* bytes based on programmed dummy clock cycles in the 
QSPI_MISC register.
+* So, check if the next transfer is dummy data transfer and 
program dummy
+* clock cycles along with the current transfer and skip next 
transfer.
+*/
+   if (!list_is_last(>transfer_list, >transfers)) {
+   struct spi_transfer *next_xfer;
+
+   next_xfer = list_next_entry(xfer, transfer_list);
+   if (next_xfer->dummy_data) {
+   u32 dummy_cycles = next_xfer->len * 8 / 
next_xfer->tx_nbits;
+
+   if (dummy_cycles <= QSPI_DUMMY_CYCLES_MAX) {
+   tqspi->dummy_cycles = dummy_cycles;
+   dummy_bytes = next_xfer->len;
+   transfer = next_xfer;
+   }
+   }
+   }
+
reinit_completion(>xfer_completion);
 
cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);
@@ -1016,7 +1044,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
goto complete_xfer;
}
 
-   msg->actual_length += xfer->len;
+   msg->actual_length += xfer->len + dummy_bytes;
 
 complete_xfer:
if (ret < 0) {
-- 
2.7.4



[PATCH v5 5/9] spi: spi-mem: Mark dummy transfers by setting dummy_data bit

2020-12-21 Thread Sowjanya Komatineni
This patch marks dummy transfer by setting dummy_data bit to 1.

Controllers supporting dummy transfer by hardware use this bit field
to skip software transfer of dummy bytes and use hardware dummy bytes
transfer.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-mem.c   | 1 +
 include/linux/spi/spi.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..c64371c 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -354,6 +354,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   xfers[xferpos].dummy_data = 1;
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..708f2f5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -827,6 +827,7 @@ extern void spi_res_release(struct spi_controller *ctlr,
  *  transfer. If 0 the default (from @spi_device) is used.
  * @bits_per_word: select a bits_per_word other than the device default
  *  for this transfer. If 0 the default (from @spi_device) is used.
+ * @dummy_data: indicates transfer is dummy bytes transfer.
  * @cs_change: affects chipselect after this transfer completes
  * @cs_change_delay: delay between cs deassert and assert when
  *  @cs_change is set and @spi_transfer is not the last in @spi_message
@@ -939,6 +940,7 @@ struct spi_transfer {
struct sg_table tx_sg;
struct sg_table rx_sg;
 
+   unsigneddummy_data:1;
unsignedcs_change:1;
unsignedtx_nbits:3;
unsignedrx_nbits:3;
-- 
2.7.4



[PATCH v5 4/9] spi: tegra210-quad: Add support for Tegra210 QSPI controller

2020-12-21 Thread Sowjanya Komatineni
Tegra SoC has a Quad SPI controller starting from Tegra210.

This patch adds support for Tegra210 QSPI controller.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/Kconfig |9 +
 drivers/spi/Makefile|1 +
 drivers/spi/spi-tegra210-quad.c | 1382 +++
 3 files changed, 1392 insertions(+)
 create mode 100644 drivers/spi/spi-tegra210-quad.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index aadaea0..f56f20e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -843,6 +843,15 @@ config SPI_MXS
help
  SPI driver for Freescale MXS devices.
 
+config SPI_TEGRA210_QUAD
+   tristate "NVIDIA Tegra QSPI Controller"
+   depends on ARCH_TEGRA || COMPILE_TEST
+   depends on RESET_CONTROLLER
+   help
+ QSPI driver for NVIDIA Tegra QSPI Controller interface. This
+ controller is different from the SPI controller and is available
+ on Tegra SoCs starting from Tegra210.
+
 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6fea582..c822c5e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ST_SSC4)   += spi-st-ssc4.o
 obj-$(CONFIG_SPI_SUN4I)+= spi-sun4i.o
 obj-$(CONFIG_SPI_SUN6I)+= spi-sun6i.o
 obj-$(CONFIG_SPI_SYNQUACER)+= spi-synquacer.o
+obj-$(CONFIG_SPI_TEGRA210_QUAD)+= spi-tegra210-quad.o
 obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o
 obj-$(CONFIG_SPI_TEGRA20_SFLASH)   += spi-tegra20-sflash.o
 obj-$(CONFIG_SPI_TEGRA20_SLINK)+= spi-tegra20-slink.o
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
new file mode 100644
index 000..e7bee8d
--- /dev/null
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -0,0 +1,1382 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 NVIDIA CORPORATION.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define QSPI_COMMAND1  0x000
+#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
+#define QSPI_PACKEDBIT(5)
+#define QSPI_INTERFACE_WIDTH_MASK  (0x03 << 7)
+#define QSPI_INTERFACE_WIDTH(x)(((x) & 0x03) << 7)
+#define QSPI_INTERFACE_WIDTH_SINGLEQSPI_INTERFACE_WIDTH(0)
+#define QSPI_INTERFACE_WIDTH_DUAL  QSPI_INTERFACE_WIDTH(1)
+#define QSPI_INTERFACE_WIDTH_QUAD  QSPI_INTERFACE_WIDTH(2)
+#define QSPI_SDR_DDR_SEL   BIT(9)
+#define QSPI_TX_EN BIT(11)
+#define QSPI_RX_EN BIT(12)
+#define QSPI_CS_SW_VAL BIT(20)
+#define QSPI_CS_SW_HW  BIT(21)
+#define QSPI_CONTROL_MODE_0(0 << 28)
+#define QSPI_CONTROL_MODE_3(3 << 28)
+#define QSPI_CONTROL_MODE_MASK (3 << 28)
+#define QSPI_M_S   BIT(30)
+#define QSPI_PIO   BIT(31)
+
+#define QSPI_COMMAND2  0x004
+#define QSPI_TX_TAP_DELAY(x)   (((x) & 0x3f) << 10)
+#define QSPI_RX_TAP_DELAY(x)   (((x) & 0xff) << 0)
+
+#define QSPI_CS_TIMING10x008
+#define QSPI_SETUP_HOLD(setup, hold)   (((setup) << 4) | (hold))
+
+#define QSPI_CS_TIMING20x00c
+#define CYCLES_BETWEEN_PACKETS_0(x)(((x) & 0x1f) << 0)
+#define CS_ACTIVE_BETWEEN_PACKETS_0BIT(5)
+
+#define QSPI_TRANS_STATUS  0x010
+#define QSPI_BLK_CNT(val)  (((val) >> 0) & 0x)
+#define QSPI_RDY   BIT(30)
+
+#define QSPI_FIFO_STATUS   0x014
+#define QSPI_RX_FIFO_EMPTY BIT(0)
+#define QSPI_RX_FIFO_FULL  BIT(1)
+#define QSPI_TX_FIFO_EMPTY BIT(2)
+#define QSPI_TX_FIFO_FULL  BIT(3)
+#define QSPI_RX_FIFO_UNF   BIT(4)
+#define QSPI_RX_FIFO_OVF   BIT(5)
+#define QSPI_TX_FIFO_UNF   BIT(6)
+#define QSPI_TX_FIFO_OVF   BIT(7)
+#define QSPI_ERR   BIT(8)
+#define QSPI_TX_FIFO_FLUSH BIT(14)
+#define QSPI_RX_FIFO_FLUSH BIT(15)
+#define QSPI_TX_FIFO_EMPTY_COUNT(val)  (((val) >> 16) & 0x7f)
+#define QSPI_RX_F

[PATCH v5 3/9] MAINTAINERS: Add Tegra Quad SPI driver section

2020-12-21 Thread Sowjanya Komatineni
Add maintainers and mailing list entries to Tegra Quad SPI driver
section.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5b20bab..19db61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17447,6 +17447,14 @@ M: Laxman Dewangan 
 S: Supported
 F: drivers/spi/spi-tegra*
 
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Sowjanya Komatineni 
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
 TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
-- 
2.7.4



[PATCH v5 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2020-12-21 Thread Sowjanya Komatineni
This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/spi/nvidia,tegra210-quad.yaml | 117 +
 1 file changed, 117 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
new file mode 100644
index 000..35a8045
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+allOf:
+  - $ref: "spi-controller.yaml#"
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi
+  - const: qspi_out
+
+  clocks:
+maxItems: 2
+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+patternProperties:
+  "@[0-9a-f]+":
+type: object
+
+properties:
+  spi-rx-bus-width:
+enum: [1, 2, 4]
+
+  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
+  - interrupts
+  - clock-names
+  - clocks
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+#address-cells = <1>;
+#size-cells = <0>;
+clocks = <_car TEGRA210_CLK_QSPI>,
+ <_car TEGRA210_CLK_QSPI_PM>;
+clock-names = "qspi", "qspi_out";
+resets = <_car 211>;
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+
+flash@0 {
+compatible = "spi-nor";
+reg = <0>;
+spi-max-frequency = <10400>;
+spi-tx-bus-width = <2>;
+spi-rx-bus-width = <2>;
+nvidia,tx-clk-tap-delay = <0>;
+nvidia,rx-clk-tap-delay = <0>;
+};
+};
-- 
2.7.4



[PATCH v5 1/9] dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM

2020-12-21 Thread Sowjanya Komatineni
Tegra210 QSPI clock output has divider DIV2_SEL which will be enabled
when using DDR interface mode.

This patch adds clock ID for this to dt-binding.

Acked-by: Rob Herring 
Signed-off-by: Sowjanya Komatineni 
---
 include/dt-bindings/clock/tegra210-car.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/tegra210-car.h 
b/include/dt-bindings/clock/tegra210-car.h
index ab8b8a7..9cfcc3b 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -307,7 +307,7 @@
 #define TEGRA210_CLK_AUDIO4 275
 #define TEGRA210_CLK_SPDIF 276
 /* 277 */
-/* 278 */
+#define TEGRA210_CLK_QSPI_PM 278
 /* 279 */
 /* 280 */
 #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
-- 
2.7.4



[PATCH v5 0/9] Add Tegra Quad SPI driver

2020-12-21 Thread Sowjanya Komatineni
This series adds Tegra210, Tegra186, and Tegra194 Quad SPI driver and
enables Quad SPI on Jetson Nano and Jetson Xavier NX.

QSPI controller is available on Tegra210, Tegra186 and Tegra194.

Tegra186 and Tegra194 has additional feature of combined sequence mode
where command, address and data can all be transferred in a single transfer.
Combined sequence mode is useful only when using DMA mode transfer.

This series does not have combined sequence mode feature as Tegra186/Tegra194
GPCDMA driver is not upstreamed yet.

This series includes
- dt-binding document
- QSPI driver for Tegra210/Tegra186/Tegra194
- Enables QSPI on Jetson Nano and Jetson Xavier NX.

Delta between patch versions:
[v5]:   Simplified implementation in Patch-0006

[v4]:   Updated dummy cycles implementation based on v3 feedback
- Added dummy_data bit field int spi_transfer to indicate corresponding
  transfer is dummy bytes transfer.
- Updated Tegra QSPI transfer_one_message to identify dummy transfer and
  to use HW supported dummy bytes transfer when dummy cycles are with in
  Tegra QSPI supported max HW dummy cycles otherwise fallsback to 
transfer
  dummy bytes from software.
- Updated dt-bindings based on v3 feedback.

[v3]:   v2 has some mixed patches sent out accidentally.
v3 sends proper patches with fixes mentioned in v2.

[v2]:   below v1 feedback
- Added SPI_MASTER_USES_HW_DUMMY_CYCLES flag for controllers supporting
  hardware dummy cycles and skips dummy bytes transfer from software for
  these controllers.
- Updated dt-binding doc with tx/rx tap delay properties.
- Added qspi_out clock to dt-binding doc which will be used later with
  ddr mode support.
- All other v1 feedback on some cleanup.


Sowjanya Komatineni (9):
  dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM
  dt-bindings: spi: Add Tegra Quad SPI device tree binding
  MAINTAINERS: Add Tegra Quad SPI driver section
  spi: tegra210-quad: Add support for Tegra210 QSPI controller
  spi: spi-mem: Mark dummy transfers by setting dummy_data bit
  spi: tegra210-quad: Add support for hardware dummy cycles transfer
  arm64: tegra: Enable QSPI on Jetson Nano
  arm64: tegra: Add QSPI nodes on Tegra194
  arm64: tegra: Enable QSPI on Jetson Xavier NX

 .../bindings/spi/nvidia,tegra210-quad.yaml |  117 ++
 MAINTAINERS|8 +
 .../dts/nvidia/tegra194-p3509-+p3668-.dts  |   12 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi   |   28 +
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts |   12 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |5 +-
 drivers/spi/Kconfig|9 +
 drivers/spi/Makefile   |1 +
 drivers/spi/spi-mem.c  |1 +
 drivers/spi/spi-tegra210-quad.c| 1410 
 include/dt-bindings/clock/tegra210-car.h   |2 +-
 include/linux/spi/spi.h|2 +
 12 files changed, 1604 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
 create mode 100644 drivers/spi/spi-tegra210-quad.c

-- 
2.7.4



Re: [PATCH v4 5/9] spi: spi-mem: Mark dummy transfers by setting dummy_data bit

2020-12-18 Thread Sowjanya Komatineni



On 12/18/20 12:44 PM, Mark Brown wrote:

On Fri, Dec 18, 2020 at 08:41:02PM +, Mark Brown wrote:

On Sat, Dec 19, 2020 at 12:49:38AM +0530, Pratyush Yadav wrote:

Anyway, if the SPI maintainers think this is worth it, I won't object.

This gets kind of circular, for me it's a question of if there's some
meaningful benefit from using the feature vs the cost to support it and
from the sounds of it we don't have numbers on the benefits from using
it at present.

...although I do have to say looking at the implementation that the cost
seems low, it's just a flag set on an existing transfer.  The only issue
is if we'd get more win from coalesing the entire transaction (or entire
transmit) into a single transfer that could be DMAed and/or requires
fewer trips through the stack which does make it seem like an unclear
tradeoff from the point of view of client drivers


Using HW dummy cycles save extra software cycle of transfer which 
involves transfer setup register writes, writing dummy bytes to TX FIFO, 
interrupt processing.


Implementation wise it just a single bit field added to spi_transfer and 
on Tegra controller driver programming dummy cycles with prior transfer 
and skipping sw dummy transfer which is actually not complex.


From quick check, I see HW dummy cycles transfer of 128KB shows 18 Mb/s 
while SW transfer of bytes shows 17.3 MB/s on average.


When back-to-back read commands are executed using HW dummy cycles will 
definitely save cycles.




Re: [PATCH v4 5/9] spi: spi-mem: Mark dummy transfers by setting dummy_data bit

2020-12-18 Thread Sowjanya Komatineni



On 12/18/20 1:57 AM, Boris Brezillon wrote:

On Fri, 18 Dec 2020 14:51:08 +0530
Pratyush Yadav  wrote:


Hi Sowjanya,

On 17/12/20 12:28PM, Sowjanya Komatineni wrote:

This patch marks dummy transfer by setting dummy_data bit to 1.

Controllers supporting dummy transfer by hardware use this bit field
to skip software transfer of dummy bytes and use hardware dummy bytes
transfer.

What is the benefit you get from this change? You add complexity in
spi-mem and the controller driver, so that must come with some benefits.
Here I don't see any. The transfer will certainly take the same amount
of time because the number or period of the dummy cycles has not
changed. So why is this needed?

Well, you don't have to queue TX bytes if you use HW-based dummy
cycles, but I agree, I'd expect the overhead to be negligible,
especially since we're talking about emitting a few bytes, not hundreds.
This being said, the complexity added to the core is reasonable IMHO,
so if it really helps reducing the CPU overhead (we might need some
numbers to prove that), I guess it's okay.


Hardware dummy cycles feature of Tegra QSPI is to save SW transfer cycle 
of dummy bytes by filling FIFO.


I don't have numbers as we always use hardware dummy cycles with Tegra QSPI.

  

Signed-off-by: Sowjanya Komatineni 
---
  drivers/spi/spi-mem.c   | 1 +
  include/linux/spi/spi.h | 2 ++
  2 files changed, 3 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..c64371c 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -354,6 +354,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   xfers[xferpos].dummy_data = 1;
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..708f2f5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -827,6 +827,7 @@ extern void spi_res_release(struct spi_controller *ctlr,
   *  transfer. If 0 the default (from @spi_device) is used.
   * @bits_per_word: select a bits_per_word other than the device default
   *  for this transfer. If 0 the default (from @spi_device) is used.
+ * @dummy_data: indicates transfer is dummy bytes transfer.
   * @cs_change: affects chipselect after this transfer completes
   * @cs_change_delay: delay between cs deassert and assert when
   *  @cs_change is set and @spi_transfer is not the last in @spi_message
@@ -939,6 +940,7 @@ struct spi_transfer {
struct sg_table tx_sg;
struct sg_table rx_sg;
  
+	unsigned	dummy_data:1;

unsignedcs_change:1;
unsignedtx_nbits:3;
unsignedrx_nbits:3;
--
2.7.4
   


[PATCH v4 7/9] arm64: tegra: Enable QSPI on Jetson Nano

2020-12-17 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Nano.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts | 12 
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |  5 +++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts 
b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
index 6a877de..a1b4603 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
@@ -638,6 +638,18 @@
};
};
 
+   spi@7041 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10400>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+   };
+
clk32k_in: clock@0 {
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 4fbf8c1..998fa81 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1536,8 +1536,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
-   clocks = <_car TEGRA210_CLK_QSPI>;
-   clock-names = "qspi";
+   clocks = <_car TEGRA210_CLK_QSPI>,
+<_car TEGRA210_CLK_QSPI_PM>;
+   clock-names = "qspi", "qspi_out";
resets = <_car 211>;
reset-names = "qspi";
dmas = < 5>, < 5>;
-- 
2.7.4



[PATCH v4 1/9] dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM

2020-12-17 Thread Sowjanya Komatineni
Tegra210 QSPI clock output has divider DIV2_SEL which will be enabled
when using DDR interface mode.

This patch adds clock ID for this to dt-binding.

Acked-by: Rob Herring 
Signed-off-by: Sowjanya Komatineni 
---
 include/dt-bindings/clock/tegra210-car.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/tegra210-car.h 
b/include/dt-bindings/clock/tegra210-car.h
index ab8b8a7..9cfcc3b 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -307,7 +307,7 @@
 #define TEGRA210_CLK_AUDIO4 275
 #define TEGRA210_CLK_SPDIF 276
 /* 277 */
-/* 278 */
+#define TEGRA210_CLK_QSPI_PM 278
 /* 279 */
 /* 280 */
 #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
-- 
2.7.4



[PATCH v4 9/9] arm64: tegra: Enable QSPI on Jetson Xavier NX

2020-12-17 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Xavier NX.

Signed-off-by: Sowjanya Komatineni 
---
 .../arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts 
b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
index 7f97b34..f1053e7 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
@@ -100,6 +100,18 @@
phy-names = "usb2-1", "usb2-2", "usb3-2";
};
 
+   spi@327 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10200>;
+   spi-tx-bus-width = <4>;
+   spi-rx-bus-width = <4>;
+   };
+   };
+
pwm@32d {
status = "okay";
};
-- 
2.7.4



[PATCH v4 8/9] arm64: tegra: Add QSPI nodes on Tegra194

2020-12-17 Thread Sowjanya Komatineni
Tegra194 has 2 QSPI controllers.

This patch adds DT node for these 2 QSPI controllers.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 25f36d6..852980f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -609,6 +609,34 @@
status = "disabled";
};
 
+   spi@327 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x327 0x1000>;
+   interrupts = ;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   clocks = < TEGRA194_CLK_QSPI0>,
+< TEGRA194_CLK_QSPI0_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI0>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
+   spi@330 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x330 0x1000>;
+   interrupts = ;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   clocks = < TEGRA194_CLK_QSPI1>,
+< TEGRA194_CLK_QSPI1_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI1>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
pwm1: pwm@328 {
compatible = "nvidia,tegra194-pwm",
 "nvidia,tegra186-pwm";
-- 
2.7.4



[PATCH v4 5/9] spi: spi-mem: Mark dummy transfers by setting dummy_data bit

2020-12-17 Thread Sowjanya Komatineni
This patch marks dummy transfer by setting dummy_data bit to 1.

Controllers supporting dummy transfer by hardware use this bit field
to skip software transfer of dummy bytes and use hardware dummy bytes
transfer.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-mem.c   | 1 +
 include/linux/spi/spi.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..c64371c 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -354,6 +354,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   xfers[xferpos].dummy_data = 1;
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..708f2f5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -827,6 +827,7 @@ extern void spi_res_release(struct spi_controller *ctlr,
  *  transfer. If 0 the default (from @spi_device) is used.
  * @bits_per_word: select a bits_per_word other than the device default
  *  for this transfer. If 0 the default (from @spi_device) is used.
+ * @dummy_data: indicates transfer is dummy bytes transfer.
  * @cs_change: affects chipselect after this transfer completes
  * @cs_change_delay: delay between cs deassert and assert when
  *  @cs_change is set and @spi_transfer is not the last in @spi_message
@@ -939,6 +940,7 @@ struct spi_transfer {
struct sg_table tx_sg;
struct sg_table rx_sg;
 
+   unsigneddummy_data:1;
unsignedcs_change:1;
unsignedtx_nbits:3;
unsignedrx_nbits:3;
-- 
2.7.4



[PATCH v4 3/9] MAINTAINERS: Add Tegra Quad SPI driver section

2020-12-17 Thread Sowjanya Komatineni
Add maintainers and mailing list entries to Tegra Quad SPI driver
section.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5b20bab..19db61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17447,6 +17447,14 @@ M: Laxman Dewangan 
 S: Supported
 F: drivers/spi/spi-tegra*
 
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Sowjanya Komatineni 
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
 TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
-- 
2.7.4



[PATCH v4 0/9] Add Tegra Quad SPI driver

2020-12-17 Thread Sowjanya Komatineni
This series adds Tegra210, Tegra186, and Tegra194 Quad SPI driver and
enables Quad SPI on Jetson Nano and Jetson Xavier NX.

QSPI controller is available on Tegra210, Tegra186 and Tegra194.

Tegra186 and Tegra194 has additional feature of combined sequence mode
where command, address and data can all be transferred in a single transfer.
Combined sequence mode is useful only when using DMA mode transfer.

This series does not have combined sequence mode feature as Tegra186/Tegra194
GPCDMA driver is not upstreamed yet.

This series includes
- dt-binding document
- QSPI driver for Tegra210/Tegra186/Tegra194
- Enables QSPI on Jetson Nano and Jetson Xavier NX.

Delta between patch versions:
[v4]:   Updated dummy cycles implementation based on v3 feedback
- Added dummy_data bit field int spi_transfer to indicate corresponding
  transfer is dummy bytes transfer.
- Updated Tegra QSPI transfer_one_message to identify dummy transfer and
  to use HW supported dummy bytes transfer when dummy cycles are with in
  Tegra QSPI supported max HW dummy cycles otherwise fallsback to 
transfer
  dummy bytes from software.
- Updated dt-bindings based on v3 feedback.

[v3]:   v2 has some mixed patches sent out accidentally.
v3 sends proper patches with fixes mentioned in v2.

[v2]:   below v1 feedback
- Added SPI_MASTER_USES_HW_DUMMY_CYCLES flag for controllers supporting
  hardware dummy cycles and skips dummy bytes transfer from software for
  these controllers.
- Updated dt-binding doc with tx/rx tap delay properties.
- Added qspi_out clock to dt-binding doc which will be used later with
  ddr mode support.
- All other v1 feedback on some cleanup.


Sowjanya Komatineni (9):
  dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM
  dt-bindings: spi: Add Tegra Quad SPI device tree binding
  MAINTAINERS: Add Tegra Quad SPI driver section
  spi: tegra210-quad: Add support for Tegra210 QSPI controller
  spi: spi-mem: Mark dummy transfers by setting dummy_data bit
  spi: tegra210-quad: Add support for hardware dummy cycles transfer
  arm64: tegra: Enable QSPI on Jetson Nano
  arm64: tegra: Add QSPI nodes on Tegra194
  arm64: tegra: Enable QSPI on Jetson Xavier NX

 .../bindings/spi/nvidia,tegra210-quad.yaml |  117 ++
 MAINTAINERS|8 +
 .../dts/nvidia/tegra194-p3509-+p3668-.dts  |   12 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi   |   28 +
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts |   12 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |5 +-
 drivers/spi/Kconfig|9 +
 drivers/spi/Makefile   |1 +
 drivers/spi/spi-mem.c  |1 +
 drivers/spi/spi-tegra210-quad.c| 1421 
 include/dt-bindings/clock/tegra210-car.h   |2 +-
 include/linux/spi/spi.h|2 +
 12 files changed, 1615 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
 create mode 100644 drivers/spi/spi-tegra210-quad.c

-- 
2.7.4



[PATCH v4 4/9] spi: tegra210-quad: Add support for Tegra210 QSPI controller

2020-12-17 Thread Sowjanya Komatineni
Tegra SoC has a Quad SPI controller starting from Tegra210.

This patch adds support for Tegra210 QSPI controller.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/Kconfig |9 +
 drivers/spi/Makefile|1 +
 drivers/spi/spi-tegra210-quad.c | 1382 +++
 3 files changed, 1392 insertions(+)
 create mode 100644 drivers/spi/spi-tegra210-quad.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index aadaea0..f56f20e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -843,6 +843,15 @@ config SPI_MXS
help
  SPI driver for Freescale MXS devices.
 
+config SPI_TEGRA210_QUAD
+   tristate "NVIDIA Tegra QSPI Controller"
+   depends on ARCH_TEGRA || COMPILE_TEST
+   depends on RESET_CONTROLLER
+   help
+ QSPI driver for NVIDIA Tegra QSPI Controller interface. This
+ controller is different from the SPI controller and is available
+ on Tegra SoCs starting from Tegra210.
+
 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6fea582..c822c5e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ST_SSC4)   += spi-st-ssc4.o
 obj-$(CONFIG_SPI_SUN4I)+= spi-sun4i.o
 obj-$(CONFIG_SPI_SUN6I)+= spi-sun6i.o
 obj-$(CONFIG_SPI_SYNQUACER)+= spi-synquacer.o
+obj-$(CONFIG_SPI_TEGRA210_QUAD)+= spi-tegra210-quad.o
 obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o
 obj-$(CONFIG_SPI_TEGRA20_SFLASH)   += spi-tegra20-sflash.o
 obj-$(CONFIG_SPI_TEGRA20_SLINK)+= spi-tegra20-slink.o
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
new file mode 100644
index 000..e7bee8d
--- /dev/null
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -0,0 +1,1382 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 NVIDIA CORPORATION.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define QSPI_COMMAND1  0x000
+#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
+#define QSPI_PACKEDBIT(5)
+#define QSPI_INTERFACE_WIDTH_MASK  (0x03 << 7)
+#define QSPI_INTERFACE_WIDTH(x)(((x) & 0x03) << 7)
+#define QSPI_INTERFACE_WIDTH_SINGLEQSPI_INTERFACE_WIDTH(0)
+#define QSPI_INTERFACE_WIDTH_DUAL  QSPI_INTERFACE_WIDTH(1)
+#define QSPI_INTERFACE_WIDTH_QUAD  QSPI_INTERFACE_WIDTH(2)
+#define QSPI_SDR_DDR_SEL   BIT(9)
+#define QSPI_TX_EN BIT(11)
+#define QSPI_RX_EN BIT(12)
+#define QSPI_CS_SW_VAL BIT(20)
+#define QSPI_CS_SW_HW  BIT(21)
+#define QSPI_CONTROL_MODE_0(0 << 28)
+#define QSPI_CONTROL_MODE_3(3 << 28)
+#define QSPI_CONTROL_MODE_MASK (3 << 28)
+#define QSPI_M_S   BIT(30)
+#define QSPI_PIO   BIT(31)
+
+#define QSPI_COMMAND2  0x004
+#define QSPI_TX_TAP_DELAY(x)   (((x) & 0x3f) << 10)
+#define QSPI_RX_TAP_DELAY(x)   (((x) & 0xff) << 0)
+
+#define QSPI_CS_TIMING10x008
+#define QSPI_SETUP_HOLD(setup, hold)   (((setup) << 4) | (hold))
+
+#define QSPI_CS_TIMING20x00c
+#define CYCLES_BETWEEN_PACKETS_0(x)(((x) & 0x1f) << 0)
+#define CS_ACTIVE_BETWEEN_PACKETS_0BIT(5)
+
+#define QSPI_TRANS_STATUS  0x010
+#define QSPI_BLK_CNT(val)  (((val) >> 0) & 0x)
+#define QSPI_RDY   BIT(30)
+
+#define QSPI_FIFO_STATUS   0x014
+#define QSPI_RX_FIFO_EMPTY BIT(0)
+#define QSPI_RX_FIFO_FULL  BIT(1)
+#define QSPI_TX_FIFO_EMPTY BIT(2)
+#define QSPI_TX_FIFO_FULL  BIT(3)
+#define QSPI_RX_FIFO_UNF   BIT(4)
+#define QSPI_RX_FIFO_OVF   BIT(5)
+#define QSPI_TX_FIFO_UNF   BIT(6)
+#define QSPI_TX_FIFO_OVF   BIT(7)
+#define QSPI_ERR   BIT(8)
+#define QSPI_TX_FIFO_FLUSH BIT(14)
+#define QSPI_RX_FIFO_FLUSH BIT(15)
+#define QSPI_TX_FIFO_EMPTY_COUNT(val)  (((val) >> 16) & 0x7f)
+#define QSPI_RX_F

[PATCH v4 6/9] spi: tegra210-quad: Add support for hardware dummy cycles transfer

2020-12-17 Thread Sowjanya Komatineni
Tegra Quad SPI controller hardware supports sending dummy bytes based
on programmed dummy clock cycles after the actual transfer bytes.

This patch adds this support of hardware dummy bytes transfer and
skips transfer of dummy bytes from the software.

For dummy cycles more than Tegra Quad SPI hardware maximum dummy
cycles limit, driver transfers dummy bytes from the software.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-tegra210-quad.c | 41 -
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index e7bee8d..695a296 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -117,6 +117,7 @@
 
 #define QSPI_MISC_REG   0x194
 #define QSPI_NUM_DUMMY_CYCLE(x)(((x) & 0xff) << 0)
+#define QSPI_DUMMY_CYCLES_MAX  0xff
 
 #define DATA_DIR_TXBIT(0)
 #define DATA_DIR_RXBIT(1)
@@ -170,6 +171,7 @@ struct tegra_qspi {
u32 def_command2_reg;
u32 spi_cs_timing1;
u32 spi_cs_timing2;
+   u8  dummy_cycles;
 
struct completion   xfer_completion;
struct spi_transfer *curr_xfer;
@@ -856,6 +858,8 @@ static int tegra_qspi_start_transfer_one(struct spi_device 
*spi,
 
tqspi->command1_reg = command1;
 
+   tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
QSPI_MISC_REG);
+
ret = tegra_qspi_flush_fifos(tqspi, false);
if (ret < 0)
return ret;
@@ -974,7 +978,8 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
 {
struct tegra_qspi *tqspi = spi_master_get_devdata(master);
struct spi_device *spi = msg->spi;
-   struct spi_transfer *xfer;
+   struct spi_transfer *xfer, *next_xfer;
+   bool use_hw_dummy_cycles = false;
bool is_first_msg = true;
int ret;
 
@@ -984,8 +989,42 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
tqspi->rx_status = 0;
 
list_for_each_entry(xfer, >transfers, transfer_list) {
+   u8 dummy_cycles = 0;
u32 cmd1;
 
+   /*
+* Skip dummy bytes transfer if they are transferred by the 
hardware along
+* with previous transfer.
+*/
+   if (xfer->dummy_data && use_hw_dummy_cycles) {
+   msg->actual_length += xfer->len;
+   continue;
+   }
+
+   /*
+* Tegra QSPI hardware supports dummy bytes transfer after 
actual transfer
+* bytes based on programmed dummy clock cycles in the 
QSPI_MISC register.
+* So, check if the next transfer is dummy data transfer and 
program dummy
+* clock cycles along with the current transfer.
+*/
+   if (!list_is_last(>transfer_list, >transfers)) {
+   next_xfer = list_next_entry(xfer, transfer_list);
+   if (next_xfer && next_xfer->dummy_data) {
+   dummy_cycles = next_xfer->len * 8 / 
next_xfer->tx_nbits;
+   use_hw_dummy_cycles = true;
+   /*
+* Use software dummy bytes transfer if dummy 
cycles exceeds
+* Tegra QSPI hardware maximum dummy cycles 
limit.
+*/
+   if (dummy_cycles > QSPI_DUMMY_CYCLES_MAX) {
+   use_hw_dummy_cycles = false;
+   dummy_cycles = 0;
+   }
+   }
+   }
+
+   tqspi->dummy_cycles = dummy_cycles;
+
reinit_completion(>xfer_completion);
 
cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);
-- 
2.7.4



[PATCH v4 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2020-12-17 Thread Sowjanya Komatineni
This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/spi/nvidia,tegra210-quad.yaml | 117 +
 1 file changed, 117 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
new file mode 100644
index 000..35a8045
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+allOf:
+  - $ref: "spi-controller.yaml#"
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi
+  - const: qspi_out
+
+  clocks:
+maxItems: 2
+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+patternProperties:
+  "@[0-9a-f]+":
+type: object
+
+properties:
+  spi-rx-bus-width:
+enum: [1, 2, 4]
+
+  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
+  - interrupts
+  - clock-names
+  - clocks
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+#address-cells = <1>;
+#size-cells = <0>;
+clocks = <_car TEGRA210_CLK_QSPI>,
+ <_car TEGRA210_CLK_QSPI_PM>;
+clock-names = "qspi", "qspi_out";
+resets = <_car 211>;
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+
+flash@0 {
+compatible = "spi-nor";
+reg = <0>;
+spi-max-frequency = <10400>;
+spi-tx-bus-width = <2>;
+spi-rx-bus-width = <2>;
+nvidia,tx-clk-tap-delay = <0>;
+nvidia,rx-clk-tap-delay = <0>;
+};
+};
-- 
2.7.4



Re: [PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-13 Thread Sowjanya Komatineni



On 12/13/20 3:28 AM, Boris Brezillon wrote:

On Sun, 13 Dec 2020 10:54:26 +0100
Boris Brezillon  wrote:


On Sat, 12 Dec 2020 09:28:50 -0800
Sowjanya Komatineni  wrote:


On 12/12/20 2:57 AM, Boris Brezillon wrote:

On Fri, 11 Dec 2020 13:15:59 -0800
Sowjanya Komatineni  wrote:


This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
that support transfer of dummy cycles by the hardware directly.

Hm, not sure this is a good idea. I mean, if we expect regular SPI
devices to use this feature, then why not, but if it's just for
spi-mem, I'd recommend implementing a driver-specific exec_op() instead
of using the default one.

dummy cycles programming is SPI device specific.

Transfer of dummy bytes by SW or HW controller can be depending on
features supported by controller.

Adding controller driver specific exec_op() Just for skipping dummy
bytes transfer will have so much of redundant code pretty much what all
spi_mem_exec_op does.

So in v1, I handled this in controller driver by skipping SW transfer of
dummy bytes during dummy phase and programming dummy cycles in
controller register to allow HW to transfer.

Based on v1 feedback discussion, added this flag
SPI_MASTER_USES_HW_DUMMY_CYCLES which can be used by controllers
supporting HW dummy bytes transfer and updated spi_mem_exec_op to skip
SW dummy bytes.

This helps other controllers supporting HW transfer of dummy bytes as
well just to set the flag and use dummy cycles directly.

Except saying a spi_message has X dummy cycle is not precise enough.
Where are those dummy cycles in the transfer sequence? spi-mem has well
defined sequencing (cmd[+addr][+dummy][+data]) so we know exacly where
dummy cycles are, but trying to retro-fit the dummy-cycle concept in
the generic spi_message is confusing IMHO. If want to avoid code
duplication, I'm pretty sure the driver can be reworked so the
spi_transfer/exec_op() path can share most of the logic (that probably
implies declaring a tegra_qspi_op).

Something like that might also do the trick:

--->8---

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index ef53290b7d24..8b0476f37fbb 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -353,6 +353,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
 xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
 xfers[xferpos].len = op->dummy.nbytes;
 xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   xfers[xferpos].dummy_data = 1;
 spi_message_add_tail([xferpos], );
 xferpos++;
 totalxferlen += op->dummy.nbytes;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 99380c0825db..ecf7989318c5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -807,6 +807,10 @@ extern void spi_res_release(struct spi_controller *ctlr,
   *  transfer. If 0 the default (from @spi_device) is used.
   * @bits_per_word: select a bits_per_word other than the device default
   *  for this transfer. If 0 the default (from @spi_device) is used.
+ * @dummy_data: set to 1 for a dummy transfer (a transfer whose data is
+ *  ignored). Controllers that are able to issue dummy cycles can ignore
+ *  tx_buf, for those that can't tx_buf will contain dummy bytes. The
+ *  number of  dummy cycles to issue is (len * tx_bits) / 8.
   * @cs_change: affects chipselect after this transfer completes
   * @cs_change_delay: delay between cs deassert and assert when
   *  @cs_change is set and @spi_transfer is not the last in @spi_message
@@ -919,6 +923,7 @@ struct spi_transfer {
 struct sg_table tx_sg;
 struct sg_table rx_sg;
  
+   unsigneddummy_data:1;

 unsignedcs_change:1;
 unsignedtx_nbits:3;
 unsignedrx_nbits:3;


Thanks Boris.

Sorry was thinking of spi flash device only as we only support quad spi 
flash on Tegra QSPI interface.


But to make it more generic where spi message preparation can happen 
from any client driver, agree order of transfers may vary.


Also having controller driver implement exec_op callback is also not 
useful considering cases where spi message transfers dont' go thru spi_mem.


Yes adding dummy_data field to indicate transfer is dummy bytes transfer 
helps for any types of message transfers.


Tegra QSPI controller dummy cycles need be programmed with transfer 
after which dummy cycles are needed.


So, will have v4 to add dummy_data to spi_transfer and will update 
controller driver to convert dummy bytes to dummy cycles and program 
dummy cycles with its previous transfer and skip dummy transfer buffer.


Thanks

Sowjanya




Re: [PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-12 Thread Sowjanya Komatineni



On 12/12/20 2:57 AM, Boris Brezillon wrote:

On Fri, 11 Dec 2020 13:15:59 -0800
Sowjanya Komatineni  wrote:


This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
that support transfer of dummy cycles by the hardware directly.

Hm, not sure this is a good idea. I mean, if we expect regular SPI
devices to use this feature, then why not, but if it's just for
spi-mem, I'd recommend implementing a driver-specific exec_op() instead
of using the default one.


dummy cycles programming is SPI device specific.

Transfer of dummy bytes by SW or HW controller can be depending on 
features supported by controller.


Adding controller driver specific exec_op() Just for skipping dummy 
bytes transfer will have so much of redundant code pretty much what all 
spi_mem_exec_op does.


So in v1, I handled this in controller driver by skipping SW transfer of 
dummy bytes during dummy phase and programming dummy cycles in 
controller register to allow HW to transfer.


Based on v1 feedback discussion, added this flag 
SPI_MASTER_USES_HW_DUMMY_CYCLES which can be used by controllers 
supporting HW dummy bytes transfer and updated spi_mem_exec_op to skip 
SW dummy bytes.


This helps other controllers supporting HW transfer of dummy bytes as 
well just to set the flag and use dummy cycles directly.



If we go for those core changes, we should at least add a
ctrl->max_dummy_cycles field so the core can fallback to regular writes
when the number of dummy cycles in the spi_mem_op exceeds what the
controller can do.
Yes makes sense. Will add this once we decide on keeping this flag to 
identify controllers supporting HW transfer of dummy bytes Vs SW transfer.

For controller with this flag set, spi-mem driver will skip dummy bytes
transfer in the spi message.

Controller drivers can get the number of dummy cycles from spi_message.

Signed-off-by: Sowjanya Komatineni 
---
  drivers/spi/spi-mem.c   | 18 +++---
  include/linux/spi/spi.h |  8 
  2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..38a523b 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
  
  	if (op->dummy.nbytes) {

-   memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
-   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
-   xfers[xferpos].len = op->dummy.nbytes;
-   xfers[xferpos].tx_nbits = op->dummy.buswidth;
-   spi_message_add_tail([xferpos], );
-   xferpos++;
-   totalxferlen += op->dummy.nbytes;
+   if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
+   msg.dummy_cycles = (op->dummy.nbytes * 8) / 
op->dummy.buswidth;
+   } else {
+   memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
op->dummy.nbytes);
+   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
+   xfers[xferpos].len = op->dummy.nbytes;
+   xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_message_add_tail([xferpos], );
+   xferpos++;
+   totalxferlen += op->dummy.nbytes;
+   }
}
  
  	if (op->data.nbytes) {

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..2024149 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -512,6 +512,8 @@ struct spi_controller {
  
  #define SPI_MASTER_GPIO_SS		BIT(5)	/* GPIO CS must select slave */
  
+#define SPI_MASTER_USES_HW_DUMMY_CYCLES	BIT(6)	/* HW dummy bytes transfer */

+
/* flag indicating this is an SPI slave controller */
boolslave;
  
@@ -1022,6 +1024,12 @@ struct spi_message {

unsignedactual_length;
int status;
  
+	/*

+* dummy cycles in the message transfer. This is used by the controller
+* drivers supports transfer of dummy cycles directly by the hardware.
+*/
+   u8  dummy_cycles;
+
/* for optional use by whatever driver currently owns the
 * spi_message ...  between calls to spi_async and then later
 * complete(), that's the spi_controller controller driver.


[PATCH v3 9/9] arm64: tegra: Enable QSPI on Jetson Xavier NX

2020-12-11 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Xavier NX.

Signed-off-by: Sowjanya Komatineni 
---
 .../arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts 
b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
index 7f97b34..f1053e7 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
@@ -100,6 +100,18 @@
phy-names = "usb2-1", "usb2-2", "usb3-2";
};
 
+   spi@327 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10200>;
+   spi-tx-bus-width = <4>;
+   spi-rx-bus-width = <4>;
+   };
+   };
+
pwm@32d {
status = "okay";
};
-- 
2.7.4



[PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-11 Thread Sowjanya Komatineni
This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
that support transfer of dummy cycles by the hardware directly.

For controller with this flag set, spi-mem driver will skip dummy bytes
transfer in the spi message.

Controller drivers can get the number of dummy cycles from spi_message.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-mem.c   | 18 +++---
 include/linux/spi/spi.h |  8 
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..38a523b 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
if (op->dummy.nbytes) {
-   memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
-   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
-   xfers[xferpos].len = op->dummy.nbytes;
-   xfers[xferpos].tx_nbits = op->dummy.buswidth;
-   spi_message_add_tail([xferpos], );
-   xferpos++;
-   totalxferlen += op->dummy.nbytes;
+   if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
+   msg.dummy_cycles = (op->dummy.nbytes * 8) / 
op->dummy.buswidth;
+   } else {
+   memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
op->dummy.nbytes);
+   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
+   xfers[xferpos].len = op->dummy.nbytes;
+   xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_message_add_tail([xferpos], );
+   xferpos++;
+   totalxferlen += op->dummy.nbytes;
+   }
}
 
if (op->data.nbytes) {
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..2024149 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -512,6 +512,8 @@ struct spi_controller {
 
 #define SPI_MASTER_GPIO_SS BIT(5)  /* GPIO CS must select slave */
 
+#define SPI_MASTER_USES_HW_DUMMY_CYCLESBIT(6)  /* HW dummy bytes 
transfer */
+
/* flag indicating this is an SPI slave controller */
boolslave;
 
@@ -1022,6 +1024,12 @@ struct spi_message {
unsignedactual_length;
int status;
 
+   /*
+* dummy cycles in the message transfer. This is used by the controller
+* drivers supports transfer of dummy cycles directly by the hardware.
+*/
+   u8  dummy_cycles;
+
/* for optional use by whatever driver currently owns the
 * spi_message ...  between calls to spi_async and then later
 * complete(), that's the spi_controller controller driver.
-- 
2.7.4



[PATCH v3 6/9] spi: tegra210-quad: Add support for hardware dummy cycles

2020-12-11 Thread Sowjanya Komatineni
Tegra Quad SPI controller hardware supports sending dummy cycles
after address bytes.

This patch adds this support.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-tegra210-quad.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index 624f395..1d1b125 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -124,6 +124,13 @@
 #define QSPI_DMA_TIMEOUT   (msecs_to_jiffies(1000))
 #define DEFAULT_QSPI_DMA_BUF_LEN   (64 * 1024)
 
+enum transfer_phase {
+   CMD_BYTE_XFER = 0,
+   ADDR_BYTES_XFER,
+   DATA_BYTES_XFER,
+   MAX_XFERS,
+};
+
 struct tegra_qspi_client_data {
int tx_clk_tap_delay;
int rx_clk_tap_delay;
@@ -857,6 +864,8 @@ static int tegra_qspi_start_transfer_one(struct spi_device 
*spi,
 
tqspi->command1_reg = command1;
 
+   tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
QSPI_MISC_REG);
+
ret = tegra_qspi_flush_fifos(tqspi, false);
if (ret < 0)
return ret;
@@ -977,7 +986,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
struct spi_device *spi = msg->spi;
struct spi_transfer *xfer;
bool is_first_msg = true;
-   int ret;
+   int ret, xfer_phase = 0;
 
msg->status = 0;
msg->actual_length = 0;
@@ -987,6 +996,15 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
list_for_each_entry(xfer, >transfers, transfer_list) {
u32 cmd1;
 
+   /*
+* Program dummy clock cycles in Tegra QSPI register only
+* during address transfer phase.
+*/
+   if (xfer_phase == ADDR_BYTES_XFER)
+   tqspi->dummy_cycles = msg->dummy_cycles;
+   else
+   tqspi->dummy_cycles = 0;
+
reinit_completion(>xfer_completion);
 
cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);
@@ -1018,6 +1036,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
}
 
msg->actual_length += xfer->len;
+   xfer_phase++;
 
 complete_xfer:
if (ret < 0) {
@@ -1203,6 +1222,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
master->mode_bits = SPI_MODE_0 | SPI_MODE_3 | SPI_CS_HIGH |
SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | 
SPI_RX_QUAD;
master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | 
SPI_BPW_MASK(8);
+   master->flags = SPI_MASTER_USES_HW_DUMMY_CYCLES;
master->setup = tegra_qspi_setup;
master->cleanup = tegra_qspi_cleanup;
master->transfer_one_message = tegra_qspi_transfer_one_message;
-- 
2.7.4



[PATCH v3 3/9] MAINTAINERS: Add Tegra Quad SPI driver section

2020-12-11 Thread Sowjanya Komatineni
Add maintainers and mailing list entries to Tegra Quad SPI driver
section.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5b20bab..19db61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17447,6 +17447,14 @@ M: Laxman Dewangan 
 S: Supported
 F: drivers/spi/spi-tegra*
 
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Sowjanya Komatineni 
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
 TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
-- 
2.7.4



[PATCH v3 0/9] Add Tegra Quad SPI driver

2020-12-11 Thread Sowjanya Komatineni
This series adds Tegra210, Tegra186, and Tegra194 Quad SPI driver and
enables Quad SPI on Jetson Nano and Jetson Xavier NX.

QSPI controller is available on Tegra210, Tegra186 and Tegra194.

Tegra186 and Tegra194 has additional feature of combined sequence mode
where command, address and data can all be transferred in a single transfer.

Combined sequence mode is useful with DMA mode transfer.

This series does not have combined sequence mode feature as Tegra186/Tegra194
GPCDMA driver is not upstreamed yet.

This series includes
- dt-binding document
- QSPI driver for Tegra210/Tegra186/Tegra194
- Enables QSPI on Jetson Nano and Jetson Xavier NX.

Delta between patch versions:
[v3]:   v2 has some mixed patches sent out accidentally.
v3 sends proper patches with fixes mentioned in v2.
[v2]:   below v1 feedback
- Added SPI_MASTER_USES_HW_DUMMY_CYCLES flag for controllers supporting
  hardware dummy cycles and skips dummy bytes transfer from software for
  these controllers.
- Updated dt-binding doc with tx/rx tap delay properties.
- Added qspi_out clock to dt-binding doc which will be used later with
  ddr mode support.
- All other v1 feedback on some cleanup.



Sowjanya Komatineni (9):
  dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM
  dt-bindings: spi: Add Tegra Quad SPI device tree binding
  MAINTAINERS: Add Tegra Quad SPI driver section
  spi: tegra210-quad: Add support for Tegra210 QSPI controller
  spi: spi-mem: Allow masters to transfer dummy cycles directly by
hardware
  spi: tegra210-quad: Add support for hardware dummy cycles
  arm64: tegra: Enable QSPI on Jetson Nano
  arm64: tegra: Add QSPI nodes on Tegra194
  arm64: tegra: Enable QSPI on Jetson Xavier NX

 .../bindings/spi/nvidia,tegra210-quad.yaml |  130 ++
 MAINTAINERS|8 +
 .../dts/nvidia/tegra194-p3509-+p3668-.dts  |   12 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi   |   24 +
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts |   12 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |5 +-
 drivers/spi/Kconfig|9 +
 drivers/spi/Makefile   |1 +
 drivers/spi/spi-mem.c  |   18 +-
 drivers/spi/spi-tegra210-quad.c| 1407 
 include/dt-bindings/clock/tegra210-car.h   |2 +-
 include/linux/spi/spi.h|8 +
 12 files changed, 1626 insertions(+), 10 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
 create mode 100644 drivers/spi/spi-tegra210-quad.c

-- 
2.7.4



[PATCH v3 8/9] arm64: tegra: Add QSPI nodes on Tegra194

2020-12-11 Thread Sowjanya Komatineni
Tegra194 has 2 QSPI controllers.

This patch adds DT node for these 2 QSPI controllers.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 25f36d6..63ed788 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -609,6 +609,30 @@
status = "disabled";
};
 
+   spi@327 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x327 0x1000>;
+   interrupts = ;
+   clocks = < TEGRA194_CLK_QSPI0>,
+< TEGRA194_CLK_QSPI0_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI0>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
+   spi@330 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x330 0x1000>;
+   interrupts = ;
+   clocks = < TEGRA194_CLK_QSPI1>,
+< TEGRA194_CLK_QSPI1_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI1>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
pwm1: pwm@328 {
compatible = "nvidia,tegra194-pwm",
 "nvidia,tegra186-pwm";
-- 
2.7.4



[PATCH v3 7/9] arm64: tegra: Enable QSPI on Jetson Nano

2020-12-11 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Nano.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts | 12 
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |  5 +++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts 
b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
index 6a877de..a1b4603 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
@@ -638,6 +638,18 @@
};
};
 
+   spi@7041 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10400>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+   };
+
clk32k_in: clock@0 {
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 4fbf8c1..998fa81 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1536,8 +1536,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
-   clocks = <_car TEGRA210_CLK_QSPI>;
-   clock-names = "qspi";
+   clocks = <_car TEGRA210_CLK_QSPI>,
+<_car TEGRA210_CLK_QSPI_PM>;
+   clock-names = "qspi", "qspi_out";
resets = <_car 211>;
reset-names = "qspi";
dmas = < 5>, < 5>;
-- 
2.7.4



[PATCH v3 4/9] spi: tegra210-quad: Add support for Tegra210 QSPI controller

2020-12-11 Thread Sowjanya Komatineni
Tegra SoC has a Quad SPI controller starting from Tegra210.

This patch adds support for Tegra210 QSPI controller.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/Kconfig |9 +
 drivers/spi/Makefile|1 +
 drivers/spi/spi-tegra210-quad.c | 1387 +++
 3 files changed, 1397 insertions(+)
 create mode 100644 drivers/spi/spi-tegra210-quad.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index aadaea0..f56f20e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -843,6 +843,15 @@ config SPI_MXS
help
  SPI driver for Freescale MXS devices.
 
+config SPI_TEGRA210_QUAD
+   tristate "NVIDIA Tegra QSPI Controller"
+   depends on ARCH_TEGRA || COMPILE_TEST
+   depends on RESET_CONTROLLER
+   help
+ QSPI driver for NVIDIA Tegra QSPI Controller interface. This
+ controller is different from the SPI controller and is available
+ on Tegra SoCs starting from Tegra210.
+
 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6fea582..c822c5e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ST_SSC4)   += spi-st-ssc4.o
 obj-$(CONFIG_SPI_SUN4I)+= spi-sun4i.o
 obj-$(CONFIG_SPI_SUN6I)+= spi-sun6i.o
 obj-$(CONFIG_SPI_SYNQUACER)+= spi-synquacer.o
+obj-$(CONFIG_SPI_TEGRA210_QUAD)+= spi-tegra210-quad.o
 obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o
 obj-$(CONFIG_SPI_TEGRA20_SFLASH)   += spi-tegra20-sflash.o
 obj-$(CONFIG_SPI_TEGRA20_SLINK)+= spi-tegra20-slink.o
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
new file mode 100644
index 000..624f395
--- /dev/null
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -0,0 +1,1387 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 NVIDIA CORPORATION.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define QSPI_COMMAND1  0x000
+#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
+#define QSPI_PACKEDBIT(5)
+#define QSPI_INTERFACE_WIDTH_MASK  (0x03 << 7)
+#define QSPI_INTERFACE_WIDTH(x)(((x) & 0x03) << 7)
+#define QSPI_INTERFACE_WIDTH_SINGLEQSPI_INTERFACE_WIDTH(0)
+#define QSPI_INTERFACE_WIDTH_DUAL  QSPI_INTERFACE_WIDTH(1)
+#define QSPI_INTERFACE_WIDTH_QUAD  QSPI_INTERFACE_WIDTH(2)
+#define QSPI_SDR_DDR_SEL   BIT(9)
+#define QSPI_TX_EN BIT(11)
+#define QSPI_RX_EN BIT(12)
+#define QSPI_CS_SW_VAL BIT(20)
+#define QSPI_CS_SW_HW  BIT(21)
+#define QSPI_CONTROL_MODE_0(0 << 28)
+#define QSPI_CONTROL_MODE_3(3 << 28)
+#define QSPI_CONTROL_MODE_MASK (3 << 28)
+#define QSPI_M_S   BIT(30)
+#define QSPI_PIO   BIT(31)
+
+#define QSPI_COMMAND2  0x004
+#define QSPI_TX_TAP_DELAY(x)   (((x) & 0x3f) << 10)
+#define QSPI_RX_TAP_DELAY(x)   (((x) & 0xff) << 0)
+
+#define QSPI_CS_TIMING10x008
+#define QSPI_SETUP_HOLD(setup, hold)   (((setup) << 4) | (hold))
+
+#define QSPI_CS_TIMING20x00c
+#define CYCLES_BETWEEN_PACKETS_0(x)(((x) & 0x1f) << 0)
+#define CS_ACTIVE_BETWEEN_PACKETS_0BIT(5)
+
+#define QSPI_TRANS_STATUS  0x010
+#define QSPI_BLK_CNT(val)  (((val) >> 0) & 0x)
+#define QSPI_RDY   BIT(30)
+
+#define QSPI_FIFO_STATUS   0x014
+#define QSPI_RX_FIFO_EMPTY BIT(0)
+#define QSPI_RX_FIFO_FULL  BIT(1)
+#define QSPI_TX_FIFO_EMPTY BIT(2)
+#define QSPI_TX_FIFO_FULL  BIT(3)
+#define QSPI_RX_FIFO_UNF   BIT(4)
+#define QSPI_RX_FIFO_OVF   BIT(5)
+#define QSPI_TX_FIFO_UNF   BIT(6)
+#define QSPI_TX_FIFO_OVF   BIT(7)
+#define QSPI_ERR   BIT(8)
+#define QSPI_TX_FIFO_FLUSH BIT(14)
+#define QSPI_RX_FIFO_FLUSH BIT(15)
+#define QSPI_TX_FIFO_EMPTY_COUNT(val)  (((val) >> 16) & 0x7f)
+#define QSPI_RX_F

[PATCH v3 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2020-12-11 Thread Sowjanya Komatineni
This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/spi/nvidia,tegra210-quad.yaml | 130 +
 1 file changed, 130 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
new file mode 100644
index 000..0b5fea6
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi
+  - const: qspi_out
+
+  clocks:
+maxItems: 2
+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+patternProperties:
+  "^.*@[0-9a-f]+":
+type: object
+
+properties:
+  compatible:
+description:
+  Compatible of the SPI device.
+
+  reg:
+maxItems: 1
+
+  spi-max-frequency:
+$ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Maximum Quad SPI clocking speed of the device in Hz.
+
+  spi-rx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for read transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [1, 2, 4]
+
+  spi-tx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for write transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+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
+  - interrupts
+  - clock-names
+  - clocks
+  - resets
+
+additionalProperties: true
+
+examples:
+  - |
+#include 
+#include 
+#include 
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+#address-cells = <1>;
+#size-cells = <0>;
+clocks = <_car TEGRA210_CLK_QSPI>,
+ <_car TEGRA210_CLK_QSPI_PM>;
+clock-names = "qspi", "qspi_out";
+resets = <_car 211>;
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+
+flash@0 {
+compatible = "spi-nor";
+reg = <0>;
+spi-max-frequency = <10400>;
+spi-tx-bus-width = <2>;
+spi-rx-bus-width = <2>;
+};
+};
-- 
2.7.4



[PATCH v3 1/9] dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM

2020-12-11 Thread Sowjanya Komatineni
Tegra210 QSPI clock output has divider DIV2_SEL which will be enabled
when using DDR interface mode.

This patch adds clock ID for this to dt-binding.

Signed-off-by: Sowjanya Komatineni 
---
 include/dt-bindings/clock/tegra210-car.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/tegra210-car.h 
b/include/dt-bindings/clock/tegra210-car.h
index ab8b8a7..9cfcc3b 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -307,7 +307,7 @@
 #define TEGRA210_CLK_AUDIO4 275
 #define TEGRA210_CLK_SPDIF 276
 /* 277 */
-/* 278 */
+#define TEGRA210_CLK_QSPI_PM 278
 /* 279 */
 /* 280 */
 #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
-- 
2.7.4



Re: [PATCH v2 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2020-12-11 Thread Sowjanya Komatineni

Sorry rob, mixed patches went out accidentally.

Will resend v2

On 12/11/20 12:56 PM, Rob Herring wrote:

On Fri, 11 Dec 2020 09:01:20 -0800, Sowjanya Komatineni wrote:

This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
  .../bindings/spi/nvidia,tegra210-quad.yaml | 130 +
  1 file changed, 130 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml



My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.example.dts:29.38-39 
syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:342: 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.example.dt.yaml] 
Error 1
make[1]: *** Waiting for unfinished jobs
make: *** [Makefile:1364: dt_binding_check] Error 2


See https://patchwork.ozlabs.org/patch/1415094

The base for the patch is generally the last rc1. Any dependencies
should be noted.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



Re: [PATCH v2 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-11 Thread Sowjanya Komatineni

Sorry mark mixed patches went out.

Will resend v2 and will add other people you have CC'd as well

On 12/11/20 10:33 AM, Mark Brown wrote:

On Fri, Dec 11, 2020 at 09:01:24AM -0800, Sowjanya Komatineni wrote:

This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
that support transfer of dummy cycles by the hardware directly.

For controller with this flag set, spi-mem driver will skip dummy bytes
transfer in the spi message.

Controller drivers can get the number of dummy cycles from spi_message.

Copying more people who've worked on spi-mem for their review - I've not
got such a good perspective on controller features.


Signed-off-by: Sowjanya Komatineni 
---
  drivers/spi/spi-mem.c   | 18 +++---
  include/linux/spi/spi.h |  8 
  2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..38a523b 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
  
  	if (op->dummy.nbytes) {

-   memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
-   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
-   xfers[xferpos].len = op->dummy.nbytes;
-   xfers[xferpos].tx_nbits = op->dummy.buswidth;
-   spi_message_add_tail([xferpos], );
-   xferpos++;
-   totalxferlen += op->dummy.nbytes;
+   if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
+   msg.dummy_cycles = (op->dummy.nbytes * 8) / 
op->dummy.buswidth;
+   } else {
+   memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
op->dummy.nbytes);
+   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
+   xfers[xferpos].len = op->dummy.nbytes;
+   xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_message_add_tail([xferpos], );
+   xferpos++;
+   totalxferlen += op->dummy.nbytes;
+   }
}
  
  	if (op->data.nbytes) {

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..2024149 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -512,6 +512,8 @@ struct spi_controller {
  
  #define SPI_MASTER_GPIO_SS		BIT(5)	/* GPIO CS must select slave */
  
+#define SPI_MASTER_USES_HW_DUMMY_CYCLES	BIT(6)	/* HW dummy bytes transfer */

+
/* flag indicating this is an SPI slave controller */
boolslave;
  
@@ -1022,6 +1024,12 @@ struct spi_message {

unsignedactual_length;
int status;
  
+	/*

+* dummy cycles in the message transfer. This is used by the controller
+* drivers supports transfer of dummy cycles directly by the hardware.
+*/
+   u8  dummy_cycles;
+
/* for optional use by whatever driver currently owns the
 * spi_message ...  between calls to spi_async and then later
 * complete(), that's the spi_controller controller driver.
--
2.7.4


[PATCH v4 12/13] media: tegra-video: Add support for x8 captures with gang ports

2020-12-11 Thread Sowjanya Komatineni
Tegra VI/CSI hardware don't have native 8 lane capture support.

Each CSI port has max 4 lanes only. So for x8 captures, consecutive
ports are ganged up for left half and right half captures on to each
x4 ports with buffer offsets based on source image split width to align
side-by-side.

All ports in gang are configured together during the corresponding
video device node streaming for x8 captures.

x8 capture with gang ports are supported with HDMI-to-CSI bridges
where they split 4K image into left half onto one x4 port and
right half onto second x4 port.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/csi.c  |  35 ++-
 drivers/staging/media/tegra-video/csi.h  |  14 +-
 drivers/staging/media/tegra-video/tegra210.c | 304 ++-
 drivers/staging/media/tegra-video/vi.c   | 139 +---
 drivers/staging/media/tegra-video/vi.h   |  19 +-
 5 files changed, 362 insertions(+), 149 deletions(-)

diff --git a/drivers/staging/media/tegra-video/csi.c 
b/drivers/staging/media/tegra-video/csi.c
index a19c85c..033a693 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -253,13 +253,14 @@ static unsigned int csi_get_pixel_rate(struct 
tegra_csi_channel *csi_chan)
 }
 
 void tegra_csi_calc_settle_time(struct tegra_csi_channel *csi_chan,
+   u8 csi_port_num,
u8 *clk_settle_time,
u8 *ths_settle_time)
 {
struct tegra_csi *csi = csi_chan->csi;
unsigned int cil_clk_mhz;
unsigned int pix_clk_mhz;
-   int clk_idx = (csi_chan->csi_port_num >> 1) + 1;
+   int clk_idx = (csi_port_num >> 1) + 1;
 
cil_clk_mhz = clk_get_rate(csi->clks[clk_idx].clk) / MHZ;
pix_clk_mhz = csi_get_pixel_rate(csi_chan) / MHZ;
@@ -410,7 +411,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
   unsigned int num_pads)
 {
struct tegra_csi_channel *chan;
-   int ret = 0;
+   int ret = 0, i;
 
chan = kzalloc(sizeof(*chan), GFP_KERNEL);
if (!chan)
@@ -418,8 +419,21 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
 
list_add_tail(>list, >csi_chans);
chan->csi = csi;
-   chan->csi_port_num = port_num;
-   chan->numlanes = lanes;
+   /*
+* Each CSI brick has maximum of 4 lanes.
+* For lanes more than 4, use multiple of immediate CSI bricks as gang.
+*/
+   if (lanes <= CSI_LANES_PER_BRICK) {
+   chan->numlanes = lanes;
+   chan->numgangports = 1;
+   } else {
+   chan->numlanes = CSI_LANES_PER_BRICK;
+   chan->numgangports = lanes / CSI_LANES_PER_BRICK;
+   }
+
+   for (i = 0; i < chan->numgangports; i++)
+   chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
+
chan->of_node = node;
chan->numpads = num_pads;
if (num_pads & 0x2) {
@@ -500,7 +514,14 @@ static int tegra_csi_channels_alloc(struct tegra_csi *csi)
}
 
lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
-   if (!lanes || ((lanes & (lanes - 1)) != 0)) {
+   /*
+* Each CSI brick has maximum 4 data lanes.
+* For lanes more than 4, validate lanes to be multiple of 4
+* so multiple of consecutive CSI bricks can be ganged up for
+* streaming.
+*/
+   if (!lanes || ((lanes & (lanes - 1)) != 0) ||
+   (lanes > CSI_LANES_PER_BRICK && ((portno & 1) != 0))) {
dev_err(csi->dev, "invalid data-lanes %d for %pOF\n",
lanes, channel);
ret = -EINVAL;
@@ -544,7 +565,7 @@ static int tegra_csi_channel_init(struct tegra_csi_channel 
*chan)
subdev->dev = csi->dev;
if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "%s-%d", "tpg",
-chan->csi_port_num);
+chan->csi_port_nums[0]);
else
snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "%s",
 kbasename(chan->of_node->full_name));
@@ -596,7 +617,7 @@ static int tegra_csi_channels_init(struct tegra_csi *csi)
if (ret) {
dev_err(csi->dev,
"failed to initialize channel-%d: %d\n",
-   chan->csi_port_num, ret);
+   chan->csi_port_nums[0], ret);
return ret;
}
}
diff --git a/drivers/staging/media/tegra-video/csi.h 
b/drivers/staging/media/teg

[PATCH v2 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-11 Thread Sowjanya Komatineni
This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
that support transfer of dummy cycles by the hardware directly.

For controller with this flag set, spi-mem driver will skip dummy bytes
transfer in the spi message.

Controller drivers can get the number of dummy cycles from spi_message.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-mem.c   | 18 +++---
 include/linux/spi/spi.h |  8 
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index f3a3f19..38a523b 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
if (op->dummy.nbytes) {
-   memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
-   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
-   xfers[xferpos].len = op->dummy.nbytes;
-   xfers[xferpos].tx_nbits = op->dummy.buswidth;
-   spi_message_add_tail([xferpos], );
-   xferpos++;
-   totalxferlen += op->dummy.nbytes;
+   if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
+   msg.dummy_cycles = (op->dummy.nbytes * 8) / 
op->dummy.buswidth;
+   } else {
+   memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
op->dummy.nbytes);
+   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
+   xfers[xferpos].len = op->dummy.nbytes;
+   xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_message_add_tail([xferpos], );
+   xferpos++;
+   totalxferlen += op->dummy.nbytes;
+   }
}
 
if (op->data.nbytes) {
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index aa09fdc..2024149 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -512,6 +512,8 @@ struct spi_controller {
 
 #define SPI_MASTER_GPIO_SS BIT(5)  /* GPIO CS must select slave */
 
+#define SPI_MASTER_USES_HW_DUMMY_CYCLESBIT(6)  /* HW dummy bytes 
transfer */
+
/* flag indicating this is an SPI slave controller */
boolslave;
 
@@ -1022,6 +1024,12 @@ struct spi_message {
unsignedactual_length;
int status;
 
+   /*
+* dummy cycles in the message transfer. This is used by the controller
+* drivers supports transfer of dummy cycles directly by the hardware.
+*/
+   u8  dummy_cycles;
+
/* for optional use by whatever driver currently owns the
 * spi_message ...  between calls to spi_async and then later
 * complete(), that's the spi_controller controller driver.
-- 
2.7.4



[PATCH v4 09/13] media: tegra-video: Implement V4L2 device notify callback

2020-12-11 Thread Sowjanya Komatineni
Implement V4L2 device notify callback to handle
V4L2_EVENT_SOURCE_CHANGE event from subdevices.

HDMI-to-CSI bridge drivers trigger V4L2_EVENT_SOURCE_CHANGE when
source DV timing changes are detected or when HDMI hotplug happens.

Runtime source parameter changes during active streaming is not
allowed and Tegra video driver calls vb2_queue_error to signal a
fatal error if a notification of this event happens during an active
streaming.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c|  3 +++
 drivers/staging/media/tegra-video/video.c | 18 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 0a85e52..d42a218 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1636,6 +1636,9 @@ static int tegra_vi_graph_notify_complete(struct 
v4l2_async_notifier *notifier)
 
v4l2_set_subdev_hostdata(subdev, chan);
 
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   v4l2_set_subdev_hostdata(subdev, chan);
+
return 0;
 
 unregister_video:
diff --git a/drivers/staging/media/tegra-video/video.c 
b/drivers/staging/media/tegra-video/video.c
index e50bd70..d966b31 100644
--- a/drivers/staging/media/tegra-video/video.c
+++ b/drivers/staging/media/tegra-video/video.c
@@ -7,6 +7,8 @@
 #include 
 #include 
 
+#include 
+
 #include "video.h"
 
 static void tegra_v4l2_dev_release(struct v4l2_device *v4l2_dev)
@@ -24,6 +26,21 @@ static void tegra_v4l2_dev_release(struct v4l2_device 
*v4l2_dev)
kfree(vid);
 }
 
+static void tegra_v4l2_dev_notify(struct v4l2_subdev *sd,
+ unsigned int notification, void *arg)
+{
+   struct tegra_vi_channel *chan;
+   const struct v4l2_event *ev = arg;
+
+   if (notification != V4L2_DEVICE_NOTIFY_EVENT)
+   return;
+
+   chan = v4l2_get_subdev_hostdata(sd);
+   v4l2_event_queue(>video, arg);
+   if (ev->type == V4L2_EVENT_SOURCE_CHANGE && 
vb2_is_streaming(>queue))
+   vb2_queue_error(>queue);
+}
+
 static int host1x_video_probe(struct host1x_device *dev)
 {
struct tegra_video_device *vid;
@@ -49,6 +66,7 @@ static int host1x_video_probe(struct host1x_device *dev)
 
vid->v4l2_dev.mdev = >media_dev;
vid->v4l2_dev.release = tegra_v4l2_dev_release;
+   vid->v4l2_dev.notify = tegra_v4l2_dev_notify;
ret = v4l2_device_register(>dev, >v4l2_dev);
if (ret < 0) {
dev_err(>dev,
-- 
2.7.4



[PATCH v4 13/13] media: tegra-video: Add custom V4L2 control V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY

2020-12-11 Thread Sowjanya Komatineni
This patch adds custom V4L2 control for syncpt timeout retry to continue
capture on error for specified retries count through this control.

This is useful for HDMI-to-CSI bridge debug purposes like for hotplug scenarios
or for ignoring captures till HDMI input is stabilized.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/tegra210.c | 10 +-
 drivers/staging/media/tegra-video/vi.c   | 26 +-
 drivers/staging/media/tegra-video/vi.h   |  4 
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 063d0a3..f10a041 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -454,6 +454,7 @@ static int chan_capture_kthread_start(void *data)
 {
struct tegra_vi_channel *chan = data;
struct tegra_channel_buffer *buf;
+   unsigned int retries = 0;
int err = 0;
 
while (1) {
@@ -483,8 +484,15 @@ static int chan_capture_kthread_start(void *data)
spin_unlock(>start_lock);
 
err = tegra_channel_capture_frame(chan, buf);
-   if (err)
+   if (!err) {
+   retries = 0;
+   continue;
+   }
+
+   if (retries++ > chan->syncpt_timeout_retry)
vb2_queue_error(>queue);
+   else
+   err = 0;
}
 
return 0;
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 4773281..70e1e18 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -956,7 +956,6 @@ static const struct v4l2_file_operations tegra_channel_fops 
= {
 /*
  * V4L2 control operations
  */
-#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
 static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
struct tegra_vi_channel *chan = container_of(ctrl->handler,
@@ -968,6 +967,9 @@ static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
/* pattern change takes effect on next stream */
chan->pg_mode = ctrl->val + 1;
break;
+   case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
+   chan->syncpt_timeout_retry = ctrl->val;
+   break;
default:
return -EINVAL;
}
@@ -979,10 +981,22 @@ static const struct v4l2_ctrl_ops vi_ctrl_ops = {
.s_ctrl = vi_s_ctrl,
 };
 
+#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
 static const char *const vi_pattern_strings[] = {
"Black/White Direct Mode",
"Color Patch Mode",
 };
+#else
+static const struct v4l2_ctrl_config syncpt_timeout_ctrl = {
+   .ops = _ctrl_ops,
+   .id = V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY,
+   .name = "Syncpt timeout retry",
+   .type = V4L2_CTRL_TYPE_INTEGER,
+   .min = 1,
+   .max = 1,
+   .step = 1,
+   .def = 5,
+};
 #endif
 
 static int tegra_channel_setup_ctrl_handler(struct tegra_vi_channel *chan)
@@ -1004,6 +1018,16 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
 #else
struct v4l2_subdev *subdev;
 
+   /* custom control */
+   v4l2_ctrl_new_custom(>ctrl_handler, _timeout_ctrl, NULL);
+   if (chan->ctrl_handler.error) {
+   dev_err(chan->vi->dev, "failed to add %s ctrl handler: %d\n",
+   syncpt_timeout_ctrl.name,
+   chan->ctrl_handler.error);
+   v4l2_ctrl_handler_free(>ctrl_handler);
+   return chan->ctrl_handler.error;
+   }
+
subdev = tegra_channel_get_remote_source_subdev(chan);
if (!subdev)
return -ENODEV;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 27061a5..a68e2c0 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -23,6 +23,8 @@
 
 #include "csi.h"
 
+#define V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY(V4L2_CTRL_CLASS_CAMERA | 
0x1001)
+
 #define TEGRA_MIN_WIDTH32U
 #define TEGRA_MAX_WIDTH32768U
 #define TEGRA_MIN_HEIGHT   32U
@@ -160,6 +162,7 @@ struct tegra_vi_graph_entity {
  * @of_node: device node of VI channel
  *
  * @ctrl_handler: V4L2 control handler of this video channel
+ * @syncpt_timeout_retry: syncpt timeout retry count for the capture
  * @fmts_bitmap: a bitmap for supported formats matching v4l2 subdev formats
  * @tpg_fmts_bitmap: a bitmap for supported TPG formats
  * @pg_mode: test pattern generator mode (disabled/direct/patch)
@@ -201,6 +204,7 @@ struct tegra_vi_channel {
struct device_node *of_node;
 
struct v4l2_ctrl_handler ctrl_handler;
+   unsigned int syncpt_timeout_retry;
DECLARE_BITMAP(fmts_bitmap, MAX_F

[PATCH v4 07/13] media: tegra-video: Add support for VIDIOC_LOG_STATUS ioctl

2020-12-11 Thread Sowjanya Komatineni
This patch adds support for log_status ioctl.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index bc38136..c280117 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -838,6 +838,15 @@ static int tegra_channel_dv_timings_cap(struct file *file, 
void *fh,
return v4l2_subdev_call(subdev, pad, dv_timings_cap, cap);
 }
 
+static int tegra_channel_log_status(struct file *file, void *fh)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+
+   v4l2_device_call_all(chan->video.v4l2_dev, 0, core, log_status);
+
+   return 0;
+}
+
 static int tegra_channel_enum_input(struct file *file, void *fh,
struct v4l2_input *inp)
 {
@@ -906,6 +915,7 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops 
= {
.vidioc_query_dv_timings= tegra_channel_query_dv_timings,
.vidioc_enum_dv_timings = tegra_channel_enum_dv_timings,
.vidioc_dv_timings_cap  = tegra_channel_dv_timings_cap,
+   .vidioc_log_status  = tegra_channel_log_status,
 };
 
 /*
-- 
2.7.4



[PATCH v4 00/13] tegra-video: Add support for capturing from HDMI-to-CSI bridge

2020-12-11 Thread Sowjanya Komatineni
This series includes below changes to allow capturing from HDMI-to-CSI bridges.
- Add DV timing, EDID and log status V4L2 IOCTLs
- Subscribe V4L2_EVENT_SOURCE_CHANGE
- Implement V4L2 device notify callback to report queue error on source change
  during active streaming.
- Add support for NV16 V4L2 Pixel format.
- Add x8 capture by multiple ports gang up for 4K captures from HDMI-to-CSI
  bridges.

Note: These patches are tested with TC358840 HDMI-to-CSI bridge.

This series also include below fixes
- Allow format change for subdevs that don't have crop support.
- Correct V4L2 Pixel format for RGB888_1X24
- Enable VI pixel transform for YUV and RGB formats.

Delta between patch versions:
[v4]:   Includes v3 minor feedback

[v3]:   Includes below changes based on v2 feedback
- Correct V4L2 pixel formats for RGB and YUV.
- Sets V4L2_IN_CAP_DV_TIMINGS capability for v4l2 input.
- Updates V4L2_FWNODE_CSI2_MAX_DATA_LANES to 8 and uses
  data-lanes property of Tegra CSI device graph endpoint
  for 8 lanes.
- Added V4L2 custom control V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY
  for HDMI-to-CSI bridge debug purposes.

[v2]:   v1 + additional patch for x8 capture support


Sowjanya Komatineni (13):
  media: tegra-video: Use zero crop settings if subdev has no
get_selection
  media: tegra-video: Enable VI pixel transform for YUV and RGB formats
  media: tegra-video: Fix V4L2 pixel format RGB and YUV
  media: tegra-video: Add support for V4L2_PIX_FMT_NV16
  media: tegra-video: Add DV timing support
  media: tegra-video: Add support for EDID ioctl ops
  media: tegra-video: Add support for VIDIOC_LOG_STATUS ioctl
  media: tegra-video: Add support for V4L2_EVENT_SOURCE_CHANGE
  media: tegra-video: Implement V4L2 device notify callback
  media: v4l2-fwnode: Update V4L2_FWNODE_CSI2_MAX_DATA_LANES to 8
  dt-bindings: tegra: Update csi data-lanes to maximum 8 lanes
  media: tegra-video: Add support for x8 captures with gang ports
  media: tegra-video: Add custom V4L2 control
V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY

 .../display/tegra/nvidia,tegra20-host1x.txt|   4 +-
 drivers/staging/media/tegra-video/csi.c|  35 ++-
 drivers/staging/media/tegra-video/csi.h|  14 +-
 drivers/staging/media/tegra-video/tegra210.c   | 340 ++---
 drivers/staging/media/tegra-video/vi.c | 338 +---
 drivers/staging/media/tegra-video/vi.h |  23 +-
 drivers/staging/media/tegra-video/video.c  |  18 ++
 include/media/v4l2-fwnode.h|   2 +-
 8 files changed, 614 insertions(+), 160 deletions(-)

-- 
2.7.4



[PATCH v4 10/13] media: v4l2-fwnode: Update V4L2_FWNODE_CSI2_MAX_DATA_LANES to 8

2020-12-11 Thread Sowjanya Komatineni
Some CSI2 receivers support 8 data lanes.

So, this patch updates CSI2 maximum data lanes to be 8.

Acked-by: Sakari Ailus 
Signed-off-by: Sowjanya Komatineni 
---
 include/media/v4l2-fwnode.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index 4e1f6e1d..92401c1 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -25,7 +25,7 @@ struct fwnode_handle;
 struct v4l2_async_notifier;
 struct v4l2_async_subdev;
 
-#define V4L2_FWNODE_CSI2_MAX_DATA_LANES4
+#define V4L2_FWNODE_CSI2_MAX_DATA_LANES8
 
 /**
  * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure
-- 
2.7.4



[PATCH v4 11/13] dt-bindings: tegra: Update csi data-lanes to maximum 8 lanes

2020-12-11 Thread Sowjanya Komatineni
Tegra VI/CSI hardware don't have native 8 lane CSI RX port.

But x8 capture can be supported by using consecutive x4 ports
simultaneously with HDMI-to-CSI bridges where source image is split
on to two x4 ports.

This patch updates dt-bindings for csi endpoint data-lane property
with maximum of 8 lanes.

Acked-by: Rob Herring 
Acked-by: Sakari Ailus 
Signed-off-by: Sowjanya Komatineni 
---
 .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt 
b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index 34d9933..8a6d3e1 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -111,8 +111,8 @@ of the following host1x client modules:
 
  endpoint (required node)
  Required properties:
- - data-lanes: an array of data lane from 1 to 4. Valid array
-   lengths are 1/2/4.
+ - data-lanes: an array of data lane from 1 to 8. Valid array
+   lengths are 1/2/4/8.
  - remote-endpoint: phandle to sensor 'endpoint' node.
 
 port@1 (required node)
-- 
2.7.4



[PATCH v4 08/13] media: tegra-video: Add support for V4L2_EVENT_SOURCE_CHANGE

2020-12-11 Thread Sowjanya Komatineni
Current implementation uses v4l2_ctrl_subscribe_event() and this
does not handle V4L2_EVENT_SOURCE_CHANGE.

So, update driver to handle V4L2_EVENT_SOURCE_CHANGE.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index c280117..0a85e52 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -642,6 +642,18 @@ static int tegra_channel_set_subdev_active_fmt(struct 
tegra_vi_channel *chan)
return 0;
 }
 
+static int
+tegra_channel_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+   switch (sub->type) {
+   case V4L2_EVENT_SOURCE_CHANGE:
+   return v4l2_event_subscribe(fh, sub, 4, NULL);
+   }
+
+   return v4l2_ctrl_subscribe_event(fh, sub);
+}
+
 static int tegra_channel_g_selection(struct file *file, void *priv,
 struct v4l2_selection *sel)
 {
@@ -904,7 +916,7 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops 
= {
.vidioc_expbuf  = vb2_ioctl_expbuf,
.vidioc_streamon= vb2_ioctl_streamon,
.vidioc_streamoff   = vb2_ioctl_streamoff,
-   .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+   .vidioc_subscribe_event = tegra_channel_subscribe_event,
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
.vidioc_g_selection = tegra_channel_g_selection,
.vidioc_s_selection = tegra_channel_s_selection,
-- 
2.7.4



[PATCH v4 03/13] media: tegra-video: Fix V4L2 pixel format RGB and YUV

2020-12-11 Thread Sowjanya Komatineni
V4L2 pixel format is incorrect for RGB and YUV formats.

This patch fixes it.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/tegra210.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 6b23aa7..68f09e4 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -619,19 +619,19 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
TEGRA210_VIDEO_FMT(RAW12, 12, SGBRG12_1X12, 2, T_R16_I, SGBRG12),
TEGRA210_VIDEO_FMT(RAW12, 12, SBGGR12_1X12, 2, T_R16_I, SBGGR12),
/* RGB888 */
-   TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, RGB24),
+   TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, XBGR32),
TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8,
-  XBGR32),
+  RGBX32),
/* YUV422 */
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 2, T_U8_Y8__V8_Y8, UYVY),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_1X16, 2, T_V8_Y8__U8_Y8, VYUY),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_1X16, 2, T_Y8_U8__Y8_V8, YUYV),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_1X16, 2, T_Y8_V8__Y8_U8, YVYU),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 2, T_U8_Y8__V8_Y8, YVYU),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_1X16, 2, T_V8_Y8__U8_Y8, YUYV),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_1X16, 2, T_Y8_U8__Y8_V8, VYUY),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_1X16, 2, T_Y8_V8__Y8_U8, UYVY),
TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_1X16, 1, T_Y8__V8U8_N422, NV16),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_2X8, 2, T_U8_Y8__V8_Y8, UYVY),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, VYUY),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, YUYV),
-   TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, YVYU),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, UYVY8_2X8, 2, T_U8_Y8__V8_Y8, YVYU),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, YUYV),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, VYUY),
+   TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, UYVY),
 };
 
 /* Tegra210 VI operations */
-- 
2.7.4



[PATCH v4 04/13] media: tegra-video: Add support for V4L2_PIX_FMT_NV16

2020-12-11 Thread Sowjanya Komatineni
NV16 are two-plane versions of YUV422 format.

VI/CSI surface0 registers corresponds to first Y plane and
surface1 registers corresponds to seconds UV plane.

This patch updates image size for NV16 format to include both planes
and programs VI/CSI surface1 registers for UV plane capture.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/tegra210.c | 13 +
 drivers/staging/media/tegra-video/vi.c   |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 68f09e4..b731aa5 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -287,6 +287,7 @@ static int tegra_channel_capture_frame(struct 
tegra_vi_channel *chan,
 {
u32 thresh, value, frame_start, mw_ack_done;
int bytes_per_line = chan->format.bytesperline;
+   u32 sizeimage = chan->format.sizeimage;
int err;
 
/* program buffer address by using surface 0 */
@@ -296,6 +297,18 @@ static int tegra_channel_capture_frame(struct 
tegra_vi_channel *chan,
vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_STRIDE, bytes_per_line);
 
/*
+* Program surface 1 for UV plane with offset sizeimage from Y plane.
+*/
+   if (chan->fmtinfo->fourcc == V4L2_PIX_FMT_NV16) {
+   vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_OFFSET_MSB,
+((u64)buf->addr + sizeimage / 2) >> 32);
+   vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_OFFSET_LSB,
+buf->addr + sizeimage / 2);
+   vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_STRIDE,
+bytes_per_line);
+   }
+
+   /*
 * Tegra VI block interacts with host1x syncpt for synchronizing
 * programmed condition of capture state and hardware operation.
 * Frame start and Memory write acknowledge syncpts has their own
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 7edd35c..525c087 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -484,6 +484,8 @@ static void tegra_channel_fmt_align(struct tegra_vi_channel 
*chan,
 
pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
pix->sizeimage = pix->bytesperline * pix->height;
+   if (pix->pixelformat == V4L2_PIX_FMT_NV16)
+   pix->sizeimage *= 2;
 }
 
 static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
-- 
2.7.4



[PATCH v4 05/13] media: tegra-video: Add DV timing support

2020-12-11 Thread Sowjanya Komatineni
This patch adds below v4l2 DV timing ioctls to support HDMI-to-CSI
bridges.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c | 99 ++
 1 file changed, 99 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 525c087..d01e88d 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -720,6 +721,97 @@ static int tegra_channel_s_selection(struct file *file, 
void *fh,
return ret;
 }
 
+static int tegra_channel_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, video, g_dv_timings))
+   return -ENOTTY;
+
+   return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+ video, g_dv_timings, timings);
+}
+
+static int tegra_channel_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+   struct v4l2_bt_timings *bt = >bt;
+   struct v4l2_dv_timings curr_timings;
+   int ret;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, video, s_dv_timings))
+   return -ENOTTY;
+
+   ret = tegra_channel_g_dv_timings(file, fh, _timings);
+   if (ret)
+   return ret;
+
+   if (v4l2_match_dv_timings(timings, _timings, 0, false))
+   return 0;
+
+   if (vb2_is_busy(>queue))
+   return -EBUSY;
+
+   ret = v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+video, s_dv_timings, timings);
+   if (ret)
+   return ret;
+
+   chan->format.width = bt->width;
+   chan->format.height = bt->height;
+   chan->format.bytesperline = bt->width * chan->fmtinfo->bpp;
+   chan->format.sizeimage = chan->format.bytesperline * bt->height;
+   tegra_channel_fmt_align(chan, >format, chan->fmtinfo->bpp);
+
+   return 0;
+}
+
+static int tegra_channel_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, video, query_dv_timings))
+   return -ENOTTY;
+
+   return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+ video, query_dv_timings, timings);
+}
+
+static int tegra_channel_enum_dv_timings(struct file *file, void *fh,
+struct v4l2_enum_dv_timings *timings)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, pad, enum_dv_timings))
+   return -ENOTTY;
+
+   return v4l2_subdev_call(subdev, pad, enum_dv_timings, timings);
+}
+
+static int tegra_channel_dv_timings_cap(struct file *file, void *fh,
+   struct v4l2_dv_timings_cap *cap)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, pad, dv_timings_cap))
+   return -ENOTTY;
+
+   return v4l2_subdev_call(subdev, pad, dv_timings_cap, cap);
+}
+
 static int tegra_channel_enum_input(struct file *file, void *fh,
struct v4l2_input *inp)
 {
@@ -732,6 +824,8 @@ static int tegra_channel_enum_input(struct file *file, void 
*fh,
inp->type = V4L2_INPUT_TYPE_CAMERA;
subdev = tegra_channel_get_remote_source_subdev(chan);
strscpy(inp->name, subdev->name, sizeof(inp->name));
+   if (v4l2_subdev_has_op(subdev, pad, dv_timings_cap))
+   inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
 
return 0;
 }
@@ -779,6 +873,11 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops 
= {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
.vidioc_g_selection = tegra_channel_g_selection,
.vidioc_s_selection = tegra_channel_s_selection,
+   .vidioc_g_dv_timings= tegra_channel_g_dv_timings,
+   .vidioc_s_dv_timings  

[PATCH v4 06/13] media: tegra-video: Add support for EDID ioctl ops

2020-12-11 Thread Sowjanya Komatineni
This patch adds support for EDID get and set v4l2 ioctl ops to use
with HDMI to CSI bridges.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index d01e88d..bc38136 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -721,6 +721,32 @@ static int tegra_channel_s_selection(struct file *file, 
void *fh,
return ret;
 }
 
+static int tegra_channel_g_edid(struct file *file, void *fh,
+   struct v4l2_edid *edid)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, pad, get_edid))
+   return -ENOTTY;
+
+   return v4l2_subdev_call(subdev, pad, get_edid, edid);
+}
+
+static int tegra_channel_s_edid(struct file *file, void *fh,
+   struct v4l2_edid *edid)
+{
+   struct tegra_vi_channel *chan = video_drvdata(file);
+   struct v4l2_subdev *subdev;
+
+   subdev = tegra_channel_get_remote_source_subdev(chan);
+   if (!v4l2_subdev_has_op(subdev, pad, set_edid))
+   return -ENOTTY;
+
+   return v4l2_subdev_call(subdev, pad, set_edid, edid);
+}
+
 static int tegra_channel_g_dv_timings(struct file *file, void *fh,
  struct v4l2_dv_timings *timings)
 {
@@ -873,6 +899,8 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops 
= {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
.vidioc_g_selection = tegra_channel_g_selection,
.vidioc_s_selection = tegra_channel_s_selection,
+   .vidioc_g_edid  = tegra_channel_g_edid,
+   .vidioc_s_edid  = tegra_channel_s_edid,
.vidioc_g_dv_timings= tegra_channel_g_dv_timings,
.vidioc_s_dv_timings= tegra_channel_s_dv_timings,
.vidioc_query_dv_timings= tegra_channel_query_dv_timings,
-- 
2.7.4



[PATCH v4 01/13] media: tegra-video: Use zero crop settings if subdev has no get_selection

2020-12-11 Thread Sowjanya Komatineni
Currently try format implementation doesn't check if subdevice has
get_selection ops implemented and returns -EINVAL on error from
direct v4l2_subdev_call of get_selection.

Selection API's are not mandatory for all V4L2 subdevices.

This patch fixes it by adding v4l2_subdev_has_ops check prior to
calling get_selection ops and continues with try or set format with
zero crop settings for subdevices that don't have get_selection and
returns -EINVAL only for subdevices that has get_selection ops.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/vi.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 560d8b3..7edd35c 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -533,11 +533,18 @@ static int __tegra_channel_try_format(struct 
tegra_vi_channel *chan,
fse.code = fmtinfo->code;
ret = v4l2_subdev_call(subdev, pad, enum_frame_size, pad_cfg, );
if (ret) {
-   ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, 
);
-   if (ret)
-   return -EINVAL;
-   pad_cfg->try_crop.width = sdsel.r.width;
-   pad_cfg->try_crop.height = sdsel.r.height;
+   if (!v4l2_subdev_has_op(subdev, pad, get_selection)) {
+   pad_cfg->try_crop.width = 0;
+   pad_cfg->try_crop.height = 0;
+   } else {
+   ret = v4l2_subdev_call(subdev, pad, get_selection,
+  NULL, );
+   if (ret)
+   return -EINVAL;
+
+   pad_cfg->try_crop.width = sdsel.r.width;
+   pad_cfg->try_crop.height = sdsel.r.height;
+   }
} else {
pad_cfg->try_crop.width = fse.max_width;
pad_cfg->try_crop.height = fse.max_height;
-- 
2.7.4



[PATCH v4 02/13] media: tegra-video: Enable VI pixel transform for YUV and RGB formats

2020-12-11 Thread Sowjanya Komatineni
VI Pixel transforms converts source pixel data to selected
destination pixel formats in memory and aligns properly.

YUV and RGB formats need this pixel transform to be enabled.

RAW formats use T_R16_I destination pixel format in memory and
does not need pixel transform as they support direct write to
memory.

So, this patch enables pixel transform for YUV and RGB and keeps
it bypass for RAW formats.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/staging/media/tegra-video/tegra210.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index ac066c0..6b23aa7 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -178,10 +178,23 @@ static int tegra_channel_capture_setup(struct 
tegra_vi_channel *chan)
u32 format = chan->fmtinfo->img_fmt;
u32 data_type = chan->fmtinfo->img_dt;
u32 word_count = (width * chan->fmtinfo->bit_width) / 8;
+   u32 bypass_pixel_transform = BIT(BYPASS_PXL_TRANSFORM_OFFSET);
+
+   /*
+* VI Pixel transformation unit converts source pixels data format
+* into selected destination pixel format and aligns properly while
+* interfacing with memory packer.
+* This pixel transformation should be enabled for YUV and RGB
+* formats and should be bypassed for RAW formats as RAW formats
+* only support direct to memory.
+*/
+   if (chan->pg_mode || data_type == TEGRA_IMAGE_DT_YUV422_8 ||
+   data_type == TEGRA_IMAGE_DT_RGB888)
+   bypass_pixel_transform = 0;
 
vi_csi_write(chan, TEGRA_VI_CSI_ERROR_STATUS, 0x);
vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_DEF,
-((chan->pg_mode ? 0 : 1) << BYPASS_PXL_TRANSFORM_OFFSET) |
+bypass_pixel_transform |
 (format << IMAGE_DEF_FORMAT_OFFSET) |
 IMAGE_DEF_DEST_MEM);
vi_csi_write(chan, TEGRA_VI_CSI_IMAGE_DT, data_type);
-- 
2.7.4



[PATCH v2 8/9] arm64: tegra: Add QSPI nodes on Tegra194

2020-12-11 Thread Sowjanya Komatineni
Tegra194 has 2 QSPI controllers.

This patch adds DT node for these 2 QSPI controllers.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 25f36d6..63ed788 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -609,6 +609,30 @@
status = "disabled";
};
 
+   spi@327 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x327 0x1000>;
+   interrupts = ;
+   clocks = < TEGRA194_CLK_QSPI0>,
+< TEGRA194_CLK_QSPI0_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI0>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
+   spi@330 {
+   compatible = "nvidia,tegra194-qspi";
+   reg = <0x330 0x1000>;
+   interrupts = ;
+   clocks = < TEGRA194_CLK_QSPI1>,
+< TEGRA194_CLK_QSPI1_PM>;
+   clock-names = "qspi", "qspi_out";
+   resets = < TEGRA194_RESET_QSPI1>;
+   reset-names = "qspi";
+   status = "disabled";
+   };
+
pwm1: pwm@328 {
compatible = "nvidia,tegra194-pwm",
 "nvidia,tegra186-pwm";
-- 
2.7.4



[PATCH v2 2/9] dt-bindings: spi: Add Tegra QSPI device tree binding

2020-12-11 Thread Sowjanya Komatineni
This patch adds YAML based device tree binding document for Tegra
QSPI driver.

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/spi/nvidia,tegra210-quad.yaml | 128 +
 1 file changed, 128 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
new file mode 100644
index 000..8d577c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -0,0 +1,128 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra-qspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi
+  - const: qspi_out
+
+  clocks:
+maxItems: 2
+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+patternProperties:
+  "^.*@[0-9a-f]+":
+type: object
+
+properties:
+  compatible:
+description:
+  Compatible of the SPI device.
+
+  reg:
+maxItems: 1
+
+  spi-max-frequency:
+$ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Maximum Quad SPI clocking speed of the device in Hz.
+
+  spi-rx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for read transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [1, 2, 4]
+
+  spi-tx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for write transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+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
+  - interrupts
+  - clock-names
+  - clocks
+  - resets
+
+additionalProperties: true
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+clocks = <_car TEGRA210_CLK_QSPI>,
+ <_car TEGRA210_CLK_QSPI_PM>;
+clock-names = "qspi", "qspi_out";
+resets = <_car 211>;
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+flash@0 {
+compatible = "spi-nor";
+reg = <0>;
+spi-max-frequency = <10400>;
+spi-tx-bus-width = <2>;
+spi-rx-bus-width = <2>;
+};
+};
-- 
2.7.4



[PATCH v2 3/9] MAINTAINERS: Add Tegra QSPI driver section

2020-12-11 Thread Sowjanya Komatineni
Add maintainers and mailing list entries to Tegra QSPI driver section.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5b20bab..19db61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17447,6 +17447,14 @@ M: Laxman Dewangan 
 S: Supported
 F: drivers/spi/spi-tegra*
 
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Sowjanya Komatineni 
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
 TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
-- 
2.7.4



[PATCH v2 1/9] dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM

2020-12-11 Thread Sowjanya Komatineni
Tegra210 QSPI clock output has divider DIV2_SEL which will be enabled
when using DDR interface mode.

This patch adds clock ID for this to dt-binding.

Signed-off-by: Sowjanya Komatineni 
---
 include/dt-bindings/clock/tegra210-car.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/tegra210-car.h 
b/include/dt-bindings/clock/tegra210-car.h
index ab8b8a7..9cfcc3b 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -307,7 +307,7 @@
 #define TEGRA210_CLK_AUDIO4 275
 #define TEGRA210_CLK_SPDIF 276
 /* 277 */
-/* 278 */
+#define TEGRA210_CLK_QSPI_PM 278
 /* 279 */
 /* 280 */
 #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
-- 
2.7.4



[PATCH v2 7/9] arm64: tegra: Enable QSPI on Jetson Nano

2020-12-11 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Nano.

Signed-off-by: Sowjanya Komatineni 
---
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts | 12 
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |  5 +++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts 
b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
index 6a877de..a1b4603 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts
@@ -638,6 +638,18 @@
};
};
 
+   spi@7041 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10400>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+   };
+
clk32k_in: clock@0 {
compatible = "fixed-clock";
clock-frequency = <32768>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 4fbf8c1..998fa81 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1536,8 +1536,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
-   clocks = <_car TEGRA210_CLK_QSPI>;
-   clock-names = "qspi";
+   clocks = <_car TEGRA210_CLK_QSPI>,
+<_car TEGRA210_CLK_QSPI_PM>;
+   clock-names = "qspi", "qspi_out";
resets = <_car 211>;
reset-names = "qspi";
dmas = < 5>, < 5>;
-- 
2.7.4



[PATCH v2 4/9] spi: tegra210-quad: Add support for Tegra210 QSPI controller

2020-12-11 Thread Sowjanya Komatineni
Tegra SoC has a Quad SPI controller starting from Tegra210.

This patch adds support for Tegra210 QSPI controller.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/Kconfig |9 +
 drivers/spi/Makefile|1 +
 drivers/spi/spi-tegra210-quad.c | 1387 +++
 3 files changed, 1397 insertions(+)
 create mode 100644 drivers/spi/spi-tegra210-quad.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index aadaea0..f56f20e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -843,6 +843,15 @@ config SPI_MXS
help
  SPI driver for Freescale MXS devices.
 
+config SPI_TEGRA210_QUAD
+   tristate "NVIDIA Tegra QSPI Controller"
+   depends on ARCH_TEGRA || COMPILE_TEST
+   depends on RESET_CONTROLLER
+   help
+ QSPI driver for NVIDIA Tegra QSPI Controller interface. This
+ controller is different from the SPI controller and is available
+ on Tegra SoCs starting from Tegra210.
+
 config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6fea582..c822c5e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ST_SSC4)   += spi-st-ssc4.o
 obj-$(CONFIG_SPI_SUN4I)+= spi-sun4i.o
 obj-$(CONFIG_SPI_SUN6I)+= spi-sun6i.o
 obj-$(CONFIG_SPI_SYNQUACER)+= spi-synquacer.o
+obj-$(CONFIG_SPI_TEGRA210_QUAD)+= spi-tegra210-quad.o
 obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o
 obj-$(CONFIG_SPI_TEGRA20_SFLASH)   += spi-tegra20-sflash.o
 obj-$(CONFIG_SPI_TEGRA20_SLINK)+= spi-tegra20-slink.o
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
new file mode 100644
index 000..624f395
--- /dev/null
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -0,0 +1,1387 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 NVIDIA CORPORATION.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define QSPI_COMMAND1  0x000
+#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
+#define QSPI_PACKEDBIT(5)
+#define QSPI_INTERFACE_WIDTH_MASK  (0x03 << 7)
+#define QSPI_INTERFACE_WIDTH(x)(((x) & 0x03) << 7)
+#define QSPI_INTERFACE_WIDTH_SINGLEQSPI_INTERFACE_WIDTH(0)
+#define QSPI_INTERFACE_WIDTH_DUAL  QSPI_INTERFACE_WIDTH(1)
+#define QSPI_INTERFACE_WIDTH_QUAD  QSPI_INTERFACE_WIDTH(2)
+#define QSPI_SDR_DDR_SEL   BIT(9)
+#define QSPI_TX_EN BIT(11)
+#define QSPI_RX_EN BIT(12)
+#define QSPI_CS_SW_VAL BIT(20)
+#define QSPI_CS_SW_HW  BIT(21)
+#define QSPI_CONTROL_MODE_0(0 << 28)
+#define QSPI_CONTROL_MODE_3(3 << 28)
+#define QSPI_CONTROL_MODE_MASK (3 << 28)
+#define QSPI_M_S   BIT(30)
+#define QSPI_PIO   BIT(31)
+
+#define QSPI_COMMAND2  0x004
+#define QSPI_TX_TAP_DELAY(x)   (((x) & 0x3f) << 10)
+#define QSPI_RX_TAP_DELAY(x)   (((x) & 0xff) << 0)
+
+#define QSPI_CS_TIMING10x008
+#define QSPI_SETUP_HOLD(setup, hold)   (((setup) << 4) | (hold))
+
+#define QSPI_CS_TIMING20x00c
+#define CYCLES_BETWEEN_PACKETS_0(x)(((x) & 0x1f) << 0)
+#define CS_ACTIVE_BETWEEN_PACKETS_0BIT(5)
+
+#define QSPI_TRANS_STATUS  0x010
+#define QSPI_BLK_CNT(val)  (((val) >> 0) & 0x)
+#define QSPI_RDY   BIT(30)
+
+#define QSPI_FIFO_STATUS   0x014
+#define QSPI_RX_FIFO_EMPTY BIT(0)
+#define QSPI_RX_FIFO_FULL  BIT(1)
+#define QSPI_TX_FIFO_EMPTY BIT(2)
+#define QSPI_TX_FIFO_FULL  BIT(3)
+#define QSPI_RX_FIFO_UNF   BIT(4)
+#define QSPI_RX_FIFO_OVF   BIT(5)
+#define QSPI_TX_FIFO_UNF   BIT(6)
+#define QSPI_TX_FIFO_OVF   BIT(7)
+#define QSPI_ERR   BIT(8)
+#define QSPI_TX_FIFO_FLUSH BIT(14)
+#define QSPI_RX_FIFO_FLUSH BIT(15)
+#define QSPI_TX_FIFO_EMPTY_COUNT(val)  (((val) >> 16) & 0x7f)
+#define QSPI_RX_F

[PATCH v2 0/9] Add Tegra Quad SPI driver

2020-12-11 Thread Sowjanya Komatineni
This series adds Tegra210, Tegra186, and Tegra194 Quad SPI driver and
enables Quad SPI on Jetson Nano and Jetson Xavier NX.

QSPI controller is available on Tegra210, Tegra186 and Tegra194.

Tegra186 and Tegra194 has additional feature of combined sequence mode
where command, address and data can all be transferred in a single transfer.

Combined sequence mode is useful with DMA mode transfer.

This series does not have combined sequence mode feature as Tegra186/Tegra194
GPCDMA driver is not upstreamed yet.

This series includes
- dt-binding document
- QSPI driver for Tegra210/Tegra186/Tegra194
- Enables QSPI on Jetson Nano and Jetson Xavier NX.

Delta between patch versions:
[v2]:   below v1 feedback
- Added SPI_MASTER_USES_HW_DUMMY_CYCLES flag for controllers supporting
  hardware dummy cycles and skips dummy bytes transfer from software for
  these controllers.
- Updated dt-binding doc with tx/rx tap delay properties.
- Added qspi_out clock to dt-binding doc which will be used later with
  ddr mode support.
- All other v1 feedback on some cleanup.


Sowjanya Komatineni (9):
  dt-bindings: clock: tegra: Add clock ID TEGRA210_CLK_QSPI_PM
  dt-bindings: spi: Add Tegra Quad SPI device tree binding
  MAINTAINERS: Add Tegra Quad SPI driver section
  spi: tegra210-quad: Add support for Tegra210 QSPI controller
  spi: spi-mem: Allow masters to transfer dummy cycles directly by
hardware
  spi: tegra210-quad: Add support for hardware dummy cycles
  arm64: tegra: Enable QSPI on Jetson Nano
  arm64: tegra: Add QSPI nodes on Tegra194
  arm64: tegra: Enable QSPI on Jetson Xavier NX

 .../bindings/spi/nvidia,tegra210-quad.yaml |  130 ++
 MAINTAINERS|8 +
 .../dts/nvidia/tegra194-p3509-+p3668-.dts  |   12 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi   |   24 +
 arch/arm64/boot/dts/nvidia/tegra210-p3450-.dts |   12 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi   |5 +-
 drivers/spi/Kconfig|9 +
 drivers/spi/Makefile   |1 +
 drivers/spi/spi-mem.c  |   18 +-
 drivers/spi/spi-tegra210-quad.c| 1407 
 include/dt-bindings/clock/tegra210-car.h   |2 +-
 include/linux/spi/spi.h|8 +
 12 files changed, 1626 insertions(+), 10 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
 create mode 100644 drivers/spi/spi-tegra210-quad.c

-- 
2.7.4



[PATCH v2 6/9] spi: tegra210-quad: Add support for hardware dummy cycles

2020-12-11 Thread Sowjanya Komatineni
Tegra Quad SPI controller hardware supports sending dummy cycles
after address bytes.

This patch adds this support.

Signed-off-by: Sowjanya Komatineni 
---
 drivers/spi/spi-tegra210-quad.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index 624f395..1d1b125 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -124,6 +124,13 @@
 #define QSPI_DMA_TIMEOUT   (msecs_to_jiffies(1000))
 #define DEFAULT_QSPI_DMA_BUF_LEN   (64 * 1024)
 
+enum transfer_phase {
+   CMD_BYTE_XFER = 0,
+   ADDR_BYTES_XFER,
+   DATA_BYTES_XFER,
+   MAX_XFERS,
+};
+
 struct tegra_qspi_client_data {
int tx_clk_tap_delay;
int rx_clk_tap_delay;
@@ -857,6 +864,8 @@ static int tegra_qspi_start_transfer_one(struct spi_device 
*spi,
 
tqspi->command1_reg = command1;
 
+   tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
QSPI_MISC_REG);
+
ret = tegra_qspi_flush_fifos(tqspi, false);
if (ret < 0)
return ret;
@@ -977,7 +986,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
struct spi_device *spi = msg->spi;
struct spi_transfer *xfer;
bool is_first_msg = true;
-   int ret;
+   int ret, xfer_phase = 0;
 
msg->status = 0;
msg->actual_length = 0;
@@ -987,6 +996,15 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
list_for_each_entry(xfer, >transfers, transfer_list) {
u32 cmd1;
 
+   /*
+* Program dummy clock cycles in Tegra QSPI register only
+* during address transfer phase.
+*/
+   if (xfer_phase == ADDR_BYTES_XFER)
+   tqspi->dummy_cycles = msg->dummy_cycles;
+   else
+   tqspi->dummy_cycles = 0;
+
reinit_completion(>xfer_completion);
 
cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);
@@ -1018,6 +1036,7 @@ static int tegra_qspi_transfer_one_message(struct 
spi_master *master, struct spi
}
 
msg->actual_length += xfer->len;
+   xfer_phase++;
 
 complete_xfer:
if (ret < 0) {
@@ -1203,6 +1222,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
master->mode_bits = SPI_MODE_0 | SPI_MODE_3 | SPI_CS_HIGH |
SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | 
SPI_RX_QUAD;
master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | 
SPI_BPW_MASK(8);
+   master->flags = SPI_MASTER_USES_HW_DUMMY_CYCLES;
master->setup = tegra_qspi_setup;
master->cleanup = tegra_qspi_cleanup;
master->transfer_one_message = tegra_qspi_transfer_one_message;
-- 
2.7.4



[PATCH v2 9/9] arm64: tegra: Enable QSPI on Jetson Xavier NX

2020-12-11 Thread Sowjanya Komatineni
This patch enables QSPI on Jetson Xavier NX.

Signed-off-by: Sowjanya Komatineni 
---
 .../arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts 
b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
index 7f97b34..f1053e7 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-+p3668-.dts
@@ -100,6 +100,18 @@
phy-names = "usb2-1", "usb2-2", "usb3-2";
};
 
+   spi@327 {
+   status = "okay";
+
+   flash@0 {
+   compatible = "spi-nor";
+   reg = <0>;
+   spi-max-frequency = <10200>;
+   spi-tx-bus-width = <4>;
+   spi-rx-bus-width = <4>;
+   };
+   };
+
pwm@32d {
status = "okay";
};
-- 
2.7.4



[PATCH v2 2/9] dt-bindings: spi: Add Tegra Quad SPI device tree binding

2020-12-11 Thread Sowjanya Komatineni
This patch adds YAML based device tree binding document for Tegra
Quad SPI driver.

Signed-off-by: Sowjanya Komatineni 
---
 .../bindings/spi/nvidia,tegra210-quad.yaml | 130 +
 1 file changed, 130 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
new file mode 100644
index 000..0b5fea6
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra210-quad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi
+  - const: qspi_out
+
+  clocks:
+maxItems: 2
+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+patternProperties:
+  "^.*@[0-9a-f]+":
+type: object
+
+properties:
+  compatible:
+description:
+  Compatible of the SPI device.
+
+  reg:
+maxItems: 1
+
+  spi-max-frequency:
+$ref: /schemas/types.yaml#/definitions/uint32
+description:
+  Maximum Quad SPI clocking speed of the device in Hz.
+
+  spi-rx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for read transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [1, 2, 4]
+
+  spi-tx-bus-width:
+description:
+  Bus width to the Quad SPI bus used for write transfers.
+$ref: /schemas/types.yaml#/definitions/uint32
+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
+  - interrupts
+  - clock-names
+  - clocks
+  - resets
+
+additionalProperties: true
+
+examples:
+  - |
+#include 
+#include 
+#include 
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+#address-cells = <1>;
+#size-cells = <0>;
+clocks = <_car TEGRA210_CLK_QSPI>,
+ <_car TEGRA210_CLK_QSPI_PM>;
+clock-names = "qspi", "qspi_out";
+resets = <_car 211>;
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+
+flash@0 {
+compatible = "spi-nor";
+reg = <0>;
+spi-max-frequency = <10400>;
+spi-tx-bus-width = <2>;
+spi-rx-bus-width = <2>;
+};
+};
-- 
2.7.4



[PATCH v2 3/9] MAINTAINERS: Add Tegra Quad SPI driver section

2020-12-11 Thread Sowjanya Komatineni
Add maintainers and mailing list entries to Tegra Quad SPI driver
section.

Signed-off-by: Sowjanya Komatineni 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5b20bab..19db61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17447,6 +17447,14 @@ M: Laxman Dewangan 
 S: Supported
 F: drivers/spi/spi-tegra*
 
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding 
+M: Jonathan Hunter 
+M: Sowjanya Komatineni 
+L: linux-te...@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
 TEGRA VIDEO DRIVER
 M: Thierry Reding 
 M: Jonathan Hunter 
-- 
2.7.4



Re: [PATCH v1 2/7] dt-bindings: spi: Add Tegra QSPI device tree binding

2020-12-10 Thread Sowjanya Komatineni



On 12/9/20 12:28 PM, Sowjanya Komatineni wrote:


On 12/9/20 9:26 AM, Rob Herring wrote:

On Tue, Dec 01, 2020 at 01:12:43PM -0800, Sowjanya Komatineni wrote:

This patch adds YAML based device tree binding document for Tegra
QSPI driver.

Signed-off-by: Sowjanya Komatineni 
---
  .../devicetree/bindings/spi/nvidia,tegra-qspi.yaml | 77 
++

  1 file changed, 77 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml


diff --git 
a/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml

new file mode 100644
index 000..038a085
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra-qspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+    enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+    items:
+  - description: QSPI registers

Just 'maxItems: 1'


+
+  interrupts:
+    maxItems: 1
+
+  clock-names:
+    items:
+  - const: qspi

Kind of a pointless name.
Thanks Rob for feedback. Do you mean to change name something like 
qspi-clk instead of qspi?


Rob, reason I added clock name is later when we add ddr mode we will 
have additional clock.


So driver uses clock name to retrieve.

Will add both clocks to dt-binding doc in v2 although support for ddr 
mode in qspi driver can be implemented later.





+
+  clocks:
+    maxItems: 1
+
+  reset-names:
+    minItems: 1
+    items:
+  - const: qspi

Same here.


+
+  resets:
+    maxItems: 1
+
+  dmas:
+    maxItems: 2
+
+  dma-names:
+    items:
+  - const: rx
+  - const: tx
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clock-names
+  - clocks
+  - reset-names
+  - resets
+
+additionalProperties: true
+
+examples:
+  - |
+    #include 
+    #include 
+    #include 
+
+    spi@7041 {
+    compatible = "nvidia,tegra210-qspi";
+    reg = <0x7041 0x1000>;
+    interrupts = ;
+    clocks = <_car TEGRA210_CLK_QSPI>;
+    clock-names = "qspi";
+    resets = <_car 211>;
+    reset-names = "qspi";
+    dmas = < 5>, < 5>;
+    dma-names = "rx", "tx";
+    };
--
2.7.4



Re: [PATCH v1 2/7] dt-bindings: spi: Add Tegra QSPI device tree binding

2020-12-09 Thread Sowjanya Komatineni



On 12/9/20 9:26 AM, Rob Herring wrote:

On Tue, Dec 01, 2020 at 01:12:43PM -0800, Sowjanya Komatineni wrote:

This patch adds YAML based device tree binding document for Tegra
QSPI driver.

Signed-off-by: Sowjanya Komatineni 
---
  .../devicetree/bindings/spi/nvidia,tegra-qspi.yaml | 77 ++
  1 file changed, 77 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml

diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml 
b/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml
new file mode 100644
index 000..038a085
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra-qspi.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nvidia,tegra-qspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra Quad SPI Controller
+
+maintainers:
+  - Thierry Reding 
+  - Jonathan Hunter 
+
+properties:
+  compatible:
+enum:
+  - nvidia,tegra210-qspi
+  - nvidia,tegra186-qspi
+  - nvidia,tegra194-qspi
+
+  reg:
+items:
+  - description: QSPI registers

Just 'maxItems: 1'


+
+  interrupts:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: qspi

Kind of a pointless name.
Thanks Rob for feedback. Do you mean to change name something like 
qspi-clk instead of qspi?



+
+  clocks:
+maxItems: 1
+
+  reset-names:
+minItems: 1
+items:
+  - const: qspi

Same here.


+
+  resets:
+maxItems: 1
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clock-names
+  - clocks
+  - reset-names
+  - resets
+
+additionalProperties: true
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+spi@7041 {
+compatible = "nvidia,tegra210-qspi";
+reg = <0x7041 0x1000>;
+interrupts = ;
+clocks = <_car TEGRA210_CLK_QSPI>;
+clock-names = "qspi";
+resets = <_car 211>;
+reset-names = "qspi";
+dmas = < 5>, < 5>;
+dma-names = "rx", "tx";
+};
--
2.7.4



Re: [PATCH v3 10/13] media: v4l2-fwnode: Update V4L2_FWNODE_CSI2_MAX_DATA_LANES to 8

2020-12-08 Thread Sowjanya Komatineni



On 12/8/20 11:59 AM, Sakari Ailus wrote:

Hi Hans,

On Mon, Dec 07, 2020 at 11:47:38AM +0100, Hans Verkuil wrote:

On 03/12/2020 19:59, Sowjanya Komatineni wrote:

Some CSI2 receivers support 8 data lanes.

So, this patch updates CSI2 maximum data lanes to be 8.

Signed-off-by: Sowjanya Komatineni 
---
  drivers/media/platform/ti-vpe/cal-camerarx.c | 2 +-
  include/media/v4l2-fwnode.h  | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c 
b/drivers/media/platform/ti-vpe/cal-camerarx.c
index 806cbf1..47e2143 100644
--- a/drivers/media/platform/ti-vpe/cal-camerarx.c
+++ b/drivers/media/platform/ti-vpe/cal-camerarx.c
@@ -534,7 +534,7 @@ static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
  {
struct v4l2_fwnode_endpoint *endpoint = >endpoint;
struct device_node *ep_node;
-   char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES * 2];
+   char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES];
unsigned int i;
int ret;
  

I'm not so sure about this change: it relies on the implicit knowledge that
this cal driver can handle only 4 lanes max, so that doubling
V4L2_FWNODE_CSI2_MAX_DATA_LANES is the same as the old 
'V4L2_FWNODE_CSI2_MAX_DATA_LANES * 2'.

I think we should either keep the existing code (which means data_lanes
is now larger than needed, so stack usage increases by 8 bytes), or perhaps
create a new define for this driver like CAL_MAX_DATA_LANES and use that.

In my opinion the original code should just be kept, but I've CC-ed Laurent
on this to hear what he thinks.

I further looked at the code there and it does *depend* on a particular
value of V4L2_FWNODE_CSI2_MAX_DATA_LANES. That needs to be fixed. This part
can (or should) be dropped from the patch though.


Thanks Sakari and Hans.

OK. Will drop updating cal-camerarx.c from this patch in next version.



Re: [PATCH v1 3/7] spi: qspi-tegra: Add support for Tegra210 QSPI controller

2020-12-07 Thread Sowjanya Komatineni



On 12/6/20 10:16 AM, Lukas Wunner wrote:

On Tue, Dec 01, 2020 at 01:12:44PM -0800, Sowjanya Komatineni wrote:

+   ret = devm_spi_register_master(>dev, master);

[...]

+static int tegra_qspi_remove(struct platform_device *pdev)
+{
+   struct spi_master *master = platform_get_drvdata(pdev);
+   struct tegra_qspi_data  *tqspi = spi_master_get_devdata(master);
+
+   free_irq(tqspi->irq, tqspi);
+
+   tegra_qspi_deinit_dma_param(tqspi, false);
+   tegra_qspi_deinit_dma_param(tqspi, true);
+
+   pm_runtime_disable(>dev);
+   if (!pm_runtime_status_suspended(>dev))
+   tegra_qspi_runtime_suspend(>dev);
+
+   return 0;
+}

With devm_spi_register_master(), the SPI controller is unregistered
*after* tegra_qspi_remove().  SPI transactions may still be ongoing
until the SPI controller is unregistered, yet you perform teardown
steps (such as freeing the IRQ) while it is still registered.

Bottom line is, you can't use devm_spi_register_master() in this case.
You need to use spi_register_master() and explicitly call
spi_unregister_master() in tegra_qspi_remove() *before* performing
teardown steps.

However, be sure to use the devm variant to *allocate* the SPI controller,
i.e. use devm_spi_alloc_master() instead of spi_alloc_master().

Thanks,

Lukas


Thanks Lukas. I see devm_spi_alloc_master() in 5.4 but not from 5.5

Thanks

Sowjanya



Re: [PATCH v1 3/7] spi: qspi-tegra: Add support for Tegra210 QSPI controller

2020-12-04 Thread Sowjanya Komatineni



On 12/4/20 2:46 PM, Mark Brown wrote:

On Fri, Dec 04, 2020 at 01:04:46PM -0800, Sowjanya Komatineni wrote:

On 12/4/20 10:52 AM, Mark Brown wrote:

On Thu, Dec 03, 2020 at 04:22:54PM -0800, Sowjanya Komatineni wrote:

Also unpack mode needs to manually put the bytes together from read data to
SPI core rx buffer.

Could you be more explicit here, I don't know what "unpack mode" is?

Tegra SPI/QSPI controller support packed mode and unpacked mode based on
bits per word in a transfer.
Packed Mode: When enabled, all 32-bits of data in FIFO contains valid data
packets of 8-bit/16-bit/32-bit length.
Non packed mode: For transfers like 24-bit data for example we disable
packed mode and only 24-bits of FIFO data are valid and other bits are 0's.
So during TX for FIFO filling and during receive when FIFO data is read, SW
need to skip invalid bits and should align order from/to SPI core tx/rx
buffers.

That's pretty surprising - is it really worth the overhead of using
non-packed mode compared to just doing the transfer in 8 bit mode?  In
any case it seems better to only do the memcpy() stuff in the cases
where it's actually required since it looks like fairly obvious overhead
otherwise, and the code could use some comments explaining why we're
doing this.  It may actually be that the implementation is already doing
the most sensible thing and it just needs more comments explaining why
that's the case.


Understand the overhead but If any device specific transfers use/need 24 
bits per word, without non-packed mode we should fail the transfer.


Tegra HW has non-packed mode for such cases.

OK. Will use dma_map/unmap for packed mode transfer and for non-packed 
mode will use dma buf for fifo data and then can fill SPI core rx_buf 
with valid bytes from dma buf contents.


Sure will add comments for non-packed mode logic.


This is not a good idea, attempting to reverse engineer the message and
guess at the contents isn't going to be robust and if it's useful it
will if nothing else lead to a bunch of duplicated code in drivers as
every device that has this feature will need to reimplment it.  Instead
we should extend the framework so there's explicit support for
specifying transfers that are padding bytes, then there's no guesswork
that can go wrong and no duplicated code between drivers.  A flag in the
transfer struct might work?

As per QSPI spec, Dummy bytes for initial read latency are always FF's. So
its not like guessing the contents.

The guesswork I was thinking of was deciding to do this rather than the
pattern being output - the bit where the driver figures out that the
intent of that transfer is to provide dummy bytes.


Tegra QSPI controller HW supports transferring dummy bytes (sending FF's
after address) based on dummy clock cycles programmed.
To allow Tegra QSPI HW transfer dummy bytes directly, controller driver need
number of dummy bytes / actual dummy clock cycles which core driver gets
from flash sfdp read data.

Sure, the use case makes sense.


So, we can add flag to transfer and based on this flag if controller HW
supports then we can ignore filling dummy bytes in spi_mem_exec_op but
controller driver still needs dummy_cycles value. So probably along with
flag, do you agree to have dummy_cycle as part of transfer struct which can
be set to nor->read_dummy value?

Yeah, or given that perhaps just skip the flag and do this by specifying
dummy_cycles.  Or if this is always a multiple of 8 (which I guess it
must be to do it using normal byte transfers) perhaps just have the flag
and use the existing length field to infer the number of cycles?  I've
not actually looked at the details at all so one or both of those
suggestions may not actually make sense, please take them with a grain
of salt.

I'd recommend doing this as a followup to introducing the base driver,
start off with the less efficient explicit writes and then add the API
and add the support in the driver - that way the new API can be
reviewed without it holding up the rest of the driver.


ok I think adding dummy_cycles to transfer is enough without flag.

If dummy cycles is 0, definitely no dummy bytes transfer.

So will get rid of code that detects dummy bytes xfer phase from list of 
transfers.



Thanks Mark.


Regards,

Sowjanya



Re: [PATCH v1 3/7] spi: qspi-tegra: Add support for Tegra210 QSPI controller

2020-12-04 Thread Sowjanya Komatineni

Thanks Thierry. Will address below suggestions in v2.

Some inline comments below regarding client data part of controller driver.

Regards,

Sowjanya

On 12/4/20 4:11 AM, Thierry Reding wrote:

On Tue, Dec 01, 2020 at 01:12:44PM -0800, Sowjanya Komatineni wrote:

Tegra SoC has a Quad SPI controller starting from Tegra210.

This patch adds support for Tegra210 QSPI controller.

Signed-off-by: Sowjanya Komatineni 
---
  drivers/spi/Kconfig  |9 +
  drivers/spi/Makefile |1 +
  drivers/spi/qspi-tegra.c | 1418 ++
  3 files changed, 1428 insertions(+)
  create mode 100644 drivers/spi/qspi-tegra.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3fd16b7..1a021e8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -844,6 +844,15 @@ config SPI_MXS
help
  SPI driver for Freescale MXS devices.
  
+config QSPI_TEGRA

You already discussed this with Mark, but perhaps a better name would be
SPI_TEGRA210_QUAD or something. SPI_TEGRA210 is too generic because
there is a regular SPI controller on Tegra210 as well.

SPI_TEGRA210_QUAD is in line with the likes of SPI_TEGRA20_SFLASH and
SPI_TEGRA20_SLINK.


+   tristate "Nvidia Tegra QSPI Controller"

NVIDIA


+   depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST

I don't think we need the ARCH_TEGRA part there because TEGRA20_APB_DMA
already depends on that. Also, there's not strictly a dependency on
TEGRA20_APB_DMA specifically, but rather a dependency on DMA_ENGINE,
right? The DMA channels could be coming from some other driver on some
other SoC generation, such as the Tegra186 and later GPCDMA.


+   depends on RESET_CONTROLLER
+   help
+ QSPI driver for Nvidia Tegra QSPI Controller interface. This

NVIDIA


+ controller is different from the spi controller and is available

SPI


+ on Tegra SoCs starting from Tegra210.
+
  config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST

[...]

diff --git a/drivers/spi/qspi-tegra.c b/drivers/spi/qspi-tegra.c

[...]

+struct tegra_qspi_client_data {
+   int tx_clk_tap_delay;
+   int rx_clk_tap_delay;
+};

If this is client data, why are we dealing with this in the controller
driver? Is this perhaps something that could be added to struct
spi_device?


tx/rx clock tap delays are based on platform design and values may vary 
depending on trace lengths to corresponding spi device.


These tap delays are programmed in Tegra QSPI controller.




+
+struct tegra_qspi_data {

That _data just seems to be 5 extra characters that don't add any value.


+   struct device   *dev;
+   struct spi_master   *master;
+   /* Lock to protect data accessed by irq */
+   spinlock_t  lock;
+
+   struct clk  *clk;
+   struct reset_control*rst;
+   void __iomem*base;
+   phys_addr_t phys;
+   unsigned intirq;
+
+   u32 cur_speed;
+   unsigned intcur_pos;
+   unsigned intwords_per_32bit;
+   unsigned intbytes_per_word;
+   unsigned intcurr_dma_words;
+   unsigned intcur_direction;
+
+   unsigned intcur_rx_pos;
+   unsigned intcur_tx_pos;
+
+   unsigned intdma_buf_size;
+   unsigned intmax_buf_size;
+   boolis_curr_dma_xfer;
+
+   struct completion   rx_dma_complete;
+   struct completion   tx_dma_complete;
+
+   u32 tx_status;
+   u32 rx_status;
+   u32 status_reg;
+   boolis_packed;
+   booluse_dma;
+
+   u32 command1_reg;
+   u32 dma_control_reg;
+   u32 def_command1_reg;
+   u32 def_command2_reg;
+   u32 spi_cs_timing1;
+   u32 spi_cs_timing2;
+   u8  dummy_cycles;
+
+   struct completion   xfer_completion;
+   struct spi_transfer *curr_xfer;
+
+   struct dma_chan  

  1   2   3   4   5   6   7   8   9   10   >