diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_power.c')
| -rw-r--r-- | drivers/gpu/drm/msm/dp/dp_power.c | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c deleted file mode 100644 index 3961ba4efc3c..000000000000 --- a/drivers/gpu/drm/msm/dp/dp_power.c +++ /dev/null @@ -1,408 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ - -#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; - struct regulator_bulk_data supplies[DP_DEV_REGULATOR_MAX]; - - struct dp_power dp_power; -}; - -static void dp_power_regulator_disable(struct dp_power_private *power) -{ - struct regulator_bulk_data *s = power->supplies; - const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; - int num = power->parser->regulator_cfg->num; - int i; - - DBG(""); - for (i = num - 1; i >= 0; i--) - if (regs[i].disable_load >= 0) - regulator_set_load(s[i].consumer, - regs[i].disable_load); - - regulator_bulk_disable(num, s); -} - -static int dp_power_regulator_enable(struct dp_power_private *power) -{ - struct regulator_bulk_data *s = power->supplies; - const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; - int num = power->parser->regulator_cfg->num; - int ret, i; - - DBG(""); - for (i = 0; i < num; i++) { - if (regs[i].enable_load >= 0) { - ret = regulator_set_load(s[i].consumer, - regs[i].enable_load); - if (ret < 0) { - pr_err("regulator %d set op mode failed, %d\n", - i, ret); - goto fail; - } - } - } - - ret = regulator_bulk_enable(num, s); - if (ret < 0) { - pr_err("regulator enable failed, %d\n", ret); - goto fail; - } - - return 0; - -fail: - for (i--; i >= 0; i--) - regulator_set_load(s[i].consumer, regs[i].disable_load); - return ret; -} - -static int dp_power_regulator_init(struct dp_power_private *power) -{ - struct regulator_bulk_data *s = power->supplies; - const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; - struct platform_device *pdev = power->pdev; - int num = power->parser->regulator_cfg->num; - int i, ret; - - for (i = 0; i < num; i++) - s[i].supply = regs[i].name; - - ret = devm_regulator_bulk_get(&pdev->dev, num, s); - if (ret < 0) { - pr_err("%s: failed to init regulator, ret=%d\n", - __func__, ret); - return ret; - } - - return 0; -} - -static int dp_power_clk_init(struct dp_power_private *power) -{ - int rc = 0; - struct dss_module_power *core, *ctrl, *stream; - struct device *dev = &power->pdev->dev; - - core = &power->parser->mp[DP_CORE_PM]; - ctrl = &power->parser->mp[DP_CTRL_PM]; - stream = &power->parser->mp[DP_STREAM_PM]; - - rc = msm_dss_get_clk(dev, core->clk_config, core->num_clk); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CORE_PM), rc); - return rc; - } - - rc = msm_dss_get_clk(dev, ctrl->clk_config, ctrl->num_clk); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CTRL_PM), rc); - msm_dss_put_clk(core->clk_config, core->num_clk); - return -ENODEV; - } - - rc = msm_dss_get_clk(dev, stream->clk_config, stream->num_clk); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CTRL_PM), rc); - msm_dss_put_clk(core->clk_config, core->num_clk); - return -ENODEV; - } - - return 0; -} - -static int dp_power_clk_deinit(struct dp_power_private *power) -{ - struct dss_module_power *core, *ctrl, *stream; - - core = &power->parser->mp[DP_CORE_PM]; - ctrl = &power->parser->mp[DP_CTRL_PM]; - stream = &power->parser->mp[DP_STREAM_PM]; - - if (!core || !ctrl || !stream) { - DRM_ERROR("invalid power_data\n"); - return -EINVAL; - } - - msm_dss_put_clk(ctrl->clk_config, ctrl->num_clk); - msm_dss_put_clk(core->clk_config, core->num_clk); - msm_dss_put_clk(stream->clk_config, stream->num_clk); - 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 (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 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); - if (rc) { - DRM_ERROR("failed to %d clks, err: %d\n", enable, rc); - return rc; - } - - return 0; -} - -int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type) -{ - if (pm_type == DP_CORE_PM) - return dp_power->core_clks_on; - - if (pm_type == DP_CTRL_PM) - return dp_power->link_clks_on; - - if (pm_type == DP_STREAM_PM) - return dp_power->stream_clks_on; - - return 0; -} - -int dp_power_clk_enable(struct dp_power *dp_power, - enum dp_pm_type pm_type, bool enable) -{ - int rc = 0; - struct dp_power_private *power; - - power = container_of(dp_power, struct dp_power_private, dp_power); - - if (pm_type != DP_CORE_PM && pm_type != DP_CTRL_PM && - pm_type != DP_STREAM_PM) { - DRM_ERROR("unsupported power module: %s\n", - dp_parser_pm_name(pm_type)); - return -EINVAL; - } - - if (enable) { - if (pm_type == DP_CORE_PM && dp_power->core_clks_on) { - DRM_DEBUG_DP("core clks already enabled\n"); - return 0; - } - - if (pm_type == DP_CTRL_PM && dp_power->link_clks_on) { - DRM_DEBUG_DP("links clks already enabled\n"); - return 0; - } - - if (pm_type == DP_STREAM_PM && dp_power->stream_clks_on) { - DRM_DEBUG_DP("pixel clks already enabled\n"); - return 0; - } - - if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) { - DRM_DEBUG_DP("Enable core clks before link clks\n"); - - rc = dp_power_clk_set_rate(power, DP_CORE_PM, enable); - if (rc) { - DRM_ERROR("fail to enable clks: %s. err=%d\n", - dp_parser_pm_name(DP_CORE_PM), rc); - return rc; - } - dp_power->core_clks_on = true; - } - } - - rc = dp_power_clk_set_rate(power, pm_type, enable); - if (rc) { - DRM_ERROR("failed to '%s' clks for: %s. err=%d\n", - enable ? "enable" : "disable", - dp_parser_pm_name(pm_type), rc); - return rc; - } - - if (pm_type == DP_CORE_PM) - dp_power->core_clks_on = enable; - else if (pm_type == DP_STREAM_PM) - dp_power->stream_clks_on = enable; - else - dp_power->link_clks_on = enable; - - DRM_DEBUG_DP("%s clocks for %s\n", - enable ? "enable" : "disable", - dp_parser_pm_name(pm_type)); - DRM_DEBUG_DP("strem_clks:%s link_clks:%s core_clks:%s\n", - dp_power->stream_clks_on ? "on" : "off", - dp_power->link_clks_on ? "on" : "off", - dp_power->core_clks_on ? "on" : "off"); - - return 0; -} - -int dp_power_client_init(struct dp_power *dp_power) -{ - int rc = 0; - struct dp_power_private *power; - - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return -EINVAL; - } - - power = container_of(dp_power, struct dp_power_private, dp_power); - - pm_runtime_enable(&power->pdev->dev); - - rc = dp_power_regulator_init(power); - if (rc) { - DRM_ERROR("failed to init regulators %d\n", rc); - goto error; - } - - rc = dp_power_clk_init(power); - if (rc) { - DRM_ERROR("failed to init clocks %d\n", rc); - goto error; - } - return 0; - -error: - pm_runtime_disable(&power->pdev->dev); - return rc; -} - -void dp_power_client_deinit(struct dp_power *dp_power) -{ - struct dp_power_private *power; - - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return; - } - - power = container_of(dp_power, struct dp_power_private, dp_power); - - dp_power_clk_deinit(power); - pm_runtime_disable(&power->pdev->dev); - -} - -int dp_power_init(struct dp_power *dp_power, bool flip) -{ - int rc = 0; - struct dp_power_private *power = NULL; - - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return -EINVAL; - } - - power = container_of(dp_power, struct dp_power_private, dp_power); - - pm_runtime_get_sync(&power->pdev->dev); - rc = dp_power_regulator_enable(power); - if (rc) { - DRM_ERROR("failed to enable regulators, %d\n", rc); - goto exit; - } - - rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true); - if (rc) { - DRM_ERROR("failed to enable DP core clocks, %d\n", rc); - goto err_clk; - } - - return 0; - -err_clk: - dp_power_regulator_disable(power); -exit: - pm_runtime_put_sync(&power->pdev->dev); - return rc; -} - -int dp_power_deinit(struct dp_power *dp_power) -{ - struct dp_power_private *power; - - power = container_of(dp_power, struct dp_power_private, dp_power); - - dp_power_clk_enable(dp_power, DP_CORE_PM, false); - dp_power_regulator_disable(power); - pm_runtime_put_sync(&power->pdev->dev); - return 0; -} - -struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) -{ - struct dp_power_private *power; - struct dp_power *dp_power; - - if (!parser) { - DRM_ERROR("invalid input\n"); - return ERR_PTR(-EINVAL); - } - - power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL); - if (!power) - return ERR_PTR(-ENOMEM); - - power->parser = parser; - power->pdev = parser->pdev; - power->dev = dev; - - dp_power = &power->dp_power; - - return dp_power; -} |
