Patchwork [U-Boot,RESEND] video:cache:fix: Buffer alignment and dcache flush for lcd subsystem

login
register
mail settings
Submitter Łukasz Majewski
Date Jan. 2, 2013, 4:25 p.m.
Message ID <1357143901-10993-1-git-send-email-l.majewski@samsung.com>
Download mbox | patch
Permalink /patch/209080/
State Superseded
Delegated to: Anatolij Gustschin
Headers show

Comments

Łukasz Majewski - Jan. 2, 2013, 4:25 p.m.
This commit makes the video subsystem code cache aware.
Memory allocated for decompressed BMP memory is now cache line aligned.

Flushing of the dcache is also performed after copying BMP data to fb
address (it is done for 32 BPP bitmap used on Trats board (Exynos4210)).


Tested-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Anatolij Gustschin <agust@denx.de>
---
 common/cmd_bmp.c |    2 +-
 common/lcd.c     |    3 +++
 2 files changed, 4 insertions(+), 1 deletions(-)
Simon Glass - Jan. 5, 2013, 1:25 a.m.
Hi Lukasz,

On Wed, Jan 2, 2013 at 8:25 AM, Lukasz Majewski <l.majewski@samsung.com> wrote:
> This commit makes the video subsystem code cache aware.
> Memory allocated for decompressed BMP memory is now cache line aligned.
>
> Flushing of the dcache is also performed after copying BMP data to fb
> address (it is done for 32 BPP bitmap used on Trats board (Exynos4210)).
>

Sorry if I have this wrong, just have a few comments.

>
> Tested-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Anatolij Gustschin <agust@denx.de>
> ---
>  common/cmd_bmp.c |    2 +-
>  common/lcd.c     |    3 +++
>  2 files changed, 4 insertions(+), 1 deletions(-)
>
> diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
> index 5a52edd..57f3eb5 100644
> --- a/common/cmd_bmp.c
> +++ b/common/cmd_bmp.c
> @@ -55,7 +55,7 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
>          * Decompress bmp image
>          */
>         len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
> -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
> +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);

Why do you need to align this one? It is just returned to the caller, isn't it?

>         if (dst == NULL) {
>                 puts("Error: malloc in gunzip failed!\n");
>                 return NULL;
> diff --git a/common/lcd.c b/common/lcd.c
> index 4778655..784d1fb 100644
> --- a/common/lcd.c
> +++ b/common/lcd.c
> @@ -1023,6 +1023,9 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
>                         }
>                         fb  -= (lcd_line_length + width * (bpix / 8));
>                 }
> +               flush_dcache_range((unsigned long) fb,
> +                                  (unsigned long) fb +
> +                                  (lcd_line_length * height));

I'm not sure this is needed - there is a call to lcd_sync() at the
bottom of this function now which should do the same thing,

Please can you take a look at currently mainline and see if you need
to do anything more?

>                 break;
>  #endif /* CONFIG_BMP_32BPP */
>         default:
> --
> 1.7.2.3
>

Regards,
Simon
Lukasz Majewski - Jan. 6, 2013, 8:03 a.m.
Hi Simon,

> Hi Lukasz,
> 
> On Wed, Jan 2, 2013 at 8:25 AM, Lukasz Majewski
> <l.majewski@samsung.com> wrote:
> > This commit makes the video subsystem code cache aware.
> > Memory allocated for decompressed BMP memory is now cache line
> > aligned.
> >
> > Flushing of the dcache is also performed after copying BMP data to
> > fb address (it is done for 32 BPP bitmap used on Trats board
> > (Exynos4210)).
> >
> 
> Sorry if I have this wrong, just have a few comments.
> 
> >
> > Tested-by: Lukasz Majewski <l.majewski@samsung.com>
> > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> > Cc: Anatolij Gustschin <agust@denx.de>
> > ---
> >  common/cmd_bmp.c |    2 +-
> >  common/lcd.c     |    3 +++
> >  2 files changed, 4 insertions(+), 1 deletions(-)
> >
> > diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
> > index 5a52edd..57f3eb5 100644
> > --- a/common/cmd_bmp.c
> > +++ b/common/cmd_bmp.c
> > @@ -55,7 +55,7 @@ bmp_image_t *gunzip_bmp(unsigned long addr,
> > unsigned long *lenp)
> >          * Decompress bmp image
> >          */
> >         len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
> > -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
> > +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
> 
> Why do you need to align this one? It is just returned to the caller,
> isn't it?

