drm/exynos: use regmap interface to set hdmiphy control bit in pmu
authorRahul Sharma <rahul.sharma@samsung.com>
Tue, 20 May 2014 05:06:05 +0000 (10:36 +0530)
committerInki Dae <daeinki@gmail.com>
Sun, 1 Jun 2014 17:07:09 +0000 (02:07 +0900)
Exynos drm hdmi driver used to get dummy hdmiphy clock to
control the PMU bit for hdmiphy. This bit needs to be set
before setting any resolution to hdmi hardware. This was
handled using dummy hdmiphy clock which is removed here.

PMU is already defined as system controller for exynos
SoCs. Hdmi driver is modified to control the phy enable bit
inside PMU using regmap interfaces.

Devicetree binding document for hdmi is also updated.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Documentation/devicetree/bindings/video/exynos_hdmi.txt
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/regs-hdmi.h

index 75ada041389e573078a52c5b56bbdc65dd4e4df8..1fd8cf9cbfaca44d2bc023c76261719832071b48 100644 (file)
@@ -28,6 +28,7 @@ Required properties:
        "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
 - ddc: phandle to the hdmi ddc node
 - phy: phandle to the hdmi phy node
+- samsung,syscon-phandle: phandle for system controller node for PMU.
 
 Example:
 
@@ -38,4 +39,5 @@ Example:
                hpd-gpio = <&gpx3 7 1>;
                ddc = <&hdmi_ddc_node>;
                phy = <&hdmi_phy_node>;
+               samsung,syscon-phandle = <&pmu_system_controller>;
        };
index ed6176ebfbcdd8dc8cd65ce7d392b6f7cdc25414..941b235ca1db66c23e7c8bdf36d7f76b1afcacb0 100644 (file)
@@ -38,6 +38,8 @@
 #include <linux/of_gpio.h>
 #include <linux/hdmi.h>
 #include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <drm/exynos_drm.h>
 
@@ -81,7 +83,6 @@ struct hdmi_resources {
        struct clk                      *sclk_hdmi;
        struct clk                      *sclk_pixel;
        struct clk                      *sclk_hdmiphy;
-       struct clk                      *hdmiphy;
        struct clk                      *mout_hdmi;
        struct regulator_bulk_data      *regul_bulk;
        int                             regul_count;
@@ -208,6 +209,7 @@ struct hdmi_context {
        const struct hdmiphy_config             *phy_confs;
        unsigned int                    phy_conf_count;
 
+       struct regmap                   *pmureg;
        enum hdmi_type                  type;
 };
 
@@ -2013,7 +2015,10 @@ static void hdmi_poweron(struct exynos_drm_display *display)
        if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
                DRM_DEBUG_KMS("failed to enable regulator bulk\n");
 
-       clk_prepare_enable(res->hdmiphy);
+       /* set pmu hdmiphy control bit to enable hdmiphy */
+       regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
+                       PMU_HDMI_PHY_ENABLE_BIT, 1);
+
        clk_prepare_enable(res->hdmi);
        clk_prepare_enable(res->sclk_hdmi);
 
@@ -2040,7 +2045,11 @@ static void hdmi_poweroff(struct exynos_drm_display *display)
 
        clk_disable_unprepare(res->sclk_hdmi);
        clk_disable_unprepare(res->hdmi);
-       clk_disable_unprepare(res->hdmiphy);
+
+       /* reset pmu hdmiphy control bit to disable hdmiphy */
+       regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
+                       PMU_HDMI_PHY_ENABLE_BIT, 0);
+
        regulator_bulk_disable(res->regul_count, res->regul_bulk);
 
        pm_runtime_put_sync(hdata->dev);
@@ -2143,11 +2152,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
                DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
                goto fail;
        }
-       res->hdmiphy = devm_clk_get(dev, "hdmiphy");
-       if (IS_ERR(res->hdmiphy)) {
-               DRM_ERROR("failed to get clock 'hdmiphy'\n");
-               goto fail;
-       }
        res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
        if (IS_ERR(res->mout_hdmi)) {
                DRM_ERROR("failed to get clock 'mout_hdmi'\n");
@@ -2383,6 +2387,13 @@ out_get_phy_port:
                goto err_hdmiphy;
        }
 
+       hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
+                       "samsung,syscon-phandle");
+       if (IS_ERR(hdata->pmureg)) {
+               DRM_ERROR("syscon regmap lookup failed.\n");
+               goto err_hdmiphy;
+       }
+
        pm_runtime_enable(dev);
        hdmi_display.ctx = hdata;
 
index 84a69cdd8e8d7425d44208edf4a2e3c80ba0093e..6d846b979045e4cd8685485482d4954567bc509e 100644 (file)
 #define HDMI_PHY_DISABLE_MODE_SET      0x80
 #define HDMI_PHY_ENABLE_MODE_SET       0x00
 
+/* PMU Registers for PHY */
+#define PMU_HDMI_PHY_CONTROL           0x700
+#define PMU_HDMI_PHY_ENABLE_BIT                BIT(0)
+
 #endif /* SAMSUNG_REGS_HDMI_H */