Re: [PATCH v6 14/18] video: tegra20: dsi: add T114 support

2024-04-19 Thread Thierry Reding
On Tue Jan 23, 2024 at 6:16 PM CET, Svyatoslav Ryhel wrote:
> Existing Tegra DSI driver mostly fits T114 apart MIPI calibration
> which on T114 has dedicated driver. To resolve this MIPI calibration
> logic was split for pre-T114 and T114+ devices.
>
> Tested-by: Ion Agorria  # HTC One X
> Tested-by: Svyatoslav Ryhel  # Nvidia Tegratab T114
> Signed-off-by: Svyatoslav Ryhel 
> ---
>  drivers/video/tegra20/tegra-dsi.c | 78 ++-
>  .../video/tegra20/tegra-dsi.h | 24 +-
>  2 files changed, 96 insertions(+), 6 deletions(-)
>  rename arch/arm/include/asm/arch-tegra30/dsi.h => 
> drivers/video/tegra20/tegra-dsi.h (90%)

Reviewed-by: Thierry Reding 


signature.asc
Description: PGP signature


[PATCH v6 14/18] video: tegra20: dsi: add T114 support

2024-01-23 Thread Svyatoslav Ryhel
Existing Tegra DSI driver mostly fits T114 apart MIPI calibration
which on T114 has dedicated driver. To resolve this MIPI calibration
logic was split for pre-T114 and T114+ devices.

Tested-by: Ion Agorria  # HTC One X
Tested-by: Svyatoslav Ryhel  # Nvidia Tegratab T114
Signed-off-by: Svyatoslav Ryhel 
---
 drivers/video/tegra20/tegra-dsi.c | 78 ++-
 .../video/tegra20/tegra-dsi.h | 24 +-
 2 files changed, 96 insertions(+), 6 deletions(-)
 rename arch/arm/include/asm/arch-tegra30/dsi.h => 
drivers/video/tegra20/tegra-dsi.h (90%)

diff --git a/drivers/video/tegra20/tegra-dsi.c 
b/drivers/video/tegra20/tegra-dsi.c
index de225ed376..25a629535e 100644
--- a/drivers/video/tegra20/tegra-dsi.c
+++ b/drivers/video/tegra20/tegra-dsi.c
@@ -20,17 +20,24 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "tegra-dc.h"
+#include "tegra-dsi.h"
 #include "mipi-phy.h"
 
+/* List of supported DSI bridges */
+enum {
+   DSI_V0,
+   DSI_V1,
+};
+
 struct tegra_dsi_priv {
struct mipi_dsi_host host;
struct mipi_dsi_device device;
struct mipi_dphy_timing dphy_timing;
 
struct udevice *panel;
+   struct udevice *mipi;
struct display_timing timing;
 
struct dsi_ctlr *dsi;
@@ -41,6 +48,8 @@ struct tegra_dsi_priv {
int dsi_clk;
int video_fifo_depth;
int host_fifo_depth;
+
+   u32 version;
 };
 
 static void tegra_dc_enable_controller(struct udevice *dev)
@@ -501,6 +510,41 @@ static void tegra_dsi_pad_calibrate(struct 
dsi_pad_ctrl_reg *pad)
writel(value, TEGRA_VI_BASE + (CSI_CIL_PAD_CONFIG << 2));
 }
 
+static void tegra_dsi_mipi_calibrate(struct tegra_dsi_priv *priv)
+{
+   struct dsi_pad_ctrl_reg *pad = &priv->dsi->pad;
+   u32 value;
+   int ret;
+
+   ret = misc_set_enabled(priv->mipi, true);
+   if (ret)
+   log_debug("%s: failed to enable MIPI calibration: %d\n",
+ __func__, ret);
+
+   writel(0, &pad->pad_ctrl);
+   writel(0, &pad->pad_ctrl_1);
+   writel(0, &pad->pad_ctrl_2);
+   writel(0, &pad->pad_ctrl_3);
+   writel(0, &pad->pad_ctrl_4);
+
+   /* DSI pad enable */
+   value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
+   writel(value, &pad->pad_ctrl);
+
+   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);
+   writel(value, &pad->pad_ctrl_2);
+
+   value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
+   DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
+   writel(value, &pad->pad_ctrl_3);
+
+   ret = misc_write(priv->mipi, 0, NULL, 0);
+   if (ret)
+   log_debug("%s: MIPI calibration failed %d\n", __func__, ret);
+}
+
 static void tegra_dsi_set_timeout(struct dsi_timeout_reg *rtimeout,
  unsigned long bclk,
  unsigned int vrefresh)
@@ -664,10 +708,25 @@ static int tegra_dsi_encoder_enable(struct udevice *dev)
u32 value;
int ret;
 
+   /* If for some reasone DSI is enabled then it needs to
+* be disabled in order for the panel initialization
+* commands to be properly sent.
+*/
+   value = readl(&misc->dsi_pwr_ctrl);
+
+   if (value & DSI_POWER_CONTROL_ENABLE) {
+   value = readl(&misc->dsi_pwr_ctrl);
+   value &= ~DSI_POWER_CONTROL_ENABLE;
+   writel(value, &misc->dsi_pwr_ctrl);
+   }
+
/* Disable interrupt */
writel(0, &misc->int_enable);
 
-   tegra_dsi_pad_calibrate(&priv->dsi->pad);
+   if (priv->version)
+   tegra_dsi_mipi_calibrate(priv);
+   else
+   tegra_dsi_pad_calibrate(&priv->dsi->pad);
 
tegra_dsi_get_muldiv(device->format, &mul, &div);
 
@@ -806,6 +865,8 @@ static int tegra_dsi_bridge_probe(struct udevice *dev)
struct mipi_dsi_panel_plat *mipi_plat;
int ret;
 
+   priv->version = dev_get_driver_data(dev);
+
priv->dsi = (struct dsi_ctlr *)dev_read_addr_ptr(dev);
if (!priv->dsi) {
printf("%s: No display controller address\n", __func__);
@@ -828,6 +889,16 @@ static int tegra_dsi_bridge_probe(struct udevice *dev)
return log_ret(ret);
}
 
+   if (priv->version) {
+   ret = uclass_get_device_by_phandle(UCLASS_MISC, dev,
+  "nvidia,mipi-calibrate",
+  &priv->mipi);
+   if (ret) {
+   log_debug("%s: cannot get MIPI: error %d\n", __func__, 
ret);
+   return ret;
+   }
+   }
+
panel_get_display_timing(priv->panel, &priv->timing);
 
mipi_plat = dev_get_plat(priv->panel);
@@ -859,7 +930,8 @@ static const struct panel_ops tegra_d