Forráskód Böngészése

Merge "disp: msm: dsi: add mutex lock before link clock frequency update"

qctecmdr 1 éve
szülő
commit
abc73d74d3
4 módosított fájl, 126 hozzáadás és 19 törlés
  1. 22 2
      msm/dsi/dsi_clk.h
  2. 51 1
      msm/dsi/dsi_clk_manager.c
  3. 1 6
      msm/dsi/dsi_ctrl.c
  4. 52 10
      msm/dsi/dsi_display.c

+ 22 - 2
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_ */

+ 51 - 1
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 <linux/of.h>
@@ -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);
+}

+ 1 - 6
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;
 }
 

+ 52 - 10
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;