From 639a8c482f84e1b996ae2a45859ffb947c8ea4f9 Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 19 Aug 2014 15:48:31 +0800 Subject: [PATCH] rk3036 hdmi: add hdmi power domain control --- arch/arm/boot/dts/rk312x.dtsi | 4 ++-- .../rockchip/hdmi/chips/rk3036/rk3036_hdmi.c | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index 6e4dca8edbd3..7f38a769961e 100755 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -716,8 +716,8 @@ pinctrl-names = "default", "gpio"; pinctrl-0 = <&hdmi_cec &hdmi_sda &hdmi_scl &hdmi_hpd>; pinctrl-1 = <&hdmi_gpio>; - clocks = <&clk_gates3 8>; - clock-names = "pclk_hdmi"; + clocks = <&clk_gates3 8>, <&pd_hdmi>; + clock-names = "pclk_hdmi", "pd_hdmi"; status = "disabled"; }; diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c index 2ab8c027bcec..b20be2082cb6 100755 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c @@ -92,7 +92,13 @@ static const struct file_operations rk3036_hdmi_reg_fops = { static int rk3036_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev) { + struct hdmi *hdmi_drv; + hdmi_drv = &hdmi_dev->driver; + if (!hdmi_dev->clk_on) { + if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { + clk_prepare_enable(hdmi_dev->pd); + } clk_prepare_enable(hdmi_dev->hclk); spin_lock(&hdmi_dev->reg_lock); hdmi_dev->clk_on = 1; @@ -104,10 +110,16 @@ static int rk3036_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev) static int rk3036_hdmi_clk_disable(struct rk_hdmi_device *hdmi_dev) { + struct hdmi *hdmi_drv; + hdmi_drv = &hdmi_dev->driver; + if (!hdmi_dev->clk_on) { spin_lock(&hdmi_dev->reg_lock); hdmi_dev->clk_on = 0; spin_unlock(&hdmi_dev->reg_lock); + if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { + clk_disable_unprepare(hdmi_dev->pd); + } clk_disable_unprepare(hdmi_dev->hclk); } @@ -175,6 +187,7 @@ static void rk3036_hdmi_early_suspend(void) wait_for_completion_interruptible_timeout(&hdmi_drv->complete, msecs_to_jiffies(5000)); flush_delayed_work(&hdmi_drv->delay_work); + rk3036_hdmi_clk_disable(hdmi_dev); } } @@ -187,6 +200,7 @@ static void rk3036_hdmi_early_resume(void) mutex_lock(&hdmi_drv->enable_mutex); if (hdmi_drv->suspend) { hdmi_drv->suspend = 0; + rk3036_hdmi_clk_enable(hdmi_dev); rk3036_hdmi_initial(hdmi_drv); if (hdmi_drv->enable && hdmi_drv->irq) { enable_irq(hdmi_drv->irq); @@ -351,6 +365,14 @@ static int rk3036_hdmi_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&hdmi_dev->rk3036_delay_work, rk3036_delay_work_func); /* enable clk */ + if(hdmi_drv->data->soc_type == HDMI_SOC_RK312X) { + hdmi_dev->pd = devm_clk_get(hdmi_drv->dev, "pd_hdmi"); + if (IS_ERR(hdmi_dev->pd)) { + dev_err(hdmi_drv->dev, "Unable to get hdmi pd\n"); + ret = -ENXIO; + goto err1; + } + } hdmi_dev->hclk = devm_clk_get(hdmi_drv->dev, "pclk_hdmi"); if (IS_ERR(hdmi_dev->hclk)) { dev_err(hdmi_drv->dev, "Unable to get hdmi hclk\n"); -- 2.34.1