Removed dependencies from libdrm sprd 06/55806/1
authorRoman Marchenko <r.marchenko@samsung.com>
Thu, 24 Dec 2015 11:18:50 +0000 (13:18 +0200)
committerRoman Marchenko <r.marchenko@samsung.com>
Tue, 29 Dec 2015 09:37:59 +0000 (11:37 +0200)
Change-Id: I48e208cee2ebb11dcfb62f6a6966d99fab2fb195
Signed-off-by: Roman Marchenko <r.marchenko@samsung.com>
configure.ac
packaging/libtdm-sprd.spec
src/tdm_sprd.c
src/tdm_sprd.h
src/tdm_sprd_display.c

index ddb7f06..725196c 100644 (file)
@@ -23,7 +23,7 @@ LT_INIT([disable-static])
 # Enable quiet compiles on automake 1.11.
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
-PKG_CHECK_MODULES(TDM_SPRD, libtdm libtbm libdrm libdrm_sprd)
+PKG_CHECK_MODULES(TDM_SPRD, libtdm libtbm libdrm)
 PKG_CHECK_MODULES(UDEV, libudev, [udev=yes], [udev=no])
 if test x"$udev" = xyes; then
        AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection])
index b31ebf4..66eda9f 100644 (file)
@@ -11,9 +11,10 @@ ExclusiveArch:
 Source0:        %{name}-%{version}.tar.gz
 Source1001:     %{name}.manifest
 BuildRequires: pkgconfig(libdrm)
-BuildRequires: pkgconfig(libdrm_sprd)
 BuildRequires: pkgconfig(libudev)
 BuildRequires: pkgconfig(libtdm)
+BuildRequires: kernel-headers-tizen-dev
+BuildConflicts: linux-glibc-devel
 
 %description
 Back-End library of Tizen Display Manager Spreadtrum : libtdm-mgr SPRD library
index 184785d..2411ca1 100644 (file)
@@ -6,7 +6,6 @@
 #include <libudev.h>
 #endif
 
-#include "sprd_drmif.h"
 #include "tdm_sprd.h"
 #include <tdm_helper.h>
 
@@ -133,6 +132,11 @@ _tdm_sprd_open_drm(void)
     }
 close_l:
 #endif
+
+#ifdef SET_DRM_IRQ
+    drmCtlInstHandler (fd, 78);
+#endif
+
     return fd;
 }
 #if 0
@@ -166,16 +170,7 @@ tdm_sprd_deinit(tdm_backend_data *bdata)
 #endif
     tdm_sprd_display_destroy_output_list(sprd_data);
     tdm_sprd_display_destroy_event_list(sprd_data);
-    if (sprd_data->plane_res)
-        drmModeFreePlaneResources(sprd_data->plane_res);
-    if (sprd_data->mode_res)
-        drmModeFreeResources(sprd_data->mode_res);
-    if (sprd_data->drm_fd >= 0)
-    {
-        if (sprd_data->sprd_drm_dev)
-            sprd_device_destroy(sprd_data->sprd_drm_dev);
-        close(sprd_data->drm_fd);
-    }
+
     free(sprd_data);
     sprd_data = NULL;
 }
@@ -223,8 +218,8 @@ tdm_sprd_init(tdm_display *dpy, tdm_error *error)
         goto failed_l;
 
     sprd_data->dpy = dpy;
-    sprd_data->fb_fd = -1;
     sprd_data->drm_fd = -1;
+
 #if 0
     /* TODO: tdm_helper_drm_fd is external drm_fd which is opened by ecore_drm.
      * This is very tricky. But we can't remove tdm_helper_drm_fd now because
@@ -233,6 +228,7 @@ tdm_sprd_init(tdm_display *dpy, tdm_error *error)
      */
     if (tdm_helper_drm_fd >= 0)
     {
+        TDM_INFO("Use tdm_helper_drm_fd\n");
         sprd_data->drm_fd = tdm_helper_drm_fd;
         drmAddUserHandler(tdm_helper_drm_fd, _tdm_sprd_drm_user_handler);
     }
@@ -245,58 +241,16 @@ tdm_sprd_init(tdm_display *dpy, tdm_error *error)
         ret = TDM_ERROR_OPERATION_FAILED;
         goto failed_l;
     }
-    if ((sprd_data->sprd_drm_dev = sprd_device_create(sprd_data->drm_fd)) == NULL)
-    {
-        ret = TDM_ERROR_OPERATION_FAILED;
-        goto failed_l;
-    }
 
 #if 0
     if (drmSetClientCap(sprd_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
         TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed_l");
 #endif
-    sprd_data->mode_res = drmModeGetResources(sprd_data->drm_fd);
-    if (!sprd_data->mode_res)
-    {
-        TDM_ERR("no drm resource: %m");
-        ret = TDM_ERROR_OPERATION_FAILED;
-        goto failed_l;
-    }
-
-    sprd_data->plane_res = drmModeGetPlaneResources(sprd_data->drm_fd);
-    if (!sprd_data->plane_res)
-    {
-        TDM_ERR("no drm plane resource: %m");
-        ret = TDM_ERROR_OPERATION_FAILED;
-        goto failed_l;
-    }
-
-    if (sprd_data->plane_res->count_planes <= 0)
-    {
-        TDM_ERR("no drm plane resource");
-        ret = TDM_ERROR_OPERATION_FAILED;
-        goto failed_l;
-    }
-
-    ret = tdm_sprd_display_get_property(sprd_data, sprd_data->plane_res->planes[0],
-                                          DRM_MODE_OBJECT_PLANE, "zpos", NULL,
-                                          &sprd_data->is_immutable_zpos);
-    if (ret == TDM_ERROR_NONE)
-    {
-        sprd_data->has_zpos_info = 1;
-        if (sprd_data->is_immutable_zpos)
-            TDM_DBG("plane has immutable zpos info");
-    }
-    else
-        TDM_DBG("plane doesn't have zpos info");
 
     ret = tdm_sprd_display_create_output_list(sprd_data);
     if (ret != TDM_ERROR_NONE)
         goto failed_l;
 
-    ret = tdm_sprd_display_create_layer_list(sprd_data);
-    if (ret != TDM_ERROR_NONE)
-        goto failed_l;
     ret = tdm_sprd_display_create_event_list(sprd_data);
     if (ret != TDM_ERROR_NONE)
         goto failed_l;
index 2471d7e..7527506 100644 (file)
@@ -14,7 +14,6 @@
 #include <fcntl.h>
 
 #include <xf86drm.h>
-#include <xf86drmMode.h>
 #include <tbm_surface.h>
 #include <tbm_surface_internal.h>
 #include <tdm_backend.h>
@@ -92,23 +91,11 @@ typedef struct _tdm_sprd_data
     struct list_head events_list;
     tdm_display *dpy;
     int drm_fd;
-    int fb_fd;
-    void * sprd_drm_dev;
+    int output_count;
 
-    /* If true, it means that the device has many planes for one crtc. If false,
-     * planes are dedicated to specific crtc.
-     */
-    int has_zpos_info;
-
-    /* If has_zpos_info is false and is_immutable_zpos is true, it means that
-     * planes are dedicated to specific crtc.
-     */
-    int is_immutable_zpos;
-
-    drmModeResPtr mode_res;
-    drmModePlaneResPtr plane_res;
     struct list_head output_list;
     struct list_head buffer_list;
+
 } tdm_sprd_data;
 
 uint32_t     tdm_sprd_format_to_drm_format(tbm_format format);
@@ -117,12 +104,6 @@ tbm_format   tdm_sprd_format_to_tbm_format(uint32_t format);
 tdm_error    tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data);
 void         tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data);
 tdm_error    tdm_sprd_display_create_layer_list(tdm_sprd_data *sprd_data);
-tdm_error    tdm_sprd_display_set_property(tdm_sprd_data *sprd_data,
-                                             unsigned int obj_id, unsigned int obj_type,
-                                             const char *name, unsigned int value);
-tdm_error    tdm_sprd_display_get_property(tdm_sprd_data *sprd_data,
-                                             unsigned int obj_id, unsigned int obj_type,
-                                             const char *name, unsigned int *value, int *is_immutable);
 
 tdm_error    tdm_sprd_pp_get_capability(tdm_sprd_data *sprd_data, tdm_caps_pp *caps);
 tdm_pp*      tdm_sprd_pp_create(tdm_sprd_data *sprd_data, tdm_error *error);
index 749c586..ecacfce 100644 (file)
@@ -2,8 +2,10 @@
 #include "config.h"
 #endif
 
-#include <drm_fourcc.h>
 #include <tdm_helper.h>
+#include <linux/fb.h>
+#include <video/sprdfb.h>
+#include <tbm_surface.h>
 #include "tdm_sprd.h"
 
 #define MIN_WIDTH   32
@@ -14,6 +16,8 @@
 typedef struct drm_event hw_event_t;
 #endif
 
+#define FB_DEV_LCD  "/dev/fb0"
+
 typedef struct _tdm_sprd_output_data tdm_sprd_output_data;
 typedef struct _tdm_sprd_layer_data tdm_sprd_layer_data;
 typedef struct _tdm_sprd_vblank_data_s tdm_sprd_vblank_data;
