tegra-drm: add t210b01 dsi support

Signed-off-by: Thomas Makin <halorocker89@gmail.com>
This commit is contained in:
2025-08-03 23:27:17 -05:00
parent 0bb8fa8047
commit 0c1e29cf14
3 changed files with 157 additions and 37 deletions

View File

@@ -1378,6 +1378,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra132-dsi", },
{ .compatible = "nvidia,tegra210-dc", },
{ .compatible = "nvidia,tegra210-dsi", },
{ .compatible = "nvidia,tegra210b01-dsi", },
{ .compatible = "nvidia,tegra210-sor", },
{ .compatible = "nvidia,tegra210-sor1", },
{ .compatible = "nvidia,tegra210-vic", },

View File

@@ -52,6 +52,21 @@ to_dsi_state(struct drm_connector_state *state)
return container_of(state, struct tegra_dsi_state, base);
}
/*
* remap of registers revised in Tegra210B01
*/
struct dsi_regmap {
int init_seq_data_15;
int slew_impedance[4];
int preemphasis;
int bias;
int ganged_mode_control;
int ganged_mode_start;
int ganged_mode_size;
int dbg_regs_cnt;
struct debugfs_reg32 dbg_regs_ext[16];
};
struct tegra_dsi {
struct host1x_client client;
struct tegra_output output;
@@ -81,6 +96,8 @@ struct tegra_dsi {
/* for ganged-mode support */
struct tegra_dsi *master;
struct tegra_dsi *slave;
const struct dsi_regmap *regmap;
};
static inline struct tegra_dsi *
@@ -122,7 +139,7 @@ static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
static const struct debugfs_reg32 tegra_dsi_regs[] = {
static const struct debugfs_reg32 tegra_dsi_regs_common[] = {
DEBUGFS_REG32(DSI_INCR_SYNCPT),
DEBUGFS_REG32(DSI_INCR_SYNCPT_CONTROL),
DEBUGFS_REG32(DSI_INCR_SYNCPT_ERROR),
@@ -181,19 +198,6 @@ static const struct debugfs_reg32 tegra_dsi_regs[] = {
DEBUGFS_REG32(DSI_PAD_CONTROL_2),
DEBUGFS_REG32(DSI_PAD_CONTROL_3),
DEBUGFS_REG32(DSI_PAD_CONTROL_4),
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
DEBUGFS_REG32(DSI_GANGED_MODE_START),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
};
static int tegra_dsi_show_regs(struct seq_file *s, void *data)
@@ -212,10 +216,17 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data)
goto unlock;
}
for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs); i++) {
unsigned int offset = tegra_dsi_regs[i].offset;
for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs_common); i++) {
unsigned int offset = tegra_dsi_regs_common[i].offset;
seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs[i].name,
seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs_common[i].name,
offset, tegra_dsi_readl(dsi, offset));
}
for (i = 0; i < dsi->regmap->dbg_regs_cnt; i++) {
unsigned int offset = dsi->regmap->dbg_regs_ext[i].offset;
seq_printf(s, "%-32s %#05x %08x\n", dsi->regmap->dbg_regs_ext[i].name,
offset, tegra_dsi_readl(dsi, offset));
}
@@ -446,11 +457,11 @@ static void tegra_dsi_ganged_enable(struct tegra_dsi *dsi, unsigned int start,
{
u32 value;
tegra_dsi_writel(dsi, start, DSI_GANGED_MODE_START);
tegra_dsi_writel(dsi, size << 16 | size, DSI_GANGED_MODE_SIZE);
tegra_dsi_writel(dsi, start, dsi->regmap->ganged_mode_start);
tegra_dsi_writel(dsi, size << 16 | size, dsi->regmap->ganged_mode_size);
value = DSI_GANGED_MODE_CONTROL_ENABLE;
tegra_dsi_writel(dsi, value, DSI_GANGED_MODE_CONTROL);
tegra_dsi_writel(dsi, value, dsi->regmap->ganged_mode_control);
}
static void tegra_dsi_enable(struct tegra_dsi *dsi)
@@ -653,9 +664,9 @@ static void tegra_dsi_video_disable(struct tegra_dsi *dsi)
static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi)
{
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_START);
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_SIZE);
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_start);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_size);
tegra_dsi_writel(dsi, 0, dsi->regmap->ganged_mode_control);
}
static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
@@ -671,7 +682,7 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
{
u32 value;
int err;
int err, i;
/*
* XXX Is this still needed? The module reset is deasserted right
@@ -679,21 +690,29 @@ static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
*/
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);
for (i = 0; i < ARRAY_SIZE(dsi->regmap->slew_impedance); i++) {
if (dsi->regmap->slew_impedance[i])
tegra_dsi_writel(dsi, 0, dsi->regmap->slew_impedance[i]);
}
/* 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);
/* do not set padctl 2 slew by default */
if (of_property_read_bool(dsi->dev->of_node, "nvidia,slew-enable")) {
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) |
value = tegra_dsi_readl(dsi, dsi->regmap->preemphasis);
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);
tegra_dsi_writel(dsi, value, dsi->regmap->preemphasis);
tegra_dsi_writel(dsi, 0, dsi->regmap->bias);
err = tegra_mipi_start_calibration(dsi->mipi);
if (err < 0)
@@ -1643,6 +1662,12 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove;
}
dsi->regmap = of_device_get_match_data(&pdev->dev);
if (IS_ERR(dsi->regmap)) {
err = PTR_ERR(dsi->regmap);
goto remove;
}
dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
if (IS_ERR(dsi->mipi)) {
err = PTR_ERR(dsi->mipi);
@@ -1698,11 +1723,87 @@ static void tegra_dsi_remove(struct platform_device *pdev)
tegra_mipi_free(dsi->mipi);
}
static const struct dsi_regmap tegra_dsi_regmap = {
.init_seq_data_15 = DSI_INIT_SEQ_DATA_15,
.slew_impedance = { DSI_PAD_CONTROL_2 },
.preemphasis = DSI_PAD_CONTROL_3,
.bias = DSI_PAD_CONTROL_4,
.ganged_mode_control = DSI_GANGED_MODE_CONTROL,
.ganged_mode_start = DSI_GANGED_MODE_START,
.ganged_mode_size = DSI_GANGED_MODE_SIZE,
.dbg_regs_cnt = 13,
.dbg_regs_ext = {
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
DEBUGFS_REG32(DSI_GANGED_MODE_START),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
},
};
static const struct dsi_regmap tegra_dsi_regmap_b01 = {
.init_seq_data_15 = DSI_INIT_SEQ_DATA_15_B01,
.slew_impedance = {
DSI_PAD_CONTROL_2,
DSI_PAD_CONTROL_3,
DSI_PAD_CONTROL_4,
DSI_PAD_CONTROL_5_B01,
},
.preemphasis = DSI_PAD_CONTROL_6_B01,
.bias = DSI_PAD_CONTROL_7_B01,
.ganged_mode_control = DSI_GANGED_MODE_CONTROL_B01,
.ganged_mode_start = DSI_GANGED_MODE_START_B01,
.ganged_mode_size = DSI_GANGED_MODE_SIZE_B01,
.dbg_regs_cnt = 16,
.dbg_regs_ext = {
DEBUGFS_REG32(DSI_PAD_CONTROL_5_B01),
DEBUGFS_REG32(DSI_PAD_CONTROL_6_B01),
DEBUGFS_REG32(DSI_PAD_CONTROL_7_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_START_B01),
DEBUGFS_REG32(DSI_GANGED_MODE_SIZE_B01),
DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT_B01),
DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14_B01),
DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15_B01),
},
};
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,tegra210b01-dsi",
.data = &tegra_dsi_regmap_b01
},
{
.compatible = "nvidia,tegra210-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra132-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra124-dsi",
.data = &tegra_dsi_regmap
},
{
.compatible = "nvidia,tegra114-dsi",
.data = &tegra_dsi_regmap
},
{ },
};
MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);

