From 4a2e5b3fe16b6810a5b285b89e7bd4e24d027f57 Mon Sep 17 00:00:00 2001 From: Nisarg Bhavsar Date: Fri, 28 Oct 2022 12:08:29 -0700 Subject: [PATCH] disp: msm: dp: Add abstract and wcd939x aux switch support Add functionality to change which aux switch is used at compile time for different targets. Add wcd939x switch support. Change-Id: Iced3b11733009680063790dfa8f180b19002f963 Signed-off-by: Nisarg Bhavsar --- config/gki_kalamadisp.conf | 1 + config/gki_kalamadispconf.h | 1 + msm/dp/dp_aux.c | 75 +++++++++++++++++++++++++++++++++++-- msm/dp/dp_aux.h | 7 ++-- msm/dp/dp_display.c | 25 +++++++------ 5 files changed, 92 insertions(+), 17 deletions(-) diff --git a/config/gki_kalamadisp.conf b/config/gki_kalamadisp.conf index 5646573683..5058638bb9 100644 --- a/config/gki_kalamadisp.conf +++ b/config/gki_kalamadisp.conf @@ -15,3 +15,4 @@ export CONFIG_HDCP_QSEECOM=y export CONFIG_DRM_SDE_VM=y export CONFIG_QTI_HW_FENCE=y export CONFIG_QCOM_SPEC_SYNC=y +export CONFIG_QCOM_FSA4480_I2C=y diff --git a/config/gki_kalamadispconf.h b/config/gki_kalamadispconf.h index 5b5bfbce01..f88dec0db1 100644 --- a/config/gki_kalamadispconf.h +++ b/config/gki_kalamadispconf.h @@ -23,3 +23,4 @@ #define CONFIG_DRM_SDE_VM 1 #define CONFIG_QTI_HW_FENCE 1 #define CONFIG_QCOM_SPEC_SYNC 1 +#define CONFIG_QCOM_FSA4480_I2C 1 diff --git a/msm/dp/dp_aux.c b/msm/dp/dp_aux.c index aad6f7183e..b31801b2ab 100644 --- a/msm/dp/dp_aux.c +++ b/msm/dp/dp_aux.c @@ -4,9 +4,14 @@ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ -#include #include +#if IS_ENABLED(CONFIG_QCOM_FSA4480_I2C) +#include +#elif IS_ENABLED(CONFIG_QCOM_WCD939X_I2C) +#include +#endif + #include "dp_aux.h" #include "dp_hpd.h" #include "dp_debug.h" @@ -755,7 +760,8 @@ static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, mutex_unlock(&aux->mutex); } -static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux, +#if IS_ENABLED(CONFIG_QCOM_FSA4480_I2C) +static int dp_aux_configure_fsa_switch(struct dp_aux *dp_aux, bool enable, int orientation) { struct dp_aux_private *aux; @@ -795,11 +801,65 @@ static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux, enable, orientation, event); rc = fsa4480_switch_event(aux->aux_switch_node, event); + if (rc) DP_AUX_ERR(dp_aux, "failed to configure fsa4480 i2c device (%d)\n", rc); end: return rc; } +#endif + +#if IS_ENABLED(CONFIG_QCOM_WCD939X_I2C) +static int dp_aux_configure_wcd_switch(struct dp_aux *dp_aux, + bool enable, int orientation) +{ + struct dp_aux_private *aux; + int rc = 0; + enum wcd_usbss_cable_status status = WCD_USBSS_CABLE_DISCONNECT; + enum wcd_usbss_cable_types event = WCD_USBSS_DP_AUX_CC1; + + if (!dp_aux) { + DP_AUX_ERR(dp_aux, "invalid input\n"); + rc = -EINVAL; + goto end; + } + + aux = container_of(dp_aux, struct dp_aux_private, dp_aux); + + if (!aux->aux_switch_node) { + DP_AUX_DEBUG(dp_aux, "undefined wcd939x switch handle\n"); + rc = -EINVAL; + goto end; + } + + if (enable) { + status = WCD_USBSS_CABLE_CONNECT; + + switch (orientation) { + case ORIENTATION_CC1: + event = WCD_USBSS_DP_AUX_CC1; + break; + case ORIENTATION_CC2: + event = WCD_USBSS_DP_AUX_CC2; + break; + default: + DP_AUX_ERR(dp_aux, "invalid orientation\n"); + rc = -EINVAL; + goto end; + } + } + + DP_AUX_DEBUG(dp_aux, "enable=%d, orientation=%d, event=%d\n", + enable, orientation, event); + + rc = wcd_usbss_switch_update(event, status); + + if (rc) + DP_AUX_ERR(dp_aux, "failed to configure wcd939x i2c device (%d)\n", rc); +end: + return rc; +} +#endif struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog, struct dp_parser *parser, struct device_node *aux_switch, @@ -841,7 +901,16 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog, dp_aux->reconfig = dp_aux_reconfig; dp_aux->abort = dp_aux_abort_transaction; dp_aux->set_sim_mode = dp_aux_set_sim_mode; - dp_aux->aux_switch = dp_aux_configure_aux_switch; + +#if IS_ENABLED(CONFIG_QCOM_FSA4480_I2C) + dp_aux->switch_configure = dp_aux_configure_fsa_switch; + dp_aux->switch_register_notifier = fsa4480_reg_notifier; + dp_aux->switch_unregister_notifier = fsa4480_unreg_notifier; +#elif IS_ENABLED(CONFIG_QCOM_WCD939X_I2C) + dp_aux->switch_configure = dp_aux_configure_wcd_switch; + dp_aux->switch_register_notifier = wcd_usbss_reg_notifier; + dp_aux->switch_unregister_notifier = wcd_usbss_unreg_notifier; +#endif return dp_aux; error: diff --git a/msm/dp/dp_aux.h b/msm/dp/dp_aux.h index 512254aa4d..314cb79fec 100644 --- a/msm/dp/dp_aux.h +++ b/msm/dp/dp_aux.h @@ -56,9 +56,10 @@ struct dp_aux { void (*deinit)(struct dp_aux *aux); void (*reconfig)(struct dp_aux *aux); void (*abort)(struct dp_aux *aux, bool abort); - void (*set_sim_mode)(struct dp_aux *aux, - struct dp_aux_bridge *sim_bridge); - int (*aux_switch)(struct dp_aux *aux, bool enable, int orientation); + void (*set_sim_mode)(struct dp_aux *aux, struct dp_aux_bridge *sim_bridge); + int (*switch_configure)(struct dp_aux *aux, bool enable, int orientation); + int (*switch_register_notifier)(struct notifier_block *nb, struct device_node *node); + int (*switch_unregister_notifier)(struct notifier_block *nb, struct device_node *node); }; struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog, diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index f5d05f09bc..a2fc200877 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -1221,8 +1220,8 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->debug->max_pclk_khz); if (!dp->debug->sim_mode && !dp->no_aux_switch && !dp->parser->gpio_aux_switch - && dp->aux_switch_node) { - rc = dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation); + && dp->aux_switch_node && dp->aux->switch_configure) { + rc = dp->aux->switch_configure(dp->aux, true, dp->hpd->orientation); if (rc) { mutex_unlock(&dp->session_lock); return rc; @@ -1400,7 +1399,7 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp, bool skip_w return rc; } -static int dp_display_fsa4480_callback(struct notifier_block *self, +static int dp_display_aux_switch_callback(struct notifier_block *self, unsigned long event, void *data) { return 0; @@ -1416,9 +1415,12 @@ static int dp_display_init_aux_switch(struct dp_display_private *dp) if (dp->aux_switch_ready) return rc; + if (!dp->aux->switch_register_notifier) + return rc; + SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY); - nb.notifier_call = dp_display_fsa4480_callback; + nb.notifier_call = dp_display_aux_switch_callback; nb.priority = 0; /* @@ -1426,7 +1428,7 @@ static int dp_display_init_aux_switch(struct dp_display_private *dp) * Bootup DP with cable connected usecase can hit this scenario. */ for (retry = 0; retry < max_retries; retry++) { - rc = fsa4480_reg_notifier(&nb, dp->aux_switch_node); + rc = dp->aux->switch_register_notifier(&nb, dp->aux_switch_node); if (rc == 0) { DP_DEBUG("registered notifier successfully\n"); dp->aux_switch_ready = true; @@ -1443,7 +1445,8 @@ static int dp_display_init_aux_switch(struct dp_display_private *dp) return rc; } - fsa4480_unreg_notifier(&nb, dp->aux_switch_node); + if (dp->aux->switch_unregister_notifier) + dp->aux->switch_unregister_notifier(&nb, dp->aux_switch_node); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, rc); return rc; @@ -1466,12 +1469,12 @@ static int dp_display_usbpd_configure_cb(struct device *dev) } if (!dp->debug->sim_mode && !dp->no_aux_switch - && !dp->parser->gpio_aux_switch && dp->aux_switch_node) { + && !dp->parser->gpio_aux_switch && dp->aux_switch_node && dp->aux->switch_configure) { rc = dp_display_init_aux_switch(dp); if (rc) return rc; - rc = dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation); + rc = dp->aux->switch_configure(dp->aux, true, dp->hpd->orientation); if (rc) return rc; } @@ -1656,8 +1659,8 @@ static void dp_display_disconnect_sync(struct dp_display_private *dp) flush_workqueue(dp->wq); if (!dp->debug->sim_mode && !dp->no_aux_switch - && !dp->parser->gpio_aux_switch) - dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE); + && !dp->parser->gpio_aux_switch && dp->aux->switch_configure) + dp->aux->switch_configure(dp->aux, false, ORIENTATION_NONE); /* * Delay the teardown of the mainlink for better interop experience.