@@ -45,6 +49,14 @@ typedef struct _tdm_sprd_display_buffer
     unsigned int fb_id;
     tbm_surface_h buffer;
     int width;
+    unsigned int height;
+    unsigned int format;
+    unsigned int handles[4];
+    unsigned int name[4];
+    unsigned int pitches[4];
+    unsigned int offsets[4];
+    unsigned int size;
+    unsigned int count;
 } tdm_sprd_display_buffer;
 
 struct _tdm_sprd_output_data
@@ -53,18 +65,12 @@ struct _tdm_sprd_output_data
 
     /* data which are fixed at initializing */
     tdm_sprd_data *sprd_data;
-    uint32_t connector_id;
-    uint32_t encoder_id;
-    uint32_t crtc_id;
     uint32_t pipe;
-    uint32_t dpms_prop_id;
     int count_modes;
-    drmModeModeInfoPtr drm_modes;
     tdm_output_mode *output_modes;
     tdm_output_type connector_type;
     unsigned int connector_type_id;
     struct list_head layer_list;
-    tdm_sprd_layer_data *primary_layer;
 
     tdm_output_vblank_handler vblank_func;
     tdm_output_commit_handler commit_func;
@@ -74,6 +80,14 @@ struct _tdm_sprd_output_data
     const tdm_output_mode *current_mode;
 
     int waiting_vblank_event;
+
+    char * fb_fd_name;
+    int fb_fd;
+
+    struct fb_var_screeninfo mi;
+
+    tdm_output_dpms dpms_value;
+
 };
 
 struct _tdm_sprd_layer_data
@@ -83,10 +97,13 @@ struct _tdm_sprd_layer_data
     /* data which are fixed at initializing */
     tdm_sprd_data *sprd_data;
     tdm_sprd_output_data *output_data;
-    uint32_t plane_id;
     tdm_layer_capability capabilities;
     int zpos;
 
+    //list of sprd formats
+    int format_count;
+    tbm_format *formats;
+
     /* not fixed data below */
     tdm_info_layer info;
     int info_changed;
@@ -103,8 +120,23 @@ typedef struct _Drm_Event_Context
                        unsigned int  tv_sec, unsigned int  tv_usec, void *user_data);
 } Drm_Event_Context;
 
+tbm_format img_layer_formats[] = {
+        TBM_FORMAT_RGB565,
+        TBM_FORMAT_XRGB8888,
+        TBM_FORMAT_ARGB8888,
+        TBM_FORMAT_NV12,
+        TBM_FORMAT_YUV420
+};
+
+tbm_format osd_layer_formats[] = {
+        TBM_FORMAT_RGB565,
+        TBM_FORMAT_XRGB8888,
+        TBM_FORMAT_ARGB8888
+};
+
+#if 0
 static tdm_error
-check_hw_restriction(unsigned int crtc_w, unsigned int buf_w,
+check_hw_restriction(unsigned int output_w, unsigned int buf_w,
                      unsigned int src_x, unsigned int src_w, unsigned int dst_x, unsigned int dst_w,
                      unsigned int *new_src_x, unsigned int *new_src_w,
                      unsigned int *new_dst_x, unsigned int *new_dst_w)
@@ -123,13 +155,13 @@ check_hw_restriction(unsigned int crtc_w, unsigned int buf_w,
         return TDM_ERROR_BAD_REQUEST;
     }
 
-    if (src_x > dst_x || ((dst_x - src_x) + buf_w) > crtc_w)
+    if (src_x > dst_x || ((dst_x - src_x) + buf_w) > output_w)
         virtual_screen = 1;
     else
         virtual_screen = 0;
 
     start = (dst_x < 0) ? 0 : dst_x;
-    end = ((dst_x + dst_w) > crtc_w) ? crtc_w : (dst_x + dst_w);
+    end = ((dst_x + dst_w) > output_w) ? output_w : (dst_x + dst_w);
 
     /* check window minimun width */
     if ((end - start) < MIN_WIDTH)
@@ -166,32 +198,8 @@ check_hw_restriction(unsigned int crtc_w, unsigned int buf_w,
 
     return TDM_ERROR_NONE;
 }
+#endif
 
-static drmModeModeInfoPtr
-_tdm_sprd_display_get_mode(tdm_sprd_output_data *output_data)
-{
-    int i;
-
-    if (!output_data->current_mode)
-    {
-        TDM_ERR("no output_data->current_mode");
-        return NULL;
-    }
-
-    for (i = 0; i < output_data->count_modes; i++)
-    {
-        drmModeModeInfoPtr drm_mode = &output_data->drm_modes[i];
-        if ((drm_mode->hdisplay == output_data->current_mode->width) &&
-            (drm_mode->vdisplay == output_data->current_mode->height) &&
-            (drm_mode->vrefresh == output_data->current_mode->refresh) &&
-            (drm_mode->flags == output_data->current_mode->flags) &&
-            (drm_mode->type == output_data->current_mode->type) &&
-            !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN)))
-            return drm_mode;
-    }
-
-    return NULL;
-}
 
 static tdm_sprd_display_buffer*
 _tdm_sprd_display_find_buffer(tdm_sprd_data *sprd_data, tbm_surface_h buffer)
@@ -207,15 +215,50 @@ _tdm_sprd_display_find_buffer(tdm_sprd_data *sprd_data, tbm_surface_h buffer)
     return NULL;
 }
 
-static void
-_tdm_sprd_display_to_tdm_mode(drmModeModeInfoPtr drm_mode, tdm_output_mode *tdm_mode)
+
+static inline uint32_t _get_refresh(struct fb_var_screeninfo * timing)
 {
-    tdm_mode->width = drm_mode->hdisplay;
-    tdm_mode->height = drm_mode->vdisplay;
-    tdm_mode->refresh = drm_mode->vrefresh;
-    tdm_mode->flags = drm_mode->flags;
-    tdm_mode->type = drm_mode->type;
-    snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", drm_mode->name);
+    uint32_t pixclock, hfreq, htotal, vtotal;
+
+    pixclock = PICOS2KHZ(timing->pixclock) * 1000;
+
+    htotal = timing->xres + timing->right_margin + timing->hsync_len +
+            timing->left_margin;
+    vtotal = timing->yres + timing->lower_margin + timing->vsync_len +
+            timing->upper_margin;
+
+    if (timing->vmode & FB_VMODE_INTERLACED)
+        vtotal /= 2;
+    if (timing->vmode & FB_VMODE_DOUBLE)
+        vtotal *= 2;
+
+    hfreq = pixclock/htotal;
+    return hfreq/vtotal;
+}
+
+/*
+ * Convert fb_var_screeninfo to tdm_output_mode
+ */
+static inline void _tdm_sprd_display_to_tdm_mode(struct fb_var_screeninfo * timing, tdm_output_mode  *mode)
+{
+
+    if (!timing->pixclock)
+        return;
+
+    mode->refresh = _get_refresh(timing);
+    mode->width = timing->xres;
+    mode->height = timing->yres;
+    mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+    if (timing->vmode & FB_VMODE_INTERLACED)
+        mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+    if (timing->vmode & FB_VMODE_DOUBLE)
+        mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+    int interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+    snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s", mode->width, mode->height,
+             interlaced ? "i" : "");
 }
 
 static int
@@ -302,157 +345,171 @@ _tdm_sprd_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
 }
 
 static tdm_error
-_tdm_sprd_display_commit_primary_layer(tdm_sprd_layer_data *layer_data)
+_tdm_sprd_display_output_disable (tdm_sprd_output_data *output_data)
 {
-    tdm_sprd_data *sprd_data = layer_data->sprd_data;
-    tdm_sprd_output_data *output_data = layer_data->output_data;
-
-    if (output_data->mode_changed && layer_data->display_buffer_changed)
+    TDM_DBG ("FB_BLANK_POWERDOWN\n");
+    if (ioctl (output_data->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0)
     {
-        drmModeModeInfoPtr mode;
+        TDM_ERR ("FB_BLANK_POWERDOWN is failed: %s\n", strerror (errno));
+        return TDM_ERROR_OPERATION_FAILED;
+    }
+    return TDM_ERROR_NONE;
+}
 
-        if (!layer_data->display_buffer)
-        {
-            TDM_ERR("primary layer should have a buffer for modestting");
-            return TDM_ERROR_BAD_REQUEST;
-        }
+static tdm_error
+_tdm_sprd_display_output_enable(tdm_sprd_output_data *output_data)
+{
+    TDM_DBG ("FB_BLANK_UNBLANK\n");
+    if (ioctl (output_data->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0)
+    {
+        TDM_ERR ("FB_BLANK_UNBLANK is failed: %s\n", strerror (errno));
+        return TDM_ERROR_OPERATION_FAILED;
+    }
+    return TDM_ERROR_NONE;
+}
 
-        output_data->mode_changed = 0;
-        layer_data->display_buffer_changed = 0;
-        layer_data->info_changed = 0;
+static tdm_error
+_tdm_sprd_tbmformat_to_sprdformat(int tbm_format, overlay_info *ovi)
+{
+    ovi->rb_switch = 0;
+    ovi->data_type = 0;
+    ovi->endian.y  = 0;
+    ovi->endian.u  = 0;
+    ovi->endian.v  = 0;
+
+    switch(tbm_format)
+    {
+    case TBM_FORMAT_RGB565:
+        ovi->data_type = SPRD_DATA_FORMAT_RGB565;
+        ovi->endian.y = SPRD_DATA_ENDIAN_B0B1B2B3;
+        ovi->endian.u = SPRD_DATA_ENDIAN_B0B1B2B3;
+        break;
+    case TBM_FORMAT_ARGB8888:
+    case TBM_FORMAT_XRGB8888:
+        ovi->data_type = SPRD_DATA_FORMAT_RGB888;
+        ovi->endian.y  = SPRD_DATA_ENDIAN_B0B1B2B3;
+        ovi->endian.u  = SPRD_DATA_ENDIAN_B0B1B2B3;
+        break;
+    case TBM_FORMAT_NV12:
+        ovi->data_type = SPRD_DATA_FORMAT_YUV420;
+        ovi->endian.y  = SPRD_DATA_ENDIAN_B3B2B1B0;
+        ovi->endian.u  = SPRD_DATA_ENDIAN_B3B2B1B0;
+        break;
+    case TBM_FORMAT_YUV420:
+        ovi->data_type = SPRD_DATA_FORMAT_YUV420_3P;
+        ovi->endian.y  = SPRD_DATA_ENDIAN_B3B2B1B0;
+        ovi->endian.u  = SPRD_DATA_ENDIAN_B3B2B1B0;
+        ovi->endian.v  = SPRD_DATA_ENDIAN_B3B2B1B0;
+        break;
+    default:
+        return TDM_ERROR_INVALID_PARAMETER;
+    }
+    return TDM_ERROR_NONE;
+}
 
-        mode = _tdm_sprd_display_get_mode(output_data);
-        if (!mode)
-        {
-            TDM_ERR("couldn't find proper mode");
-            return TDM_ERROR_BAD_REQUEST;
-        }
+static tdm_error
+_tdm_sprd_display_do_commit(tdm_sprd_output_data *output_data)
+{
+    tdm_error res = TDM_ERROR_NONE;
+    tdm_sprd_layer_data *layer_data;
+    overlay_info ovi;
+    overlay_display ov_disp = {0,};
+    int layer_index;
 
-        if (drmModeSetCrtc(sprd_data->drm_fd, output_data->crtc_id,
-                           layer_data->display_buffer->fb_id, 0, 0,
-                           &output_data->connector_id, 1, mode))
-        {
-            TDM_ERR("set crtc failed: %m");
-            return TDM_ERROR_OPERATION_FAILED;
-        }
+    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
 
-        return TDM_ERROR_NONE;
+    if (output_data->dpms_value == TDM_OUTPUT_DPMS_OFF)
+    {
+        output_data->dpms_value = TDM_OUTPUT_DPMS_ON;
+        _tdm_sprd_display_output_enable(output_data);
     }
-    else if (layer_data->display_buffer_changed)
+
+    LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
     {
-        layer_data->display_buffer_changed = 0;
+        if(!layer_data->display_buffer_changed && !layer_data->info_changed)
+            continue;
 
-        if (!layer_data->display_buffer)
+        if (layer_data->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
         {
-            if (drmModeSetCrtc(sprd_data->drm_fd, output_data->crtc_id,
-                               0, 0, 0, NULL, 0, NULL))
-            {
-                TDM_ERR("unset crtc failed: %m");
-                return TDM_ERROR_OPERATION_FAILED;
-            }
+            layer_index = SPRD_LAYER_OSD;
+        }
+        else if (layer_data->capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
+        {
+            layer_index = SPRD_LAYER_IMG;
         }
         else
         {
-#if 0
-            if (drmModePageFlip(sprd_data->drm_fd, output_data->crtc_id,
-                                layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, layer_data->display_buffer))
+            TDM_ERR ("layer capability (0x%x) not supported\n", layer_data->capabilities);
+            continue;
+        }
+
+        if(layer_data->display_buffer)
+        {
+            ovi.layer_index = layer_index;
+            ov_disp.layer_index |= layer_index;
+
+            //TODO:: support differet formats
+            if(_tdm_sprd_tbmformat_to_sprdformat(layer_data->info.src_config.format, &ovi) != TDM_ERROR_NONE)
             {
-                TDM_ERR("pageflip failed: %m");
-                return TDM_ERROR_OPERATION_FAILED;
-            }
-#endif
-            drmModeModeInfoPtr mode;
-            mode = _tdm_sprd_display_get_mode(output_data);
-            if (drmModeSetCrtc(sprd_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id, 0 ,0,
-                               &output_data->connector_id, 1, mode)) {
+                ovi.data_type = SPRD_DATA_FORMAT_RGB888;
+                ovi.endian.y = SPRD_DATA_ENDIAN_B0B1B2B3;
+                ovi.endian.u = SPRD_DATA_ENDIAN_B0B1B2B3;
+                ovi.endian.v = SPRD_DATA_ENDIAN_B0B1B2B3;
+                TDM_WRN("Unsupported format\n");
             }
-        }
-    }
 
-    return TDM_ERROR_NONE;
-}
+            ovi.size.hsize = layer_data->display_buffer->pitches[0] / 4;
+            ovi.size.vsize = layer_data->display_buffer->height;
 
-static tdm_error
-_tdm_sprd_display_commit_layer(tdm_sprd_layer_data *layer_data)
-{
-    tdm_sprd_data *sprd_data = layer_data->sprd_data;
-    tdm_sprd_output_data *output_data = layer_data->output_data;
-    unsigned int new_src_x, new_src_w;
-    unsigned int new_dst_x, new_dst_w;
-    uint32_t fx, fy, fw, fh;
-    int crtc_w;
-
-    if (!layer_data->display_buffer_changed && !layer_data->info_changed)
-        return TDM_ERROR_NONE;
+            ovi.rect.x = layer_data->info.dst_pos.x;
+            ovi.rect.y = layer_data->info.dst_pos.y;
 
-    if (output_data->current_mode)
-        crtc_w = output_data->current_mode->width;
-    else
-    {
-        drmModeCrtcPtr crtc = drmModeGetCrtc(sprd_data->drm_fd, output_data->crtc_id);
-        if (!crtc)
-        {
-            TDM_ERR("getting crtc failed");
-            return TDM_ERROR_OPERATION_FAILED;
+            //restrict width
+            int output_width = output_data->mi.xres;
+            int width = layer_data->info.src_config.pos.w;
+            int x = layer_data->info.dst_pos.x;
+            
+            ovi.rect.w = (width + x) <= output_width ? width : output_width - x;
+            ovi.rect.h = layer_data->info.src_config.pos.h;
+
+            if (ovi.layer_index == SPRD_LAYER_OSD)
+            {
+                ov_disp.osd_handle = layer_data->display_buffer->name[0];
+            }
+            else if (ovi.layer_index == SPRD_LAYER_IMG)
+            {
+                ov_disp.img_handle = layer_data->display_buffer->name[0];
+            }
+
+            TDM_DBG("SPRD_FB_SET_OVERLAY(%d) rect:%dx%d+%d+%d size:%dx%d\n", ovi.layer_index,
+                    ovi.rect.w, ovi.rect.h, ovi.rect.x, ovi.rect.y, ovi.size.hsize, ovi.size.vsize);
+            if (ioctl (layer_data->output_data->fb_fd, SPRD_FB_SET_OVERLAY, &ovi) == -1)
+            {
+                TDM_ERR ("SPRD_FB_SET_OVERLAY(%d) error:%s\n", layer_index, strerror (errno));
+            }
         }
-        crtc_w = crtc->width;
-        if (crtc_w == 0)
+        else
         {
-            TDM_ERR("getting crtc width failed");
-            return TDM_ERROR_OPERATION_FAILED;
+            if (ioctl(layer_data->output_data->fb_fd, SPRD_FB_UNSET_OVERLAY, &layer_index) == -1)
+            {
+                TDM_ERR ("SPRD_FB_UNSET_OVERLAY(%d) error:%s\n", layer_index, strerror (errno));
+            }
         }
     }
 
-    layer_data->display_buffer_changed = 0;
-    layer_data->info_changed = 0;
 
-    if (!layer_data->display_buffer)
+    if (ov_disp.layer_index)
     {
-        if (drmModeSetPlane(sprd_data->drm_fd, layer_data->plane_id,
-                            output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
-            TDM_WRN("unset plane(%d) filed: %m", layer_data->plane_id);
+        ov_disp.display_mode = SPRD_DISPLAY_OVERLAY_SYNC;
 
-       return TDM_ERROR_NONE;
-    }
-
-    /* check hw restriction*/
-    if (check_hw_restriction(crtc_w, layer_data->display_buffer->width,
-                             layer_data->info.src_config.pos.x,
-                             layer_data->info.src_config.pos.w,
-                             layer_data->info.dst_pos.x,
-                             layer_data->info.dst_pos.w,
-                             &new_src_x, &new_src_w, &new_dst_x, &new_dst_w) != TDM_ERROR_NONE)
-    {
-        TDM_WRN("not going to set plane(%d)", layer_data->plane_id);
-        return TDM_ERROR_NONE;
-    }
-
-    if (layer_data->info.src_config.pos.x != new_src_x)
-        TDM_DBG("src_x changed: %d => %d", layer_data->info.src_config.pos.x, new_src_x);
-    if (layer_data->info.src_config.pos.w != new_src_w)
-        TDM_DBG("src_w changed: %d => %d", layer_data->info.src_config.pos.w, new_src_w);
-    if (layer_data->info.dst_pos.x != new_dst_x)
-        TDM_DBG("dst_x changed: %d => %d", layer_data->info.dst_pos.x, new_dst_x);
-    if (layer_data->info.dst_pos.w != new_dst_w)
-        TDM_DBG("dst_w changed: %d => %d", layer_data->info.dst_pos.w, new_dst_w);
-
-    /* Source values are 16.16 fixed point */
-    fx = ((unsigned int)new_src_x) << 16;
-    fy = ((unsigned int)layer_data->info.src_config.pos.y) << 16;
-    fw = ((unsigned int)new_src_w) << 16;
-    fh = ((unsigned int)layer_data->info.src_config.pos.h) << 16;
-
-    if (drmModeSetPlane(sprd_data->drm_fd, layer_data->plane_id,
-                        output_data->crtc_id, layer_data->display_buffer->fb_id, 0,
-                        new_dst_x, layer_data->info.dst_pos.y,
-                        new_dst_w, layer_data->info.dst_pos.h,
-                        fx, fy, fw, fh) < 0)
-    {
-        TDM_ERR("set plane(%d) failed: %m", layer_data->plane_id);
-        return TDM_ERROR_OPERATION_FAILED;
+        TDM_DBG("SPRD_FB_DISPLAY_OVERLAY(%d) osd_handle:%d img_handle:%d\n", ov_disp.layer_index, ov_disp.osd_handle, ov_disp.img_handle);
+        if (ioctl(output_data->fb_fd, SPRD_FB_DISPLAY_OVERLAY, &ov_disp) == -1) {
+            TDM_ERR( "SPRD_FB_DISPLAY_OVERLAY(%d) error: %s \n", strerror (errno), ov_disp.layer_index);
+            res = TDM_ERROR_OPERATION_FAILED;
+        }
     }
 
-    return TDM_ERROR_NONE;
+    return res;
 }
 
 #if 0
@@ -544,615 +601,222 @@ _tdm_sprd_display_events_handle(int fd, Drm_Event_Context *evctx)
     return 0;
 }
 #endif
-static tdm_error
-_tdm_sprd_display_create_layer_list_type(tdm_sprd_data *sprd_data)
-{
-    tdm_error ret;
-    int i;
-
-    for (i = 0; i < sprd_data->plane_res->count_planes; i++)
-    {
-        tdm_sprd_output_data *output_data = NULL;
-        tdm_sprd_layer_data *layer_data;
-        drmModePlanePtr plane;
-        unsigned int type = 0;
-
-        plane = drmModeGetPlane(sprd_data->drm_fd, sprd_data->plane_res->planes[i]);
-        if (!plane)
-        {
-            TDM_ERR("no plane");
-            continue;
-        }
-
-        ret = tdm_sprd_display_get_property(sprd_data, sprd_data->plane_res->planes[i],
-                                              DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
-        if (ret != TDM_ERROR_NONE)
-        {
-            TDM_ERR("plane(%d) doesn't have 'type' info", sprd_data->plane_res->planes[i]);
-            drmModeFreePlane(plane);
-            continue;
-        }
-
-        layer_data = calloc(1, sizeof(tdm_sprd_layer_data));
-        if (!layer_data)
-        {
-            TDM_ERR("alloc failed");
-            drmModeFreePlane(plane);
-            continue;
-        }
-
-        LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
-        {
-            if (plane->possible_crtcs & (1 << output_data->pipe))
-                break;
-        }
-
-        if (!output_data)
-        {
-            TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
-            drmModeFreePlane(plane);
-            free(layer_data);
-            continue;
-        }
-
-        layer_data->sprd_data = sprd_data;
-        layer_data->output_data = output_data;
-        layer_data->plane_id = sprd_data->plane_res->planes[i];
-
-        if (type == DRM_PLANE_TYPE_CURSOR)
-        {
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR | TDM_LAYER_CAPABILITY_GRAPHIC;
-            layer_data->zpos = 2;
-        }
-        else if (type == DRM_PLANE_TYPE_OVERLAY)
-        {
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY | TDM_LAYER_CAPABILITY_GRAPHIC;
-            layer_data->zpos = 1;
-        }
-        else if (type == DRM_PLANE_TYPE_PRIMARY)
-        {
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
-            layer_data->zpos = 0;
-            output_data->primary_layer = layer_data;
-        }
-        else
-        {
-            drmModeFreePlane(plane);
-            free(layer_data);
-            continue;
-        }
-
-        TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                layer_data->zpos, layer_data->capabilities);
-
-        LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
-
-        drmModeFreePlane(plane);
-    }
-
-    return TDM_ERROR_NONE;
-}
 
 static tdm_error
-_tdm_sprd_display_create_layer_list_immutable_zpos(tdm_sprd_data *sprd_data)
+_tdm_sprd_display_create_layer_list_LCD(tdm_sprd_output_data *output_data)
 {
-    tdm_error ret;
-    int i;
-
-    for (i = 0; i < sprd_data->plane_res->count_planes; i++)
-    {
-        tdm_sprd_output_data *output_data = NULL;
-        tdm_sprd_layer_data *layer_data;
-        drmModePlanePtr plane;
-        unsigned int type = 0, zpos = 0;
-
-        plane = drmModeGetPlane(sprd_data->drm_fd, sprd_data->plane_res->planes[i]);
-        if (!plane)
-        {
-            TDM_ERR("no plane");
-            continue;
-        }
-
-        ret = tdm_sprd_display_get_property(sprd_data, sprd_data->plane_res->planes[i],
-                                              DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
-        if (ret != TDM_ERROR_NONE)
-        {
-            TDM_ERR("plane(%d) doesn't have 'type' info", sprd_data->plane_res->planes[i]);
-            drmModeFreePlane(plane);
-            continue;
-        }
-
-        ret = tdm_sprd_display_get_property(sprd_data, sprd_data->plane_res->planes[i],
-                                              DRM_MODE_OBJECT_PLANE, "zpos", &zpos, NULL);
-        if (ret != TDM_ERROR_NONE)
-        {
-            TDM_ERR("plane(%d) doesn't have 'zpos' info", sprd_data->plane_res->planes[i]);
-            drmModeFreePlane(plane);
-            continue;
-        }
-
-        layer_data = calloc(1, sizeof(tdm_sprd_layer_data));
-        if (!layer_data)
-        {
-            TDM_ERR("alloc failed");
-            drmModeFreePlane(plane);
-            continue;
-        }
-
-        LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
-        {
-            if (plane->possible_crtcs & (1 << output_data->pipe))
-                break;
-        }
-
-        if (!output_data)
-        {
-            TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
-            drmModeFreePlane(plane);
-            free(layer_data);
-            continue;
-        }
+    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
 
-        layer_data->sprd_data = sprd_data;
-        layer_data->output_data = output_data;
-        layer_data->plane_id = sprd_data->plane_res->planes[i];
-        layer_data->zpos = zpos;
+    tdm_sprd_data *sprd_data = output_data->sprd_data;
+    tdm_sprd_layer_data *layer_data;
 
-        if (type == DRM_PLANE_TYPE_CURSOR)
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR | TDM_LAYER_CAPABILITY_GRAPHIC;
-        else if (type == DRM_PLANE_TYPE_OVERLAY)
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY | TDM_LAYER_CAPABILITY_GRAPHIC;
-        else if (type == DRM_PLANE_TYPE_PRIMARY)
-        {
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
-            output_data->primary_layer = layer_data;
-        }
-        else
-        {
-            drmModeFreePlane(plane);
-            free(layer_data);
-            continue;
-        }
-
-        TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                layer_data->zpos, layer_data->capabilities);
-
-        LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
-
-        drmModeFreePlane(plane);
-    }
-
-    return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_sprd_display_create_layer_list_not_fixed(tdm_sprd_data *sprd_data)
-{
-    int i, find_pipe = -1;
-
-    if (sprd_data->mode_res->count_connectors * LAYER_COUNT_PER_OUTPUT > sprd_data->plane_res->count_planes)
+    //create OSD layer
+    layer_data = calloc (1, sizeof(tdm_sprd_layer_data));
+    if (!layer_data)
     {
-        TDM_ERR("not enough layers");
-        return TDM_ERROR_OPERATION_FAILED;
+        TDM_ERR("alloc failed");
     }
 
-    for (i = 0; i < sprd_data->plane_res->count_planes; i++)
-    {
-        tdm_sprd_output_data *output_data = NULL;
-        tdm_sprd_layer_data *layer_data;
-        drmModePlanePtr plane;
+    layer_data->sprd_data = sprd_data;
+    layer_data->output_data = output_data;
 
-        plane = drmModeGetPlane(sprd_data->drm_fd, sprd_data->plane_res->planes[i]);
-        if (!plane)
-        {
-            TDM_ERR("no plane");
-            continue;
-        }
+    layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
+    layer_data->zpos = 1;
 
-        layer_data = calloc(1, sizeof(tdm_sprd_layer_data));
-        if (!layer_data)
-        {
-            TDM_ERR("alloc failed");
-            drmModeFreePlane(plane);
-            continue;
-        }
+    layer_data->format_count = sizeof(osd_layer_formats)/sizeof(int);
+    layer_data->formats = osd_layer_formats;
 
-        /* TODO
-         * Currently, kernel doesn give us the correct device infomation.
-         * Primary connector type is invalid. plane's count is not correct.
-         * So we need to fix all of them with kernel.
-         * Temporarily we dedicate only 2 plane to each output.
-         * First plane is primary layer. Second plane's zpos is 1.
-         */
-        if (i % LAYER_COUNT_PER_OUTPUT == 0)
-            find_pipe++;
-
-        LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
-        {
-            if (output_data->pipe == find_pipe)
-                break;
-        }
+    TDM_DBG("layer_data(%p) capabilities(%x)", layer_data, layer_data->capabilities);
 
-        if (i == sprd_data->mode_res->count_connectors * LAYER_COUNT_PER_OUTPUT)
-        {
-            TDM_DBG("no more plane(%d) need for outputs", plane->plane_id);
-            drmModeFreePlane(plane);
-            free(layer_data);
-            return TDM_ERROR_NONE;
-        }
-
-        layer_data->sprd_data = sprd_data;
-        layer_data->output_data = output_data;
-        layer_data->plane_id = sprd_data->plane_res->planes[i];
+    LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
 
-        layer_data->zpos = i % 2;
-        if (layer_data->zpos == 0)
-        {
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
-            output_data->primary_layer = layer_data;
-        }
-        else
-        {
-            tdm_error ret;
 
-            layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY | TDM_LAYER_CAPABILITY_GRAPHIC;
+    //create IMG layer
+    layer_data = calloc (1, sizeof(tdm_sprd_layer_data));
+    if (!layer_data)
+    {
+        TDM_ERR("alloc failed");
+    }
+    layer_data->sprd_data = sprd_data;
+    layer_data->output_data = output_data;
+    layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY | TDM_LAYER_CAPABILITY_GRAPHIC;
+    layer_data->zpos = 0;
 
-            ret = tdm_sprd_display_set_property(sprd_data, layer_data->plane_id,
-                                                  DRM_MODE_OBJECT_PLANE, "zpos", layer_data->zpos);
-            if (ret != TDM_ERROR_NONE)
-            {
-                drmModeFreePlane(plane);
-                free(layer_data);
-                return TDM_ERROR_OPERATION_FAILED;
-            }
-        }
+    layer_data->format_count = sizeof(img_layer_formats)/sizeof(int);
+    layer_data->formats = img_layer_formats;
 
-        TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                layer_data->zpos, layer_data->capabilities);
+    TDM_DBG("layer_data(%p) capabilities(%x)", layer_data, layer_data->capabilities);
 
-        LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
+    LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
 
-        drmModeFreePlane(plane);
-    }
 
     return TDM_ERROR_NONE;
 }
 
-static void
-_tdm_sprd_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data)
+tdm_error
+_tdm_sprd_display_output_update(tdm_sprd_output_data * output)
 {
-    tdm_sprd_data *sprd_data;
-    tdm_sprd_display_buffer *display_buffer;
-    int ret;
+    RETURN_VAL_IF_FAIL(output, TDM_ERROR_OPERATION_FAILED);
+    RETURN_VAL_IF_FAIL(output->fb_fd_name, TDM_ERROR_OPERATION_FAILED);
 
-    if (!user_data)
-    {
-        TDM_ERR("no user_data");
-        return;
-    }
-    if (!buffer)
-    {
-        TDM_ERR("no buffer");
-        return;
-    }
+    if (!output->fb_fd)
+        output->fb_fd = open (output->fb_fd_name, O_RDWR, 0);
 
-    sprd_data = (tdm_sprd_data *)user_data;
+    if (output->fb_fd <= 0)
+        goto failed;
 
-    display_buffer = _tdm_sprd_display_find_buffer(sprd_data, buffer);
-    if (!display_buffer)
-    {
-        TDM_ERR("no display_buffer");
-        return;
-    }
-    LIST_DEL(&display_buffer->link);
+   if (ioctl (output->fb_fd, FBIOGET_VSCREENINFO, &output->mi) == -1)
+        goto failed;
+
+    output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
 
-    if (display_buffer->fb_id > 0)
+    if (output->mi.activate & FB_ACTIVATE_VBL)
     {
-        ret = drmModeRmFB(sprd_data->drm_fd, display_buffer->fb_id);
-        if (ret < 0)
-        {
-            TDM_ERR("rm fb failed");
-            return;
-        }
-        TDM_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id);
+        output->dpms_value = TDM_OUTPUT_DPMS_ON;
     }
     else
-        TDM_DBG("drmModeRmFB not called fb_id:%d", display_buffer->fb_id);
-
-    free(display_buffer);
-}
-
-tdm_error
-tdm_sprd_display_create_layer_list(tdm_sprd_data *sprd_data)
-{
-    tdm_sprd_output_data *output_data = NULL;
-    tdm_error ret;
-
-    if (!sprd_data->has_zpos_info)
-        ret = _tdm_sprd_display_create_layer_list_type(sprd_data);
-    else if (sprd_data->is_immutable_zpos)
-        ret = _tdm_sprd_display_create_layer_list_immutable_zpos(sprd_data);
-    else
-        ret = _tdm_sprd_display_create_layer_list_not_fixed(sprd_data);
-
-    if (ret != TDM_ERROR_NONE)
-        return ret;
-
-    LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
     {
-        if (!output_data->primary_layer)
-        {
-            TDM_ERR("output(%d) no primary layer", output_data->pipe);
-            return TDM_ERROR_OPERATION_FAILED;
-        }
+        output->dpms_value = TDM_OUTPUT_DPMS_OFF;
     }
 
+
     return TDM_ERROR_NONE;
-}
 
-void
-tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
-{
-    tdm_sprd_output_data *o = NULL, *oo = NULL;
 
-    if (LIST_IS_EMPTY(&sprd_data->output_list))
-        return;
+failed:
 
-    LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link)
+    if (output->fb_fd > 0)
     {
-        LIST_DEL(&o->link);
-        if (!LIST_IS_EMPTY(&o->layer_list))
-        {
-            tdm_sprd_layer_data *l = NULL, *ll = NULL;
-            LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link)
-            {
-                LIST_DEL(&l->link);
-                free(l);
-            }
-        }
-        free(o->drm_modes);
-        free(o->output_modes);
-        free(o);
+        output->fb_fd = 0;
+        close(output->fb_fd);
     }
-}
-
-tdm_error
-tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data)
-{
-    tdm_sprd_output_data *output_data;
-    int i;
-    tdm_error ret;
-    int allocated = 0;
-
-    RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
-
-    for (i = 0; i < sprd_data->mode_res->count_connectors; i++)
-    {
-        drmModeConnectorPtr connector;
-        drmModeEncoderPtr encoder;
-        int crtc_id = 0, c, j;
-
-        connector = drmModeGetConnector(sprd_data->drm_fd, sprd_data->mode_res->connectors[i]);
-        if (!connector)
-        {
-            TDM_ERR("no connector");
-            ret = TDM_ERROR_OPERATION_FAILED;
-            goto failed_create;
-        }
-
-        if (connector->count_encoders != 1)
-        {
-            TDM_ERR("too many encoders: %d", connector->count_encoders);
-            drmModeFreeConnector(connector);
-            ret = TDM_ERROR_OPERATION_FAILED;
-            goto failed_create;
-        }
-
-        encoder = drmModeGetEncoder(sprd_data->drm_fd, connector->encoders[0]);
-        if (!encoder)
-        {
-            TDM_ERR("no encoder");
-            drmModeFreeConnector(connector);
-            ret = TDM_ERROR_OPERATION_FAILED;
-            goto failed_create;
-        }
+    output->dpms_value = TDM_OUTPUT_DPMS_OFF;
+    output->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+    return TDM_ERROR_OPERATION_FAILED;
+}
 
-        for (c = 0; c < sprd_data->mode_res->count_crtcs; c++)
-        {
-            if (allocated & (1 << c))
-                continue;
+static void
+_tdm_sprd_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data)
+{
+    tdm_sprd_data *sprd_data;
+    tdm_sprd_display_buffer *display_buffer;
 
-            if ((encoder->possible_crtcs & (1 << c)) == 0)
-                continue;
+    if (!user_data)
+    {
+        TDM_ERR("no user_data");
+        return;
+    }
+    if (!buffer)
+    {
+        TDM_ERR("no buffer");
+        return;
+    }
 
-            crtc_id = sprd_data->mode_res->crtcs[c];
-            allocated |= (1 << c);
-            break;
-        }
+    sprd_data = (tdm_sprd_data *)user_data;
 
-        if (crtc_id == 0)
-        {
-            TDM_ERR("no possible crtc");
-            drmModeFreeConnector(connector);
-            ret = TDM_ERROR_OPERATION_FAILED;
-            goto failed_create;
-        }
+    display_buffer = _tdm_sprd_display_find_buffer(sprd_data, buffer);
+    if (!display_buffer)
+    {
+        TDM_ERR("no display_buffer");
+        return;
+    }
+    LIST_DEL(&display_buffer->link);
 
-        output_data = calloc(1, sizeof(tdm_sprd_output_data));
-        if (!output_data)
-        {
-            TDM_ERR("alloc failed");
-            drmModeFreeConnector(connector);
-            drmModeFreeEncoder(encoder);
-            ret = TDM_ERROR_OUT_OF_MEMORY;
-            goto failed_create;
-        }
+    free(display_buffer);
+}
 
-        LIST_INITHEAD(&output_data->layer_list);
+tdm_sprd_output_data *
+_tdm_sprd_display_create_output_LCD(tdm_sprd_data *sprd_data)
+{
+    tdm_sprd_output_data *output_data = NULL;
 
-        output_data->sprd_data = sprd_data;
-        output_data->connector_id = sprd_data->mode_res->connectors[i];
-        output_data->encoder_id = encoder->encoder_id;
-        output_data->crtc_id = crtc_id;
-        output_data->pipe = c;
-        output_data->connector_type = connector->connector_type;
-        output_data->connector_type_id = connector->connector_type_id;
+    output_data = calloc (1, sizeof(tdm_sprd_output_data));
+    if (!output_data)
+    {
+        TDM_ERR("alloc failed");
+        return NULL;
+    }
 
-        if (connector->connection == DRM_MODE_CONNECTED)
-            output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
-        else
-            output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+    output_data->sprd_data = sprd_data;
+    output_data->pipe = 0;
+    output_data->connector_type = TDM_OUTPUT_TYPE_LVDS;
+    output_data->count_modes = 0;
+    output_data->fb_fd_name = FB_DEV_LCD;
+    LIST_INITHEAD(&output_data->layer_list);
 
-        for (j = 0; j < connector->count_props; j++)
-        {
-            drmModePropertyPtr prop = drmModeGetProperty(sprd_data->drm_fd, connector->props[i]);
-            if (!prop)
-                continue;
-            if (!strcmp(prop->name, "DPMS"))
-            {
-                output_data->dpms_prop_id = connector->props[i];
-                drmModeFreeProperty(prop);
-                break;
-            }
-            drmModeFreeProperty(prop);
-        }
+    _tdm_sprd_display_output_update (output_data);
 
-        output_data->count_modes = connector->count_modes;
-        output_data->drm_modes = calloc(connector->count_modes, sizeof(drmModeModeInfo));
-        if (!output_data->drm_modes)
-        {
-            TDM_ERR("alloc failed");
-            free(output_data);
-            drmModeFreeConnector(connector);
-            drmModeFreeEncoder(encoder);
-            ret = TDM_ERROR_OUT_OF_MEMORY;
-            goto failed_create;
-        }
-        output_data->output_modes = calloc(connector->count_modes, sizeof(tdm_output_mode));
+    if (output_data->status == TDM_OUTPUT_CONN_STATUS_CONNECTED)
+    {
+        //LCD has only one mode
+        output_data->count_modes = 1;
+        output_data->output_modes = calloc (output_data->count_modes, sizeof(tdm_output_mode));
         if (!output_data->output_modes)
         {
             TDM_ERR("alloc failed");
-            free(output_data);
-            free(output_data->drm_modes);
-            drmModeFreeConnector(connector);
-            drmModeFreeEncoder(encoder);
-            ret = TDM_ERROR_OUT_OF_MEMORY;
+            free (output_data);
             goto failed_create;
         }
-        for (j = 0; j < connector->count_modes; j++)
-        {
-            output_data->drm_modes[j] = connector->modes[j];
-            _tdm_sprd_display_to_tdm_mode(&output_data->drm_modes[j], &output_data->output_modes[j]);
-        }
-
-        LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
+        _tdm_sprd_display_to_tdm_mode (&output_data->mi, &output_data->output_modes[0]);
+    }
 
-        TDM_DBG("output_data(%p) connector_id(%d:%d:%d-%d) encoder_id(%d) crtc_id(%d) pipe(%d) dpms_id(%d)",
-                output_data, output_data->connector_id, output_data->status, output_data->connector_type,
-                output_data->connector_type_id, output_data->encoder_id, output_data->crtc_id,
-                output_data->pipe, output_data->dpms_prop_id);
+    TDM_DBG("output(%p, status:%d type:%d-%d) pipe(%d) dpms(%d)", output_data, output_data->status,
+            output_data->connector_type, output_data->connector_type_id, output_data->pipe, output_data->dpms_value);
 
-        drmModeFreeEncoder(encoder);
-        drmModeFreeConnector(connector);
-    }
+    _tdm_sprd_display_create_layer_list_LCD(output_data);
 
-    TDM_DBG("output count: %d", sprd_data->mode_res->count_connectors);
 
-    return TDM_ERROR_NONE;
+    return output_data;
 failed_create:
-    tdm_sprd_display_destroy_output_list(sprd_data);
-    return ret;
+
+    if (output_data->output_modes)
+        free(output_data->output_modes);
+
+    return NULL;
 }
 
-tdm_error
-tdm_sprd_display_set_property(tdm_sprd_data *sprd_data,
-                                unsigned int obj_id, unsigned int obj_type,
-                                const char *name, unsigned int value)
+
+void
+tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
 {
-    drmModeObjectPropertiesPtr props = NULL;
-    unsigned int i;
+    tdm_sprd_output_data *o = NULL, *oo = NULL;
 
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, obj_id, obj_type);
-    if (!props)
-    {
-        TDM_ERR("drmModeObjectGetProperties failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
-    for (i = 0; i < props->count_props; i++)
+    if (LIST_IS_EMPTY(&sprd_data->output_list))
+        return;
+
+    LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link)
     {
-        drmModePropertyPtr prop = drmModeGetProperty(sprd_data->drm_fd, props->props[i]);
-        int ret;
-        if (!prop)
-        {
-            TDM_ERR("drmModeGetProperty failed: %m");
-            drmModeFreeObjectProperties(props);
-            return TDM_ERROR_OPERATION_FAILED;
-        }
-        if (!strcmp(prop->name, name))
+        LIST_DEL(&o->link);
+        if (!LIST_IS_EMPTY(&o->layer_list))
         {
-            ret = drmModeObjectSetProperty(sprd_data->drm_fd, obj_id, obj_type, prop->prop_id, value);
-            if (ret < 0)
+            tdm_sprd_layer_data *l = NULL, *ll = NULL;
+            LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link)
             {
-                TDM_ERR("drmModeObjectSetProperty failed: %m");
-                drmModeFreeProperty(prop);
-                drmModeFreeObjectProperties(props);
-                return TDM_ERROR_OPERATION_FAILED;
+                LIST_DEL(&l->link);
+                free(l);
             }
-            drmModeFreeProperty(prop);
-            drmModeFreeObjectProperties(props);
-            return TDM_ERROR_NONE;
         }
-        drmModeFreeProperty(prop);
+        free(o->output_modes);
+        free(o);
     }
-
-    TDM_ERR("not found '%s' property", name);
-
-    drmModeFreeObjectProperties(props);
-    /* TODO
-    * kernel info error
-    * it must be changed to 'return TDM_ERROR_OPERATION_FAILED' after kernel fix.
-    */
-    return TDM_ERROR_NONE;
 }
 
 tdm_error
-tdm_sprd_display_get_property(tdm_sprd_data *sprd_data,
-                                unsigned int obj_id, unsigned int obj_type,
-                                const char *name, unsigned int *value, int *is_immutable)
+tdm_sprd_display_create_output_list (tdm_sprd_data *sprd_data)
 {
-    drmModeObjectPropertiesPtr props = NULL;
-    int i;
-
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, obj_id, obj_type);
-    if (!props)
-        return TDM_ERROR_OPERATION_FAILED;
+    tdm_sprd_output_data *output_data = NULL;
 
-    for (i = 0; i < props->count_props; i++)
-    {
-        drmModePropertyPtr prop = drmModeGetProperty(sprd_data->drm_fd, props->props[i]);
+    RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
 
-        if (!prop)
-            continue;
+    //have only LCD output
+    output_data = _tdm_sprd_display_create_output_LCD(sprd_data);
+    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
+    LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
+    sprd_data->output_count = 1;
 
-        if (!strcmp(prop->name, name))
-        {
-            if (is_immutable)
-                *is_immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
-            if (value)
-                *value = (unsigned int)props->prop_values[i];
-            drmModeFreeProperty(prop);
-            drmModeFreeObjectProperties(props);
-            return TDM_ERROR_NONE;
-        }
+    TDM_DBG("output count: %d", sprd_data->output_count);
 
-        drmModeFreeProperty(prop);
-    }
-    drmModeFreeObjectProperties(props);
-    TDM_DBG("coundn't find '%s' property", name);
-    return TDM_ERROR_OPERATION_FAILED;
+    return TDM_ERROR_NONE;
 }
 
 tdm_error
@@ -1292,10 +956,6 @@ tdm_error
 sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
 {
     tdm_sprd_output_data *output_data = output;
-    tdm_sprd_data *sprd_data;
-    drmModeConnectorPtr connector = NULL;
-    drmModeCrtcPtr crtc = NULL;
-    drmModeObjectPropertiesPtr props = NULL;
     int i;
     tdm_error ret;
 
@@ -1304,16 +964,11 @@ sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
 
     memset(caps, 0, sizeof(tdm_caps_output));
 
-    sprd_data = output_data->sprd_data;
-
     caps->status = output_data->status;
     caps->type = output_data->connector_type;
     caps->type_id = output_data->connector_type_id;
 
-    connector = drmModeGetConnector(sprd_data->drm_fd, output_data->connector_id);
-    RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED);
-
-    caps->mode_count = connector->count_modes;
+    caps->mode_count = output_data->count_modes;
     caps->modes = calloc(1, sizeof(tdm_output_mode) * caps->mode_count);
     if (!caps->modes)
     {
@@ -1324,62 +979,25 @@ sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
     for (i = 0; i < caps->mode_count; i++)
         caps->modes[i] = output_data->output_modes[i];
 
-    caps->mmWidth = connector->mmWidth;
-    caps->mmHeight = connector->mmHeight;
-    caps->subpixel = connector->subpixel;
+    caps->mmWidth = output_data->mi.width;
+    caps->mmHeight = output_data->mi.height;
+    caps->subpixel = 0;
 
-    caps->min_w = sprd_data->mode_res->min_width;
-    caps->min_h = sprd_data->mode_res->min_height;
-    caps->max_w = sprd_data->mode_res->max_width;
-    caps->max_h = sprd_data->mode_res->max_height;
+    caps->min_w = 0;
+    caps->min_h = 0;
+    caps->max_w = output_data->mi.xres_virtual;
+    caps->max_h = output_data->mi.yres_virtual;
     caps->preferred_align = -1;
 
-    crtc = drmModeGetCrtc(sprd_data->drm_fd, output_data->crtc_id);
-    if (!crtc)
-    {
-        ret = TDM_ERROR_OPERATION_FAILED;
-        TDM_ERR("get crtc failed: %m\n");
-        goto failed_get;
-    }
-
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, output_data->crtc_id, DRM_MODE_OBJECT_CRTC);
-    if (!props)
-    {
-        ret = TDM_ERROR_OPERATION_FAILED;
-        TDM_ERR("get crtc properties failed: %m\n");
-        goto failed_get;
-    }
-
-    caps->prop_count = props->count_props;
-    caps->props = calloc(1, sizeof(tdm_prop) * caps->prop_count);
-    if (!caps->props)
-    {
-        ret = TDM_ERROR_OUT_OF_MEMORY;
-        TDM_ERR("alloc failed\n");
-        goto failed_get;
-    }
-
-    for (i = 0; i < caps->prop_count; i++)
-    {
-        drmModePropertyPtr prop = drmModeGetProperty(sprd_data->drm_fd, props->props[i]);
-        if (!prop)
-            continue;
-        snprintf(caps->props[i].name, TDM_NAME_LEN, "%s", prop->name);
-        caps->props[i].id = props->props[i];
-        drmModeFreeProperty(prop);
-    }
-
-    drmModeFreeObjectProperties(props);
-    drmModeFreeCrtc(crtc);
-    drmModeFreeConnector(connector);
+    caps->prop_count = 0;
+    caps->props = NULL;
 
     return TDM_ERROR_NONE;
 failed_get:
-    drmModeFreeCrtc(crtc);
-    drmModeFreeObjectProperties(props);
-    drmModeFreeConnector(connector);
-    free(caps->modes);
-    free(caps->props);
+    if (caps->modes)
+        free(caps->modes);
+    if (caps->props)
+        free(caps->props);
     memset(caps, 0, sizeof(tdm_caps_output));
     return ret;
 }
@@ -1433,56 +1051,13 @@ failed_get:
 tdm_error
 sprd_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
 {
-    tdm_sprd_output_data *output_data = output;
-    tdm_sprd_data *sprd_data;
-    int ret;
-
-    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
-
-    sprd_data = output_data->sprd_data;
-    ret = drmModeObjectSetProperty(sprd_data->drm_fd,
-                                   output_data->crtc_id, DRM_MODE_OBJECT_CRTC,
-                                   id, value.u32);
-    if (ret < 0)
-    {
-        TDM_ERR("set property failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
-
-    return TDM_ERROR_NONE;
+    return TDM_ERROR_NOT_IMPLEMENTED;
 }
 
 tdm_error
 sprd_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
 {
-    tdm_sprd_output_data *output_data = output;
-    tdm_sprd_data *sprd_data;
-    drmModeObjectPropertiesPtr props;
-    int i;
-
-    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
-
-    sprd_data = output_data->sprd_data;
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, output_data->crtc_id, DRM_MODE_OBJECT_CRTC);
-    if (props == NULL)
-    {
-        TDM_ERR("get property failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
-
-    for (i = 0; i < props->count_props; i++)
-        if (props->props[i] == id)
-        {
-            (*value).u32 = (uint)props->prop_values[i];
-            break;
-        }
-
-    drmModeFreeObjectProperties(props);
-
-    return TDM_ERROR_NONE;
+    return TDM_ERROR_NOT_IMPLEMENTED;
 }
 
 tdm_error
@@ -1541,28 +1116,13 @@ sprd_output_commit(tdm_output *output, int sync, void *user_data)
 {
     tdm_sprd_output_data *output_data = output;
     tdm_sprd_data *sprd_data;
-    tdm_sprd_layer_data *layer_data = NULL;
-    tdm_error ret;
+    tdm_error ret = TDM_ERROR_NONE;
 
     RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
 
     sprd_data = output_data->sprd_data;
 
-    LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
-    {
-        if (layer_data == output_data->primary_layer)
-        {
-            ret = _tdm_sprd_display_commit_primary_layer(layer_data);
-            if (ret != TDM_ERROR_NONE)
-                return ret;
-        }
-        else
-        {
-            ret = _tdm_sprd_display_commit_layer(layer_data);
-            if (ret != TDM_ERROR_NONE)
-                return ret;
-        }
-    }
+    _tdm_sprd_display_do_commit(output_data);
 
     /* TODO: tdm_helper_drm_fd is external drm_fd which is opened by ecore_drm.
      * This is very tricky. But we can't remove tdm_helper_drm_fd now because
@@ -1621,51 +1181,37 @@ tdm_error
 sprd_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
 {
     tdm_sprd_output_data *output_data = output;
-    tdm_sprd_data *sprd_data;
-    int ret;
-
-    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+    tdm_error ret;
 
-    sprd_data = output_data->sprd_data;
-    ret = drmModeObjectSetProperty(sprd_data->drm_fd,
-                                   output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
-                                   output_data->dpms_prop_id, dpms_value);
-    if (ret < 0)
+    if (output_data->dpms_value == dpms_value)
     {
-        TDM_ERR("set dpms failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
+        return TDM_ERROR_NONE;
     }
 
-    return TDM_ERROR_NONE;
+    output_data->dpms_value = dpms_value;
+
+    if (dpms_value == TDM_OUTPUT_DPMS_OFF)
+    {
+        ret = _tdm_sprd_display_output_disable(output_data);
+    }
+    else
+    {
+        ret = _tdm_sprd_display_output_enable(output_data);
+    }
+    return ret;
 }
 
 tdm_error
 sprd_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
 {
-    tdm_sprd_output_data *output_data = output;
-    tdm_sprd_data *sprd_data;
-    drmModeObjectPropertiesPtr props;
-    int i;
-
-    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+    RETURN_VAL_IF_FAIL(output, TDM_ERROR_INVALID_PARAMETER);
     RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER);
 
-    sprd_data = output_data->sprd_data;
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR);
-    if (props == NULL)
-    {
-        TDM_ERR("get property failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
+    tdm_sprd_output_data *output_data = output;
 
-    for (i = 0; i < props->count_props; i++)
-        if (props->props[i] == output_data->dpms_prop_id)
-        {
-            *dpms_value = (uint)props->prop_values[i];
-            break;
-        }
+    RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
 
-    drmModeFreeObjectProperties(props);
+    *dpms_value = output_data->dpms_value;
 
     return TDM_ERROR_NONE;
 }
@@ -1701,9 +1247,6 @@ tdm_error
 sprd_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
 {
     tdm_sprd_layer_data *layer_data = layer;
-    tdm_sprd_data *sprd_data;
-    drmModePlanePtr plane = NULL;
-    drmModeObjectPropertiesPtr props = NULL;
     int i;
     tdm_error ret;
 
@@ -1712,19 +1255,10 @@ sprd_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
 
     memset(caps, 0, sizeof(tdm_caps_layer));
 
-    sprd_data = layer_data->sprd_data;
-    plane = drmModeGetPlane(sprd_data->drm_fd, layer_data->plane_id);
-    if (!plane)
-    {
-        TDM_ERR("get plane failed: %m");
-        ret = TDM_ERROR_OPERATION_FAILED;
-        goto failed_get;
-    }
-
     caps->capabilities = layer_data->capabilities;
-    caps->zpos = layer_data->zpos;  /* if VIDEO layer, zpos is -1 */
+    caps->zpos = -1;  /* if VIDEO layer, zpos is -1 */
 
-    caps->format_count = plane->count_formats;
+    caps->format_count = layer_data->format_count;
     caps->formats = calloc(1, sizeof(tbm_format) * caps->format_count);
     if (!caps->formats)
     {
@@ -1735,51 +1269,14 @@ sprd_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
 
     for (i = 0; i < caps->format_count; i++)
     {
-        /* TODO: kernel reports wrong formats */
-        if (plane->formats[i] != DRM_FORMAT_XRGB8888 && plane->formats[i] != DRM_FORMAT_ARGB8888)
-           continue;
-        caps->formats[i] = tdm_sprd_format_to_tbm_format(plane->formats[i]);
-    }
-
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, layer_data->plane_id, DRM_MODE_OBJECT_PLANE);
-    if (!props)
-    {
-        ret = TDM_ERROR_OPERATION_FAILED;
-        TDM_ERR("get plane properties failed: %m\n");
-        goto failed_get;
-    }
-
-    caps->props = calloc(1, sizeof(tdm_prop) * props->count_props);
-    if (!caps->props)
-    {
-        ret = TDM_ERROR_OUT_OF_MEMORY;
-        TDM_ERR("alloc failed\n");
-        goto failed_get;
+        caps->formats[i] = layer_data->formats[i];
     }
 
     caps->prop_count = 0;
-    for (i = 0; i < props->count_props; i++)
-    {
-        drmModePropertyPtr prop = drmModeGetProperty(sprd_data->drm_fd, props->props[i]);
-        if (!prop)
-            continue;
-        if (!strncmp(prop->name, "type", TDM_NAME_LEN))
-            continue;
-        if (!strncmp(prop->name, "zpos", TDM_NAME_LEN))
-            continue;
-        snprintf(caps->props[i].name, TDM_NAME_LEN, "%s", prop->name);
-        caps->props[i].id = props->props[i];
-        caps->prop_count++;
-        drmModeFreeProperty(prop);
-    }
-
-    drmModeFreeObjectProperties(props);
-    drmModeFreePlane(plane);
+    caps->props = NULL;
 
     return TDM_ERROR_NONE;
 failed_get:
-    drmModeFreeObjectProperties(props);
-    drmModeFreePlane(plane);
     free(caps->formats);
     free(caps->props);
     memset(caps, 0, sizeof(tdm_caps_layer));
@@ -1789,57 +1286,13 @@ failed_get:
 tdm_error
 sprd_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
 {
-    tdm_sprd_layer_data *layer_data = layer;
-    tdm_sprd_data *sprd_data;
-    int ret;
-
-    RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
-
-    sprd_data = layer_data->sprd_data;
-    ret = drmModeObjectSetProperty(sprd_data->drm_fd,
-                                   layer_data->plane_id, DRM_MODE_OBJECT_PLANE,
-                                   id, value.u32);
-    if (ret < 0)
-    {
-        TDM_ERR("set property failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
-
-    return TDM_ERROR_NONE;
+    return TDM_ERROR_NOT_IMPLEMENTED;
 }
 
 tdm_error
 sprd_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
 {
-    tdm_sprd_layer_data *layer_data = layer;
-    tdm_sprd_data *sprd_data;
-    drmModeObjectPropertiesPtr props;
-    int i;
-
-    RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
-
-    sprd_data = layer_data->sprd_data;
-    props = drmModeObjectGetProperties(sprd_data->drm_fd, layer_data->plane_id,
-                                       DRM_MODE_OBJECT_PLANE);
-    if (props == NULL)
-    {
-        TDM_ERR("get property failed: %m");
-        return TDM_ERROR_OPERATION_FAILED;
-    }
-
-    for (i = 0; i < props->count_props; i++)
-        if (props->props[i] == id)
-        {
-            (*value).u32 = (uint)props->prop_values[i];
-            break;
-        }
-
-    drmModeFreeObjectProperties(props);
-
-    return TDM_ERROR_NONE;
+    return TDM_ERROR_NOT_IMPLEMENTED;
 }
 
 tdm_error
@@ -1870,19 +1323,19 @@ sprd_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
 }
 
 tdm_error
-sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
+sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h surface)
 {
     tdm_sprd_layer_data *layer_data = layer;
     tdm_sprd_data *sprd_data;
     tdm_sprd_display_buffer *display_buffer;
     tdm_error err = TDM_ERROR_NONE;
-    int ret, i, count;
+    int i, count;
 
     RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-    RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
+    RETURN_VAL_IF_FAIL(surface, TDM_ERROR_INVALID_PARAMETER);
 
     sprd_data = layer_data->sprd_data;
-    display_buffer = _tdm_sprd_display_find_buffer(sprd_data, buffer);
+    display_buffer = _tdm_sprd_display_find_buffer(sprd_data, surface);
     if (!display_buffer)
     {
         display_buffer = calloc(1, sizeof(tdm_sprd_display_buffer));
@@ -1891,9 +1344,9 @@ sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
             TDM_ERR("alloc failed");
             return TDM_ERROR_OUT_OF_MEMORY;
         }
-        display_buffer->buffer = buffer;
+        display_buffer->buffer = surface;
 
-        err = tdm_buffer_add_destroy_handler(buffer, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
+        err = tdm_buffer_add_destroy_handler(surface, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
         if (err != TDM_ERROR_NONE)
         {
             TDM_ERR("add destroy handler fail");
@@ -1901,49 +1354,34 @@ sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
             return TDM_ERROR_OPERATION_FAILED;
         }
         LIST_ADDTAIL(&display_buffer->link, &sprd_data->buffer_list);
-    }
 
-    if (display_buffer->fb_id == 0)
-    {
-        unsigned int width;
-        unsigned int height;
-        unsigned int format;
-        unsigned int handles[4] = {0,};
-        unsigned int pitches[4] = {0,};
-        unsigned int offsets[4] = {0,};
-        unsigned int size;
-
-        width = tbm_surface_get_width(buffer);
-        height = tbm_surface_get_height(buffer);
-        format = tbm_surface_get_format(buffer);
-        count = tbm_surface_internal_get_num_bos(buffer);
-        for (i = 0; i < count; i++)
+        display_buffer->width = tbm_surface_get_width(surface);
+        display_buffer->height = tbm_surface_get_height(surface);
+        display_buffer->format = tbm_surface_get_format(surface);
+        display_buffer->count = tbm_surface_internal_get_num_bos(surface);
+        for (i = 0; i < display_buffer->count; i++)
         {
-            tbm_bo bo = tbm_surface_internal_get_bo(buffer, i);
-            handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+            tbm_bo bo = tbm_surface_internal_get_bo (surface, i);
+            display_buffer->handles[i] = tbm_bo_get_handle (bo, TBM_DEVICE_DEFAULT).u32;
+            display_buffer->name[i] = tbm_bo_export(bo);
         }
-        count = tbm_surface_internal_get_num_planes(format);
+        count = tbm_surface_internal_get_num_planes (display_buffer->format);
         for (i = 0; i < count; i++)
-            tbm_surface_internal_get_plane_data(buffer, i, &size, &offsets[i], &pitches[i]);
-
-        ret = drmModeAddFB2(sprd_data->drm_fd, width, height, format,
-                            handles, pitches, offsets, &display_buffer->fb_id, 0);
-        if (ret < 0)
-        {
-            TDM_ERR("add fb failed: %m");
-            return TDM_ERROR_OPERATION_FAILED;
-        }
+            tbm_surface_internal_get_plane_data (surface, i, &display_buffer->size, &display_buffer->offsets[i],
+                                                 &display_buffer->pitches[i]);
 
-        if (IS_RGB(format))
-            display_buffer->width = pitches[0] >> 2;
+        if (IS_RGB(display_buffer->format))
+            display_buffer->width = display_buffer->pitches[0] >> 2;
         else
-            display_buffer->width = pitches[0];
+            display_buffer->width = display_buffer->pitches[0];
     }
+
     TDM_DBG("sprd_data->drm_fd : %d, display_buffer->fb_id:%u", sprd_data->drm_fd, display_buffer->fb_id);
     layer_data->display_buffer = display_buffer;
     layer_data->display_buffer_changed = 1;
 
     return TDM_ERROR_NONE;
+
 }
 
 tdm_error
@@ -1989,6 +1427,7 @@ _sprd_drm_vblank_event (int fd, tdm_sprd_data *sprd_data_p, void* hw_event_data)
                                      vblank_data->user_data);
         break;
     case VBLANK_TYPE_COMMIT:
+
         if (output_data->commit_func)
             output_data->commit_func(output_data, hw_vblank->sequence,
                                      hw_vblank->tv_sec, hw_vblank->tv_usec,