View File

@@ -130,6 +130,24 @@
#define DSI_INIT_SEQ_DATA_14 0x5e
#define DSI_INIT_SEQ_DATA_15 0x5f
// Tegra210B01 has a revised set of regs
#define DSI_PAD_CONTROL_5_B01 0x53
#define DSI_PAD_CONTROL_6_B01 0x54
#define DSI_PAD_CONTROL_7_B01 0x55
#define DSI_GANGED_MODE_CONTROL_B01 0x56
#define DSI_GANGED_MODE_START_B01 0x57
#define DSI_GANGED_MODE_SIZE_B01 0x58
#define DSI_RAW_DATA_BYTE_COUNT_B01 0x59
#define DSI_ULTRA_LOW_POWER_CONTROL_B01 0x5a
#define DSI_INIT_SEQ_DATA_8_B01 0x5b
#define DSI_INIT_SEQ_DATA_9_B01 0x5c
#define DSI_INIT_SEQ_DATA_10_B01 0x5d
#define DSI_INIT_SEQ_DATA_11_B01 0x5e
#define DSI_INIT_SEQ_DATA_12_B01 0x5f
#define DSI_INIT_SEQ_DATA_13_B01 0x60
#define DSI_INIT_SEQ_DATA_14_B01 0x61
#define DSI_INIT_SEQ_DATA_15_B01 0x62
/*
* pixel format as used in the DSI_CONTROL_FORMAT field
*/