Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Chandan Uddaraju | 807 | 72.12% | 1 | 11.11% |
Kuogee Hsieh | 220 | 19.66% | 4 | 44.44% |
Dmitry Eremin-Solenikov | 73 | 6.52% | 2 | 22.22% |
Maitreyee Rao | 16 | 1.43% | 1 | 11.11% |
Stephen Boyd | 3 | 0.27% | 1 | 11.11% |
Total | 1119 | 9 |
// 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 drm_device *drm_dev; struct clk *link_clk_src; struct clk *pixel_provider; struct clk *link_provider; struct dp_power dp_power; }; 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 = devm_clk_bulk_get(dev, core->num_clk, core->clocks); if (rc) { DRM_ERROR("failed to get %s clk. err=%d\n", dp_parser_pm_name(DP_CORE_PM), rc); return rc; } rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks); if (rc) { DRM_ERROR("failed to get %s clk. err=%d\n", dp_parser_pm_name(DP_CTRL_PM), rc); return -ENODEV; } rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks); if (rc) { DRM_ERROR("failed to get %s clk. err=%d\n", dp_parser_pm_name(DP_CTRL_PM), rc); return -ENODEV; } return 0; } int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type) { struct dp_power_private *power; power = container_of(dp_power, struct dp_power_private, dp_power); drm_dbg_dp(power->drm_dev, "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n", dp_power->core_clks_on, dp_power->link_clks_on, dp_power->stream_clks_on); 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; struct dss_module_power *mp; 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_dbg_dp(power->drm_dev, "core clks already enabled\n"); return 0; } if (pm_type == DP_CTRL_PM && dp_power->link_clks_on) { drm_dbg_dp(power->drm_dev, "links clks already enabled\n"); return 0; } if (pm_type == DP_STREAM_PM && dp_power->stream_clks_on) { drm_dbg_dp(power->drm_dev, "pixel clks already enabled\n"); return 0; } if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) { drm_dbg_dp(power->drm_dev, "Enable core clks before link clks\n"); mp = &power->parser->mp[DP_CORE_PM]; rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); 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; } } mp = &power->parser->mp[pm_type]; if (enable) { rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); if (rc) { DRM_ERROR("failed to enable clks, err: %d\n", rc); return rc; } } else { clk_bulk_disable_unprepare(mp->num_clk, mp->clocks); } 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_dbg_dp(power->drm_dev, "%s clocks for %s\n", enable ? "enable" : "disable", dp_parser_pm_name(pm_type)); drm_dbg_dp(power->drm_dev, "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_clk_init(power); if (rc) DRM_ERROR("failed to init clocks %d\n", rc); 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); 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_clk_enable(dp_power, DP_CORE_PM, true); if (rc) { DRM_ERROR("failed to enable DP core clocks, %d\n", rc); goto exit; } return 0; 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); 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; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1