Commit 9bd0946d authored by Dmitry Baryshkov's avatar Dmitry Baryshkov

drm/msm/dp: simplify stream clocks handling

There is only a single DP_STREAM_PM clock, stream_pixel. Instead of
using a separate dss_module_power instance for this single clock, handle
this clock directly. This allows us to drop several wrapping functions.
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
Reviewed-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/576102/
Link: https://lore.kernel.org/r/20240126-dp-power-parser-cleanup-v3-6-098d5f581dd3@linaro.org
parent 17cb153f
......@@ -79,6 +79,8 @@ struct dp_ctrl_private {
struct dp_parser *parser;
struct dp_catalog *catalog;
struct clk *pixel_clk;
struct completion idle_comp;
struct completion psr_op_comp;
struct completion video_comp;
......@@ -1315,27 +1317,6 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl,
return ret;
}
static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
enum dp_pm_type module, char *name, unsigned long rate)
{
u32 num = ctrl->parser->mp[module].num_clk;
struct clk_bulk_data *cfg = ctrl->parser->mp[module].clocks;
while (num && strcmp(cfg->id, name)) {
num--;
cfg++;
}
drm_dbg_dp(ctrl->drm_dev, "setting rate=%lu on clk=%s\n",
rate, name);
if (num)
clk_set_rate(cfg->clk, rate);
else
DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
name, rate);
}
int dp_ctrl_clk_enable(struct dp_ctrl *dp_ctrl,
enum dp_pm_type pm_type, bool enable)
{
......@@ -1346,8 +1327,7 @@ int dp_ctrl_clk_enable(struct dp_ctrl *dp_ctrl,
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) {
pm_type != DP_CTRL_PM) {
DRM_ERROR("unsupported ctrl module: %s\n",
dp_parser_pm_name(pm_type));
return -EINVAL;
......@@ -1366,12 +1346,6 @@ int dp_ctrl_clk_enable(struct dp_ctrl *dp_ctrl,
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");
......@@ -1396,8 +1370,6 @@ int dp_ctrl_clk_enable(struct dp_ctrl *dp_ctrl,
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;
......@@ -1729,13 +1701,22 @@ 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 = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
if (ret) {
DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
return ret;
}
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, true);
if (ctrl->stream_clks_on) {
drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
} else {
ret = clk_prepare_enable(ctrl->pixel_clk);
if (ret) {
DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
return ret;
}
ctrl->stream_clks_on = true;
}
dp_ctrl_send_phy_test_pattern(ctrl);
......@@ -1972,13 +1953,22 @@ 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 = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
if (ret) {
DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
goto end;
}
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_STREAM_PM, true);
if (ctrl->stream_clks_on) {
drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
} else {
ret = clk_prepare_enable(ctrl->pixel_clk);
if (ret) {
DRM_ERROR("Unable to start pixel clocks. ret=%d\n", ret);
DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
goto end;
}
ctrl->stream_clks_on = true;
}
if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl))
dp_ctrl_link_retrain(ctrl);
......@@ -2031,11 +2021,8 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, 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;
}
clk_disable_unprepare(ctrl->pixel_clk);
ctrl->stream_clks_on = false;
}
dev_pm_opp_set_rate(ctrl->dev, 0);
......@@ -2103,9 +2090,10 @@ int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
dp_catalog_ctrl_reset(ctrl->catalog);
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);
if (ctrl->stream_clks_on) {
clk_disable_unprepare(ctrl->pixel_clk);
ctrl->stream_clks_on = false;
}
dev_pm_opp_set_rate(ctrl->dev, 0);
ret = dp_ctrl_clk_enable(&ctrl->dp_ctrl, DP_CTRL_PM, false);
......@@ -2169,7 +2157,7 @@ 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 dss_module_power *core, *ctrl;
struct device *dev;
ctrl_private = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
......@@ -2177,7 +2165,6 @@ static int dp_ctrl_clk_init(struct dp_ctrl *dp_ctrl)
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)
......@@ -2187,9 +2174,9 @@ static int dp_ctrl_clk_init(struct dp_ctrl *dp_ctrl)
if (rc)
return -ENODEV;
rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks);
if (rc)
return -ENODEV;
ctrl_private->pixel_clk = devm_clk_get(dev, "stream_pixel");
if (IS_ERR(ctrl_private->pixel_clk))
return PTR_ERR(ctrl_private->pixel_clk);
return 0;
}
......
......@@ -150,12 +150,11 @@ static inline bool dp_parser_check_prefix(const char *clk_prefix,
static int dp_parser_init_clk_data(struct dp_parser *parser)
{
int num_clk, i, rc;
int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
int core_clk_count = 0, ctrl_clk_count = 0;
const char *clk_name;
struct device *dev = &parser->pdev->dev;
struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
num_clk = of_property_count_strings(dev->of_node, "clock-names");
if (num_clk <= 0) {
......@@ -174,9 +173,6 @@ static int dp_parser_init_clk_data(struct dp_parser *parser)
if (dp_parser_check_prefix("ctrl", clk_name))
ctrl_clk_count++;
if (dp_parser_check_prefix("stream", clk_name))
stream_clk_count++;
}
/* Initialize the CORE power module */
......@@ -207,47 +203,30 @@ static int dp_parser_init_clk_data(struct dp_parser *parser)
return -ENOMEM;
}
/* Initialize the STREAM power module */
if (stream_clk_count == 0) {
DRM_ERROR("no stream (pixel) clocks are defined\n");
return -EINVAL;
}
stream_power->num_clk = stream_clk_count;
stream_power->clocks = devm_kcalloc(dev,
stream_power->num_clk, sizeof(struct clk_bulk_data),
GFP_KERNEL);
if (!stream_power->clocks) {
stream_power->num_clk = 0;
return -ENOMEM;
}
return 0;
return num_clk;
}
static int dp_parser_clock(struct dp_parser *parser)
{
int rc = 0, i = 0;
int num_clk = 0;
int core_clk_index = 0, ctrl_clk_index = 0, stream_clk_index = 0;
int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
int core_clk_index = 0, ctrl_clk_index = 0;
int core_clk_count = 0, ctrl_clk_count = 0;
const char *clk_name;
struct device *dev = &parser->pdev->dev;
struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
rc = dp_parser_init_clk_data(parser);
if (rc) {
if (rc < 0) {
DRM_ERROR("failed to initialize power data %d\n", rc);
return -EINVAL;
return rc;
}
num_clk = rc;
core_clk_count = core_power->num_clk;
ctrl_clk_count = ctrl_power->num_clk;
stream_clk_count = stream_power->num_clk;
num_clk = core_clk_count + ctrl_clk_count + stream_clk_count;
for (i = 0; i < num_clk; i++) {
rc = of_property_read_string_index(dev->of_node, "clock-names",
......@@ -260,10 +239,6 @@ static int dp_parser_clock(struct dp_parser *parser)
core_clk_index < core_clk_count) {
core_power->clocks[core_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
core_clk_index++;
} else if (dp_parser_check_prefix("stream", clk_name) &&
stream_clk_index < stream_clk_count) {
stream_power->clocks[stream_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
stream_clk_index++;
} else if (dp_parser_check_prefix("ctrl", clk_name) &&
ctrl_clk_index < ctrl_clk_count) {
ctrl_power->clocks[ctrl_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
......
......@@ -19,7 +19,6 @@
enum dp_pm_type {
DP_CORE_PM,
DP_CTRL_PM,
DP_STREAM_PM,
DP_MAX_PM
};
......@@ -40,7 +39,6 @@ static inline const char *dp_parser_pm_name(enum dp_pm_type module)
switch (module) {
case DP_CORE_PM: return "DP_CORE_PM";
case DP_CTRL_PM: return "DP_CTRL_PM";
case DP_STREAM_PM: return "DP_STREAM_PM";
default: return "???";
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment