Преглед на файлове

disp: msm: dp: add qos vote during hdcp authentication

HDCP authentication has strict timing requirements and if the
display is on static screen during this time, it is possible
that SDE removes the QOS vote when it detects static display,
thereby affecting the hdcp authentication process.

This change adds qos support in dp driver to vote exclusively
for DP. If valid QOS settings are provided in dtsi, then the
driver adds the vote when it starts authentication and removes
the vote when authentication is completed.

Change-Id: I1d8bc098d0857b13fdf1ca089b6dd2d3f381bdb8
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah преди 3 години
родител
ревизия
6c8c95f99e
променени са 3 файла, в които са добавени 64 реда и са изтрити 1 реда
  1. 38 0
      msm/dp/dp_display.c
  2. 21 0
      msm/dp/dp_parser.c
  3. 5 1
      msm/dp/dp_parser.h

+ 38 - 0
msm/dp/dp_display.c

@@ -13,6 +13,7 @@
 #include <linux/soc/qcom/fsa4480-i2c.h>
 #include <linux/usb/phy.h>
 #include <linux/jiffies.h>
+#include <linux/pm_qos.h>
 
 #include "sde_connector.h"
 
@@ -201,6 +202,8 @@ struct dp_display_private {
 	u32 tot_dsc_blks_in_use;
 
 	bool process_hpd_connect;
+	struct dev_pm_qos_request pm_qos_req[NR_CPUS];
+	bool pm_qos_requested;
 
 	struct notifier_block usb_nb;
 };
@@ -285,6 +288,36 @@ static void dp_audio_enable(struct dp_display_private *dp, bool enable)
 	}
 }
 
+static void dp_display_qos_request(struct dp_display_private *dp, bool add_vote)
+{
+	struct device *cpu_dev;
+	int cpu = 0;
+	struct cpumask *cpu_mask;
+	u32 latency = dp->parser->qos_cpu_latency;
+	unsigned long mask = dp->parser->qos_cpu_mask;
+
+	if (!dp->parser->qos_cpu_mask || (dp->pm_qos_requested == add_vote))
+		return;
+
+	cpu_mask = to_cpumask(&mask);
+	for_each_cpu(cpu, cpu_mask) {
+		cpu_dev = get_cpu_device(cpu);
+		if (!cpu_dev) {
+			SDE_DEBUG("%s: failed to get cpu%d device\n", __func__, cpu);
+			continue;
+		}
+
+		if (add_vote)
+			dev_pm_qos_add_request(cpu_dev, &dp->pm_qos_req[cpu],
+				DEV_PM_QOS_RESUME_LATENCY, latency);
+		else
+			dev_pm_qos_remove_request(&dp->pm_qos_req[cpu]);
+	}
+
+	SDE_EVT32_EXTERNAL(add_vote, mask, latency);
+	dp->pm_qos_requested = add_vote;
+}
+
 static void dp_display_update_hdcp_status(struct dp_display_private *dp,
 					bool reset)
 {
@@ -499,6 +532,11 @@ static void dp_display_hdcp_process_state(struct dp_display_private *dp)
 		dp->debug->force_encryption && ops && ops->force_encryption)
 		ops->force_encryption(data, dp->debug->force_encryption);
 
+	if (status->hdcp_state == HDCP_STATE_AUTHENTICATED)
+		dp_display_qos_request(dp, false);
+	else
+		dp_display_qos_request(dp, true);
+
 	switch (status->hdcp_state) {
 	case HDCP_STATE_INACTIVE:
 		dp_display_hdcp_register_streams(dp);

+ 21 - 0
msm/dp/dp_parser.c

@@ -742,6 +742,26 @@ static void dp_parser_dsc(struct dp_parser *parser)
 			parser->dsc_continuous_pps);
 }
 
+static void dp_parser_qos(struct dp_parser *parser)
+{
+	struct device *dev = &parser->pdev->dev;
+	u32 mask, latency;
+	int rc;
+
+	rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-latency-us", &latency);
+	if (rc)
+		return;
+
+	rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-mask", &mask);
+	if (rc)
+		return;
+
+	parser->qos_cpu_mask = mask;
+	parser->qos_cpu_latency = latency;
+
+	DP_DEBUG("qos parsing successful. mask:%x latency:%ld\n", mask, latency);
+}
+
 static void dp_parser_fec(struct dp_parser *parser)
 {
 	struct device *dev = &parser->pdev->dev;
@@ -817,6 +837,7 @@ static int dp_parser_parse(struct dp_parser *parser)
 	dp_parser_dsc(parser);
 	dp_parser_fec(parser);
 	dp_parser_widebus(parser);
+	dp_parser_qos(parser);
 err:
 	return rc;
 }

+ 5 - 1
msm/dp/dp_parser.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DP_PARSER_H_
@@ -198,6 +198,8 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type)
  * @dsc_continuous_pps: PPS sent every frame by HW
  * @has_widebus: widebus (2PPC) feature eanble status
   *@mst_fixed_port: mst port_num reserved for fixed topology
+ * @qos_cpu_mask: CPU mask for QOS
+ * @qos_cpu_latency: CPU Latency setting for QOS
  * @parse: function to be called by client to parse device tree.
  * @get_io: function to be called by client to get io data.
  * @get_io_buf: function to be called by client to get io buffers.
@@ -227,6 +229,8 @@ struct dp_parser {
 	bool gpio_aux_switch;
 	bool lphw_hpd;
 	u32 mst_fixed_port[MAX_DP_MST_STREAMS];
+	u32 qos_cpu_mask;
+	unsigned long qos_cpu_latency;
 
 	int (*parse)(struct dp_parser *parser);
 	struct dp_io_data *(*get_io)(struct dp_parser *parser, char *name);