CHROMIUM: drm/exynos: fbdev: Offset is always zero
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_drm_fbdev.c
index d5586cc..e3c4826 100644 (file)
@@ -46,8 +46,23 @@ struct exynos_drm_fbdev {
        struct exynos_drm_gem_obj       *exynos_gem_obj;
 };
 
+static int
+exynos_drm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
+{
+       int ret;
+
+       vma->vm_pgoff = 0;
+       ret = dma_mmap_writecombine(info->device, vma, info->screen_base,
+                       info->fix.smem_start, vma->vm_end - vma->vm_start);
+       if (ret)
+               printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
+
+       return ret;
+}
+
 static struct fb_ops exynos_drm_fb_ops = {
        .owner          = THIS_MODULE,
+       .fb_mmap        = exynos_drm_fb_mmap,
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
@@ -63,9 +78,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
 {
        struct fb_info *fbi = helper->fbdev;
        struct drm_device *dev = helper->dev;
+       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
        struct exynos_drm_gem_buf *buffer;
        unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
-       unsigned long offset;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -73,18 +88,15 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
        drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
 
        /* RGB formats use only one buffer */
-       buffer = exynos_drm_fb_buffer(fb, 0);
+       buffer = exynos_drm_fb_buffer(exynos_fb, 0);
        if (!buffer) {
                DRM_LOG_KMS("buffer is null.\n");
                return -EFAULT;
        }
 
-       offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
-       offset += fbi->var.yoffset * fb->pitches[0];
-
        dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
-       fbi->screen_base = buffer->kvaddr + offset;
-       fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
+       fbi->screen_base = buffer->kvaddr;
+       fbi->fix.smem_start = (unsigned long)(buffer->dma_addr);
        fbi->screen_size = size;
        fbi->fix.smem_len = size;
 
@@ -96,6 +108,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 {
        struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
        struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct exynos_drm_fb *exynos_fb;
        struct drm_device *dev = helper->dev;
        struct fb_info *fbi;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
@@ -135,14 +148,15 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 
        exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
 
-       helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd,
-                       &exynos_gem_obj->base);
-       if (IS_ERR_OR_NULL(helper->fb)) {
+       exynos_fb = exynos_drm_fb_init(dev, &mode_cmd);
+       if (IS_ERR_OR_NULL(exynos_fb)) {
                DRM_ERROR("failed to create drm framebuffer.\n");
-               ret = PTR_ERR(helper->fb);
+               ret = PTR_ERR(exynos_fb);
                goto out;
        }
+       exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;
 
+       helper->fb = &exynos_fb->fb;
        helper->fbdev = fbi;
 
        fbi->par = helper;