drm/tegra: dpaux: Configure pads as I2C by default
authorThierry Reding <treding@nvidia.com>
Mon, 27 Apr 2015 13:16:26 +0000 (15:16 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 13 Aug 2015 11:47:47 +0000 (13:47 +0200)
The DPAUX code paths already configure the pads in AUX mode, but there
is no way to reconfigure them in I2C mode for HDMI (the DPAUX module is
unused in that case). Enabling the pads in I2C mode by default is the
quickest way to support HDMI. Eventually this may need an explicit call
in the user drivers.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/dpaux.c
drivers/gpu/drm/tegra/dpaux.h

index c96c21b..909072d 100644 (file)
@@ -359,6 +359,24 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
        if (err < 0)
                return err;
 
+       /*
+        * Assume that by default the DPAUX/I2C pads will be used for HDMI,
+        * so power them up and configure them in I2C mode.
+        *
+        * The DPAUX code paths reconfigure the pads in AUX mode, but there
+        * is no possibility to perform the I2C mode configuration in the
+        * HDMI path.
+        */
+       value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
+       value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
+       tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
+
+       value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_PADCTL);
+       value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
+               DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
+               DPAUX_HYBRID_PADCTL_MODE_I2C;
+       tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
+
        /* enable and clear all interrupts */
        value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT |
                DPAUX_INTR_UNPLUG_EVENT | DPAUX_INTR_PLUG_EVENT;
@@ -377,6 +395,12 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 static int tegra_dpaux_remove(struct platform_device *pdev)
 {
        struct tegra_dpaux *dpaux = platform_get_drvdata(pdev);
+       u32 value;
+
+       /* make sure pads are powered down when not in use */
+       value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
+       value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
+       tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
 
        drm_dp_aux_unregister(&dpaux->aux);
 
@@ -394,6 +418,7 @@ static int tegra_dpaux_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id tegra_dpaux_of_match[] = {
+       { .compatible = "nvidia,tegra210-dpaux", },
        { .compatible = "nvidia,tegra124-dpaux", },
        { },
 };
index 806e245..20783d9 100644 (file)
@@ -57,6 +57,8 @@
 #define DPAUX_DP_AUX_CONFIG 0x45
 
 #define DPAUX_HYBRID_PADCTL 0x49
+#define DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV (1 << 15)
+#define DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV (1 << 14)
 #define DPAUX_HYBRID_PADCTL_AUX_CMH(x) (((x) & 0x3) << 12)
 #define DPAUX_HYBRID_PADCTL_AUX_DRVZ(x) (((x) & 0x7) << 8)
 #define DPAUX_HYBRID_PADCTL_AUX_DRVI(x) (((x) & 0x3f) << 2)