From d640b4d3184f8c28f7494a5c77a4dddfc51ebb9c Mon Sep 17 00:00:00 2001 From: Maxim Schwalm Date: Sat, 1 Jul 2023 20:08:40 +0200 Subject: [PATCH 1/3] Revert "drm/tegra: rgb: Hacks for S6E63M0" This reverts commit fcae068abfcbe8be0aab00587d0c1d1a26c4d126. --- drivers/gpu/drm/tegra/rgb.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index b0837a5c7aea..ebfa90c7308b 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -34,7 +34,7 @@ struct reg_entry { unsigned long value; }; -static struct reg_entry rgb_enable[] = { +static const struct reg_entry rgb_enable[] = { { DC_COM_PIN_OUTPUT_ENABLE(0), 0x00000000 }, { DC_COM_PIN_OUTPUT_ENABLE(1), 0x00000000 }, { DC_COM_PIN_OUTPUT_ENABLE(2), 0x00000000 }, @@ -103,15 +103,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) struct tegra_rgb *rgb = to_rgb(output); u32 value; - /* - * Temporal hack for S6E63M0 - * - * Pins DATA_ENABLE, H_SYNC, V_SYNC, PIXEL_CLOCK are low polarity, - * set this in the registers to make the panel working. - */ - if (of_machine_is_compatible("samsung,i927")) - rgb_enable[7].value = 0x00000100; - tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; @@ -121,10 +112,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1)); value &= ~LVS_OUTPUT_POLARITY_LOW; value &= ~LHS_OUTPUT_POLARITY_LOW; - if (of_machine_is_compatible("samsung,i927")) { - value |= LVS_OUTPUT_POLARITY_LOW; - value |= LHS_OUTPUT_POLARITY_LOW; - } tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1)); /* XXX: parameterize? */ From 53dc19e1a8e21fc6a9d6a0d3b283fbdcc7a3ae26 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Aug 2015 13:34:36 +0200 Subject: [PATCH 2/3] drm/tegra: rgb: Parameterize V- and H-sync polarities The polarities of the V- and H-sync signals are encoded as flags in the display mode, so use the existing information to setup the signals for the RGB interface. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/rgb.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index ebfa90c7308b..d12d8d45188e 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -99,6 +99,7 @@ static void tegra_rgb_encoder_disable(struct drm_encoder *encoder) 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; @@ -108,10 +109,21 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS); - /* XXX: parameterize? */ + /* configure H- and V-sync signal polarities */ value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1)); - value &= ~LVS_OUTPUT_POLARITY_LOW; - value &= ~LHS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + value &= ~LHS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + value |= LHS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + value &= ~LVS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + value |= LVS_OUTPUT_POLARITY_LOW; + tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1)); /* XXX: parameterize? */ From 89de49f02063e9cb6d4c7327fa324da5336cfdb5 Mon Sep 17 00:00:00 2001 From: Maxim Schwalm Date: Fri, 14 Jul 2023 20:25:08 +0200 Subject: [PATCH 3/3] drm/tegra: rgb: Parameterize pixel clock and DE polarities For some Tegra devices, like the Samsung SGH-I927, the pixel clock and data enable (DE) signal polarities have to be programmed differently than in the default case. To accommodate this, add support for configuring the signal polarities for the RGB interface based on the DRM bus flags. Signed-off-by: Maxim Schwalm --- drivers/gpu/drm/tegra/dc.h | 10 ++++++++-- drivers/gpu/drm/tegra/rgb.c | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 0559fa6b1bf7..c785abde2b43 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -269,9 +269,15 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc); #define DC_COM_CRC_CONTROL_ENABLE (1 << 0) #define DC_COM_CRC_CHECKSUM 0x301 #define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x)) + #define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x)) -#define LVS_OUTPUT_POLARITY_LOW (1 << 28) -#define LHS_OUTPUT_POLARITY_LOW (1 << 30) +/* DC_COM_PIN_OUTPUT_POLARITY(1) bits */ +#define LHS_OUTPUT_POLARITY_LOW (1 << 30) +#define LVS_OUTPUT_POLARITY_LOW (1 << 28) +#define LSC0_OUTPUT_POLARITY_LOW (1 << 24) +/* DC_COM_PIN_OUTPUT_POLARITY(3) bits */ +#define LSPI_OUTPUT_POLARITY_LOW (1 << 8) + #define DC_COM_PIN_OUTPUT_DATA(x) (0x30a + (x)) #define DC_COM_PIN_INPUT_ENABLE(x) (0x30e + (x)) #define DC_COM_PIN_INPUT_DATA(x) (0x312 + (x)) diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index d12d8d45188e..730172a4a6e3 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -101,6 +101,7 @@ 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 drm_connector *connector = drm_panel_bridge_connector(output->bridge); struct tegra_rgb *rgb = to_rgb(output); u32 value; @@ -109,7 +110,7 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) 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_PHSYNC) @@ -124,8 +125,25 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) if (mode->flags & DRM_MODE_FLAG_NVSYNC) value |= LVS_OUTPUT_POLARITY_LOW; + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) + value &= ~LSC0_OUTPUT_POLARITY_LOW; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) + value |= LSC0_OUTPUT_POLARITY_LOW; + tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1)); + /* configure DE signal polarities */ + value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(3)); + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_HIGH) + value &= ~LSPI_OUTPUT_POLARITY_LOW; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) + value |= LSPI_OUTPUT_POLARITY_LOW; + + tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(3)); + /* XXX: parameterize? */ if (of_machine_is_compatible("samsung,i927")) { /* Set DISP_COLOR_SWAP bit to swap red and blue colors */