aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fb.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c72
1 files changed, 34 insertions, 38 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 294c0513f58..65a22cad7b3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -20,9 +20,10 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
+#include "exynos_drm_fbdev.h"
#include "exynos_drm_gem.h"
#include "exynos_drm_iommu.h"
-#include "exynos_drm_encoder.h"
+#include "exynos_drm_crtc.h"
#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb)
@@ -70,10 +71,8 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
unsigned int i;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* make sure that overlay data are updated before relesing fb. */
- exynos_drm_encoder_complete_scanout(fb);
+ exynos_drm_crtc_complete_scanout(fb);
drm_framebuffer_cleanup(fb);
@@ -97,7 +96,9 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
- DRM_DEBUG_KMS("%s\n", __FILE__);
+ /* This fb should have only one gem object. */
+ if (WARN_ON(exynos_fb->buf_cnt != 1))
+ return -EINVAL;
return drm_gem_handle_create(file_priv,
&exynos_fb->exynos_gem_obj[0]->base, handle);
@@ -108,8 +109,6 @@ static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
unsigned color, struct drm_clip_rect *clips,
unsigned num_clips)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO */
return 0;
@@ -158,10 +157,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
}
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
- if (!exynos_fb) {
- DRM_ERROR("failed to allocate exynos drm framebuffer\n");
+ if (!exynos_fb)
return ERR_PTR(-ENOMEM);
- }
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;
@@ -217,21 +214,19 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_gem_object *obj;
+ struct exynos_drm_gem_obj *exynos_gem_obj;
struct exynos_drm_fb *exynos_fb;
int i, ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
+ exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
+ if (!exynos_fb)
+ return ERR_PTR(-ENOMEM);
obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
- return ERR_PTR(-ENOENT);
- }
-
- exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
- if (!exynos_fb) {
- DRM_ERROR("failed to allocate exynos drm framebuffer\n");
- return ERR_PTR(-ENOMEM);
+ ret = -ENOENT;
+ goto err_free;
}
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
@@ -241,43 +236,44 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
for (i = 1; i < exynos_fb->buf_cnt; i++) {
- struct exynos_drm_gem_obj *exynos_gem_obj;
- int ret;
-
obj = drm_gem_object_lookup(dev, file_priv,
mode_cmd->handles[i]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
- kfree(exynos_fb);
- return ERR_PTR(-ENOENT);
+ ret = -ENOENT;
+ exynos_fb->buf_cnt = i;
+ goto err_unreference;
}
exynos_gem_obj = to_exynos_gem_obj(obj);
+ exynos_fb->exynos_gem_obj[i] = exynos_gem_obj;
ret = check_fb_gem_memory_type(dev, exynos_gem_obj);
if (ret < 0) {
DRM_ERROR("cannot use this gem memory type for fb.\n");
- kfree(exynos_fb);
- return ERR_PTR(ret);
+ goto err_unreference;
}
-
- exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj);
}
ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
if (ret) {
- for (i = 0; i < exynos_fb->buf_cnt; i++) {
- struct exynos_drm_gem_obj *gem_obj;
-
- gem_obj = exynos_fb->exynos_gem_obj[i];
- drm_gem_object_unreference_unlocked(&gem_obj->base);
- }
-
- kfree(exynos_fb);
- return ERR_PTR(ret);
+ DRM_ERROR("failed to init framebuffer.\n");
+ goto err_unreference;
}
return &exynos_fb->fb;
+
+err_unreference:
+ for (i = 0; i < exynos_fb->buf_cnt; i++) {
+ struct drm_gem_object *obj;
+
+ obj = &exynos_fb->exynos_gem_obj[i]->base;
+ if (obj)
+ drm_gem_object_unreference_unlocked(obj);
+ }
+err_free:
+ kfree(exynos_fb);
+ return ERR_PTR(ret);
}
struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
@@ -286,8 +282,6 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
struct exynos_drm_gem_buf *buffer;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (index >= MAX_FB_BUFFER)
return NULL;
@@ -307,6 +301,8 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev)
if (fb_helper)
drm_fb_helper_hotplug_event(fb_helper);
+ else
+ exynos_drm_fbdev_init(dev);
}
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {