summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-12-20 13:51:16 +0100
committerHans de Goede <hdegoede@redhat.com>2015-01-14 14:56:38 +0100
commit876aaafdbd5eb2764b6e921306c7d37f9c9f3f09 (patch)
treeeecd31bd2ee1fa7856574fbd46f45880df342692
parent40f1b87ce7f84a7ff74fd519dc2c75b333068815 (diff)
downloadu-boot-imx-876aaafdbd5eb2764b6e921306c7d37f9c9f3f09.zip
u-boot-imx-876aaafdbd5eb2764b6e921306c7d37f9c9f3f09.tar.gz
u-boot-imx-876aaafdbd5eb2764b6e921306c7d37f9c9f3f09.tar.bz2
sunxi: video: Set input sync enable
Add a write to the "unknown" (*) register to enable auto input sync, when initially adding sunxi hdmi output support this magic write from the android kernel code was missed, causing lcdc -> hdmi encoder sync problems. With this write added, we can drop the modesetting retries and the extra delays added to work around these sync problems. With the retries dropped there also is no need to 0 all the enable flags at the beginning of the modeset, as they are initialized to 0 already by engines_init. *) "unknown" is the actual name of this register in the android kernel sources Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk> Acked-by: Anatolij Gustschin <agust@denx.de>
-rw-r--r--arch/arm/include/asm/arch-sunxi/display.h1
-rw-r--r--drivers/video/sunxi_display.c27
2 files changed, 5 insertions, 23 deletions
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 838b217..00e3466 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -236,6 +236,7 @@ struct sunxi_hdmi_reg {
#define SUNXI_HDMI_PKT_CTRL0 0x00000f21
#define SUNXI_HDMI_PKT_CTRL1 0x0000000f
+#define SUNXI_HDMI_UNKNOWN_INPUT_SYNC 0x08000000
#ifdef CONFIG_MACH_SUN6I
#define SUNXI_HMDI_DDC_CTRL_ENABLE (1 << 0)
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 5a14785..ced5ce5 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -501,6 +501,9 @@ static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
if (hdmi_mode)
sunxi_hdmi_setup_info_frames(mode);
+ /* Set input sync enable */
+ writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown);
+
/* Init various registers, select pll3 as clock source */
writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity);
writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0);
@@ -556,41 +559,19 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, char *monitor,
struct sunxi_hdmi_reg * const hdmi =
(struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
int clk_div, clk_double;
- int retries = 3;
bool hdmi_mode = strcmp(monitor, "hdmi") == 0;
-retry:
- clrbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
- clrbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
- clrbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
-
sunxi_composer_mode_set(mode, address);
sunxi_lcdc_mode_set(mode, &clk_div, &clk_double);
sunxi_hdmi_mode_set(mode, hdmi_mode, clk_div, clk_double);
setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
-
- udelay(1000000 / mode->refresh + 500);
-
setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
- udelay(1000000 / mode->refresh + 500);
+ udelay(100);
setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
-
- udelay(1000000 / mode->refresh + 500);
-
- /*
- * Sometimes the display pipeline does not sync up properly, if
- * this happens the hdmi fifo underrun or overrun bits are set.
- */
- if (readl(&hdmi->irq) &
- (SUNXI_HDMI_IRQ_STATUS_FIFO_UF | SUNXI_HDMI_IRQ_STATUS_FIFO_OF)) {
- if (retries--)
- goto retry;
- printf("HDMI fifo under or overrun\n");
- }
}
void *video_hw_init(void)