* [PATCH v2 1/4] clk: tegra20: reparent dsi clock to pll_d_out0
2025-09-06 13:16 [PATCH v2 0/4] gpu/drm: tegra: add DSI support for Tegra20/Tegra30 Svyatoslav Ryhel
@ 2025-09-06 13:16 ` Svyatoslav Ryhel
2025-09-21 20:08 ` Stephen Boyd
2025-09-06 13:16 ` [PATCH v2 2/4] gpu/drm: tegra: dsi: move prepare function at the top of encoder enable Svyatoslav Ryhel
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Svyatoslav Ryhel @ 2025-09-06 13:16 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Thierry Reding, Jonathan Hunter, Prashant Gaikwad,
Michael Turquette, Stephen Boyd, Mikko Perttunen, David Airlie,
Simona Vetter, Svyatoslav Ryhel, Dmitry Osipenko, Charan Pedumuru
Cc: devicetree, linux-tegra, linux-kernel, linux-clk, dri-devel
Reparent DSI clock to PLLD_OUT0 instead of directly descend from PLLD.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/clk/tegra/clk-tegra20.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index bf9a9f8ddf62..9160f27a6cf0 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -801,9 +801,9 @@ static void __init tegra20_periph_clk_init(void)
clks[TEGRA20_CLK_MC] = clk;
/* dsi */
- clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
- 48, periph_clk_enb_refcnt);
- clk_register_clkdev(clk, NULL, "dsi");
+ clk = tegra_clk_register_periph_gate("dsi", "pll_d_out0", 0,
+ clk_base, 0, TEGRA20_CLK_DSI,
+ periph_clk_enb_refcnt);
clks[TEGRA20_CLK_DSI] = clk;
/* csus */
--
2.48.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 3/4] gpu/drm: tegra: dsi: add support for Tegra20/Tegra30
2025-09-06 13:16 [PATCH v2 0/4] gpu/drm: tegra: add DSI support for Tegra20/Tegra30 Svyatoslav Ryhel
2025-09-06 13:16 ` [PATCH v2 1/4] clk: tegra20: reparent dsi clock to pll_d_out0 Svyatoslav Ryhel
2025-09-06 13:16 ` [PATCH v2 2/4] gpu/drm: tegra: dsi: move prepare function at the top of encoder enable Svyatoslav Ryhel
@ 2025-09-06 13:16 ` Svyatoslav Ryhel
2025-09-06 13:16 ` [PATCH v2 4/4] ARM: tegra: adjust DSI nodes " Svyatoslav Ryhel
3 siblings, 0 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2025-09-06 13:16 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Thierry Reding, Jonathan Hunter, Prashant Gaikwad,
Michael Turquette, Stephen Boyd, Mikko Perttunen, David Airlie,
Simona Vetter, Svyatoslav Ryhel, Dmitry Osipenko, Charan Pedumuru
Cc: devicetree, linux-tegra, linux-kernel, linux-clk, dri-devel
Tegra20 and Tegra30 are fully compatible with existing tegra DSI driver
apart from clock configuration and PAD calibration which are addressed by
this patch.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/gpu/drm/tegra/drm.c | 2 +
drivers/gpu/drm/tegra/dsi.c | 88 ++++++++++++++++++++++++-------------
drivers/gpu/drm/tegra/dsi.h | 15 +++++++
3 files changed, 74 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 4596073fe28f..5d64cd57e764 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1359,10 +1359,12 @@ static SIMPLE_DEV_PM_OPS(host1x_drm_pm_ops, host1x_drm_suspend,
static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra20-dc", },
+ { .compatible = "nvidia,tegra20-dsi", },
{ .compatible = "nvidia,tegra20-hdmi", },
{ .compatible = "nvidia,tegra20-gr2d", },
{ .compatible = "nvidia,tegra20-gr3d", },
{ .compatible = "nvidia,tegra30-dc", },
+ { .compatible = "nvidia,tegra30-dsi", },
{ .compatible = "nvidia,tegra30-hdmi", },
{ .compatible = "nvidia,tegra30-gr2d", },
{ .compatible = "nvidia,tegra30-gr3d", },
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 8e80c7efe8b4..d079aa7d2a85 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -53,6 +53,10 @@ to_dsi_state(struct drm_connector_state *state)
return container_of(state, struct tegra_dsi_state, base);
}
+struct tegra_dsi_config {
+ u32 dsi_version;
+};
+
struct tegra_dsi {
struct host1x_client client;
struct tegra_output output;
@@ -82,6 +86,8 @@ struct tegra_dsi {
/* for ganged-mode support */
struct tegra_dsi *master;
struct tegra_dsi *slave;
+
+ const struct tegra_dsi_config *config;
};
static inline struct tegra_dsi *
@@ -663,39 +669,46 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
{
u32 value;
- value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
- tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
+ if (dsi->config->dsi_version == TEGRA_DSI_V1) {
+ /*
+ * XXX Is this still needed? The module reset is deasserted right
+ * before this function is called.
+ */
+ tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
+ tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
+ tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
+ tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
+ tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);
+
+ value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
+ tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
+
+ value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
+ DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
+ DSI_PAD_OUT_CLK(0x0);
+ tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);
+
+ value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
+ DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
+ tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
+ } else {
+ value = DSI_PAD_CONTROL_LPUPADJ(0x1) | DSI_PAD_CONTROL_LPDNADJ(0x1) |
+ DSI_PAD_CONTROL_PREEMP_EN(0x1) | DSI_PAD_CONTROL_SLEWDNADJ(0x6) |
+ DSI_PAD_CONTROL_SLEWUPADJ(0x6) | DSI_PAD_CONTROL_PDIO(0) |
+ DSI_PAD_CONTROL_PDIO_CLK(0) | DSI_PAD_CONTROL_PULLDN_ENAB(0);
+ tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
+ }
return 0;
}
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
{
- u32 value;
int err;
- /*
- * XXX Is this still needed? The module reset is deasserted right
- * before this function is called.
- */
- tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
- tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
- tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
- tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
- tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);
-
/* start calibration */
tegra_dsi_pad_enable(dsi);
- value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
- DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
- DSI_PAD_OUT_CLK(0x0);
- tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);
-
- value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
- DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
- tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
-
err = tegra_mipi_start_calibration(dsi->mipi);
if (err < 0)
return err;
@@ -1577,6 +1590,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
if (!dsi)
return -ENOMEM;
+ dsi->config = of_device_get_match_data(&pdev->dev);
dsi->output.dev = dsi->dev = &pdev->dev;
dsi->video_fifo_depth = 1920;
dsi->host_fifo_depth = 64;
@@ -1615,7 +1629,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove;
}
- dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
+ dsi->clk_lp = devm_clk_get_optional(&pdev->dev, "lp");
if (IS_ERR(dsi->clk_lp)) {
err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
"cannot get low-power clock\n");
@@ -1636,10 +1650,12 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove;
}
- err = tegra_dsi_setup_clocks(dsi);
- if (err < 0) {
- dev_err(&pdev->dev, "cannot setup clocks\n");
- goto remove;
+ if (dsi->config->dsi_version == TEGRA_DSI_V1) {
+ err = tegra_dsi_setup_clocks(dsi);
+ if (err < 0) {
+ dev_err(&pdev->dev, "cannot setup clocks\n");
+ goto remove;
+ }
}
dsi->regs = devm_platform_ioremap_resource(pdev, 0);
@@ -1703,11 +1719,21 @@ static void tegra_dsi_remove(struct platform_device *pdev)
tegra_mipi_free(dsi->mipi);
}
+static const struct tegra_dsi_config tegra20_dsi_config = {
+ .dsi_version = TEGRA_DSI_V0,
+};
+
+static const struct tegra_dsi_config tegra114_dsi_config = {
+ .dsi_version = TEGRA_DSI_V1,
+};
+
static const struct of_device_id tegra_dsi_of_match[] = {
- { .compatible = "nvidia,tegra210-dsi", },
- { .compatible = "nvidia,tegra132-dsi", },
- { .compatible = "nvidia,tegra124-dsi", },
- { .compatible = "nvidia,tegra114-dsi", },
+ { .compatible = "nvidia,tegra210-dsi", .data = &tegra114_dsi_config },
+ { .compatible = "nvidia,tegra132-dsi", .data = &tegra114_dsi_config },
+ { .compatible = "nvidia,tegra124-dsi", .data = &tegra114_dsi_config },
+ { .compatible = "nvidia,tegra114-dsi", .data = &tegra114_dsi_config },
+ { .compatible = "nvidia,tegra30-dsi", .data = &tegra20_dsi_config },
+ { .compatible = "nvidia,tegra20-dsi", .data = &tegra20_dsi_config },
{ },
};
MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);
diff --git a/drivers/gpu/drm/tegra/dsi.h b/drivers/gpu/drm/tegra/dsi.h
index f39594e65e97..5049ec7813c7 100644
--- a/drivers/gpu/drm/tegra/dsi.h
+++ b/drivers/gpu/drm/tegra/dsi.h
@@ -95,6 +95,16 @@
#define DSI_TALLY_LRX(x) (((x) & 0xff) << 8)
#define DSI_TALLY_HTX(x) (((x) & 0xff) << 0)
#define DSI_PAD_CONTROL_0 0x4b
+/* DSI V0 */
+#define DSI_PAD_CONTROL_PULLDN_ENAB(x) (((x) & 0x1) << 28)
+#define DSI_PAD_CONTROL_SLEWUPADJ(x) (((x) & 0x7) << 24)
+#define DSI_PAD_CONTROL_SLEWDNADJ(x) (((x) & 0x7) << 20)
+#define DSI_PAD_CONTROL_PREEMP_EN(x) (((x) & 0x1) << 19)
+#define DSI_PAD_CONTROL_PDIO_CLK(x) (((x) & 0x1) << 18)
+#define DSI_PAD_CONTROL_PDIO(x) (((x) & 0x3) << 16)
+#define DSI_PAD_CONTROL_LPUPADJ(x) (((x) & 0x3) << 14)
+#define DSI_PAD_CONTROL_LPDNADJ(x) (((x) & 0x3) << 12)
+/* DSI V1 */
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
@@ -140,4 +150,9 @@ enum tegra_dsi_format {
TEGRA_DSI_FORMAT_24P,
};
+enum tegra_dsi_version {
+ TEGRA_DSI_V0,
+ TEGRA_DSI_V1,
+};
+
#endif
--
2.48.1
^ permalink raw reply related [flat|nested] 6+ messages in thread