Yes, it is returned to the caller, but afterwards lcd_display_bitmap
takes this pointer (and thereof probably unaligned buffer) and works on
it. (At least in the case of trats the bmp is gzipped).

> 
> >         if (dst == NULL) {
> >                 puts("Error: malloc in gunzip failed!\n");
> >                 return NULL;
> > diff --git a/common/lcd.c b/common/lcd.c
> > index 4778655..784d1fb 100644
> > --- a/common/lcd.c
> > +++ b/common/lcd.c
> > @@ -1023,6 +1023,9 @@ int lcd_display_bitmap(ulong bmp_image, int
> > x, int y) }
> >                         fb  -= (lcd_line_length + width * (bpix /
> > 8)); }
> > +               flush_dcache_range((unsigned long) fb,
> > +                                  (unsigned long) fb +
> > +                                  (lcd_line_length * height));
> 
> I'm not sure this is needed - there is a call to lcd_sync() at the
> bottom of this function now which should do the same thing,
> 
> Please can you take a look at currently mainline and see if you need
> to do anything more?

Ok, I've checked. You are right, there is lcd_sync. Thanks for pointing.

I will force trats board to use it, and prepare patches.

> 
> >                 break;
> >  #endif /* CONFIG_BMP_32BPP */
> >         default:
> > --
> > 1.7.2.3
> >
> 
> Regards,
> Simon
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Simon Glass - Jan. 6, 2013, 3:47 p.m.
Hi Lukasz,

On Sun, Jan 6, 2013 at 12:03 AM, Lukasz Majewski <l.majewski@majess.pl> wrote:
> Hi Simon,
>
>> Hi Lukasz,
>>
>> On Wed, Jan 2, 2013 at 8:25 AM, Lukasz Majewski
>> <l.majewski@samsung.com> wrote:
>> > This commit makes the video subsystem code cache aware.
>> > Memory allocated for decompressed BMP memory is now cache line
>> > aligned.
>> >
>> > Flushing of the dcache is also performed after copying BMP data to
>> > fb address (it is done for 32 BPP bitmap used on Trats board
>> > (Exynos4210)).
>> >
>>
>> Sorry if I have this wrong, just have a few comments.
>>
>> >
>> > Tested-by: Lukasz Majewski <l.majewski@samsung.com>
>> > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
>> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>> > Cc: Anatolij Gustschin <agust@denx.de>
>> > ---
>> >  common/cmd_bmp.c |    2 +-
>> >  common/lcd.c     |    3 +++
>> >  2 files changed, 4 insertions(+), 1 deletions(-)
>> >
>> > diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
>> > index 5a52edd..57f3eb5 100644
>> > --- a/common/cmd_bmp.c
>> > +++ b/common/cmd_bmp.c
>> > @@ -55,7 +55,7 @@ bmp_image_t *gunzip_bmp(unsigned long addr,
>> > unsigned long *lenp)
>> >          * Decompress bmp image
>> >          */
>> >         len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
>> > -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
>> > +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
>>
>> Why do you need to align this one? It is just returned to the caller,
>> isn't it?
>
> Yes, it is returned to the caller, but afterwards lcd_display_bitmap
> takes this pointer (and thereof probably unaligned buffer) and works on
> it. (At least in the case of trats the bmp is gzipped).

OK, so it is directly used as a frame buffer? In that case it looks
right to me. I doubt you want to be able to control the cache features
for this area, since you only write it once. But if you did, then the
memory would currently need to be section-aligned.

