summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Ceresoli <luca.ceresoli@bootlin.com>2026-04-16 16:59:55 +0300
committerLuca Ceresoli <luca.ceresoli@bootlin.com>2026-05-04 13:20:03 +0300
commit55a412e3a78104036bbb1036e2ebe8fa4fb41770 (patch)
tree3991791ae079af05d981d77bfccd758fa933ef71
parent528578941a240e0916942bbb5b910c57bbfb3614 (diff)
downloadlinux-55a412e3a78104036bbb1036e2ebe8fa4fb41770.tar.xz
drm/bridge: ti-sn65dsi83: add test pattern generation support
Generation of a test pattern output is a useful tool for panel bringup and debugging, and very simple to support with this chip. The value of REG_VID_CHA_ACTIVE_LINE_LENGTH_LOW needs to be divided by two for the test pattern to work in dual LVDS mode. While not clearly stated in the datasheet, this is needed according to the DSI Tuner [0] output. And some dual-LVDS panels refuse to show any picture without this division by two. [0] https://www.ti.com/tool/DSI-TUNER Reviewed-by: Louis Chauvet <louis.chauvet@boootlin.com> Link: https://patch.msgid.link/20260416-ti-sn65dsi83-dual-lvds-fixes-and-test-pattern-v3-1-143886aebc6b@bootlin.com Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 17a885244e1e..2b6f6a54edb7 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -114,6 +114,7 @@
#define REG_VID_CHA_HORIZONTAL_FRONT_PORCH 0x38
#define REG_VID_CHA_VERTICAL_FRONT_PORCH 0x3a
#define REG_VID_CHA_TEST_PATTERN 0x3c
+#define REG_VID_CHA_TEST_PATTERN_EN BIT(4)
/* IRQ registers */
#define REG_IRQ_GLOBAL 0xe0
#define REG_IRQ_GLOBAL_IRQ_EN BIT(0)
@@ -134,6 +135,9 @@
#define REG_IRQ_STAT_CHA_SOT_BIT_ERR BIT(2)
#define REG_IRQ_STAT_CHA_PLL_UNLOCK BIT(0)
+static bool sn65dsi83_test_pattern;
+module_param_named(test_pattern, sn65dsi83_test_pattern, bool, 0644);
+
enum sn65dsi83_channel {
CHANNEL_A,
CHANNEL_B
@@ -523,6 +527,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
const struct drm_display_mode *mode;
struct drm_connector *connector;
struct drm_crtc *crtc;
+ bool test_pattern = sn65dsi83_test_pattern;
bool lvds_format_24bpp;
bool lvds_format_jeida;
unsigned int pval;
@@ -645,7 +650,11 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
REG_LVDS_LANE_CHB_LVDS_TERM : 0));
regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
- le16val = cpu_to_le16(mode->hdisplay);
+ /*
+ * Active line length needs to be halved for test pattern
+ * generation in dual LVDS output.
+ */
+ le16val = cpu_to_le16(mode->hdisplay / (test_pattern ? dual_factor : 1));
regmap_bulk_write(ctx->regmap, REG_VID_CHA_ACTIVE_LINE_LENGTH_LOW,
&le16val, 2);
le16val = cpu_to_le16(mode->vdisplay);
@@ -668,7 +677,8 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
(mode->hsync_start - mode->hdisplay) / dual_factor);
regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH,
mode->vsync_start - mode->vdisplay);
- regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00);
+ regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN,
+ test_pattern ? REG_VID_CHA_TEST_PATTERN_EN : 0);
/* Enable PLL */
regmap_write(ctx->regmap, REG_RC_PLL_EN, REG_RC_PLL_EN_PLL_EN);