#define SN_NUM_GPIOS 4
#define SN_GPIO_PHYSICAL_OFFSET 1
+#define SN_LINK_TRAINING_TRIES 10
+
/**
* struct ti_sn_bridge - Platform data for ti-sn65dsi86 driver.
* @dev: Pointer to our device.
{
unsigned int val;
int ret;
+ int i;
/* set dp clk frequency value */
regmap_update_bits(pdata->regmap, SN_DATARATE_CONFIG_REG,
goto exit;
}
- /* Semi auto link training mode */
- regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0x0A);
- ret = regmap_read_poll_timeout(pdata->regmap, SN_ML_TX_MODE_REG, val,
- val == ML_TX_MAIN_LINK_OFF ||
- val == ML_TX_NORMAL_MODE, 1000,
- 500 * 1000);
- if (ret) {
- *last_err_str = "Training complete polling failed";
- } else if (val == ML_TX_MAIN_LINK_OFF) {
- *last_err_str = "Link training failed, link is off";
- ret = -EIO;
+ /*
+ * We'll try to link train several times. As part of link training
+ * the bridge chip will write DP_SET_POWER_D0 to DP_SET_POWER. If
+ * the panel isn't ready quite it might respond NAK here which means
+ * we need to try again.
+ */
+ for (i = 0; i < SN_LINK_TRAINING_TRIES; i++) {
+ /* Semi auto link training mode */
+ regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0x0A);
+ ret = regmap_read_poll_timeout(pdata->regmap, SN_ML_TX_MODE_REG, val,
+ val == ML_TX_MAIN_LINK_OFF ||
+ val == ML_TX_NORMAL_MODE, 1000,
+ 500 * 1000);
+ if (ret) {
+ *last_err_str = "Training complete polling failed";
+ } else if (val == ML_TX_MAIN_LINK_OFF) {
+ *last_err_str = "Link training failed, link is off";
+ ret = -EIO;
+ continue;
+ }
+
+ break;
}
+ /* If we saw quite a few retries, add a note about it */
+ if (!ret && i > SN_LINK_TRAINING_TRIES / 2)
+ DRM_DEV_INFO(pdata->dev, "Link training needed %d retries\n", i);
+
exit:
/* Disable the PLL if we failed */
if (ret)