aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/udl/udl_transfer.c39
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
85static bool pixel_repeats(const void *pixel, const uint32_t repeat, int bpp) 85static 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