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 <[email protected]>
---
 drivers/gpu/drm/tegra/rgb.c | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index bc1c93c7554c5..e72e076b13d5f 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>
@@ -103,14 +104,19 @@ static void tegra_rgb_encoder_enable(struct drm_encoder 
*encoder)
        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
        struct tegra_output *output = encoder_to_output(encoder);
        struct tegra_rgb *rgb = to_rgb(output);
-       u32 value;
+       struct drm_bridge_state *bridge_state;
+       u32 bus_flags, value;
+
+       /* Get but flags from the bridge state. */
+       bridge_state = drm_bridge_get_current_state(output->bridge);
+       bus_flags = bridge_state->input_bus_cfg.flags;
 
        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)
@@ -123,11 +129,31 @@ static void tegra_rgb_encoder_enable(struct drm_encoder 
*encoder)
        else
                value &= ~LVS_OUTPUT_POLARITY_LOW;
 
+       if (bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE)
+               value |= LSC0_OUTPUT_POLARITY_LOW;
+       else
+               value &= ~LSC0_OUTPUT_POLARITY_LOW;
+
        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 |= LSPI_OUTPUT_POLARITY_LOW;
+       else
+               value &= ~LSPI_OUTPUT_POLARITY_LOW;
+
+       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

Reply via email to