Merge changes If50226c5,Iafbee4d9,Iced3b117 into display-kernel.lnx.5.15.r1-rel
* changes: disp: config: add support for fsa and wcd aux switch for crow target disp: msm: dp: Parse device tree to find specific aux switch disp: msm: dp: Add abstract and wcd939x aux switch support
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
155e704e54
@@ -14,3 +14,5 @@ export CONFIG_DISPLAY_BUILD=m
|
||||
export CONFIG_HDCP_QSEECOM=y
|
||||
export CONFIG_DRM_SDE_VM=y
|
||||
export CONFIG_QCOM_SPEC_SYNC=y
|
||||
export CONFIG_QCOM_WCD939X_I2C=y
|
||||
export CONFIG_QCOM_FSA4480_I2C=y
|
||||
|
||||
@@ -20,3 +20,5 @@
|
||||
#define CONFIG_HDCP_QSEECOM 1
|
||||
#define CONFIG_DRM_SDE_VM 1
|
||||
#define CONFIG_QCOM_SPEC_SYNC 1
|
||||
#define CONFIG_QCOM_WCD939X_I2C 1
|
||||
#define CONFIG_QCOM_FSA4480_I2C 1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
// 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) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/soc/qcom/fsa4480-i2c.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_FSA4480_I2C)
|
||||
#include <linux/soc/qcom/fsa4480-i2c.h>
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_QCOM_WCD939X_I2C)
|
||||
#include <linux/soc/qcom/wcd939x-i2c.h>
|
||||
#endif
|
||||
|
||||
#include "dp_aux.h"
|
||||
#include "dp_hpd.h"
|
||||
#include "dp_debug.h"
|
||||
@@ -755,7 +761,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,15 +802,69 @@ 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,
|
||||
struct dp_aux_bridge *aux_bridge)
|
||||
struct dp_aux_bridge *aux_bridge, enum dp_aux_switch_type switch_type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dp_aux_private *aux;
|
||||
@@ -841,7 +902,24 @@ 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;
|
||||
|
||||
/*Condition to avoid allocating function pointers for aux bypass mode*/
|
||||
if (switch_type != DP_AUX_SWITCH_BYPASS) {
|
||||
#if IS_ENABLED(CONFIG_QCOM_FSA4480_I2C)
|
||||
if (switch_type == DP_AUX_SWITCH_FSA4480) {
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_QCOM_WCD939X_I2C)
|
||||
if (switch_type == DP_AUX_SWITCH_WCD939x) {
|
||||
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:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
#define DP_STATE_AUX_TIMEOUT BIT(12)
|
||||
#define DP_STATE_PLL_LOCKED BIT(13)
|
||||
|
||||
enum dp_aux_switch_type {
|
||||
DP_AUX_SWITCH_BYPASS,
|
||||
DP_AUX_SWITCH_FSA4480,
|
||||
DP_AUX_SWITCH_WCD939x,
|
||||
};
|
||||
|
||||
enum dp_aux_error {
|
||||
DP_AUX_ERR_NONE = 0,
|
||||
DP_AUX_ERR_ADDR = -1,
|
||||
@@ -52,14 +58,15 @@ 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,
|
||||
struct dp_parser *parser, struct device_node *aux_switch,
|
||||
struct dp_aux_bridge *aux_bridge);
|
||||
struct dp_aux_bridge *aux_bridge, enum dp_aux_switch_type switch_type);
|
||||
void dp_aux_put(struct dp_aux *aux);
|
||||
|
||||
#endif /*__DP_AUX_H_*/
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <linux/component.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/soc/qcom/fsa4480-i2c.h>
|
||||
#include <linux/usb/phy.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/pm_qos.h>
|
||||
@@ -169,6 +168,7 @@ struct dp_display_private {
|
||||
|
||||
enum drm_connector_status cached_connector_status;
|
||||
enum dp_display_states state;
|
||||
enum dp_aux_switch_type switch_type;
|
||||
|
||||
struct platform_device *pdev;
|
||||
struct device_node *aux_switch_node;
|
||||
@@ -1221,8 +1221,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 +1400,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 +1416,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 +1429,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 +1446,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 +1470,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;
|
||||
}
|
||||
@@ -1709,8 +1713,8 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
|
||||
dp->aux->abort(dp->aux, true);
|
||||
|
||||
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);
|
||||
|
||||
dp_display_disconnect_sync(dp);
|
||||
|
||||
@@ -2158,8 +2162,15 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
|
||||
dp->no_aux_switch = true;
|
||||
}
|
||||
|
||||
if (!strcmp(dp->aux_switch_node->name, "fsa4480"))
|
||||
dp->switch_type = DP_AUX_SWITCH_FSA4480;
|
||||
else if (!strcmp(dp->aux_switch_node->name, "wcd939x_i2c"))
|
||||
dp->switch_type = DP_AUX_SWITCH_WCD939x;
|
||||
else
|
||||
dp->switch_type = DP_AUX_SWITCH_BYPASS;
|
||||
|
||||
dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser,
|
||||
dp->aux_switch_node, dp->aux_bridge);
|
||||
dp->aux_switch_node, dp->aux_bridge, dp->switch_type);
|
||||
if (IS_ERR(dp->aux)) {
|
||||
rc = PTR_ERR(dp->aux);
|
||||
DP_ERR("failed to initialize aux, rc = %d\n", rc);
|
||||
|
||||
Reference in New Issue
Block a user