Commit 99ec9e77 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Dave Airlie

drm/udl: fix display corruption of the last line

The displaylink hardware has such a peculiarity that it doesn't render a
command until next command is received. This produces occasional
corruption, such as when setting 22x11 font on the console, only the first
line of the cursor will be blinking if the cursor is located at some
specific columns.

When we end up with a repeating pixel, the driver has a bug that it leaves
one uninitialized byte after the command (and this byte is enough to flush
the command and render it - thus it fixes the screen corruption), however
whe we end up with a non-repeating pixel, there is no byte appended and
this results in temporary screen corruption.

This patch fixes the screen corruption by always appending a byte 0xAF at
the end of URB. It also removes the uninitialized byte.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 021c9179
...@@ -137,7 +137,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, ...@@ -137,7 +137,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
if (cmd > (char *) urb->transfer_buffer) { if (cmd > (char *) urb->transfer_buffer) {
/* Send partial buffer remaining before exiting */ /* Send partial buffer remaining before exiting */
int len = cmd - (char *) urb->transfer_buffer; int len;
if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length)
*cmd++ = 0xAF;
len = cmd - (char *) urb->transfer_buffer;
ret = udl_submit_urb(dev, urb, len); ret = udl_submit_urb(dev, urb, len);
bytes_sent += len; bytes_sent += len;
} else } else
......
...@@ -153,11 +153,11 @@ static void udl_compress_hline16( ...@@ -153,11 +153,11 @@ static void udl_compress_hline16(
raw_pixels_count_byte = cmd++; /* we'll know this later */ raw_pixels_count_byte = cmd++; /* we'll know this later */
raw_pixel_start = pixel; raw_pixel_start = pixel;
cmd_pixel_end = pixel + (min(MAX_CMD_PIXELS + 1, cmd_pixel_end = pixel + min3(MAX_CMD_PIXELS + 1UL,
min((int)(pixel_end - pixel) / bpp, (unsigned long)(pixel_end - pixel) / bpp,
(int)(cmd_buffer_end - cmd) / 2))) * bpp; (unsigned long)(cmd_buffer_end - 1 - cmd) / 2) * bpp;
prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); prefetch_range((void *) pixel, cmd_pixel_end - pixel);
pixel_val16 = get_pixel_val16(pixel, bpp); pixel_val16 = get_pixel_val16(pixel, bpp);
while (pixel < cmd_pixel_end) { while (pixel < cmd_pixel_end) {
...@@ -193,6 +193,9 @@ static void udl_compress_hline16( ...@@ -193,6 +193,9 @@ static void udl_compress_hline16(
if (pixel > raw_pixel_start) { if (pixel > raw_pixel_start) {
/* finalize last RAW span */ /* finalize last RAW span */
*raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) & 0xFF; *raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) & 0xFF;
} else {
/* undo unused byte */
cmd--;
} }
*cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) & 0xFF; *cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) & 0xFF;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment