Browse Source

disp: msm: dsi: add DCS get scan line command

Add DCS command to read the panel scan line value and associated
time stamp in nano-seconds.

Change-Id: I06a76d3a6c5ad7a2e7681413c741e5b97b34d73f
Signed-off-by: Amine Najahi <[email protected]>
Amine Najahi 2 years ago
parent
commit
d4a444a3d1

+ 3 - 0
msm/dsi/dsi_ctrl.c

@@ -2855,6 +2855,8 @@ static irqreturn_t dsi_ctrl_isr(int irq, void *ptr)
 					dsi_ctrl->cmd_success_line,
 					dsi_ctrl->cmd_success_line,
 					dsi_ctrl->cmd_success_frame);
 					dsi_ctrl->cmd_success_frame);
 		}
 		}
+
+		dsi_ctrl->cmd_success_ts =  ktime_get();
 		atomic_set(&dsi_ctrl->dma_irq_trig, 1);
 		atomic_set(&dsi_ctrl->dma_irq_trig, 1);
 		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
 		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
 					DSI_SINT_CMD_MODE_DMA_DONE);
 					DSI_SINT_CMD_MODE_DMA_DONE);
@@ -3501,6 +3503,7 @@ int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd)
 					rc);
 					rc);
 	}
 	}
 
 
+	cmd->ts = dsi_ctrl->cmd_success_ts;
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_CMD_TX, 0x0);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_CMD_TX, 0x0);
 
 
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
 	mutex_unlock(&dsi_ctrl->ctrl_lock);

+ 2 - 0
msm/dsi/dsi_ctrl.h

