aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/udl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/udl')
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c22
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c9
-rw-r--r--drivers/gpu/drm/udl/udl_transfer.c39
3 files changed, 42 insertions, 28 deletions
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 8cbcb4589bd3..5fc16cecd3ba 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -589,19 +589,27 @@ int udl_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &ufbdev->helper,
1, 1);
- if (ret) {
- kfree(ufbdev);
- return ret;
-
- }
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
+ ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&ufbdev->helper);
+free:
+ kfree(ufbdev);
+ return ret;
}
void udl_fbdev_cleanup(struct drm_device *dev)
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 1701f1dfb23f..677190a65e82 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -340,11 +340,11 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
wrptr = udl_dummy_render(wrptr);
- ufb->active_16 = true;
if (old_fb) {
struct udl_framebuffer *uold_fb = to_udl_fb(old_fb);
uold_fb->active_16 = false;
}
+ ufb->active_16 = true;
udl->mode_buf_len = wrptr - buf;
/* damage all of it */
@@ -373,6 +373,13 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
unsigned long flags;
+ struct drm_framebuffer *old_fb = crtc->primary->fb;
+ if (old_fb) {
+ struct udl_framebuffer *uold_fb = to_udl_fb(old_fb);
+ uold_fb->active_16 = false;
+ }
+ ufb->active_16 = true;
+
udl_handle_damage(ufb, 0, 0, fb->width, fb->height);
spin_lock_irqsave(&dev->event_lock, flags);
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)
((pixel >> 8) & 0xf800));
}
-static bool pixel_repeats(const void *pixel, const uint32_t repeat, int bpp)
+static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp)
{
+ u16 pixel_val16 = 0;
if (bpp == 2)
- return *(const uint16_t *)pixel == repeat;
- else
- return *(const uint32_t *)pixel == repeat;
+ pixel_val16 = *(const uint16_t *)pixel;
+ else if (bpp == 4)
+ pixel_val16 = pixel32_to_be16(*(const uint32_t *)pixel);
+ return pixel_val16;
}
/*
@@ -134,6 +136,7 @@ static void udl_compress_hline16(
uint8_t *cmd_pixels_count_byte = NULL;
const u8 *raw_pixel_start = NULL;
const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
+ uint16_t pixel_val16;
prefetchw((void *) cmd); /* pull in one cache line at least */
@@ -154,33 +157,29 @@ static void udl_compress_hline16(
(int)(cmd_buffer_end - cmd) / 2))) * bpp;
prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
+ pixel_val16 = get_pixel_val16(pixel, bpp);
while (pixel < cmd_pixel_end) {
const u8 *const start = pixel;
- u32 repeating_pixel;
-
- if (bpp == 2) {
- repeating_pixel = *(uint16_t *)pixel;
- *(uint16_t *)cmd = cpu_to_be16(repeating_pixel);
- } else {
- repeating_pixel = *(uint32_t *)pixel;
- *(uint16_t *)cmd = cpu_to_be16(pixel32_to_be16(repeating_pixel));
- }
+ const uint16_t repeating_pixel_val16 = pixel_val16;
+
+ *(uint16_t *)cmd = cpu_to_be16(pixel_val16);
cmd += 2;
pixel += bpp;
- if (unlikely((pixel < cmd_pixel_end) &&
- (pixel_repeats(pixel, repeating_pixel, bpp)))) {
+ while (pixel < cmd_pixel_end) {
+ pixel_val16 = get_pixel_val16(pixel, bpp);
+ if (pixel_val16 != repeating_pixel_val16)
+ break;
+ pixel += bpp;
+ }
+
+ if (unlikely(pixel > start + bpp)) {
/* go back and fill in raw pixel count */
*raw_pixels_count_byte = (((start -
raw_pixel_start) / bpp) + 1) & 0xFF;
- while ((pixel < cmd_pixel_end) &&
- (pixel_repeats(pixel, repeating_pixel, bpp))) {
- pixel += bpp;
- }
-
/* immediately after raw data is repeat byte */
*cmd++ = (((pixel - start) / bpp) - 1) & 0xFF;