Skip to content

Commit 9330573

Browse files
committed
[WIP] grate: dsi: add T30 support
Signed-off-by: Svyatoslav Ryhel <[email protected]>
1 parent cb2c72e commit 9330573

File tree

4 files changed

+140
-23
lines changed

4 files changed

+140
-23
lines changed

arch/arm/boot/dts/nvidia/tegra30.dtsi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@
321321
clock-names = "dsi", "parent";
322322
resets = <&tegra_car 48>;
323323
reset-names = "dsi";
324+
nvidia,mipi-calibrate = <&mipi 0x220>;
324325
power-domains = <&pd_core>;
325326
operating-points-v2 = <&dsia_dvfs_opp_table>;
326327
status = "disabled";
@@ -337,6 +338,7 @@
337338
clock-names = "dsi", "parent";
338339
resets = <&tegra_car 84>;
339340
reset-names = "dsi";
341+
nvidia,mipi-calibrate = <&mipi 0x220>;
340342
power-domains = <&pd_core>;
341343
operating-points-v2 = <&dsib_dvfs_opp_table>;
342344
status = "disabled";
@@ -373,6 +375,15 @@
373375
cache-level = <2>;
374376
};
375377

378+
mipi: mipi@54080000 {
379+
compatible = "nvidia,tegra30-mipi";
380+
reg = <0x54080000 0x00040000>;
381+
clocks = <&tegra_car TEGRA30_CLK_VI>,
382+
<&tegra_car TEGRA30_CLK_CSI>;
383+
clock-names = "vi", "csi";
384+
#nvidia,mipi-calibrate-cells = <1>;
385+
};
386+
376387
lic: interrupt-controller@60004000 {
377388
compatible = "nvidia,tegra30-ictlr";
378389
reg = <0x60004000 0x100>,

drivers/gpu/drm/grate/dsi.c

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -661,39 +661,47 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
661661
{
662662
u32 value;
663663

664-
value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
665-
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
664+
if (of_device_is_compatible(dsi->dev->of_node, "nvidia,tegra30-dsi")) {
665+
dev_info(dsi->dev, "T30 start pad and mipi calibration\n");
666+
value = DSI_PAD_CONTROL_LPUPADJ(0x1) | DSI_PAD_CONTROL_LPDNADJ(0x1) |
667+
DSI_PAD_CONTROL_PREEMP_EN(0x1) | DSI_PAD_CONTROL_SLEWDNADJ(0x6) |
668+
DSI_PAD_CONTROL_SLEWUPADJ(0x6) | DSI_PAD_CONTROL_PDIO(0) |
669+
DSI_PAD_CONTROL_PDIO_CLK(0) | DSI_PAD_CONTROL_PULLDN_ENAB(0);
670+
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
671+
} else {
672+
/*
673+
* XXX Is this still needed? The module reset is deasserted right
674+
* before this function is called.
675+
*/
676+
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
677+
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
678+
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
679+
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
680+
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);
681+
682+
value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
683+
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
684+
685+
value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
686+
DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
687+
DSI_PAD_OUT_CLK(0x0);
688+
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);
689+
690+
value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
691+
DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
692+
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
693+
}
666694

667695
return 0;
668696
}
669697

670698
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
671699
{
672-
u32 value;
673700
int err;
674701

675-
/*
676-
* XXX Is this still needed? The module reset is deasserted right
677-
* before this function is called.
678-
*/
679-
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
680-
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
681-
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
682-
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
683-
tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);
684-
685702
/* start calibration */
686703
tegra_dsi_pad_enable(dsi);
687704

688-
value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
689-
DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
690-
DSI_PAD_OUT_CLK(0x0);
691-
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);
692-
693-
value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
694-
DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
695-
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
696-
697705
err = tegra_mipi_start_calibration(dsi->mipi);
698706
if (err < 0)
699707
return err;
@@ -1608,7 +1616,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
16081616
return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
16091617
"cannot get DSI clock\n");
16101618

1611-
dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
1619+
dsi->clk_lp = devm_clk_get_optional(&pdev->dev, "lp");
16121620
if (IS_ERR(dsi->clk_lp))
16131621
return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
16141622
"cannot get low-power clock\n");

drivers/gpu/drm/grate/dsi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@
9595
#define DSI_TALLY_LRX(x) (((x) & 0xff) << 8)
9696
#define DSI_TALLY_HTX(x) (((x) & 0xff) << 0)
9797
#define DSI_PAD_CONTROL_0 0x4b
98+
/* T30 */
99+
#define DSI_PAD_CONTROL_PULLDN_ENAB(x) (((x) & 0x1) << 28)
100+
#define DSI_PAD_CONTROL_SLEWUPADJ(x) (((x) & 0x7) << 24)
101+
#define DSI_PAD_CONTROL_SLEWDNADJ(x) (((x) & 0x7) << 20)
102+
#define DSI_PAD_CONTROL_PREEMP_EN(x) (((x) & 0x1) << 19)
103+
#define DSI_PAD_CONTROL_PDIO_CLK(x) (((x) & 0x1) << 18)
104+
#define DSI_PAD_CONTROL_PDIO(x) (((x) & 0x3) << 16)
105+
#define DSI_PAD_CONTROL_LPUPADJ(x) (((x) & 0x3) << 14)
106+
#define DSI_PAD_CONTROL_LPDNADJ(x) (((x) & 0x3) << 12)
107+
/* T114+ */
98108
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
99109
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
100110
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)

