#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
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;
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
/* 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;
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
/* 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;
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)
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)
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)
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
}
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
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
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;
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)
{
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;
}
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
{
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
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;
}
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;
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)
{
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));
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
}
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));
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");
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
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,