diff --git a/msm/dsi/dsi_clk.h b/msm/dsi/dsi_clk.h index c450b30c86..443d5d063f 100644 --- a/msm/dsi/dsi_clk.h +++ b/msm/dsi/dsi_clk.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DSI_CLK_H_ @@ -304,6 +304,15 @@ int dsi_display_clk_ctrl(void *handle, u32 clk_type, u32 clk_state); int dsi_clk_set_link_frequencies(void *client, struct link_clk_freq freq, u32 index); +/** + * dsi_clk_get_link_frequencies() - get link clk frequencies + * @link_freq: Structure to get link clock frequencies + * @client: DSI clock client pointer. + * @index: Index of the DSI controller. + * + * return: error code in case of failure or 0 for success. + */ +int dsi_clk_get_link_frequencies(struct link_clk_freq *link_freq, void *client, u32 index); /** * dsi_clk_set_pixel_clk_rate() - set frequency for pixel_clk @@ -314,7 +323,6 @@ int dsi_clk_set_link_frequencies(void *client, struct link_clk_freq freq, */ int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index); - /** * dsi_clk_set_byte_clk_rate() - set frequency for byte clock * @client: DSI clock client pointer. @@ -354,4 +362,16 @@ void dsi_clk_disable_unprepare(struct dsi_clk_link_set *clk); */ int dsi_display_dump_clk_handle_state(void *client); +/** + * dsi_clk_acquire_mngr_lock() - acquire clk manager mutex lock + * @client: DSI clock client pointer. + */ +void dsi_clk_acquire_mngr_lock(void *client); + +/** + * dsi_clk_release_mngr_lock() - release clk manager mutex lock + * @client: DSI clock client pointer. + */ +void dsi_clk_release_mngr_lock(void *client); + #endif /* _DSI_CLK_H_ */ diff --git a/msm/dsi/dsi_clk_manager.c b/msm/dsi/dsi_clk_manager.c index 3da5dbaa33..a0e7d28ae9 100644 --- a/msm/dsi/dsi_clk_manager.c +++ b/msm/dsi/dsi_clk_manager.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -106,6 +106,30 @@ int dsi_clk_set_link_frequencies(void *client, struct link_clk_freq freq, return rc; } +/** + * dsi_clk_get_link_frequencies() - get link clk frequencies + * @link_freq: Structure to get link clock frequencies + * @client: DSI clock client pointer. + * @index: Index of the DSI controller. + * + * return: error code in case of failure or 0 for success. + */ +int dsi_clk_get_link_frequencies(struct link_clk_freq *link_freq, void *client, u32 index) +{ + struct dsi_clk_client_info *c = client; + struct dsi_clk_mngr *mngr; + + if (!client || !link_freq) { + DSI_ERR("invalid params\n"); + return -EINVAL; + } + + mngr = c->mngr; + memcpy(link_freq, &mngr->link_clks[index].freq, sizeof(struct link_clk_freq)); + + return 0; +} + /** * dsi_clk_set_pixel_clk_rate() - set frequency for pixel clock * @clks: DSI link clock information. @@ -1505,3 +1529,29 @@ int dsi_display_clk_mngr_deregister(void *clk_mngr) kfree(mngr); return rc; } + +/** + * dsi_clk_acquire_mngr_lock() - acquire clk manager mutex lock + * @client: DSI clock client pointer. + */ +void dsi_clk_acquire_mngr_lock(void *client) +{ + struct dsi_clk_mngr *mngr; + struct dsi_clk_client_info *c = client; + + mngr = c->mngr; + mutex_lock(&mngr->clk_mutex); +} + +/** + * dsi_clk_release_mngr_lock() - release clk manager mutex lock + * @client: DSI clock client pointer. + */ +void dsi_clk_release_mngr_lock(void *client) +{ + struct dsi_clk_mngr *mngr; + struct dsi_clk_client_info *c = client; + + mngr = c->mngr; + mutex_unlock(&mngr->clk_mutex); +} diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 35e90f1e3b..440a682a97 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -1114,11 +1114,6 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->clk_freq.pix_clk_rate = pclk_rate; dsi_ctrl->clk_freq.esc_clk_rate = config->esc_clk_rate_hz; - rc = dsi_clk_set_link_frequencies(clk_handle, dsi_ctrl->clk_freq, - dsi_ctrl->cell_index); - if (rc) - DSI_CTRL_ERR(dsi_ctrl, "Failed to update link frequencies\n"); - return rc; } diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 84480e3f52..b8650e3522 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -2840,7 +2840,7 @@ int dsi_display_phy_configure(void *priv, bool commit) struct dsi_display *display = priv; struct dsi_display_ctrl *m_ctrl; struct dsi_pll_resource *pll_res; - struct dsi_ctrl *ctrl; + struct link_clk_freq link_freq; if (!display) { DSI_ERR("invalid arguments\n"); @@ -2862,9 +2862,15 @@ int dsi_display_phy_configure(void *priv, bool commit) return -EINVAL; } - ctrl = m_ctrl->ctrl; - pll_res->byteclk_rate = ctrl->clk_freq.byte_clk_rate; - pll_res->pclk_rate = ctrl->clk_freq.pix_clk_rate; + rc = dsi_clk_get_link_frequencies(&link_freq, display->dsi_clk_handle, + display->clk_master_idx); + if (rc) { + DSI_ERR("Failed to get link frequencies\n"); + return rc; + } + + pll_res->byteclk_rate = link_freq.byte_clk_rate; + pll_res->pclk_rate = link_freq.pix_clk_rate; rc = dsi_phy_configure(m_ctrl->phy, commit); @@ -4481,6 +4487,26 @@ void dsi_display_update_byte_intf_div(struct dsi_display *display) config->byte_intf_clk_div = 2; } +static int dsi_display_set_link_frequencies(struct dsi_display *display) +{ + int rc = 0, i = 0; + + dsi_clk_acquire_mngr_lock(display->dsi_clk_handle); + display_for_each_ctrl(i, display) { + struct dsi_display_ctrl *ctrl = &display->ctrl[i]; + + rc = dsi_clk_set_link_frequencies(display->dsi_clk_handle, ctrl->ctrl->clk_freq, i); + if (rc) { + DSI_ERR("Failed to update link frequencies of ctrl_%d, rc=%d\n", i, rc); + dsi_clk_release_mngr_lock(display->dsi_clk_handle); + return rc; + } + } + dsi_clk_release_mngr_lock(display->dsi_clk_handle); + + return rc; +} + static int dsi_display_update_dsi_bitrate(struct dsi_display *display, u32 bit_clk_rate) { @@ -4563,12 +4589,6 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display, ctrl->clk_freq.byte_clk_rate = byte_clk_rate; ctrl->clk_freq.byte_intf_clk_rate = byte_intf_clk_rate; ctrl->clk_freq.pix_clk_rate = pclk_rate; - rc = dsi_clk_set_link_frequencies(display->dsi_clk_handle, - ctrl->clk_freq, ctrl->cell_index); - if (rc) { - DSI_ERR("Failed to update link frequencies\n"); - goto error; - } ctrl->host_config.bit_clk_rate_hz = bit_clk_rate; error: @@ -4579,6 +4599,12 @@ error: return rc; } + rc = dsi_display_set_link_frequencies(display); + if (rc) { + DSI_ERR("Failed to set display link frequencies\n"); + return rc; + } + return 0; } @@ -5233,6 +5259,15 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, } } + if (!(mode->dsi_mode_flags & (DSI_MODE_FLAG_SEAMLESS | DSI_MODE_FLAG_VRR | + DSI_MODE_FLAG_DYN_CLK))) { + rc = dsi_display_set_link_frequencies(display); + if (rc) { + DSI_ERR("Failed to set display link frequencies\n"); + goto error; + } + } + if ((mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) && (display->panel->panel_mode == DSI_OP_CMD_MODE)) { u64 cur_bitclk = display->panel->cur_mode->timing.clk_rate_hz; @@ -7461,6 +7496,13 @@ int dsi_display_update_transfer_time(void *display, u32 transfer_time) return rc; } } + + rc = dsi_display_set_link_frequencies(disp); + if (rc) { + DSI_ERR("Failed to set display link frequencies\n"); + return rc; + } + atomic_set(&disp->clkrate_change_pending, 1); return 0;