drivers/gpu/host1x-grate/mipi.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@
5959
#define MIPI_CAL_CONFIG_DSID_CLK 0x1d
6060
#define MIPI_CAL_CONFIG_CSIE_CLK 0x1d
6161

62+
/* T30 DSI V0 controller */
63+
#define CSI_CIL_PAD_CONFIG0 0x09
64+
#define CSI_CILA_MIPI_CAL_CONFIG 0x0a
65+
#define CSI_CILB_MIPI_CAL_CONFIG 0x0b
66+
#define CSI_DSI_MIPI_CAL_CONFIG 0x14
67+
#define CSI_MIPIBIAS_PAD_CONFIG0 0x15
68+
6269
/* for data and clock lanes */
6370
#define MIPI_CAL_CONFIG_SELECT (1 << 21)
6471

@@ -90,6 +97,8 @@ struct tegra_mipi_pad {
9097
};
9198

9299
struct tegra_mipi_soc {
100+
bool dsi_v0;
101+
93102
bool has_clk_lane;
94103
const struct tegra_mipi_pad *pads;
95104
unsigned int num_pads;
@@ -120,6 +129,7 @@ struct tegra_mipi {
120129
void __iomem *regs;
121130
struct mutex lock;
122131
struct clk *clk;
132+
struct clk *csi_clk;
123133

124134
unsigned long usage_count;
125135
};
@@ -263,6 +273,9 @@ int tegra_mipi_enable(struct tegra_mipi_device *dev)
263273
{
264274
int err = 0;
265275

276+
if (dev->mipi->soc->dsi_v0)
277+
return err;
278+
266279
mutex_lock(&dev->mipi->lock);
267280

268281
if (dev->mipi->usage_count++ == 0)
@@ -279,6 +292,9 @@ int tegra_mipi_disable(struct tegra_mipi_device *dev)
279292
{
280293
int err = 0;
281294

295+
if (dev->mipi->soc->dsi_v0)
296+
return err;
297+
282298
mutex_lock(&dev->mipi->lock);
283299

284300
if (--dev->mipi->usage_count == 0)
@@ -298,6 +314,9 @@ int tegra_mipi_finish_calibration(struct tegra_mipi_device *device)
298314
u32 value;
299315
int err;
300316

317+
if (mipi->soc->dsi_v0)
318+
return 0;
319+
301320
err = readl_relaxed_poll_timeout(status_reg, value,
302321
!(value & MIPI_CAL_STATUS_ACTIVE) &&
303322
(value & MIPI_CAL_STATUS_DONE), 50,
@@ -309,6 +328,43 @@ int tegra_mipi_finish_calibration(struct tegra_mipi_device *device)
309328
}
310329
EXPORT_SYMBOL(tegra_mipi_finish_calibration);
311330

331+
static int tegra30_mipi_calibration(struct tegra_mipi_device *device)
332+
{
333+
struct tegra_mipi *mipi = device->mipi;
334+
const struct tegra_mipi_soc *soc = mipi->soc;
335+
u32 value;
336+
int err;
337+
338+
err = clk_enable(device->mipi->csi_clk);
339+
if (err < 0)
340+
return err;
341+
342+
mutex_lock(&device->mipi->lock);
343+
344+
value = MIPI_CAL_CONFIG_TERMOS(soc->termos);
345+
tegra_mipi_writel(device->mipi, value, CSI_CILA_MIPI_CAL_CONFIG);
346+
347+
value = MIPI_CAL_CONFIG_TERMOS(soc->termos);
348+
tegra_mipi_writel(device->mipi, value, CSI_CILB_MIPI_CAL_CONFIG);
349+
350+
value = MIPI_CAL_CONFIG_HSPDOS(soc->hspdos) |
351+
MIPI_CAL_CONFIG_HSPUOS(soc->hspuos);
352+
tegra_mipi_writel(device->mipi, value, CSI_DSI_MIPI_CAL_CONFIG);
353+
354+
value = MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc->pad_drive_down_ref) |
355+
MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc->pad_drive_up_ref);
356+
tegra_mipi_writel(device->mipi, value, CSI_MIPIBIAS_PAD_CONFIG0);
357+
358+
tegra_mipi_writel(device->mipi, 0x0, CSI_CIL_PAD_CONFIG0);
359+
360+
mutex_unlock(&device->mipi->lock);
361+
362+
clk_disable(device->mipi->csi_clk);
363+
clk_disable(device->mipi->clk);
364+
365+
return 0;
366+
}
367+
312368
int tegra_mipi_start_calibration(struct tegra_mipi_device *device)
313369
{
314370
const struct tegra_mipi_soc *soc = device->mipi->soc;
@@ -320,6 +376,9 @@ int tegra_mipi_start_calibration(struct tegra_mipi_device *device)
320376
if (err < 0)
321377
return err;
322378

379+
if (device->mipi->soc->dsi_v0)
380+
return tegra30_mipi_calibration(device);
381+
323382
mutex_lock(&device->mipi->lock);
324383

325384
value = MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc->pad_drive_down_ref) |
@@ -384,6 +443,15 @@ int tegra_mipi_start_calibration(struct tegra_mipi_device *device)
384443
}
385444
EXPORT_SYMBOL(tegra_mipi_start_calibration);
386445

