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
