ソースを参照

disp: msm: dp: fix configuration of aux switches and HPD sources

Decouple the configuration and parsing of aux switches with the
parsing and configuration of HPD sources. HPD notification can come from
either GPIO based approach or a PD module through a SW interface. The
presence of AUX switch on the board should have no bearing in deciding
which configuration for HPD detection is used. Update the implementation
to allow for flexibility in selecting any combination of the HPD source
and aux switches.

Change-Id: I96d558f1d88a359d523fae6dc746045393884d5a
Signed-off-by: Aravind Venkateswaran <[email protected]>
Signed-off-by: Rajkumar Subbiah <[email protected]>
Signed-off-by: Sandeep Gangadharaiah <[email protected]>
Aravind Venkateswaran 4 年 前
コミット
78c45e9d5d
9 ファイル変更64 行追加104 行削除
  1. 2 5
      msm/dp/dp_aux.c
  2. 7 3
      msm/dp/dp_display.c
  3. 10 8
      msm/dp/dp_gpio_hpd.c
  4. 29 30
      msm/dp/dp_hpd.c
  5. 11 8
      msm/dp/dp_lphw_hpd.c
  6. 1 24
      msm/dp/dp_parser.c
  7. 1 4
      msm/dp/dp_parser.h
  8. 1 21
      msm/dp/dp_power.c
  9. 2 1
      msm/dp/dp_usbpd.c

+ 2 - 5
msm/dp/dp_aux.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -762,10 +762,7 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
 	struct dp_aux_private *aux;
 	struct dp_aux *dp_aux;
 
