diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_power.c')
| -rw-r--r-- | drivers/gpu/drm/msm/dp/dp_power.c | 44 | 
1 files changed, 40 insertions, 4 deletions
| diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c index 17c1fc6a2d44..9c4ea00a5f2a 100644 --- a/drivers/gpu/drm/msm/dp/dp_power.c +++ b/drivers/gpu/drm/msm/dp/dp_power.c @@ -8,12 +8,14 @@  #include <linux/clk.h>  #include <linux/clk-provider.h>  #include <linux/regulator/consumer.h> +#include <linux/pm_opp.h>  #include "dp_power.h"  #include "msm_drv.h"  struct dp_power_private {  	struct dp_parser *parser;  	struct platform_device *pdev; +	struct device *dev;  	struct clk *link_clk_src;  	struct clk *pixel_provider;  	struct clk *link_provider; @@ -148,18 +150,51 @@ static int dp_power_clk_deinit(struct dp_power_private *power)  	return 0;  } +static int dp_power_clk_set_link_rate(struct dp_power_private *power, +			struct dss_clk *clk_arry, int num_clk, int enable) +{ +	u32 rate; +	int i, rc = 0; + +	for (i = 0; i < num_clk; i++) { +		if (clk_arry[i].clk) { +			if (clk_arry[i].type == DSS_CLK_PCLK) { +				if (enable) +					rate = clk_arry[i].rate; +				else +					rate = 0; + +				rc = dev_pm_opp_set_rate(power->dev, rate); +				if (rc) +					break; +			} + +		} +	} +	return rc; +} +  static int dp_power_clk_set_rate(struct dp_power_private *power,  		enum dp_pm_type module, bool enable)  {  	int rc = 0;  	struct dss_module_power *mp = &power->parser->mp[module]; -	if (enable) { -		rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); +	if (module == DP_CTRL_PM) { +		rc = dp_power_clk_set_link_rate(power, mp->clk_config, mp->num_clk, enable);  		if (rc) { -			DRM_ERROR("failed to set clks rate.\n"); +			DRM_ERROR("failed to set link clks rate\n");  			return rc;  		} +	} else { + +		if (enable) { +			rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); +			if (rc) { +				DRM_ERROR("failed to set clks rate\n"); +				return rc; +			} +		}  	}  	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable); @@ -349,7 +384,7 @@ int dp_power_deinit(struct dp_power *dp_power)  	return 0;  } -struct dp_power *dp_power_get(struct dp_parser *parser) +struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser)  {  	struct dp_power_private *power;  	struct dp_power *dp_power; @@ -365,6 +400,7 @@ struct dp_power *dp_power_get(struct dp_parser *parser)  	power->parser = parser;  	power->pdev = parser->pdev; +	power->dev = dev;  	dp_power = &power->dp_power; | 
