drm/tegra: hdmi - Add connector supply support
authorThierry Reding <treding@nvidia.com>
Fri, 28 Feb 2014 15:57:34 +0000 (16:57 +0100)
committerThierry Reding <treding@nvidia.com>
Thu, 5 Jun 2014 21:09:21 +0000 (23:09 +0200)
Revert commit 18ebc0f404d5 "drm/tegra: hdmi: Enable VDD earlier for
hotplug/DDC" and instead add a new supply for the +5V pin on the HDMI
connector.

The vdd-supply property refers to the regulator that supplies the
AVDD_HDMI input on Tegra, rather than the +5V HDMI connector pin. This
was never a problem before, because all boards had that pin hooked up to
a regulator that was always on. Starting with Dalmore and continuing
with Venice2, the +5V pin is controllable via a GPIO. For reasons
unknown, the GPIO ended up as the controlling GPIO of the AVDD_HDMI
supply in the Dalmore and Venice2 DTS files. But that's not correct.
Instead, a separate supply must be introduced so that the +5V pin can be
controlled separately from the supplies that feed the HDMI block within
Tegra.

A new hdmi-supply property is introduced that takes the place of the
vdd-supply and vdd-supply is only enabled when HDMI is enabled rather
than all the time.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
drivers/gpu/drm/tegra/hdmi.c

index efa8b8451f93be2600cbb41fa5c8275c7ea5ddaf..f13a6b8263d38fbcd432423db5cfa23c9eb6de99 100644 (file)
@@ -136,6 +136,7 @@ of the following host1x client modules:
   - compatible: "nvidia,tegra<chip>-hdmi"
   - reg: Physical base address and length of the controller's registers.
   - interrupts: The interrupt outputs from the controller.
+  - hdmi-supply: supply for the +5V HDMI connector pin
   - vdd-supply: regulator for supply voltage
   - pll-supply: regulator for PLL
   - clocks: Must contain an entry for each entry in clock-names.
index 6928015d11a49e9fd6e499aed2ed5f02d6d1730e..8b797913470a6df0b94c5318e39c9f38547591d3 100644 (file)
@@ -42,6 +42,7 @@ struct tegra_hdmi {
        struct device *dev;
        bool enabled;
 
+       struct regulator *hdmi;
        struct regulator *vdd;
        struct regulator *pll;
 
@@ -710,6 +711,12 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
        h_back_porch = mode->htotal - mode->hsync_end;
        h_front_porch = mode->hsync_start - mode->hdisplay;
 
+       err = regulator_enable(hdmi->vdd);
+       if (err < 0) {
+               dev_err(hdmi->dev, "failed to enable VDD regulator: %d\n", err);
+               return err;
+       }
+
        err = regulator_enable(hdmi->pll);
        if (err < 0) {
                dev_err(hdmi->dev, "failed to enable PLL regulator: %d\n", err);
@@ -950,6 +957,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output)
        reset_control_assert(hdmi->rst);
        clk_disable(hdmi->clk);
        regulator_disable(hdmi->pll);
+       regulator_disable(hdmi->vdd);
 
        hdmi->enabled = false;
 
@@ -1256,13 +1264,6 @@ static int tegra_hdmi_init(struct host1x_client *client)
        struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
        int err;
 
-       err = regulator_enable(hdmi->vdd);
-       if (err < 0) {
-               dev_err(client->dev, "failed to enable VDD regulator: %d\n",
-                       err);
-               return err;
-       }
-
        hdmi->output.type = TEGRA_OUTPUT_HDMI;
        hdmi->output.dev = client->dev;
        hdmi->output.ops = &hdmi_ops;
@@ -1279,6 +1280,13 @@ static int tegra_hdmi_init(struct host1x_client *client)
                        dev_err(client->dev, "debugfs setup failed: %d\n", err);
        }
 
+       err = regulator_enable(hdmi->hdmi);
+       if (err < 0) {
+               dev_err(client->dev, "failed to enable HDMI regulator: %d\n",
+                       err);
+               return err;
+       }
+
        return 0;
 }
 
@@ -1287,6 +1295,8 @@ static int tegra_hdmi_exit(struct host1x_client *client)
        struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
        int err;
 
+       regulator_disable(hdmi->hdmi);
+
        if (IS_ENABLED(CONFIG_DEBUG_FS)) {
                err = tegra_hdmi_debugfs_exit(hdmi);
                if (err < 0)
@@ -1306,8 +1316,6 @@ static int tegra_hdmi_exit(struct host1x_client *client)
                return err;
        }
 
-       regulator_disable(hdmi->vdd);
-
        return 0;
 }
 
@@ -1399,6 +1407,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
                return err;
        }
 
+       hdmi->hdmi = devm_regulator_get(&pdev->dev, "hdmi");
+       if (IS_ERR(hdmi->hdmi)) {
+               dev_err(&pdev->dev, "failed to get HDMI regulator\n");
+               return PTR_ERR(hdmi->hdmi);
+       }
+
        hdmi->vdd = devm_regulator_get(&pdev->dev, "vdd");
        if (IS_ERR(hdmi->vdd)) {
                dev_err(&pdev->dev, "failed to get VDD regulator\n");