-	if (!catalog || !parser ||
-			(!parser->no_aux_switch &&
-				!aux_switch &&
-				!parser->gpio_aux_switch)) {
+	if (!catalog || !parser) {
 		DP_ERR("invalid input\n");
 		rc = -ENODEV;
 		goto error;

+ 7 - 3
msm/dp/dp_display.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -195,6 +196,7 @@ struct dp_display_private {
 	struct work_struct attention_work;
 	struct mutex session_lock;
 	bool hdcp_delayed_off;
+	bool no_aux_switch;
 
 	u32 active_stream_cnt;
 	struct dp_mst mst;
@@ -1435,7 +1437,7 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
 		return -ENODEV;
 	}
 
-	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch
+	if (!dp->debug->sim_mode && !dp->no_aux_switch
 	    && !dp->parser->gpio_aux_switch && dp->aux_switch_node) {
 		rc = dp_display_init_aux_switch(dp);
 		if (rc)
@@ -1677,7 +1679,7 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
 	dp_display_state_remove(DP_STATE_CONFIGURED);
 	mutex_unlock(&dp->session_lock);
 
-	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch
+	if (!dp->debug->sim_mode && !dp->no_aux_switch
 	    && !dp->parser->gpio_aux_switch)
 		dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE);
 
@@ -2041,8 +2043,10 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
 	dp_core_revision = dp_catalog_get_dp_core_version(dp->catalog);
 
 	dp->aux_switch_node = of_parse_phandle(dp->pdev->dev.of_node, phandle, 0);
-	if (!dp->aux_switch_node)
+	if (!dp->aux_switch_node) {
 		DP_DEBUG("cannot parse %s handle\n", phandle);
+		dp->no_aux_switch = true;
+	}
 
 	dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser,
 			dp->aux_switch_node, dp->aux_bridge);

+ 10 - 8
msm/dp/dp_gpio_hpd.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
@@ -218,6 +219,7 @@ struct dp_hpd *dp_gpio_hpd_get(struct device *dev,
 	const char *hpd_gpio_name = "qcom,dp-hpd-gpio";
 	struct dp_gpio_hpd_private *gpio_hpd;
 	struct dp_pinctrl pinctrl = {0};
+	unsigned int gpio;
 
 	if (!dev || !cb) {
 		DP_ERR("invalid device\n");
@@ -225,6 +227,13 @@ struct dp_hpd *dp_gpio_hpd_get(struct device *dev,
 		goto error;
 	}
 
+	gpio = of_get_named_gpio(dev->of_node, hpd_gpio_name, 0);
+	if (!gpio_is_valid(gpio)) {
+		DP_DEBUG("%s gpio not specified\n", hpd_gpio_name);
+		rc = -EINVAL;
+		goto error;
+	}
+
 	gpio_hpd = devm_kzalloc(dev, sizeof(*gpio_hpd), GFP_KERNEL);
 	if (!gpio_hpd) {
 		rc = -ENOMEM;
@@ -245,14 +254,7 @@ struct dp_hpd *dp_gpio_hpd_get(struct device *dev,
 		}
 	}
 
-	gpio_hpd->gpio_cfg.gpio = of_get_named_gpio(dev->of_node,
-		hpd_gpio_name, 0);
-	if (!gpio_is_valid(gpio_hpd->gpio_cfg.gpio)) {
-		DP_ERR("%s gpio not specified\n", hpd_gpio_name);
-		rc = -EINVAL;
-		goto gpio_error;
-	}
-
+	gpio_hpd->gpio_cfg.gpio = gpio;
 	strlcpy(gpio_hpd->gpio_cfg.gpio_name, hpd_gpio_name,
 		sizeof(gpio_hpd->gpio_cfg.gpio_name));
 	gpio_hpd->gpio_cfg.value = 0;

+ 29 - 30
msm/dp/dp_hpd.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -45,46 +46,43 @@ struct dp_hpd *dp_hpd_get(struct device *dev, struct dp_parser *parser,
 		struct dp_aux_bridge *aux_bridge,
 		struct dp_hpd_cb *cb)
 {
-	struct dp_hpd *dp_hpd;
+	struct dp_hpd *dp_hpd = NULL;
 
 	if (aux_bridge && (aux_bridge->flag & DP_AUX_BRIDGE_HPD)) {
 		dp_hpd = dp_bridge_hpd_get(dev, cb, aux_bridge);
-		if (IS_ERR(dp_hpd)) {
-			pr_err("failed to get bridge hpd\n");
-			return dp_hpd;
-		}
-		dp_hpd->type = DP_HPD_BRIDGE;
-	} else if (parser->no_aux_switch && parser->lphw_hpd) {
-		dp_hpd = dp_lphw_hpd_get(dev, parser, catalog, cb);
-		if (IS_ERR_OR_NULL(dp_hpd)) {
-			DP_ERR("failed to get lphw hpd\n");
-			return dp_hpd;
+		if (!IS_ERR(dp_hpd)) {
+			dp_hpd->type = DP_HPD_BRIDGE;
+			goto config;
 		}
+	}
+
+	dp_hpd = dp_lphw_hpd_get(dev, parser, catalog, cb);
+	if (!IS_ERR_OR_NULL(dp_hpd)) {
 		dp_hpd->type = DP_HPD_LPHW;
-	} else if (parser->no_aux_switch) {
-		dp_hpd = dp_gpio_hpd_get(dev, cb);
-		if (IS_ERR_OR_NULL(dp_hpd)) {
-			DP_ERR("failed to get gpio hpd\n");
-			return dp_hpd;
-		}
+		goto config;
+	}
+
+	dp_hpd = dp_gpio_hpd_get(dev, cb);
+	if (!IS_ERR_OR_NULL(dp_hpd)) {
 		dp_hpd->type = DP_HPD_GPIO;
-	} else {
-		dp_hpd = dp_altmode_get(dev, cb);
-		if (!IS_ERR_OR_NULL(dp_hpd)) {
-			dp_hpd->type = DP_HPD_ALTMODE;
-			goto config;
-		}
-		DP_WARN("dp_altmode failed (%ld), falling back to dp_usbpd\n",
-				PTR_ERR(dp_hpd));
+		goto config;
+	}
 
-		dp_hpd = dp_usbpd_get(dev, cb);
-		if (IS_ERR_OR_NULL(dp_hpd)) {
-			DP_ERR("failed to get usbpd\n");
-			return dp_hpd;
-		}
+	dp_hpd = dp_altmode_get(dev, cb);
+	if (!IS_ERR_OR_NULL(dp_hpd)) {
+		dp_hpd->type = DP_HPD_ALTMODE;
+		goto config;
+	}
+
+	dp_hpd = dp_usbpd_get(dev, cb);
+	if (!IS_ERR_OR_NULL(dp_hpd)) {
 		dp_hpd->type = DP_HPD_USBPD;
+		goto config;
 	}
 
+	DP_ERR("Failed to detect HPD type\n");
+	goto end;
+
 config:
 	if (!dp_hpd->host_init)
 		dp_hpd->host_init	= dp_hpd_host_init;
@@ -93,6 +91,7 @@ config:
 	if (!dp_hpd->isr)
 		dp_hpd->isr		= dp_hpd_isr;
 
+end:
 	return dp_hpd;
 }
 

+ 11 - 8
msm/dp/dp_lphw_hpd.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  */
 
@@ -320,6 +321,7 @@ static void dp_lphw_hpd_init(struct dp_lphw_hpd_private *lphw_hpd)
 			if (rc)
 				DP_ERR("failed to set hpd_active state\n");
 		}
+		pinctrl.state_hpd_tlmm = pinctrl.state_hpd_ctrl = NULL;
 	}
 }
 
@@ -344,6 +346,7 @@ struct dp_hpd *dp_lphw_hpd_get(struct device *dev, struct dp_parser *parser,
 	int rc = 0;
 	const char *hpd_gpio_name = "qcom,dp-hpd-gpio";
 	struct dp_lphw_hpd_private *lphw_hpd;
+	unsigned int gpio;
 
 	if (!dev || !parser || !cb) {
 		DP_ERR("invalid device\n");
@@ -351,20 +354,20 @@ struct dp_hpd *dp_lphw_hpd_get(struct device *dev, struct dp_parser *parser,
 		goto error;
 	}
 
+	gpio = of_get_named_gpio(dev->of_node, hpd_gpio_name, 0);
+	if (!gpio_is_valid(gpio)) {
+		DP_DEBUG("%s gpio not specified\n", hpd_gpio_name);
+		rc = -EINVAL;
+		goto gpio_error;
+	}
+
 	lphw_hpd = devm_kzalloc(dev, sizeof(*lphw_hpd), GFP_KERNEL);
 	if (!lphw_hpd) {
 		rc = -ENOMEM;
 		goto error;
 	}
 
-	lphw_hpd->gpio_cfg.gpio = of_get_named_gpio(dev->of_node,
-		hpd_gpio_name, 0);
-	if (!gpio_is_valid(lphw_hpd->gpio_cfg.gpio)) {
-		DP_ERR("%s gpio not specified\n", hpd_gpio_name);
-		rc = -EINVAL;
-		goto gpio_error;
-	}
-
+	lphw_hpd->gpio_cfg.gpio = gpio;
 	strlcpy(lphw_hpd->gpio_cfg.gpio_name, hpd_gpio_name,
 		sizeof(lphw_hpd->gpio_cfg.gpio_name));
 	lphw_hpd->gpio_cfg.value = 0;

+ 1 - 24
msm/dp/dp_parser.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -205,23 +206,6 @@ static int dp_parser_pinctrl(struct dp_parser *parser)
 		goto error;
 	}
 
-	if (parser->no_aux_switch && parser->lphw_hpd) {
-		pinctrl->state_hpd_tlmm = pinctrl->state_hpd_ctrl = NULL;
-
-		pinctrl->state_hpd_tlmm = pinctrl_lookup_state(pinctrl->pin,
-					"mdss_dp_hpd_tlmm");
-		if (!IS_ERR_OR_NULL(pinctrl->state_hpd_tlmm)) {
-			pinctrl->state_hpd_ctrl = pinctrl_lookup_state(
-				pinctrl->pin, "mdss_dp_hpd_ctrl");
-		}
-
-		if (!pinctrl->state_hpd_tlmm || !pinctrl->state_hpd_ctrl) {
-			pinctrl->state_hpd_tlmm = NULL;
-			pinctrl->state_hpd_ctrl = NULL;
-			DP_DEBUG("tlmm or ctrl pinctrl state does not exist\n");
-		}
-	}
-
 	pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin,
 					"mdss_dp_active");
 	if (IS_ERR_OR_NULL(pinctrl->state_active)) {
@@ -253,13 +237,6 @@ static int dp_parser_gpio(struct dp_parser *parser)
 		"qcom,usbplug-cc-gpio",
 	};
 
-	if (of_find_property(of_node, "qcom,dp-hpd-gpio", NULL)) {
-		parser->no_aux_switch = true;
-		parser->lphw_hpd = of_find_property(of_node,
-				"qcom,dp-low-power-hw-hpd", NULL);
-		return 0;
-	}
-
 	if (of_find_property(of_node, "qcom,dp-gpio-aux-switch", NULL))
 		parser->gpio_aux_switch = true;
 	mp->gpio_config = devm_kzalloc(dev,

+ 1 - 4
msm/dp/dp_parser.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -194,7 +194,6 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type)
  * @hw_cfg: DP HW specific settings
  * @has_mst: MST feature enable status
  * @has_mst_sideband: MST sideband feature enable status
- * @no_aux_switch: presence AUX switch status
  * @gpio_aux_switch: presence GPIO AUX switch status
  * @dsc_feature_enable: DSC feature enable status
  * @fec_feature_enable: FEC feature enable status
@@ -224,13 +223,11 @@ struct dp_parser {
 	struct dp_hw_cfg hw_cfg;
 	bool has_mst;
 	bool has_mst_sideband;
-	bool no_aux_switch;
 	bool dsc_feature_enable;
 	bool fec_feature_enable;
 	bool dsc_continuous_pps;
 	bool has_widebus;
 	bool gpio_aux_switch;
-	bool lphw_hpd;
 	u32 mst_fixed_port[MAX_DP_MST_STREAMS];
 	u32 qos_cpu_mask;
 	unsigned long qos_cpu_latency;

+ 1 - 21
msm/dp/dp_power.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -132,23 +132,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active)
 	if (IS_ERR_OR_NULL(parser->pinctrl.pin))
 		return 0;
 
-	if (parser->no_aux_switch && parser->lphw_hpd) {
-		pin_state = active ? parser->pinctrl.state_hpd_ctrl
-				: parser->pinctrl.state_hpd_tlmm;
-		if (!IS_ERR_OR_NULL(pin_state)) {
-			rc = pinctrl_select_state(parser->pinctrl.pin,
-				pin_state);
-			if (rc) {
-				DP_ERR("cannot direct hpd line to %s\n",
-					active ? "ctrl" : "tlmm");
-				return rc;
-			}
-		}
-	}
-
-	if (parser->no_aux_switch)
-		return 0;
-
 	pin_state = active ? parser->pinctrl.state_active
 				: parser->pinctrl.state_suspend;
 	if (!IS_ERR_OR_NULL(pin_state)) {
@@ -557,9 +540,6 @@ static int dp_power_config_gpios(struct dp_power_private *power, bool flip,
 	struct dss_module_power *mp;
 	struct dss_gpio *config;
 
-	if (power->parser->no_aux_switch)
-		return 0;
-
 	mp = &power->parser->mp[DP_CORE_PM];
 	config = mp->gpio_config;
 

+ 2 - 1
msm/dp/dp_usbpd.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
  */
 
@@ -538,7 +539,7 @@ struct dp_hpd *dp_usbpd_get(struct device *dev, struct dp_hpd_cb *cb)
 
 	pd = devm_usbpd_get_by_phandle(dev, pd_phandle);
 	if (IS_ERR(pd)) {
-		DP_ERR("usbpd phandle failed (%ld)\n", PTR_ERR(pd));
+		DP_DEBUG("usbpd phandle failed (%ld)\n", PTR_ERR(pd));
 		rc = PTR_ERR(pd);
 		goto error;
 	}