sunxi: display: Add support for interlaced modes
Add support for interlaced modes, this is a preparation patch for adding composite out support. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>
This commit is contained in:
parent
0ecb43a8d0
commit
f6d9d32462
@ -445,6 +445,10 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
|
||||
writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
|
||||
|
||||
setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
setbits_le32(&de_be->mode,
|
||||
SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
|
||||
SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
|
||||
}
|
||||
|
||||
static void sunxi_composer_enable(void)
|
||||
@ -668,6 +672,8 @@ static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)
|
||||
int delay;
|
||||
|
||||
delay = mode->lower_margin + mode->vsync_len + mode->upper_margin;
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
delay /= 2;
|
||||
if (tcon == 1)
|
||||
delay -= 2;
|
||||
|
||||
@ -767,7 +773,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
||||
{
|
||||
struct sunxi_lcdc_reg * const lcdc =
|
||||
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
|
||||
int bp, clk_delay, total, val;
|
||||
int bp, clk_delay, total, val, yres;
|
||||
|
||||
/* Use tcon1 */
|
||||
clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
|
||||
@ -775,13 +781,18 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
||||
|
||||
clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
|
||||
writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
|
||||
((mode->vmode == FB_VMODE_INTERLACED) ?
|
||||
SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
|
||||
SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
|
||||
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
yres = mode->yres;
|
||||
if (mode->vmode == FB_VMODE_INTERLACED)
|
||||
yres /= 2;
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_source);
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_scale);
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
|
||||
writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
|
||||
&lcdc->tcon1_timing_out);
|
||||
|
||||
bp = mode->hsync_len + mode->left_margin;
|
||||
@ -791,7 +802,9 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
|
||||
|
||||
bp = mode->vsync_len + mode->upper_margin;
|
||||
total = mode->yres + mode->lower_margin + bp;
|
||||
writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(2 * total) |
|
||||
if (mode->vmode == FB_VMODE_NONINTERLACED)
|
||||
total *= 2;
|
||||
writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
|
||||
SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
|
||||
|
||||
writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
|
||||
@ -1223,14 +1236,6 @@ void *video_hw_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode->vmode != FB_VMODE_NONINTERLACED) {
|
||||
printf("Only non-interlaced modes supported, falling back to 1024x768\n");
|
||||
mode = &res_mode_init[RES_MODE_1024x768];
|
||||
} else {
|
||||
printf("Setting up a %dx%d %s console\n", mode->xres,
|
||||
mode->yres, sunxi_get_mon_desc(sunxi_display.monitor));
|
||||
}
|
||||
|
||||
sunxi_display.fb_size =
|
||||
(mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
|
||||
if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
|
||||
@ -1240,6 +1245,10 @@ void *video_hw_init(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Setting up a %dx%d%s %s console\n", mode->xres, mode->yres,
|
||||
(mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
|
||||
sunxi_get_mon_desc(sunxi_display.monitor));
|
||||
|
||||
gd->fb_base = gd->bd->bi_dram[0].start +
|
||||
gd->bd->bi_dram[0].size - sunxi_display.fb_size;
|
||||
sunxi_engines_init();
|
||||
|
Loading…
Reference in New Issue
Block a user