Merge tag 'drm-misc-next-2018-11-28' of git://anongit.freedesktop.org/drm/drm-misc...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / drm_fb_cma_helper.c
index 9ac1f2e0f064cb72528834ed6c21a82daf37be45..5b516615881a0029c54a8fad9db2696f02406b80 100644 (file)
@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
 EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
 
 /**
- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
+ * formats where values are grouped in blocks this will get you the beginning of
+ * the block
  * @fb: The framebuffer
  * @state: Which state of drm plane
  * @plane: Which plane
@@ -86,14 +88,33 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
 {
        struct drm_gem_cma_object *obj;
        dma_addr_t paddr;
+       u8 h_div = 1, v_div = 1;
+       u32 block_w = drm_format_info_block_width(fb->format, plane);
+       u32 block_h = drm_format_info_block_height(fb->format, plane);
+       u32 block_size = fb->format->char_per_block[plane];
+       u32 sample_x;
+       u32 sample_y;
+       u32 block_start_y;
+       u32 num_hblocks;
 
        obj = drm_fb_cma_get_gem_obj(fb, plane);
        if (!obj)
                return 0;
 
        paddr = obj->paddr + fb->offsets[plane];
-       paddr += fb->format->cpp[plane] * (state->src_x >> 16);
-       paddr += fb->pitches[plane] * (state->src_y >> 16);
+
+       if (plane > 0) {
+               h_div = fb->format->hsub;
+               v_div = fb->format->vsub;
+       }
+
+       sample_x = (state->src_x >> 16) / h_div;
+       sample_y = (state->src_y >> 16) / v_div;
+       block_start_y = (sample_y / block_h) * block_h;
+       num_hblocks = sample_x / block_w;
+
+       paddr += fb->pitches[plane] * block_start_y;
+       paddr += block_size * num_hblocks;
 
        return paddr;
 }
@@ -117,10 +138,7 @@ int drm_fb_cma_fbdev_init(struct drm_device *dev, unsigned int preferred_bpp,
 
        /* dev->fb_helper will indirectly point to fbdev_cma after this call */
        fbdev_cma = drm_fbdev_cma_init(dev, preferred_bpp, max_conn_count);
-       if (IS_ERR(fbdev_cma))
-               return PTR_ERR(fbdev_cma);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(fbdev_cma);
 }
 EXPORT_SYMBOL_GPL(drm_fb_cma_fbdev_init);
 
@@ -219,36 +237,3 @@ void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma)
                drm_fb_helper_hotplug_event(&fbdev_cma->fb_helper);
 }
 EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event);
-
-/**
- * drm_fbdev_cma_set_suspend - wrapper around drm_fb_helper_set_suspend
- * @fbdev_cma: The drm_fbdev_cma struct, may be NULL
- * @state: desired state, zero to resume, non-zero to suspend
- *
- * Calls drm_fb_helper_set_suspend, which is a wrapper around
- * fb_set_suspend implemented by fbdev core.
- */
-void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, bool state)
-{
-       if (fbdev_cma)
-               drm_fb_helper_set_suspend(&fbdev_cma->fb_helper, state);
-}
-EXPORT_SYMBOL(drm_fbdev_cma_set_suspend);
-
-/**
- * drm_fbdev_cma_set_suspend_unlocked - wrapper around
- *                                      drm_fb_helper_set_suspend_unlocked
- * @fbdev_cma: The drm_fbdev_cma struct, may be NULL
- * @state: desired state, zero to resume, non-zero to suspend
- *
- * Calls drm_fb_helper_set_suspend, which is a wrapper around
- * fb_set_suspend implemented by fbdev core.
- */
-void drm_fbdev_cma_set_suspend_unlocked(struct drm_fbdev_cma *fbdev_cma,
-                                       bool state)
-{
-       if (fbdev_cma)
-               drm_fb_helper_set_suspend_unlocked(&fbdev_cma->fb_helper,
-                                                  state);
-}
-EXPORT_SYMBOL(drm_fbdev_cma_set_suspend_unlocked);