diff options
Diffstat (limited to 'drivers/gpu/drm/udl')
-rw-r--r-- | drivers/gpu/drm/udl/udl_fb.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_modeset.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_transfer.c | 39 |
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; |