[U-Boot] [PATCH 3/3] sunxi: display: Add overscan correction
Hans de Goede
hdegoede at redhat.com
Wed Aug 12 14:44:58 CEST 2015
Hi,
On 12-08-15 12:45, Ian Campbell wrote:
> On Wed, 2015-08-05 at 17:17 +0200, Hans de Goede wrote:
>> > > sunxi_display.fb_size =
>> > > > (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
>> +> > overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
>> +> > /* We want to keep the fb_base for simplefb page aligned, where as
>> +> > * the sunxi dma engines will happily accept an unaligned address. */
>> +> > if (overscan_offset)
>> +> > > sunxi_display.fb_size += 0x1000;
>
> Why plus 4K regardless of the magnitude of overscan_offset? What if it was
> 0x1004?
If overscan offset is 0x1004 then we make the simplefb start point to
fb_base + 0x2000:
sunxi_display.fb_addr = gd->fb_base
sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff
And make the dma engine start at fb_base + 0xffc:
fb_dma_addr = gd->fb_base
fb_dma_addr += 0x1000 - (overscan_offset & 0xfff)
Notice how we make the dma_engine start at less then 0x1000 offset of
fb_base, so making fb_size 0x1000 larger is enough.
Basically to page-align the start of the simplefb / sunxi_display.fb_addr
we only need a single page, the rest we can get by offsetting
sunxi_display.fb_addr from fb_base by a multiple of the page size.
> Also, what's the link between fb_base's alignment and fb_size which is
> implied by the comment?
To align we need a page extra size as the dma-engine may start at
an offset of up-to a page-size from gd->fb_base and the dma-engine
will dma a full framebuffer size, including the black borders.
>
>> > > gd->fb_base = gd->bd->bi_dram[0].start +
>> > > > gd->bd->bi_dram[0].size - sunxi_display.fb_size;
>> > > sunxi_engines_init();
>> -> > sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE);
>> +
>> +> > fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
>> +> > sunxi_display.fb_addr = gd->fb_base;
>> +> > if (overscan_offset) {
>> +> > > fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
>> +> > > sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
>> +> > > memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
>> +> > > flush_cache(gd->fb_base, sunxi_display.fb_size);
>> +> > }
>
> Hrm, I think this starts to answer, but I'm still not sure I follow, sorry.
Correct this is the answer, sorry for the tricky maths, this is the best
solution without wasting a ton of memory with large overscans.
I hope the above explanation helps, if not keep asking.
>> + sunxi_mode_set(mode, fb_dma_addr);
>>
>> /*
>> > > * These are the only members of this structure that are used. All the
>> > > * others are driver specific. There is nothing to decribe pitch or
>
>
> Pre-existing typo "describe".
Will fix,
Regards,
Hans
More information about the U-Boot
mailing list