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 | 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
