mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
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:
committed by
Laxman Dewangan
parent
9d71b422fc
commit
36a425b6f7
@@ -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__);
|
||||
|
||||
Reference in New Issue
Block a user