video: udlfb: Fix unaligned access
PATCH 1/2 video: udlfb: Fix unaligned access
Driver generates lots of alignment trap exceptions on ARM. Fix that by replacing typecasting of odd addresses with byte shifting and remove uneccessary typecasting.
---
Here's what happens on at91sam9g20 few minutes after boot:
$ cat /proc/cpu/alignment User: 0 System: 10747836 (dlfb_render_hline+0x22c/0x2f0 [udlfb]) Skipped: 0 Half: 10747971 Word: 159 DWord: 0 Multi: 0 Each hline transfer causes dozens alignment exceptions and few are in dlfb_parse_vendor_descriptor function.
drivers/video/fbdev/udlfb.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/video/fbdev/udlfb.c +12 -11
@@ -441,9 +441,9 @@ static void dlfb_compress_hline( *cmd++ =0xAF ; *cmd++ =0x6B ; - *cmd++ = (uint8_t ) ((dev_addr >>16 ) &0xFF ); - *cmd++ = (uint8_t ) ((dev_addr >>8 ) &0xFF ); - *cmd++ = (uint8_t ) ((dev_addr) &0xFF ); + *cmd++ = dev_addr >>16 ; + *cmd++ = dev_addr >>8 ; + *cmd++ = dev_addr; cmd_pixels_count_byte = cmd++;/* we'll know this later */ cmd_pixel_start = pixel;
@@ -460,8 +460,8 @@ static void dlfb_compress_hline(while (pixel < cmd_pixel_end) {const uint16_t *const repeating_pixel = pixel; - *(uint16_t *)cmd =cpu_to_be16p (pixel); - cmd +=2 ; + *cmd++ = *pixel >>8 ; + *cmd++ = *pixel; pixel++; if (unlikely((pixel < cmd_pixel_end) &&
@@ -1531,15 +1531,16 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,u8 length;u16 key; - key =le16_to_cpu (*((u16 *) desc)); - desc +=sizeof (u16); - length = *desc; - desc++; + key = *desc++; + key |= (u16)*desc++ <<8 ; + length = *desc++;switch (key) {case 0x0200 : {/* max_area */ -u32 max_area; - max_area =le32_to_cpu (*((u32 *)desc)); +u32 max_area = *desc++; + max_area |= (u32)*desc++ <<8 ; + max_area |= (u32)*desc++ <<16 ; + max_area |= (u32)*desc++ <<24 ;dev_warn (&intf->dev,"DL chip limited to %d pixel modes\n" , max_area);
Signature · 1 line
2.16.1
Quoted 5 lines · Ladislav Michl
Driver generates lots of alignment trap exceptions on ARM. Fix that by replacing typecasting of odd addresses with byte shifting and remove uneccessary typecasting.
Signed-off-by Ladislav Michl <[email protected]>
Patch queued for 4.17, thanks.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
PATCH 2/2 video: udlfb: Use already defined BPP constant
Replace const variable with already defined constant.
--- drivers/video/fbdev/udlfb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/video/fbdev/udlfb.c +3 -4
@@ -428,7 +428,6 @@ static void dlfb_compress_hline(const uint16_t *pixel = *pixel_start_ptr;uint32_t dev_addr = *device_address_ptr;uint8_t *cmd = *command_buffer_ptr; -const int bpp =2 ;while ((pixel_end > pixel) && (cmd_buffer_end -MIN_RLX_CMD_BYTES > cmd)) {
@@ -453,9 +452,9 @@ static void dlfb_compress_hline( cmd_pixel_end = pixel +min (MAX_CMD_PIXELS +1 ,min ((int )(pixel_end - pixel), - (int )(cmd_buffer_end - cmd) / bpp)); + (int )(cmd_buffer_end - cmd) /BPP )); -prefetch_range ((void *) pixel, (cmd_pixel_end - pixel) * bpp); +prefetch_range ((void *) pixel, (cmd_pixel_end - pixel) *BPP );while (pixel < cmd_pixel_end) {const uint16_t *const repeating_pixel = pixel;
@@ -490,7 +489,7 @@ static void dlfb_compress_hline( } *cmd_pixels_count_byte = (pixel - cmd_pixel_start) &0xFF ; - dev_addr += (pixel - cmd_pixel_start) * bpp; + dev_addr += (pixel - cmd_pixel_start) *BPP ; }if (cmd_buffer_end <=MIN_RLX_CMD_BYTES + cmd) {
Signature · 1 line
2.16.1
Re: [PATCH 2/2] video: udlfb: Use already defined BPP constant
Quoted 3 lines · Ladislav Michl
Replace const variable with already defined constant.
Signed-off-by Ladislav Michl <[email protected]>
Patch queued for 4.17, thanks.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics