dc: bridge: maxim: remove GMSL lock worker thread

This change removes worker thread from serializer driver
which waits on both links to lock. If both links are not set
via DTS entry then it does not proceed further which causes
no video output.

As it is possible that one link can be connected to deserializer,
this does not require the worker to wait on link locks. So removing
worker thread and enabling video immediately fixes this issue.

bug 3727875

Change-Id: Ie427103a7d455201a4f783d690c6250b38a9113c
Signed-off-by: Prafull Suryawanshi <prafulls@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2775207
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Shu Zhong <shuz@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Prafull Suryawanshi
2022-09-12 16:04:43 +05:30
committed by Laxman Dewangan
parent 9d71b422fc
commit 36a425b6f7

View File

@@ -138,9 +138,6 @@ struct max_gmsl_dp_ser_priv {
u8 dprx_link_rate;
struct mutex mutex;
struct regmap *regmap;
struct work_struct work;
struct delayed_work delay_work;
struct workqueue_struct *wq;
int ser_errb;
unsigned int ser_irq;
bool enable_mst;
@@ -292,19 +289,6 @@ static bool max_gmsl_dp_ser_check_dups(u32 *ids)
return true;
}
static int max_gmsl_read_lock(struct max_gmsl_dp_ser_priv *priv,
u32 reg_addr, u32 mask,
u32 expected_value)
{
u8 reg_data;
reg_data = max_gmsl_dp_ser_read(priv, reg_addr);
if ((reg_data & mask) == expected_value)
return 0;
return -1;
}
static void max_gmsl_detect_internal_crc_error(struct max_gmsl_dp_ser_priv *priv,
struct device *dev)
{
@@ -373,77 +357,6 @@ static irqreturn_t max_gsml_dp_ser_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void tegra_poll_gmsl_training_lock(struct work_struct *work)
{
struct delayed_work *dwork = container_of(work,
struct delayed_work, work);
struct max_gmsl_dp_ser_priv *priv = container_of(dwork,
struct max_gmsl_dp_ser_priv, delay_work);
int ret = 0;
ret = max_gmsl_read_lock(priv, MAX_GMSL_DP_SER_CTRL3,
MAX_GMSL_DP_SER_CTRL3_LOCK_MASK,
MAX_GMSL_DP_SER_CTRL3_LOCK_VAL);
if (ret < 0) {
dev_dbg(&priv->client->dev, "GMSL Lock is not set\n");
goto reschedule;
}
if (priv->link_a_is_enabled) {
ret = max_gmsl_read_lock(priv, MAX_GMSL_DP_SER_LCTRL2_A,
MAX_GMSL_DP_SER_LCTRL2_LOCK_MASK,
MAX_GMSL_DP_SER_LCTRL2_LOCK_VAL);
if (ret < 0) {
dev_dbg(&priv->client->dev, "GMSL Lock set failed for Link A\n");
goto reschedule;
}
}
if (priv->link_b_is_enabled) {
ret = max_gmsl_read_lock(priv, MAX_GMSL_DP_SER_LCTRL2_B,
MAX_GMSL_DP_SER_LCTRL2_LOCK_MASK,
MAX_GMSL_DP_SER_LCTRL2_LOCK_VAL);
if (ret < 0) {
dev_dbg(&priv->client->dev, "GMSL Lock set failed for Link B\n");
goto reschedule;
}
}
ret = max_gmsl_read_lock(priv, MAX_GMSL_DP_SER_DPRX_TRAIN,
MAX_GMSL_DP_SER_DPRX_TRAIN_STATE_MASK,
MAX_GMSL_DP_SER_DPRX_TRAIN_STATE_VAL);
if (ret < 0) {
dev_dbg(&priv->client->dev,
"DP Link tranining hasn't completed\n");
goto reschedule;
}
/* enable internal CRC after link training */
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_X,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_Y,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_Z,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_U,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_X,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_Y,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_Z,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_U,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
return;
reschedule:
queue_delayed_work(priv->wq,
&priv->delay_work, msecs_to_jiffies(500));
}
static int max_gmsl_dp_ser_init(struct device *dev)
{
struct max_gmsl_dp_ser_priv *priv;
@@ -521,9 +434,6 @@ static int max_gmsl_dp_ser_init(struct device *dev)
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_LINK_ENABLE,
MAX_GMSL_DP_SER_LINK_ENABLE_MASK, 0x1);
queue_delayed_work(priv->wq, &priv->delay_work,
msecs_to_jiffies(500));
ret = max_gmsl_dp_ser_read(priv, MAX_GMSL_DP_SER_INTR9);
if (ret < 0) {
dev_err(dev, "%s: INTR9 register read failed\n", __func__);
@@ -544,6 +454,26 @@ static int max_gmsl_dp_ser_init(struct device *dev)
MAX_GMSL_DP_SER_INTR8_MASK,
MAX_GMSL_DP_SER_INTR8_VAL);
/* enable internal CRC after link training */
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_X,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_Y,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_Z,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
max_gmsl_dp_ser_write(priv, MAX_GMSL_DP_SER_INTERNAL_CRC_U,
MAX_GMSL_DP_SER_INTERNAL_CRC_ENABLE);
/* enable video output */
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_X,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_Y,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_Z,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
max_gmsl_dp_ser_update(priv, MAX_GMSL_DP_SER_VID_TX_U,
MAX_GMSL_DP_SER_VID_TX_MASK, 0x1);
return ret;
}
@@ -722,9 +652,6 @@ static int max_gmsl_dp_ser_probe(struct i2c_client *client)
return -EFAULT;
}
priv->wq = alloc_workqueue("tegra_poll_gmsl_training_lock", WQ_HIGHPRI, 0);
INIT_DELAYED_WORK(&priv->delay_work, tegra_poll_gmsl_training_lock);
ret = max_gmsl_dp_ser_init(&client->dev);
if (ret < 0) {
dev_err(dev, "%s: dp serializer init failed\n", __func__);