@@ -253,6 +253,7 @@ struct dsi_ctrl_interrupts {
  *				which command transfer is successful.
  *				which command transfer is successful.
  * @cmd_engine_refcount: Reference count enforcing single instance of cmd engine
  * @cmd_engine_refcount: Reference count enforcing single instance of cmd engine
  * @pending_cmd_flags: Flags associated with command that is currently being txed or pending.
  * @pending_cmd_flags: Flags associated with command that is currently being txed or pending.
+ * @cmd_success_ts:             Time stamp of when command transfer is successful in nano-seconds.
  */
  */
 struct dsi_ctrl {
 struct dsi_ctrl {
 	struct platform_device *pdev;
 	struct platform_device *pdev;
@@ -321,6 +322,7 @@ struct dsi_ctrl {
 	u32 cmd_success_frame;
 	u32 cmd_success_frame;
 	u32 cmd_engine_refcount;
 	u32 cmd_engine_refcount;
 	u32 pending_cmd_flags;
 	u32 pending_cmd_flags;
+	ktime_t cmd_success_ts;
 };
 };
 
 
 /**
 /**

+ 3 - 1
msm/dsi/dsi_defs.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
 /*
- * Copyright (c) 2021-2022 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.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -366,6 +366,7 @@ enum dsi_video_traffic_mode {
  * @post_wait_ms:        post wait duration
  * @post_wait_ms:        post wait duration
  * @ctrl:                index of DSI controller
  * @ctrl:                index of DSI controller
  * @ctrl_flags:          controller flags
  * @ctrl_flags:          controller flags
+ * @ts:                  dsi command time stamp in nano-seconds.
  */
  */
 struct dsi_cmd_desc {
 struct dsi_cmd_desc {
 	struct mipi_dsi_msg msg;
 	struct mipi_dsi_msg msg;
@@ -373,6 +374,7 @@ struct dsi_cmd_desc {
 	u32  post_wait_ms;
 	u32  post_wait_ms;
 	u32 ctrl;
 	u32 ctrl;
 	u32 ctrl_flags;
 	u32 ctrl_flags;
+	ktime_t ts;
 };
 };
 
 
 /**
 /**

+ 34 - 2
msm/dsi/dsi_display.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // SPDX-License-Identifier: GPL-2.0-only
 /*
 /*
- * Copyright (c) 2021-2022 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.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -9,6 +9,7 @@
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/version.h>
 #include <linux/version.h>
+#include <linux/ktime.h>
 
 
 #include "msm_drv.h"
 #include "msm_drv.h"
 #include "sde_connector.h"
 #include "sde_connector.h"
@@ -1229,7 +1230,7 @@ static void _dsi_display_continuous_clk_ctrl(struct dsi_display *display,
 }
 }
 
 
 int dsi_display_cmd_receive(void *display, const char *cmd_buf,
 int dsi_display_cmd_receive(void *display, const char *cmd_buf,
-		u32 cmd_buf_len,  u8 *recv_buf, u32 recv_buf_len)
+		u32 cmd_buf_len,  u8 *recv_buf, u32 recv_buf_len, ktime_t *ts)
 {
 {
 	struct dsi_display *dsi_display = display;
 	struct dsi_display *dsi_display = display;
 	struct dsi_cmd_desc cmd = {};
 	struct dsi_cmd_desc cmd = {};
@@ -1282,6 +1283,9 @@ int dsi_display_cmd_receive(void *display, const char *cmd_buf,
 	if (rc <= 0)
 	if (rc <= 0)
 		DSI_ERR("[DSI] Display command receive failed, rc=%d\n", rc);
 		DSI_ERR("[DSI] Display command receive failed, rc=%d\n", rc);
 
 
+	if (ts)
+		*ts = cmd.ts;
+
 end:
 end:
 	mutex_unlock(&dsi_display->display_lock);
 	mutex_unlock(&dsi_display->display_lock);
 	return rc;
 	return rc;
@@ -7414,6 +7418,34 @@ int dsi_display_update_transfer_time(void *display, u32 transfer_time)
 	return 0;
 	return 0;
 }
 }
 
 
+int dsi_display_get_panel_scan_line(void *display, u16 *scan_line, ktime_t *scan_line_ts)
+{
+	struct dsi_display *dsi_display = (struct dsi_display *)display;
+	u8 scan_line_tx_buffer[] = {0x6, 0x1, 0x0, 0xa, 0x0, 0x0, 0x1, 0x45};
+	u8 rx_buffer[2];
+	int rx_len, rc = 0;
+	ktime_t ts = 0;
+
+	if (!dsi_display || !scan_line || !scan_line_ts)
+		return -EINVAL;
+
+	SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
+	rx_len = dsi_display_cmd_receive(dsi_display, scan_line_tx_buffer,
+			ARRAY_SIZE(scan_line_tx_buffer), rx_buffer, ARRAY_SIZE(rx_buffer), &ts);
+	if (rx_len <= 0) {
+		rc = -EINVAL;
+		goto end;
+	}
+
+	*scan_line = (rx_buffer[0] << 8) | rx_buffer[1];
+	*scan_line_ts = ts;
+
+end:
+	SDE_EVT32(SDE_EVTLOG_FUNC_EXIT, rx_len, rx_buffer[0], rx_buffer[1],
+			ktime_us_delta(ktime_get(), ts));
+	return rc;
+}
+
 static bool dsi_display_match_timings(const struct dsi_display_mode *mode1,
 static bool dsi_display_match_timings(const struct dsi_display_mode *mode1,
 		struct dsi_display_mode *mode2, unsigned int match_flags)
 		struct dsi_display_mode *mode2, unsigned int match_flags)
 {
 {

+ 14 - 2
msm/dsi/dsi_display.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
 /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -12,6 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
+#include <linux/ktime.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_bridge.h>
 
 
@@ -710,9 +711,10 @@ int dsi_display_cmd_transfer(struct drm_connector *connector,
  * @cmd_buf_len:        Command buffer length in bytes
  * @cmd_buf_len:        Command buffer length in bytes
  * @recv_buf:           Receive buffer
  * @recv_buf:           Receive buffer
  * @recv_buf_len:       Receive buffer length in bytes
  * @recv_buf_len:       Receive buffer length in bytes
+ * @ts:                 Command time stamp in nano-seconds.
  */
  */
 int dsi_display_cmd_receive(void *display, const char *cmd_buf,
 int dsi_display_cmd_receive(void *display, const char *cmd_buf,
-			    u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len);
+			    u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len, ktime_t *ts);
 
 
 /**
 /**
  * dsi_display_soft_reset() - perform a soft reset on DSI controller
  * dsi_display_soft_reset() - perform a soft reset on DSI controller
@@ -844,4 +846,14 @@ bool dsi_display_mode_match(const struct dsi_display_mode *mode1,
  */
  */
 int dsi_display_update_transfer_time(void *display, u32 transfer_time);
 int dsi_display_update_transfer_time(void *display, u32 transfer_time);
 
 
+/**
+ * dsi_display_get_panel_scan_line() - get panel scan line
+ * @display:     handle to display
+ * @scan_line:   scan line buffer value
+ * @scan_line_ts:   scan line time stamp value in nano-seconds
+ *
+ * Return: error code
+ */
+int dsi_display_get_panel_scan_line(void *display, u16 *scan_line, ktime_t *scan_line_ts);
+
 #endif /* _DSI_DISPLAY_H_ */
 #endif /* _DSI_DISPLAY_H_ */

+ 1 - 1
msm/sde/sde_connector.c

@@ -2468,7 +2468,7 @@ static ssize_t _sde_debugfs_conn_cmd_rx_write(struct file *file,
 
 
 	mutex_lock(&c_conn->lock);
 	mutex_lock(&c_conn->lock);
 	c_conn->rx_len = c_conn->ops.cmd_receive(c_conn->display, buffer + 1,
 	c_conn->rx_len = c_conn->ops.cmd_receive(c_conn->display, buffer + 1,
-			buf_size - 1, c_conn->cmd_rx_buf, buffer[0]);
+			buf_size - 1, c_conn->cmd_rx_buf, buffer[0], NULL);
 	mutex_unlock(&c_conn->lock);
 	mutex_unlock(&c_conn->lock);
 
 
 	if (c_conn->rx_len <= 0)
 	if (c_conn->rx_len <= 0)

+ 11 - 2
msm/sde/sde_connector.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
 /*
- * Copyright (c) 2021-2022 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.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -287,11 +287,12 @@ struct sde_connector_ops {
 	 * @cmd_buf_len: Command buffer length in bytes
 	 * @cmd_buf_len: Command buffer length in bytes
 	 * @recv_buf: rx buffer
 	 * @recv_buf: rx buffer
 	 * @recv_buf_len: rx buffer length
 	 * @recv_buf_len: rx buffer length
+	 * @ts: time stamp in nano-seconds of when the command was received
 	 * Returns: number of bytes read, if successful, negative for failure
 	 * Returns: number of bytes read, if successful, negative for failure
 	 */
 	 */
 
 
 	int (*cmd_receive)(void *display, const char *cmd_buf,
 	int (*cmd_receive)(void *display, const char *cmd_buf,
-			   u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len);
+			   u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len, ktime_t *ts);
 
 
 	/**
 	/**
 	 * config_hdr - configure HDR
 	 * config_hdr - configure HDR
@@ -438,6 +439,14 @@ struct sde_connector_ops {
 	 */
 	 */
 	int (*update_transfer_time)(void *display, u32 transfer_time);
 	int (*update_transfer_time)(void *display, u32 transfer_time);
 
 
+	/*
+	 * get_panel_scan_line -  get panel scan line
+	 * @display: Pointer to private display structure
+	 * @scan_line: Pointer to scan_line buffer value
+	 * @scan_line_ts:   scan line time stamp value in nano-seconds
+	 */
+	int (*get_panel_scan_line)(void *display, u16 *scan_line, ktime_t *scan_line_ts);
+
 };
 };
 
 
 /**
 /**

+ 2 - 1
msm/sde/sde_kms.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <[email protected]>
  * Author: Rob Clark <[email protected]>
@@ -1834,6 +1834,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
 		.set_submode_info = dsi_conn_set_submode_blob_info,
 		.set_submode_info = dsi_conn_set_submode_blob_info,
 		.get_num_lm_from_mode = dsi_conn_get_lm_from_mode,
 		.get_num_lm_from_mode = dsi_conn_get_lm_from_mode,
 		.update_transfer_time = dsi_display_update_transfer_time,
 		.update_transfer_time = dsi_display_update_transfer_time,
+		.get_panel_scan_line = dsi_display_get_panel_scan_line,
 	};
 	};
 	static const struct sde_connector_ops wb_ops = {
 	static const struct sde_connector_ops wb_ops = {
 		.post_init =    sde_wb_connector_post_init,
 		.post_init =    sde_wb_connector_post_init,