[PATCH v5 09/11] drm/tegra: rgb: Parameterize configuration based on bus flags

From: Svyatoslav Ryhel

Date: Thu Oct 29 2026 - 11:36:03 EST


Parameterize configuration based on bus flags passed from the bridge or
panel. The list of supported flags includes now pixel clock polarity,
display enable (DE) polarity, and data alignment.

Signed-off-by: Svyatoslav Ryhel <clamor95@xxxxxxxxx>
---
drivers/gpu/drm/tegra/rgb.c | 39 +++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 7dea0cac61233..d8f41d1ca350e 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -5,6 +5,7 @@
*/

#include <linux/clk.h>
+#include <linux/media-bus-format.h>
#include <linux/of.h>

#include <drm/drm_atomic_helper.h>
@@ -106,6 +107,7 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder,
struct tegra_output *output = encoder_to_output(encoder);
struct tegra_rgb *rgb = to_rgb(output);
struct drm_connector_state *conn_state;
+ struct drm_bridge_state *bridge_state;
struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
struct drm_display_mode *mode;
@@ -117,12 +119,21 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder,
crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
mode = &crtc_state->adjusted_mode;

+ /* Get but flags from the bridge state. */
+ bridge_state = drm_atomic_get_new_bridge_state(state, output->bridge);
+ if (bridge_state)
+ bus_flags = bridge_state->input_bus_cfg.flags;
+ else
+ bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
+ DRM_BUS_FLAG_DE_HIGH |
+ DRM_BUS_FLAG_DATA_MSB_TO_LSB;
+
tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));

value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS);

- /* configure H- and V-sync signal polarities */
+ /* configure H- and V-sync and pixel clock signal polarities */
value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1));

if (mode->flags & DRM_MODE_FLAG_NHSYNC)
@@ -135,11 +146,31 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder,
else
value &= ~BIT(PIN_LVS);

+ if (bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE)
+ value &= ~BIT(PIN_LSC0);
+ else
+ value |= BIT(PIN_LSC0);
+
tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));

- /* XXX: parameterize? */
- value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB |
- DISP_ORDER_RED_BLUE;
+ /* configure DE signal polarities */
+ value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(3));
+
+ if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+ value |= BIT(PIN_LSPI);
+ else
+ value &= ~BIT(PIN_LSPI);
+
+ tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(3));
+
+ /* configure DATA order and alignment */
+ value = DISP_DATA_FORMAT_DF1P1C | DISP_ORDER_RED_BLUE;
+
+ if (bus_flags & DRM_BUS_FLAG_DATA_LSB_TO_MSB)
+ value |= DISP_ALIGNMENT_LSB;
+ else
+ value &= ~DISP_ALIGNMENT_LSB;
+
tegra_dc_writel(rgb->dc, value, DC_DISP_DISP_INTERFACE_CONTROL);

tegra_dc_commit(rgb->dc);
--
2.53.0