>
>>
>> >         if (dst == NULL) {
>> >                 puts("Error: malloc in gunzip failed!\n");
>> >                 return NULL;
>> > diff --git a/common/lcd.c b/common/lcd.c
>> > index 4778655..784d1fb 100644
>> > --- a/common/lcd.c
>> > +++ b/common/lcd.c
>> > @@ -1023,6 +1023,9 @@ int lcd_display_bitmap(ulong bmp_image, int
>> > x, int y) }
>> >                         fb  -= (lcd_line_length + width * (bpix /
>> > 8)); }
>> > +               flush_dcache_range((unsigned long) fb,
>> > +                                  (unsigned long) fb +
>> > +                                  (lcd_line_length * height));
>>
>> I'm not sure this is needed - there is a call to lcd_sync() at the
>> bottom of this function now which should do the same thing,
>>
>> Please can you take a look at currently mainline and see if you need
>> to do anything more?
>
> Ok, I've checked. You are right, there is lcd_sync. Thanks for pointing.
>
> I will force trats board to use it, and prepare patches.

OK.

>
>>
>> >                 break;
>> >  #endif /* CONFIG_BMP_32BPP */
>> >         default:
>> > --
>> > 1.7.2.3
>> >
>>
>> Regards,
>> Simon
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot@lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>

Regards,
Simon
Wolfgang Denk - Jan. 6, 2013, 8:21 p.m.
Dear Lukasz & Simon,

In message
<CAPnjgZ3tfvRJO-16ncwE43hPptdMEtOmPEK7pfeLkrMn-rVrgw@mail.gmail.com>
Simon Glass wrote:
> 
> >> > -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
> >> > +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
> >>
> >> Why do you need to align this one? It is just returned to the caller,
> >> isn't it?
> >
> > Yes, it is returned to the caller, but afterwards lcd_display_bitmap
> > takes this pointer (and thereof probably unaligned buffer) and works on
> > it. (At least in the case of trats the bmp is gzipped).
> 
> OK, so it is directly used as a frame buffer? In that case it looks
> right to me. I doubt you want to be able to control the cache features
> for this area, since you only write it once. But if you did, then the
> memory would currently need to be section-aligned.

I don't think this is as it should be.  Any frame buffer that actually
gets used as such should be located in the memory area specifically
allocated for this purpose using lcd_setmem().  This is especially
important when you load a splash screen image and intend to display it
flicker-free when booting an OS.  If you use malloc() or memalign(),
it will be memory in the malloc arena, which gets overwritten when an
OS boots, resulting in a corrupted display.

Note: I added Anatolij, our video custodian to the Cc: list.

Best regards,

Wolfgang Denk
Simon Glass - Jan. 6, 2013, 9:38 p.m.
Hi Wolfgang,

On Sun, Jan 6, 2013 at 12:21 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lukasz & Simon,
>
> In message
> <CAPnjgZ3tfvRJO-16ncwE43hPptdMEtOmPEK7pfeLkrMn-rVrgw@mail.gmail.com>
> Simon Glass wrote:
>>
>> >> > -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
>> >> > +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
>> >>
>> >> Why do you need to align this one? It is just returned to the caller,
>> >> isn't it?
>> >
>> > Yes, it is returned to the caller, but afterwards lcd_display_bitmap
>> > takes this pointer (and thereof probably unaligned buffer) and works on
>> > it. (At least in the case of trats the bmp is gzipped).
>>
>> OK, so it is directly used as a frame buffer? In that case it looks
>> right to me. I doubt you want to be able to control the cache features
>> for this area, since you only write it once. But if you did, then the
>> memory would currently need to be section-aligned.
>
> I don't think this is as it should be.  Any frame buffer that actually
> gets used as such should be located in the memory area specifically
> allocated for this purpose using lcd_setmem().  This is especially
> important when you load a splash screen image and intend to display it
> flicker-free when booting an OS.  If you use malloc() or memalign(),
> it will be memory in the malloc arena, which gets overwritten when an
> OS boots, resulting in a corrupted display.
>
> Note: I added Anatolij, our video custodian to the Cc: list.

OK, well in that case we should deprecate this business of using a
separate memory buffer as a frame buffer, and make people uncompress
the BMP to the normal frame buffer. It would simplify a few things and
I doubt there would be a speed penalty (or at least it could be
corrected by decompressing directly to the frame buffer).

Regards,
Simon

>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> If you think the problem is bad now, just wait until we've solved it.
>                                                         Epstein's Law
Anatolij Gustschin - Jan. 6, 2013, 10:54 p.m.
Hi Simon, Lukasz,

