aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fbdev.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 1f4b3d1a7713..836f41008187 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -33,6 +33,7 @@
33 33
34#include "exynos_drm_drv.h" 34#include "exynos_drm_drv.h"
35#include "exynos_drm_fb.h" 35#include "exynos_drm_fb.h"
36#include "exynos_drm_gem.h"
36#include "exynos_drm_buf.h" 37#include "exynos_drm_buf.h"
37 38
38#define MAX_CONNECTOR 4 39#define MAX_CONNECTOR 4
@@ -85,15 +86,13 @@ static struct fb_ops exynos_drm_fb_ops = {
85}; 86};
86 87
87static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, 88static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
88 struct drm_framebuffer *fb, 89 struct drm_framebuffer *fb)
89 unsigned int fb_width,
90 unsigned int fb_height)
91{ 90{
92 struct fb_info *fbi = helper->fbdev; 91 struct fb_info *fbi = helper->fbdev;
93 struct drm_device *dev = helper->dev; 92 struct drm_device *dev = helper->dev;
94 struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper); 93 struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper);
95 struct exynos_drm_buf_entry *entry; 94 struct exynos_drm_gem_buf *buffer;
96 unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3); 95 unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
97 unsigned long offset; 96 unsigned long offset;
98 97
99 DRM_DEBUG_KMS("%s\n", __FILE__); 98 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -101,20 +100,20 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
101 exynos_fb->fb = fb; 100 exynos_fb->fb = fb;
102 101
103 drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth); 102 drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
104 drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height); 103 drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
105 104
106 entry = exynos_drm_fb_get_buf(fb); 105 buffer = exynos_drm_fb_get_buf(fb);
107 if (!entry) { 106 if (!buffer) {
108 DRM_LOG_KMS("entry is null.\n"); 107 DRM_LOG_KMS("buffer is null.\n");
109 return -EFAULT; 108 return -EFAULT;
110 } 109 }
111 110
112 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); 111 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
113 offset += fbi->var.yoffset * fb->pitch; 112 offset += fbi->var.yoffset * fb->pitch;
114 113
115 dev->mode_config.fb_base = entry->paddr; 114 dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
116 fbi->screen_base = entry->vaddr + offset; 115 fbi->screen_base = buffer->kvaddr + offset;
117 fbi->fix.smem_start = entry->paddr + offset; 116 fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
118 fbi->screen_size = size; 117 fbi->screen_size = size;
119 fbi->fix.smem_len = size; 118 fbi->fix.smem_len = size;
120 119
@@ -171,8 +170,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
171 goto out; 170 goto out;
172 } 171 }
173 172
174 ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width, 173 ret = exynos_drm_fbdev_update(helper, helper->fb);
175 sizes->fb_height);
176 if (ret < 0) 174 if (ret < 0)
177 fb_dealloc_cmap(&fbi->cmap); 175 fb_dealloc_cmap(&fbi->cmap);
178 176
@@ -235,8 +233,7 @@ static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
235 } 233 }
236 234
237 helper->fb = exynos_fbdev->fb; 235 helper->fb = exynos_fbdev->fb;
238 return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width, 236 return exynos_drm_fbdev_update(helper, helper->fb);
239 sizes->fb_height);
240} 237}
241 238
242static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, 239static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
@@ -405,6 +402,18 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
405 fb_helper = private->fb_helper; 402 fb_helper = private->fb_helper;
406 403
407 if (fb_helper) { 404 if (fb_helper) {
405 struct list_head temp_list;
406
407 INIT_LIST_HEAD(&temp_list);
408
409 /*
410 * fb_helper is reintialized but kernel fb is reused
411 * so kernel_fb_list need to be backuped and restored
412 */
413 if (!list_empty(&fb_helper->kernel_fb_list))
414 list_replace_init(&fb_helper->kernel_fb_list,
415 &temp_list);
416
408 drm_fb_helper_fini(fb_helper); 417 drm_fb_helper_fini(fb_helper);
409 418
410 ret = drm_fb_helper_init(dev, fb_helper, 419 ret = drm_fb_helper_init(dev, fb_helper,
@@ -414,6 +423,9 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
414 return ret; 423 return ret;
415 } 424 }
416 425
426 if (!list_empty(&temp_list))
427 list_replace(&temp_list, &fb_helper->kernel_fb_list);
428
417 ret = drm_fb_helper_single_add_all_connectors(fb_helper); 429 ret = drm_fb_helper_single_add_all_connectors(fb_helper);
418 if (ret < 0) { 430 if (ret < 0) {
419 DRM_ERROR("failed to add fb helper to connectors\n"); 431 DRM_ERROR("failed to add fb helper to connectors\n");