sunxi: display: Add overscan correction
Subsystems (2)
cover sunxi: display: Add overscan correction
Hi Anatolij, Ian,
This series sits on top of the composite video out series Ian has just reviewed.
The first 2 patches are preparation patches adding support for stride != width to the cfbconsole code. Anatolij, can you either merge these 2 through your tree, or give us your ack for merging these through the sunxi tree ?
Thanks & Regards,
Hans
PATCH 1/3 cfbconsole: Remove width argument from the logo functions
The passed in width is always VIDEO_COLS. This is a preparation patch for adding stride != width support to the cfbconsole code.
--- drivers/video/cfb_console.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/video/cfb_console.c +8 -13
@@ -1826,20 +1826,16 @@ int video_display_bitmap(ulong bmp_image, int x, int y)static int video_logo_xpos;static int video_logo_ypos; -static void plot_logo_or_black (void *screen,int width,int x,int y, \ -int black); +static void plot_logo_or_black (void *screen,int x,int y,int black); -static void logo_plot (void *screen,int width,int x,int y) +static void logo_plot (void *screen,int x,int y) { -plot_logo_or_black (screen, width, x, y,0 ); +plot_logo_or_black (screen, x, y,0 ); }static void logo_black (void ) { -plot_logo_or_black (video_fb_address, \ -VIDEO_COLS , \ - video_logo_xpos, \ - video_logo_ypos, \ +plot_logo_or_black (video_fb_address, video_logo_xpos, video_logo_ypos,1 ); }
@@ -1858,11 +1854,11 @@ U_BOOT_CMD(" " ); -static void plot_logo_or_black (void *screen,int width,int x,int y,int black) +static void plot_logo_or_black (void *screen,int x,int y,int black) {int xcount, i; -int skip = (width -VIDEO_LOGO_WIDTH ) *VIDEO_PIXEL_SIZE ; +int skip = (VIDEO_COLS -VIDEO_LOGO_WIDTH ) *VIDEO_PIXEL_SIZE ;int ycount = video_logo_height;unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;unsigned char *source;
@@ -1880,7 +1876,7 @@ static void plot_logo_or_black(void *screen, int width, int x, int y, int black) y =max (0 , (int )(VIDEO_VISIBLE_ROWS -VIDEO_LOGO_HEIGHT + y +1 ));#endif /* CONFIG_SPLASH_SCREEN_ALIGN */ - dest = (unsigned char *)screen + (y * width + x) *VIDEO_PIXEL_SIZE ; + dest = (unsigned char *)screen + (y *VIDEO_COLS + x) *VIDEO_PIXEL_SIZE ;#ifdef CONFIG_VIDEO_BMP_LOGO source = bmp_logo_bitmap;
@@ -2009,8 +2005,7 @@ static void *video_logo(void) }#endif /* CONFIG_SPLASH_SCREEN */ -logo_plot (video_fb_address,VIDEO_COLS , - video_logo_xpos, video_logo_ypos); +logo_plot (video_fb_address, video_logo_xpos, video_logo_ypos);#ifdef CONFIG_SPLASH_SCREEN_ALIGN /*
Signature · 1 line
2.4.3
PATCH 1/3 cfbconsole: Remove width argument from the logo functions
Quoted 4 lines · On Wed, 5 Aug 2015 17:17:29 +0200 Hans de Goede <[email protected]> wrote:
The passed in width is always
VIDEO_COLS. This is a preparation patch for adding stride != width support to the cfbconsole code.Signed-off-by Hans de Goede <[email protected]>
PATCH 2/3 cfbconsole: Add support for stride != width
In reply to Hans de Goedecfbconsole currently assumes that the width and stride of the framebuffer are the same, in most places where stride matters it uses a VIDEO_LINE_LEN helper macro.
This commit changes the few places not using VIDEO_LINE_LEN to also use VIDEO_LINE_LEN, and protects the default VIDEO_LINE_LEN with a #ifndef guard, allowing the boards config.h to override and, and thus support cases where stride != width.
--- drivers/video/cfb_console.c | 72 +++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 35 deletions(-)
drivers/video/cfb_console.c +37 -35
@@ -283,9 +283,10 @@ void console_cursor(int state);#define VIDEO_COLS VIDEO_VISIBLE_COLS#define VIDEO_ROWS VIDEO_VISIBLE_ROWS -#define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE) -#define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2) -#define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE) +#ifndef VIDEO_LINE_LEN +#define VIDEO_LINE_LEN (VIDEO_COLS * VIDEO_PIXEL_SIZE) +#endif +#define VIDEO_SIZE (VIDEO_ROWS * VIDEO_LINE_LEN)#define VIDEO_BURST_LEN (VIDEO_COLS/8)#ifdef CONFIG_VIDEO_LOGO
@@ -1306,7 +1307,7 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff,struct palette p[256 ];struct bmp_color_table_entry cte;int green_shift, red_off; -int limit =VIDEO_COLS *VIDEO_ROWS ; +int limit = (VIDEO_LINE_LEN /VIDEO_PIXEL_SIZE ) *VIDEO_ROWS ;int pixels =0 ; x =0 ;
@@ -1314,7 +1315,8 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, ncolors =__le32_to_cpu (img->header.colors_used); bpp =VIDEO_PIXEL_SIZE ; fbp = (unsigned char *) ((unsigned int ) video_fb_address + - (((y + yoff) *VIDEO_COLS ) + xoff) * bpp); + (y + yoff) *VIDEO_LINE_LEN + + xoff * bpp); bm = (uchar *) img +__le32_to_cpu (img->header.data_offset);
@@ -1368,8 +1370,8 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, y--; fbp = (unsigned char *) ((unsigned int ) video_fb_address + - (((y + yoff) *VIDEO_COLS ) + - xoff) * bpp); + (y + yoff) *VIDEO_LINE_LEN + + xoff * bpp);continue ;case 1 :/* end of bitmap data marker */
@@ -1381,8 +1383,8 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, y -= bm[3 ]; fbp = (unsigned char *) ((unsigned int ) video_fb_address + - (((y + yoff) *VIDEO_COLS ) + - x + xoff) * bpp); + (y + yoff) *VIDEO_LINE_LEN + + xoff * bpp); bm +=4 ;break ;default :
@@ -1561,7 +1563,7 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap = (uchar *) bmp +le32_to_cpu (bmp->header.data_offset); fb = (uchar *) (video_fb_address + - ((y + height -1 ) *VIDEO_COLS *VIDEO_PIXEL_SIZE ) + + ((y + height -1 ) *VIDEO_LINE_LEN ) + x *VIDEO_PIXEL_SIZE );#ifdef CONFIG_VIDEO_BMP_RLE8
@@ -1597,7 +1599,7 @@ int video_display_bitmap(ulong bmp_image, int x, int y) cte.blue); } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * + fb -=VIDEO_LINE_LEN + width *VIDEO_PIXEL_SIZE ; }break ;
@@ -1628,8 +1630,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) *fb++ = *bmap++; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF__8BIT_332RGB :
@@ -1642,8 +1644,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) cte.blue); } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_15BIT_555RGB :
@@ -1666,8 +1668,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y)#endif } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_16BIT_565RGB :
@@ -1680,8 +1682,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) cte.blue); } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_32BIT_X888RGB :
@@ -1694,8 +1696,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) cte.blue); } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_24BIT_888RGB :
@@ -1708,8 +1710,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) cte.blue); } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ; }
@@ -1728,8 +1730,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap +=3 ; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_15BIT_555RGB :
@@ -1751,8 +1753,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap +=3 ; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_16BIT_565RGB :
@@ -1765,8 +1767,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap +=3 ; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_32BIT_X888RGB :
@@ -1779,8 +1781,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap +=3 ; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;case GDF_24BIT_888RGB :
@@ -1793,8 +1795,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) bmap +=3 ; } bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * -VIDEO_PIXEL_SIZE ; + fb -=VIDEO_LINE_LEN + width * +VIDEO_PIXEL_SIZE ; }break ;default :
@@ -1858,7 +1860,7 @@ static void plot_logo_or_black(void *screen, int x, int y, int black) {int xcount, i; -int skip = (VIDEO_COLS -VIDEO_LOGO_WIDTH ) *VIDEO_PIXEL_SIZE ; +int skip =VIDEO_LINE_LEN -VIDEO_LOGO_WIDTH *VIDEO_PIXEL_SIZE ;int ycount = video_logo_height;unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;unsigned char *source;
@@ -1876,7 +1878,7 @@ static void plot_logo_or_black(void *screen, int x, int y, int black) y =max (0 , (int )(VIDEO_VISIBLE_ROWS -VIDEO_LOGO_HEIGHT + y +1 ));#endif /* CONFIG_SPLASH_SCREEN_ALIGN */ - dest = (unsigned char *)screen + (y *VIDEO_COLS + x) *VIDEO_PIXEL_SIZE ; + dest = (unsigned char *)screen + y *VIDEO_LINE_LEN + x *VIDEO_PIXEL_SIZE ;#ifdef CONFIG_VIDEO_BMP_LOGO source = bmp_logo_bitmap;
Signature · 1 line
2.4.3
PATCH 2/3 cfbconsole: Add support for stride != width
Quoted 10 lines · On Wed, 5 Aug 2015 17:17:30 +0200 Hans de Goede <[email protected]> wrote:
cfbconsole currently assumes that the width and stride of the framebuffer are the same, in most places where stride matters it uses a
VIDEO_LINE_LENhelper macro.This commit changes the few places not using
VIDEO_LINE_LENto also useVIDEO_LINE_LEN, and protects the defaultVIDEO_LINE_LENwith a #ifndef guard, allowing the boardsconfig.hto override and, and thus support cases where stride != width.Signed-off-by Hans de Goede <[email protected]>
PATCH 3/3 sunxi: display: Add overscan correction
In reply to Hans de GoedeAdd support for making the visual area of the framebuffer smaller and drawing a black border around it. This is intended for use with overscanning monitors (esp. with composite video out), to avoid part of the picture being invisible.
--- doc/README.video | 5 +++++ drivers/video/sunxi_display.c | 48 +++++++++++++++++++++++++++++++++--------- include/configs/sunxi-common.h | 1 + 3 files changed, 44 insertions(+), 10 deletions(-)
doc/README.video +5 -0
@@ -68,6 +68,11 @@ The sunxi u-boot driver supports the following video-mode options: overrides the xres, yres and refresh from the video-mode env. variable. Defaults to edid=1. +- overscan_x/overscan_y=<int> - Set x/y overscan value + This configures a black border on the left and right resp. top and bottom + to deal with overscanning displays. Defaults to overscan_x=32 and + overscan_y=20 for composite monitors, 0 for other monitors. + For example to always use the hdmi connector, even if no cable is inserted, using edid info when available and otherwise initalizing it at 1024x768 at 60Hz, use: "setenv video-mode sunxi:1024x768-24 at 60,monitor=dvi,hpd=0,edid=1".
drivers/video/sunxi_display.c +38 -10
108 lines not on this page · raw message
include/configs/sunxi-common.h +1 -0
@@ -302,6 +302,7 @@ extern int soft_i2c_gpio_scl;#define CONFIG_VIDEO_LOGO #define CONFIG_VIDEO_STD_TIMINGS #define CONFIG_I2C_EDID +#define VIDEO_LINE_LEN (pGD->plnSizeX)/* allow both serial and cfb console. */ #define CONFIG_CONSOLE_MUX
Signature · 1 line
2.4.3
PATCH 3/3 sunxi: display: Add overscan correction
Quoted 7 lines · Hans de Goede
Quoted 2 lines
> sunxi_display.fb_size = > > (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;+> >
overscan_offset= (overscan_y*mode->xres+overscan_x) * 4;
+> > /* We want to keep thefb_basefor 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?
Also, what's the link between fb_base's alignment and fb_size which is implied by the comment?
Quoted 13 lines
Quoted 3 lines
> 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.
drivers/video/sunxi_display.c void *video_hw_init(void)
Quoted 5 lines
drivers/video/sunxi_display.c +1
-0+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".
PATCH 3/3 sunxi: display: Add overscan correction
Hi,
Quoted 11 lines · Ian Campbell
Quoted 7 lines · Hans de Goede
Quoted 2 lines
> sunxi_display.fb_size = > > (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;+> >
overscan_offset= (overscan_y*mode->xres+overscan_x) * 4;
+> > /* We want to keep thefb_basefor 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 was0x1004?
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_basefb_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.
Quoted 2 lines
Also, what's the link between fb_base's alignment and
fb_sizewhich 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.
Quoted 15 lines
Quoted 4 lines
Quoted 4 lines
> gd->fb_base = gd->bd->bi_dram[0].start + > > gd->bd->bi_dram[0].size - sunxi_display.fb_size; > sunxi_engines_init();Quoted 10 lines
-> >
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);
+> > }
Quoted 1 line
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.
Quoted 8 lines
drivers/video/sunxi_display.c void *video_hw_init(void)
Quoted 5 lines
drivers/video/sunxi_display.c +1
-0+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
PATCH 3/3 sunxi: display: Add overscan correction
Quoted 1 line · Hans de Goede
[...big snip...]
Quoted 1 line
I hope the above explanation helps, if not keep asking.
It very much did, thanks.
PATCH 3/3 sunxi: display: Add overscan correction
In reply to Ian CampbellHi,
On 08/12/2015 12:45 PM, Ian Campbell wrote:
<snip>
Quoted 8 lines
drivers/video/sunxi_display.c void *video_hw_init(void)
Quoted 5 lines
drivers/video/sunxi_display.c +1
-0+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".
Actually part of the overscan patch series is adding support for pitch != width to the cfbconsole code, so that comment is no longer accurate, I've squashed a fix for the comment into the patch adding overscan support to drivers/video/sunxi_display.c
Regards,
Hans
PATCH 3/3 sunxi: display: Add overscan correction
In reply to Hans de GoedeQuoted 6 lines · On Wed, 5 Aug 2015 17:17:31 +0200 Hans de Goede <[email protected]> wrote:
Add support for making the visual area of the framebuffer smaller and drawing a black border around it. This is intended for use with overscanning monitors (esp. with composite video out), to avoid part of the picture being invisible.
Signed-off-by Hans de Goede <[email protected]>
cover sunxi: display: Add overscan correction
In reply to Hans de GoedeHi Hans,
On Wed, 5 Aug 2015 17:17:28 +0200
Hans de Goede <[email protected]> wrote:
...
Quoted 4 lines
The first 2 patches are preparation patches adding support for stride != width to the cfbconsole code. Anatolij, can you either merge these 2 through your tree, or give us your ack for merging these through the sunxi tree ?
I've replied with acks, please merge through the sunxi tree.
Thanks,
Anatolij