On Sun, 6 Jan 2013 07:47:58 -0800
Simon Glass <sjg@chromium.org> wrote:
...
> >> > diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
> >> > index 5a52edd..57f3eb5 100644
> >> > --- a/common/cmd_bmp.c
> >> > +++ b/common/cmd_bmp.c
> >> > @@ -55,7 +55,7 @@ bmp_image_t *gunzip_bmp(unsigned long addr,
> >> > unsigned long *lenp)
> >> >          * Decompress bmp image
> >> >          */
> >> >         len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
> >> > -       dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
> >> > +       dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
> >>
> >> Why do you need to align this one? It is just returned to the caller,
> >> isn't it?
> >
> > Yes, it is returned to the caller, but afterwards lcd_display_bitmap
> > takes this pointer (and thereof probably unaligned buffer) and works on
> > it. (At least in the case of trats the bmp is gzipped).
> 
> OK, so it is directly used as a frame buffer? 

the allocated area isn't directly used as a frame buffer, it is
a buffer for bmp image which will be processed by lcd_display_bitmap().
The latter looks at the image header/palette and fills the
frame buffer (lcd_base) with the image data. This image buffer can
be unaligned I think.

Thanks,
Anatolij
Anatolij Gustschin - Jan. 6, 2013, 11:09 p.m.
Hello Wolfgang,

On Sun, 06 Jan 2013 21:21:00 +0100
Wolfgang Denk <wd@denx.de> wrote:
...
> > OK, so it is directly used as a frame buffer? In that case it looks
> > right to me. I doubt you want to be able to control the cache features
> > for this area, since you only write it once. But if you did, then the
> > memory would currently need to be section-aligned.
> 
> I don't think this is as it should be.  Any frame buffer that actually
> gets used as such should be located in the memory area specifically
> allocated for this purpose using lcd_setmem().  This is especially
> important when you load a splash screen image and intend to display it
> flicker-free when booting an OS.  If you use malloc() or memalign(),
> it will be memory in the malloc arena, which gets overwritten when an
> OS boots, resulting in a corrupted display.

yes, for lcd.c driver the frame buffer is allocated by lcd_setmem().
malloc() is used only to buffer uncompressed BMP data here and it will
be freed right after extracting the pixel data to the actual frame buffer.

Thanks,
Anatolij
Wolfgang Denk - Jan. 6, 2013, 11:40 p.m.
Dear Simon,

In message <CAPnjgZ1X+anT6x4C0D6ZCoB3VvVVm1aBudkrcGkxg122F8XGmQ@mail.gmail.com> you wrote:
> 
> > I don't think this is as it should be.  Any frame buffer that actually
> > gets used as such should be located in the memory area specifically
> > allocated for this purpose using lcd_setmem().  This is especially
> > important when you load a splash screen image and intend to display it
> > flicker-free when booting an OS.  If you use malloc() or memalign(),
> > it will be memory in the malloc arena, which gets overwritten when an
> > OS boots, resulting in a corrupted display.
> >
> > Note: I added Anatolij, our video custodian to the Cc: list.
> 
> OK, well in that case we should deprecate this business of using a
> separate memory buffer as a frame buffer, and make people uncompress
> the BMP to the normal frame buffer. It would simplify a few things and
> I doubt there would be a speed penalty (or at least it could be
> corrected by decompressing directly to the frame buffer).

Agreed - thanks!

Best regards,

Wolfgang Denk

Patch

diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index 5a52edd..57f3eb5 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -55,7 +55,7 @@  bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
 	 * Decompress bmp image
 	 */
 	len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
-	dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
+	dst = memalign(CONFIG_SYS_CACHELINE_SIZE, len);
 	if (dst == NULL) {
 		puts("Error: malloc in gunzip failed!\n");
 		return NULL;
diff --git a/common/lcd.c b/common/lcd.c
index 4778655..784d1fb 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -1023,6 +1023,9 @@  int lcd_display_bitmap(ulong bmp_image, int x, int y)
 			}
 			fb  -= (lcd_line_length + width * (bpix / 8));
 		}
+		flush_dcache_range((unsigned long) fb,
+				   (unsigned long) fb +
+				   (lcd_line_length * height));
 		break;
 #endif /* CONFIG_BMP_32BPP */
 	default: