diff options
| -rw-r--r-- | drivers/gpu/drm/udl/udl_transfer.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index f343db73e095..917dcb978c2c 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c | |||
| @@ -82,12 +82,14 @@ static inline u16 pixel32_to_be16(const uint32_t pixel) | |||
| 82 | ((pixel >> 8) & 0xf800)); | 82 | ((pixel >> 8) & 0xf800)); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static bool pixel_repeats(const void *pixel, const uint32_t repeat, int bpp) | 85 | static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp) |
| 86 | { | 86 | { |
| 87 | u16 pixel_val16 = 0; | ||
| 87 | if (bpp == 2) | 88 | if (bpp == 2) |
| 88 | return *(const uint16_t *)pixel == repeat; | 89 | pixel_val16 = *(const uint16_t *)pixel; |
| 89 | else | 90 | else if (bpp == 4) |
| 90 | return *(const uint32_t *)pixel == repeat; | 91 | pixel_val16 = pixel32_to_be16(*(const uint32_t *)pixel); |
| 92 | return pixel_val16; | ||
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | /* | 95 | /* |
| @@ -134,6 +136,7 @@ static void udl_compress_hline16( | |||
| 134 | uint8_t *cmd_pixels_count_byte = NULL; | 136 | uint8_t *cmd_pixels_count_byte = NULL; |
| 135 | const u8 *raw_pixel_start = NULL; | 137 | const u8 *raw_pixel_start = NULL; |
| 136 | const u8 *cmd_pixel_start, *cmd_pixel_end = NULL; | 138 | const u8 *cmd_pixel_start, *cmd_pixel_end = NULL; |
| 139 | uint16_t pixel_val16; | ||
| 137 | 140 | ||
| 138 | prefetchw((void *) cmd); /* pull in one cache line at least */ | 141 | prefetchw((void *) cmd); /* pull in one cache line at least */ |
| 139 | 142 | ||
| @@ -154,33 +157,29 @@ static void udl_compress_hline16( | |||
| 154 | (int)(cmd_buffer_end - cmd) / 2))) * bpp; | 157 | (int)(cmd_buffer_end - cmd) / 2))) * bpp; |
| 155 | 158 | ||
| 156 | prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); | 159 | prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); |
| 160 | pixel_val16 = get_pixel_val16(pixel, bpp); | ||
| 157 | 161 | ||
| 158 | while (pixel < cmd_pixel_end) { | 162 | while (pixel < cmd_pixel_end) { |
| 159 | const u8 *const start = pixel; | 163 | const u8 *const start = pixel; |
| 160 | u32 repeating_pixel; | 164 | const uint16_t repeating_pixel_val16 = pixel_val16; |
| 161 | 165 | ||
| 162 | if (bpp == 2) { | 166 | *(uint16_t *)cmd = cpu_to_be16(pixel_val16); |
| 163 | repeating_pixel = *(uint16_t *)pixel; | ||
| 164 | *(uint16_t *)cmd = cpu_to_be16(repeating_pixel); | ||
| 165 | } else { | ||
| 166 | repeating_pixel = *(uint32_t *)pixel; | ||
| 167 | *(uint16_t *)cmd = cpu_to_be16(pixel32_to_be16(repeating_pixel)); | ||
| 168 | } | ||
| 169 | 167 | ||
| 170 | cmd += 2; | 168 | cmd += 2; |
| 171 | pixel += bpp; | 169 | pixel += bpp; |
| 172 | 170 | ||
| 173 | if (unlikely((pixel < cmd_pixel_end) && | 171 | while (pixel < cmd_pixel_end) { |
| 174 | (pixel_repeats(pixel, repeating_pixel, bpp)))) { | 172 | pixel_val16 = get_pixel_val16(pixel, bpp); |
| 173 | if (pixel_val16 != repeating_pixel_val16) | ||
| 174 | break; | ||
| 175 | pixel += bpp; | ||
| 176 | } | ||
| 177 | |||
| 178 | if (unlikely(pixel > start + bpp)) { | ||
| 175 | /* go back and fill in raw pixel count */ | 179 | /* go back and fill in raw pixel count */ |
| 176 | *raw_pixels_count_byte = (((start - | 180 | *raw_pixels_count_byte = (((start - |
| 177 | raw_pixel_start) / bpp) + 1) & 0xFF; | 181 | raw_pixel_start) / bpp) + 1) & 0xFF; |
| 178 | 182 | ||
| 179 | while ((pixel < cmd_pixel_end) && | ||
| 180 | (pixel_repeats(pixel, repeating_pixel, bpp))) { | ||
| 181 | pixel += bpp; | ||
| 182 | } | ||
| 183 | |||
| 184 | /* immediately after raw data is repeat byte */ | 183 | /* immediately after raw data is repeat byte */ |
| 185 | *cmd++ = (((pixel - start) / bpp) - 1) & 0xFF; | 184 | *cmd++ = (((pixel - start) / bpp) - 1) & 0xFF; |
| 186 | 185 | ||
