mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
drm/msm/dp: fold dp_power into dp_ctrl module
The dp_power submodule is limited to handling the clocks only following previous cleanups. Fold it into the dp_ctrl submodule, removing one unnecessary level of indirection. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com> Reviewed-by: Kuogee Hsieh <quic_khsieh@quicinc.com> Patchwork: https://patchwork.freedesktop.org/patch/576104/ Link: https://lore.kernel.org/r/20240126-dp-power-parser-cleanup-v3-5-098d5f581dd3@linaro.org
This commit is contained in:
parent
47103b5824
commit
17cb153f81
6 changed files with 142 additions and 283 deletions
|
@ -128,7 +128,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
|
|||
dp/dp_link.o \
|
||||
dp/dp_panel.o \
|
||||
dp/dp_parser.o \
|
||||
dp/dp_power.o \
|
||||
dp/dp_audio.o
|
||||
|
||||
msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
|
||||
|
|
|
@ -76,13 +76,16 @@ struct dp_ctrl_private {
|
|||
struct drm_dp_aux *aux;
|
||||
struct dp_panel *panel;
|
||||
struct dp_link *link;
|
||||
struct dp_power *power;
|
||||
struct dp_parser *parser;
|
||||
struct dp_catalog *catalog;
|
||||
|
||||
struct completion idle_comp;
|
||||
struct completion psr_op_comp;
|
||||
struct completion video_comp;
|
||||
|
||||
bool core_clks_on;
|
||||
bool link_clks_on;
|
||||
bool stream_clks_on;
|
||||
};
|
||||
|
||||
static int dp_aux_link_configure(struct drm_dp_aux *aux,
|
||||
|
@ -1333,6 +1336,83 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
|
|||
name, rate);
|
||||
}
|
||||
|
||||
int dp_ctrl_clk_enable(struct dp_ctrl *dp_ctrl,
|
||||
enum dp_pm_type pm_type, bool enable)
|
||||
{
|
||||
struct dp_ctrl_private *ctrl;
|
||||
struct dss_module_power *mp;
|
||||
int ret = 0;
|
||||
|
||||
ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
|
||||
|
||||
if (pm_type != DP_CORE_PM &&
|
||||
pm_type != DP_CTRL_PM &&
|
||||
pm_type != DP_STREAM_PM) {
|
||||
DRM_ERROR("unsupported ctrl module: %s\n",
|
||||
dp_parser_pm_name(pm_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
if (pm_type == DP_CORE_PM && ctrl->core_clks_on) {
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"core clks already enabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pm_type == DP_CTRL_PM && ctrl->link_clks_on) {
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"links clks already enabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pm_type == DP_STREAM_PM && ctrl->stream_clks_on) {
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"pixel clks already enabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((pm_type == DP_CTRL_PM) && (!ctrl->core_clks_on)) {
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"Enable core clks before link clks\n");
|
||||
mp = &ctrl->parser->mp[DP_CORE_PM];
|
||||
|
||||
ret = clk_bulk_prepare_enable(mp->num_clk, mp->clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctrl->core_clks_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
mp = &ctrl->parser->mp[pm_type];
|
||||
if (enable) {
|
||||
ret = clk_bulk_prepare_enable(mp->num_clk, mp->clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
clk_bulk_disable_unprepare(mp->num_clk, mp->clocks);
|
||||
}
|
||||
|
||||
if (pm_type == DP_CORE_PM)
|
||||
ctrl->core_clks_on = enable;
|
||||
else if (pm_type == DP_STREAM_PM)
|
||||
ctrl->stream_clks_on = enable;
|
||||
else
|
||||
ctrl->link_clks_on = enable;
|
||||
|
||||
drm_dbg_dp(ctrl->drm_dev, "%s clocks for %s\n",
|
||||
enable ? "enable" : "disable",
|
||||
dp_parser_pm_name(pm_type));
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"stream_clks:%s link_clks:%s core_clks:%s\n",
|
||||
ctrl->stream_clks_on ? "on" : "off",
|
||||
ctrl->link_clks_on ? "on" : "off",
|
||||
ctrl->core_clks_on ? "on" : "off");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -1349,7 +1429,7 @@ static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)
|
|||
phy_power_on(phy);
|
||||
|
||||
dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000);
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, true);
|
||||
if (ret)
|
||||
DRM_ERROR("Unable to start link clocks. ret=%d\n", ret);
|
||||
|
||||
|
@ -1497,7 +1577,7 @@ static int dp_ctrl_reinitialize_mainlink(struct dp_ctrl_private *ctrl)
|
|||
* link maintenance.
|
||||
*/
|
||||
dev_pm_opp_set_rate(ctrl->dev, 0);
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable clocks. ret=%d\n", ret);
|
||||
return ret;
|
||||
|
@ -1529,7 +1609,7 @@ static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl)
|
|||
dp_catalog_ctrl_reset(ctrl->catalog);
|
||||
|
||||
dev_pm_opp_set_rate(ctrl->dev, 0);
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
|
||||
}
|
||||
|
@ -1651,7 +1731,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl)
|
|||
pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
|
||||
dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000);
|
||||
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
|
||||
return ret;
|
||||
|
@ -1747,7 +1827,7 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl)
|
|||
rate = ctrl->panel->link_info.rate;
|
||||
pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
|
||||
|
||||
dp_power_clk_enable(ctrl->power, DP_CORE_PM, true);
|
||||
dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CORE_PM, true);
|
||||
|
||||
if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
|
@ -1880,7 +1960,11 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
|
|||
ctrl->link->link_params.rate,
|
||||
ctrl->link->link_params.num_lanes, pixel_rate);
|
||||
|
||||
if (!dp_power_clk_status(ctrl->power, DP_CTRL_PM)) { /* link clk is off */
|
||||
drm_dbg_dp(ctrl->drm_dev,
|
||||
"core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
|
||||
ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);
|
||||
|
||||
if (!ctrl->link_clks_on) { /* link clk is off */
|
||||
ret = dp_ctrl_enable_mainlink_clocks(ctrl);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
|
||||
|
@ -1890,7 +1974,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
|
|||
|
||||
dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000);
|
||||
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("Unable to start pixel clocks. ret=%d\n", ret);
|
||||
goto end;
|
||||
|
@ -1946,8 +2030,8 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
|
|||
|
||||
dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
|
||||
|
||||
if (dp_power_clk_status(ctrl->power, DP_STREAM_PM)) {
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false);
|
||||
if (ctrl->stream_clks_on) {
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable pclk. ret=%d\n", ret);
|
||||
return ret;
|
||||
|
@ -1955,7 +2039,7 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
|
|||
}
|
||||
|
||||
dev_pm_opp_set_rate(ctrl->dev, 0);
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
|
||||
return ret;
|
||||
|
@ -1985,7 +2069,7 @@ int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl)
|
|||
|
||||
dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
|
||||
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
|
||||
}
|
||||
|
@ -2019,12 +2103,12 @@ int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
|
|||
|
||||
dp_catalog_ctrl_reset(ctrl->catalog);
|
||||
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, false);
|
||||
if (ret)
|
||||
DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret);
|
||||
|
||||
dev_pm_opp_set_rate(ctrl->dev, 0);
|
||||
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
|
||||
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
|
||||
}
|
||||
|
@ -2081,9 +2165,38 @@ irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int dp_ctrl_clk_init(struct dp_ctrl *dp_ctrl)
|
||||
{
|
||||
struct dp_ctrl_private *ctrl_private;
|
||||
int rc = 0;
|
||||
struct dss_module_power *core, *ctrl, *stream;
|
||||
struct device *dev;
|
||||
|
||||
ctrl_private = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
|
||||
dev = ctrl_private->dev;
|
||||
|
||||
core = &ctrl_private->parser->mp[DP_CORE_PM];
|
||||
ctrl = &ctrl_private->parser->mp[DP_CTRL_PM];
|
||||
stream = &ctrl_private->parser->mp[DP_STREAM_PM];
|
||||
|
||||
rc = devm_clk_bulk_get(dev, core->num_clk, core->clocks);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks);
|
||||
if (rc)
|
||||
return -ENODEV;
|
||||
|
||||
rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks);
|
||||
if (rc)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
|
||||
struct dp_panel *panel, struct drm_dp_aux *aux,
|
||||
struct dp_power *power, struct dp_catalog *catalog,
|
||||
struct dp_catalog *catalog,
|
||||
struct dp_parser *parser)
|
||||
{
|
||||
struct dp_ctrl_private *ctrl;
|
||||
|
@ -2120,11 +2233,16 @@ struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
|
|||
/* in parameters */
|
||||
ctrl->parser = parser;
|
||||
ctrl->panel = panel;
|
||||
ctrl->power = power;
|
||||
ctrl->aux = aux;
|
||||
ctrl->link = link;
|
||||
ctrl->catalog = catalog;
|
||||
ctrl->dev = dev;
|
||||
|
||||
ret = dp_ctrl_clk_init(&ctrl->dp_ctrl);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to init clocks\n");
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return &ctrl->dp_ctrl;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "dp_panel.h"
|
||||
#include "dp_link.h"
|
||||
#include "dp_parser.h"
|
||||
#include "dp_power.h"
|
||||
#include "dp_catalog.h"
|
||||
|
||||
struct dp_ctrl {
|
||||
|
@ -28,7 +27,7 @@ irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl);
|
|||
void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl);
|
||||
struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
|
||||
struct dp_panel *panel, struct drm_dp_aux *aux,
|
||||
struct dp_power *power, struct dp_catalog *catalog,
|
||||
struct dp_catalog *catalog,
|
||||
struct dp_parser *parser);
|
||||
|
||||
void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable);
|
||||
|
@ -39,4 +38,7 @@ void dp_ctrl_irq_phy_exit(struct dp_ctrl *dp_ctrl);
|
|||
void dp_ctrl_set_psr(struct dp_ctrl *dp_ctrl, bool enable);
|
||||
void dp_ctrl_config_psr(struct dp_ctrl *dp_ctrl);
|
||||
|
||||
int dp_ctrl_clk_enable(struct dp_ctrl *ctrl, enum dp_pm_type pm_type,
|
||||
bool enable);
|
||||
|
||||
#endif /* _DP_CTRL_H_ */
|
||||
|
|
|
@ -16,13 +16,12 @@
|
|||
#include "msm_drv.h"
|
||||
#include "msm_kms.h"
|
||||
#include "dp_parser.h"
|
||||
#include "dp_power.h"
|
||||
#include "dp_ctrl.h"
|
||||
#include "dp_catalog.h"
|
||||
#include "dp_aux.h"
|
||||
#include "dp_reg.h"
|
||||
#include "dp_link.h"
|
||||
#include "dp_panel.h"
|
||||
#include "dp_ctrl.h"
|
||||
#include "dp_display.h"
|
||||
#include "dp_drm.h"
|
||||
#include "dp_audio.h"
|
||||
|
@ -90,7 +89,6 @@ struct dp_display_private {
|
|||
struct dentry *root;
|
||||
|
||||
struct dp_parser *parser;
|
||||
struct dp_power *power;
|
||||
struct dp_catalog *catalog;
|
||||
struct drm_dp_aux *aux;
|
||||
struct dp_link *link;
|
||||
|
@ -435,7 +433,7 @@ static void dp_display_host_init(struct dp_display_private *dp)
|
|||
dp->dp_display.connector_type, dp->core_initialized,
|
||||
dp->phy_initialized);
|
||||
|
||||
dp_power_clk_enable(dp->power, DP_CORE_PM, true);
|
||||
dp_ctrl_clk_enable(dp->ctrl, DP_CORE_PM, true);
|
||||
dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
|
||||
dp_aux_init(dp->aux);
|
||||
dp->core_initialized = true;
|
||||
|
@ -449,7 +447,7 @@ static void dp_display_host_deinit(struct dp_display_private *dp)
|
|||
|
||||
dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
|
||||
dp_aux_deinit(dp->aux);
|
||||
dp_power_clk_enable(dp->power, DP_CORE_PM, false);
|
||||
dp_ctrl_clk_enable(dp->ctrl, DP_CORE_PM, false);
|
||||
dp->core_initialized = false;
|
||||
}
|
||||
|
||||
|
@ -732,14 +730,6 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
|||
goto error;
|
||||
}
|
||||
|
||||
dp->power = dp_power_get(dev, dp->parser);
|
||||
if (IS_ERR(dp->power)) {
|
||||
rc = PTR_ERR(dp->power);
|
||||
DRM_ERROR("failed to initialize power, rc = %d\n", rc);
|
||||
dp->power = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dp->aux = dp_aux_get(dev, dp->catalog, dp->dp_display.is_edp);
|
||||
if (IS_ERR(dp->aux)) {
|
||||
rc = PTR_ERR(dp->aux);
|
||||
|
@ -769,7 +759,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
|||
}
|
||||
|
||||
dp->ctrl = dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
|
||||
dp->power, dp->catalog, dp->parser);
|
||||
dp->catalog, dp->parser);
|
||||
if (IS_ERR(dp->ctrl)) {
|
||||
rc = PTR_ERR(dp->ctrl);
|
||||
DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
|
||||
|
@ -1267,12 +1257,6 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
rc = dp_power_client_init(dp->power);
|
||||
if (rc) {
|
||||
DRM_ERROR("Power client create failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* setup event q */
|
||||
mutex_init(&dp->event_mutex);
|
||||
init_waitqueue_head(&dp->event_q);
|
||||
|
|
|
@ -1,170 +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 device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
|
||||
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->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)
|
||||
return rc;
|
||||
|
||||
rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks);
|
||||
if (rc)
|
||||
return -ENODEV;
|
||||
|
||||
rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks);
|
||||
if (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)
|
||||
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)
|
||||
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)
|
||||
{
|
||||
struct dp_power_private *power;
|
||||
|
||||
power = container_of(dp_power, struct dp_power_private, dp_power);
|
||||
|
||||
return dp_power_clk_init(power);
|
||||
}
|
||||
|
||||
struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser)
|
||||
{
|
||||
struct dp_power_private *power;
|
||||
struct dp_power *dp_power;
|
||||
|
||||
power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
|
||||
if (!power)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
power->parser = parser;
|
||||
power->dev = dev;
|
||||
|
||||
dp_power = &power->dp_power;
|
||||
|
||||
return dp_power;
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_POWER_H_
|
||||
#define _DP_POWER_H_
|
||||
|
||||
#include "dp_parser.h"
|
||||
|
||||
/**
|
||||
* sruct dp_power - DisplayPort's power related data
|
||||
*
|
||||
* @init: initializes the regulators/core clocks/GPIOs/pinctrl
|
||||
* @deinit: turns off the regulators/core clocks/GPIOs/pinctrl
|
||||
* @clk_enable: enable/disable the DP clocks
|
||||
* @set_pixel_clk_parent: set the parent of DP pixel clock
|
||||
*/
|
||||
struct dp_power {
|
||||
bool core_clks_on;
|
||||
bool link_clks_on;
|
||||
bool stream_clks_on;
|
||||
};
|
||||
|
||||
/**
|
||||
* dp_power_clk_status() - display controller clocks status
|
||||
*
|
||||
* @power: instance of power module
|
||||
* @pm_type: type of pm, core/ctrl/phy
|
||||
* return: status of power clocks
|
||||
*
|
||||
* This API return status of DP clocks
|
||||
*/
|
||||
|
||||
int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type);
|
||||
|
||||
/**
|
||||
* dp_power_clk_enable() - enable display controller clocks
|
||||
*
|
||||
* @power: instance of power module
|
||||
* @pm_type: type of pm, core/ctrl/phy
|
||||
* @enable: enables or disables
|
||||
* return: pointer to allocated power module data
|
||||
*
|
||||
* This API will call setrate and enable for DP clocks
|
||||
*/
|
||||
|
||||
int dp_power_clk_enable(struct dp_power *power, enum dp_pm_type pm_type,
|
||||
bool enable);
|
||||
|
||||
/**
|
||||
* dp_power_client_init() - initialize clock and regulator modules
|
||||
*
|
||||
* @power: instance of power module
|
||||
* return: 0 for success, error for failure.
|
||||
*
|
||||
* This API will configure the DisplayPort's clocks and regulator
|
||||
* modules.
|
||||
*/
|
||||
int dp_power_client_init(struct dp_power *power);
|
||||
|
||||
/**
|
||||
* dp_power_get() - configure and get the DisplayPort power module data
|
||||
*
|
||||
* @parser: instance of parser module
|
||||
* return: pointer to allocated power module data
|
||||
*
|
||||
* This API will configure the DisplayPort's power module and provides
|
||||
* methods to be called by the client to configure the power related
|
||||
* modules.
|
||||
*/
|
||||
struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser);
|
||||
|
||||
#endif /* _DP_POWER_H_ */
|
Loading…
Add table
Reference in a new issue