sunxi: video: Fix lvds panel support for sun6i+

We've never tested the lvds panel support on sun6i+ SoCs until now, and
unsurprisingly the lvds code needed some fixes to work on my ga10h A33
tablet with lvds panel. This makes the panel on that tablet actually work.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
This commit is contained in:
Hans de Goede 2015-05-14 18:52:54 +02:00
parent 8975cdf4bc
commit 83edb2ace6
3 changed files with 32 additions and 1 deletions

View File

@ -331,6 +331,9 @@ struct sunxi_ccm_reg {
#define AHB_RESET_OFFSET_LCD1 5
#define AHB_RESET_OFFSET_LCD0 4
/* ahb_reset2 offsets */
#define AHB_RESET_OFFSET_LVDS 0
/* apb2 reset */
#define APB2_RESET_UART_SHIFT (16)
#define APB2_RESET_UART_MASK (0xff << APB2_RESET_UART_SHIFT)

View File

@ -363,6 +363,11 @@ struct sunxi_tve_reg {
#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n) (((n) - 1) << 16)
#define SUNXI_LCDC_TCON0_TIMING_V_BP(n) (((n) - 1) << 0)
#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n) (((n) * 2) << 16)
#ifdef CONFIG_SUNXI_GEN_SUN6I
#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 (1 << 20)
#else
#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 0 /* NA */
#endif
#define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n) ((n) << 26)
#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31)
#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x) ((x) << 28)
@ -372,8 +377,15 @@ struct sunxi_tve_reg {
#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16)
#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0)
#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) (((n) * 2) << 16)
#ifdef CONFIG_SUNXI_GEN_SUN6I
#define SUNXI_LCDC_LVDS_ANA0 0x40040320
#define SUNXI_LCDC_LVDS_ANA0_EN_MB (1 << 31)
#define SUNXI_LCDC_LVDS_ANA0_DRVC (1 << 24)
#define SUNXI_LCDC_LVDS_ANA0_DRVD(x) ((x) << 20)
#else
#define SUNXI_LCDC_LVDS_ANA0 0x3f310000
#define SUNXI_LCDC_LVDS_ANA0_UPDATE (1 << 22)
#endif
#define SUNXI_LCDC_LVDS_ANA1_INIT1 (0x1f << 26 | 0x1f << 10)
#define SUNXI_LCDC_LVDS_ANA1_INIT2 (0x1f << 16 | 0x1f << 00)

View File

@ -558,7 +558,11 @@ static void sunxi_lcdc_init(void)
/* Clock on */
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
#ifdef CONFIG_SUNXI_GEN_SUN6I
setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS);
#else
setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
#endif
#endif
/* Init lcdc */
@ -582,6 +586,16 @@ static void sunxi_lcdc_enable(void)
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE);
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0);
#ifdef CONFIG_SUNXI_GEN_SUN6I
udelay(2); /* delay at least 1200 ns */
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB);
udelay(2); /* delay at least 1200 ns */
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC);
if (sunxi_display.depth == 18)
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7));
else
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf));
#else
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
udelay(2); /* delay at least 1200 ns */
setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1);
@ -589,6 +603,7 @@ static void sunxi_lcdc_enable(void)
setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2);
setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
#endif
#endif
}
static void sunxi_lcdc_panel_enable(void)
@ -706,7 +721,8 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
#endif
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
val = (sunxi_display.depth == 18) ? 1 : 0;
writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val), &lcdc->tcon0_lvds_intf);
writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
#endif
if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {