Skip to content

Commit b3f1b76

Browse files
Sowjanya Komatinenithierryreding
authored andcommitted
gpu: host1x: mipi: Split tegra_mipi_calibrate() and tegra_mipi_wait()
SW can trigger MIPI pads calibration any time after power on but calibration results will be latched and applied to the pads by MIPI CAL unit only when the link is in LP-11 state and then status register will be updated. For CSI, trigger of pads calibration happen during CSI stream enable where CSI receiver is kept ready prior to sensor or CSI transmitter stream start. So, pads may not be in LP-11 at this time and waiting for the calibration to be done immediate after calibration start will result in timeout. This patch splits tegra_mipi_calibrate() and tegra_mipi_wait() so triggering for calibration and waiting for it to complete can happen at different stages. Signed-off-by: Sowjanya Komatineni <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 7d14098 commit b3f1b76

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

drivers/gpu/drm/tegra/dsi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
670670
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
671671
{
672672
u32 value;
673+
int err;
673674

674675
/*
675676
* XXX Is this still needed? The module reset is deasserted right
@@ -693,7 +694,11 @@ static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
693694
DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
694695
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
695696

696-
return tegra_mipi_calibrate(dsi->mipi);
697+
err = tegra_mipi_calibrate(dsi->mipi);
698+
if (err < 0)
699+
return err;
700+
701+
return tegra_mipi_wait(dsi->mipi);
697702
}
698703

699704
static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,

drivers/gpu/host1x/mipi.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,29 @@ int tegra_mipi_disable(struct tegra_mipi_device *dev)
293293
}
294294
EXPORT_SYMBOL(tegra_mipi_disable);
295295

296-
static int tegra_mipi_wait(struct tegra_mipi *mipi)
296+
int tegra_mipi_wait(struct tegra_mipi_device *device)
297297
{
298+
struct tegra_mipi *mipi = device->mipi;
298299
void __iomem *status_reg = mipi->regs + (MIPI_CAL_STATUS << 2);
299300
u32 value;
300301
int err;
301302

303+
err = clk_enable(device->mipi->clk);
304+
if (err < 0)
305+
return err;
306+
307+
mutex_lock(&device->mipi->lock);
308+
302309
err = readl_relaxed_poll_timeout(status_reg, value,
303310
!(value & MIPI_CAL_STATUS_ACTIVE) &&
304311
(value & MIPI_CAL_STATUS_DONE), 50,
305312
250000);
313+
mutex_unlock(&device->mipi->lock);
314+
clk_disable(device->mipi->clk);
315+
306316
return err;
307317
}
318+
EXPORT_SYMBOL(tegra_mipi_wait);
308319

309320
int tegra_mipi_calibrate(struct tegra_mipi_device *device)
310321
{
@@ -370,12 +381,10 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device)
370381
value |= MIPI_CAL_CTRL_START;
371382
tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
372383

373-
err = tegra_mipi_wait(device->mipi);
374-
375384
mutex_unlock(&device->mipi->lock);
376385
clk_disable(device->mipi->clk);
377386

378-
return err;
387+
return 0;
379388
}
380389
EXPORT_SYMBOL(tegra_mipi_calibrate);
381390

include/linux/host1x.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,5 +334,6 @@ void tegra_mipi_free(struct tegra_mipi_device *device);
334334
int tegra_mipi_enable(struct tegra_mipi_device *device);
335335
int tegra_mipi_disable(struct tegra_mipi_device *device);
336336
int tegra_mipi_calibrate(struct tegra_mipi_device *device);
337+
int tegra_mipi_wait(struct tegra_mipi_device *device);
337338

338339
#endif

0 commit comments

Comments
 (0)