446+
static const struct tegra_mipi_soc tegra30_mipi_soc = {
447+
.dsi_v0 = true,
448+
.pad_drive_down_ref = 0x5,
449+
.pad_drive_up_ref = 0x7,
450+
.hspdos = 0x4,
451+
.hspuos = 0x3,
452+
.termos = 0x4,
453+
};
454+
387455
static const struct tegra_mipi_pad tegra114_mipi_pads[] = {
388456
{ .data = MIPI_CAL_CONFIG_CSIA },
389457
{ .data = MIPI_CAL_CONFIG_CSIB },
@@ -397,6 +465,7 @@ static const struct tegra_mipi_pad tegra114_mipi_pads[] = {
397465
};
398466

399467
static const struct tegra_mipi_soc tegra114_mipi_soc = {
468+
.dsi_v0 = false,
400469
.has_clk_lane = false,
401470
.pads = tegra114_mipi_pads,
402471
.num_pads = ARRAY_SIZE(tegra114_mipi_pads),
@@ -424,6 +493,7 @@ static const struct tegra_mipi_pad tegra124_mipi_pads[] = {
424493
};
425494

426495
static const struct tegra_mipi_soc tegra124_mipi_soc = {
496+
.dsi_v0 = false,
427497
.has_clk_lane = true,
428498
.pads = tegra124_mipi_pads,
429499
.num_pads = ARRAY_SIZE(tegra124_mipi_pads),
@@ -441,6 +511,7 @@ static const struct tegra_mipi_soc tegra124_mipi_soc = {
441511
};
442512

443513
static const struct tegra_mipi_soc tegra132_mipi_soc = {
514+
.dsi_v0 = false,
444515
.has_clk_lane = true,
445516
.pads = tegra124_mipi_pads,
446517
.num_pads = ARRAY_SIZE(tegra124_mipi_pads),
@@ -471,6 +542,7 @@ static const struct tegra_mipi_pad tegra210_mipi_pads[] = {
471542
};
472543

473544
static const struct tegra_mipi_soc tegra210_mipi_soc = {
545+
.dsi_v0 = false,
474546
.has_clk_lane = true,
475547
.pads = tegra210_mipi_pads,
476548
.num_pads = ARRAY_SIZE(tegra210_mipi_pads),
@@ -488,6 +560,7 @@ static const struct tegra_mipi_soc tegra210_mipi_soc = {
488560
};
489561

490562
static const struct of_device_id tegra_mipi_of_match[] = {
563+
{ .compatible = "nvidia,tegra30-mipi", .data = &tegra30_mipi_soc },
491564
{ .compatible = "nvidia,tegra114-mipi", .data = &tegra114_mipi_soc },
492565
{ .compatible = "nvidia,tegra124-mipi", .data = &tegra124_mipi_soc },
493566
{ .compatible = "nvidia,tegra132-mipi", .data = &tegra132_mipi_soc },
@@ -530,6 +603,18 @@ static int tegra_mipi_probe(struct platform_device *pdev)
530603
if (err < 0)
531604
return err;
532605

606+
if (mipi->soc->dsi_v0) {
607+
mipi->csi_clk = devm_clk_get(&pdev->dev, "csi");
608+
if (IS_ERR(mipi->csi_clk)) {
609+
dev_err(&pdev->dev, "failed to get CSI clock\n");
610+
return PTR_ERR(mipi->csi_clk);
611+
}
612+
613+
err = clk_prepare(mipi->csi_clk);
614+
if (err < 0)
615+
return err;
616+
}
617+
533618
platform_set_drvdata(pdev, mipi);
534619

535620
return 0;
@@ -541,6 +626,9 @@ static int tegra_mipi_remove(struct platform_device *pdev)
541626

542627
clk_unprepare(mipi->clk);
543628

629+
if (mipi->soc->dsi_v0)
630+
clk_unprepare(mipi->csi_clk);
631+
544632
return 0;
545633
}
546634

0 commit comments

Comments
 (0)