diff --git a/msm/dsi/dsi_clk_manager.c b/msm/dsi/dsi_clk_manager.c index b8b5bec682c4..a213c6959b38 100644 --- a/msm/dsi/dsi_clk_manager.c +++ b/msm/dsi/dsi_clk_manager.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ @@ -172,6 +173,16 @@ int dsi_clk_update_parent(struct dsi_clk_link_set *parent, { int rc = 0; + if (!parent->byte_clk || !parent->pixel_clk) { + DSI_ERR("Invalid parent\n"); + return -EINVAL; + } + + if (!child->byte_clk || !child->pixel_clk) { + DSI_ERR("Invalid child\n"); + return -EINVAL; + } + rc = clk_set_parent(child->byte_clk, parent->byte_clk); if (rc) { DSI_ERR("failed to set byte clk parent\n"); diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 2330d73f5c0f..b72dabdc7b59 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -2657,6 +2658,38 @@ error: return rc; } +#ifdef CONFIG_DEEPSLEEP +static int dsi_display_unset_clk_src(struct dsi_display *display) +{ + int rc = 0; + int i; + struct dsi_display_ctrl *ctrl; + + DSI_DEBUG("[%s] unset source clocks\n", display->name); + + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + if (!ctrl->ctrl) + continue; + + /* set ctrl clocks to xo source */ + rc = dsi_ctrl_set_clock_source(ctrl->ctrl, + &display->clock_info.xo_clks); + if (rc) { + DSI_ERR("[%s] failed to set source clocks, rc=%d\n", + display->name, rc); + return rc; + } + } + return 0; +} +#else +static inline int dsi_display_unset_clk_src(struct dsi_display *display) +{ + return 0; +} +#endif + static int dsi_display_set_clk_src(struct dsi_display *display) { int rc = 0; @@ -3442,6 +3475,7 @@ static int dsi_display_clocks_init(struct dsi_display *display) { int i, rc = 0, num_clk = 0; const char *clk_name; + const char *xo_byte = "xo_byte", *xo_pixel = "xo_pixel"; const char *src_byte = "src_byte", *src_pixel = "src_pixel"; const char *mux_byte = "mux_byte", *mux_pixel = "mux_pixel"; const char *cphy_byte = "cphy_byte", *cphy_pixel = "cphy_pixel"; @@ -3449,6 +3483,7 @@ static int dsi_display_clocks_init(struct dsi_display *display) const char *shadow_cphybyte = "shadow_cphybyte", *shadow_cphypixel = "shadow_cphypixel"; struct clk *dsi_clk; + struct dsi_clk_link_set *xo = &display->clock_info.xo_clks; struct dsi_clk_link_set *src = &display->clock_info.src_clks; struct dsi_clk_link_set *mux = &display->clock_info.mux_clks; struct dsi_clk_link_set *cphy = &display->clock_info.cphy_clks; @@ -3479,6 +3514,15 @@ static int dsi_display_clocks_init(struct dsi_display *display) DSI_ERR("failed to get %s, rc=%d\n", clk_name, rc); + if (dsi_display_check_prefix(xo_byte, clk_name)) { + xo->byte_clk = NULL; + goto error; + } + if (dsi_display_check_prefix(xo_pixel, clk_name)) { + xo->pixel_clk = NULL; + goto error; + } + if (dsi_display_check_prefix(mux_byte, clk_name)) { mux->byte_clk = NULL; goto error; @@ -3524,6 +3568,16 @@ static int dsi_display_clocks_init(struct dsi_display *display) } } + if (dsi_display_check_prefix(xo_byte, clk_name)) { + xo->byte_clk = dsi_clk; + continue; + } + + if (dsi_display_check_prefix(xo_pixel, clk_name)) { + xo->pixel_clk = dsi_clk; + continue; + } + if (dsi_display_check_prefix(src_byte, clk_name)) { src->byte_clk = dsi_clk; continue; @@ -8586,6 +8640,12 @@ int dsi_display_unprepare(struct dsi_display *display) DSI_ERR("[%s] failed to disable Link clocks, rc=%d\n", display->name, rc); + /* set to dsi clocks to xo clocks */ + rc = dsi_display_unset_clk_src(display); + if (rc) + DSI_ERR("[%s] failed to unset clocks, rc=%d\n", + display->name, rc); + rc = dsi_display_ctrl_deinit(display); if (rc) DSI_ERR("[%s] failed to deinit controller, rc=%d\n", diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 2dc7bc7dd137..e2932a0d530d 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -110,6 +111,7 @@ struct dsi_display_boot_param { * @shadow_cphy_clks: Used for C-phy clock switch. */ struct dsi_display_clk_info { + struct dsi_clk_link_set xo_clks; struct dsi_clk_link_set src_clks; struct dsi_clk_link_set mux_clks; struct dsi_clk_link_set cphy_clks;