summaryrefslogtreecommitdiff
path: root/src/libtdm-exynos/tdm_exynos_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtdm-exynos/tdm_exynos_output.c')
-rw-r--r--src/libtdm-exynos/tdm_exynos_output.c1085
1 files changed, 0 insertions, 1085 deletions
diff --git a/src/libtdm-exynos/tdm_exynos_output.c b/src/libtdm-exynos/tdm_exynos_output.c
deleted file mode 100644
index acf2a42..0000000
--- a/src/libtdm-exynos/tdm_exynos_output.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <drm_fourcc.h>
-#include <tdm_helper.h>
-#include "tdm_exynos.h"
-
-#define MIN_WIDTH 32
-
-#define LIST_INSERT_AFTER(__after, __item) \
- (__item)->prev = (__after); \
- (__item)->next = (__after)->next; \
- (__after)->next->prev = (__item); \
- (__after)->next = (__item);
-
-static tdm_error
-check_hw_restriction_crtc(unsigned int crtc_w,
- unsigned int buf_w, unsigned int buf_h,
- unsigned int src_x, unsigned int src_y,
- unsigned int src_w, unsigned int src_h,
- unsigned int dst_w, unsigned int dst_h,
- unsigned int *new_x, unsigned int *new_y)
-{
- int tmp;
- int dx = 1, dy = 1;
- int changed_x = 0;
- int changed_y = 0;
-
- (void) crtc_w;
- (void) dst_w;
- (void) dst_h;
-
- *new_x = src_x;
- *new_y = src_y;
-
- if (src_x + src_w > buf_w) {
- tmp = src_x;
- while (tmp + src_w != buf_w)
- tmp -= dx;
-
- changed_x = 1;
- *new_x = tmp;
- }
-
- if (src_y + src_h > buf_h) {
- tmp = src_y;
- while (tmp + src_h != buf_h)
- tmp -= dy;
-
- changed_y = 1;
- *new_y = tmp;
- }
-
- if (changed_x == 1 || changed_y == 1)
- return TDM_ERROR_INVALID_PARAMETER;
- return TDM_ERROR_NONE;
-}
-
-static tdm_error
-check_hw_restriction(unsigned int crtc_w, unsigned int crtc_h, unsigned int buf_w,
- unsigned int src_x, unsigned int src_w,
- unsigned int dst_x, unsigned int dst_y, unsigned int dst_w,
- unsigned int *new_src_x, unsigned int *new_src_w,
- unsigned int *new_dst_x, unsigned int *new_dst_w)
-{
- int start, end, diff;
- int virtual_screen;
-
- *new_src_x = src_x;
- *new_src_w = src_w;
- *new_dst_x = dst_x;
- *new_dst_w = dst_w;
-
- if (buf_w < MIN_WIDTH || buf_w % 2) {
- TDM_ERR("buf_w(%u) not 2's multiple or less than %u", buf_w, MIN_WIDTH);
- return TDM_ERROR_BAD_REQUEST;
- }
-
- if (dst_x > crtc_w || dst_y > crtc_h) {
- TDM_ERR("dst_pos(%u,%u) is out of crtc(%ux%u)", dst_x, dst_y, crtc_w, crtc_h);
- return TDM_ERROR_BAD_REQUEST;
- }
-
- if (src_x > dst_x || ((dst_x - src_x) + buf_w) > crtc_w)
- virtual_screen = 1;
- else
- virtual_screen = 0;
-
- start = dst_x;
- end = ((dst_x + dst_w) > crtc_w) ? crtc_w : (dst_x + dst_w);
-
- /* check window minimun width */
- if ((end - start) < MIN_WIDTH) {
- TDM_ERR("visible_w(%d) less than %u", end - start, MIN_WIDTH);
- return TDM_ERROR_BAD_REQUEST;
- }
-
- if (!virtual_screen) {
- /* Pagewidth of window (= 8 byte align / bytes-per-pixel ) */
- if ((end - start) % 2)
- end--;
- } else {
- /* You should align the sum of PAGEWIDTH_F and OFFSIZE_F double-word (8 byte) boundary. */
- if (end % 2)
- end--;
- }
-
- *new_dst_x = start;
- *new_dst_w = end - start;
- *new_src_w = *new_dst_w;
- diff = start - dst_x;
- *new_src_x += diff;
-
- RETURN_VAL_IF_FAIL(*new_src_w > 0, TDM_ERROR_BAD_REQUEST);
- RETURN_VAL_IF_FAIL(*new_dst_w > 0, TDM_ERROR_BAD_REQUEST);
-
- if (src_x != *new_src_x || src_w != *new_src_w || dst_x != *new_dst_x ||
- dst_w != *new_dst_w)
- TDM_DBG("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
- buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start,
- end);
-
- return TDM_ERROR_NONE;
-}
-
-static drmModeModeInfoPtr
-_tdm_exynos_output_get_mode(tdm_exynos_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 (exynos_screen_prerotation_hint % 180) {
- if ((drm_mode->hdisplay == output_data->current_mode->vdisplay) &&
- (drm_mode->vdisplay == output_data->current_mode->hdisplay) &&
- (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
- (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;
- } else {
- if ((drm_mode->hdisplay == output_data->current_mode->hdisplay) &&
- (drm_mode->vdisplay == output_data->current_mode->vdisplay) &&
- (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
- (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_error
-_tdm_exynos_output_get_cur_msc(int fd, int pipe, uint *msc)
-{
- drmVBlank vbl;
-
- vbl.request.type = DRM_VBLANK_RELATIVE;
- if (pipe == 1)
- vbl.request.type |= DRM_VBLANK_SECONDARY;
- else if (pipe > 1)
- vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
-
- vbl.request.sequence = 0;
- if (drmWaitVBlank(fd, &vbl)) {
- TDM_ERR("get vblank counter failed: %m");
- *msc = 0;
- return TDM_ERROR_OPERATION_FAILED;
- }
-
- *msc = vbl.reply.sequence;
-
- return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_output_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
-{
- drmVBlank vbl;
-
- vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
- if (pipe == 1)
- vbl.request.type |= DRM_VBLANK_SECONDARY;
- else if (pipe > 1)
- vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
-
- vbl.request.sequence = *target_msc;
- vbl.request.signal = (unsigned long)(uintptr_t)data;
-
- if (drmWaitVBlank(fd, &vbl)) {
- TDM_ERR("wait vblank failed: %m");
- *target_msc = 0;
- return TDM_ERROR_OPERATION_FAILED;
- }
-
- *target_msc = vbl.reply.sequence;
-
- return TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_output_transform_layer_info(int width, int height, tdm_info_layer *info)
-{
- tdm_pos dst_pos;
-
- switch (exynos_screen_prerotation_hint) {
- case 90:
- dst_pos.x = info->dst_pos.y;
- dst_pos.y = width - info->dst_pos.x - info->dst_pos.w;
- dst_pos.w = info->dst_pos.h;
- dst_pos.h = info->dst_pos.w;
- break;
- case 180:
- dst_pos.x = width - info->dst_pos.x - info->dst_pos.w;
- dst_pos.y = height - info->dst_pos.y - info->dst_pos.h;
- dst_pos.w = info->dst_pos.w;
- dst_pos.h = info->dst_pos.h;
- break;
- case 270:
- dst_pos.x = height - info->dst_pos.y - info->dst_pos.h;
- dst_pos.y = info->dst_pos.x;
- dst_pos.w = info->dst_pos.h;
- dst_pos.h = info->dst_pos.w;
- break;
- default:
- return;
- }
-
- info->dst_pos = dst_pos;
-}
-
-static tdm_error
-_tdm_exynos_output_commit_primary_layer(tdm_exynos_layer_data *layer_data,
- void *user_data, int *do_waitvblank)
-{
- tdm_exynos_data *exynos_data = layer_data->exynos_data;
- tdm_exynos_output_data *output_data = layer_data->output_data;
- unsigned int new_x = -1, new_y = -1;
- uint32_t fx, fy;
- int crtc_w, crtc_h;
-
- if (output_data->mode_changed && layer_data->display_buffer_changed) {
- tdm_info_layer layer_info = layer_data->info;
- drmModeModeInfoPtr mode;
-
- if (!layer_data->display_buffer) {
- TDM_ERR("primary layer should have a buffer for modestting");
- return TDM_ERROR_BAD_REQUEST;
- }
-
- if (output_data->current_mode) {
- crtc_w = output_data->current_mode->hdisplay;
- crtc_h = output_data->current_mode->vdisplay;
- } else {
- drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
- if (!crtc) {
- TDM_ERR("getting crtc failed");
- return TDM_ERROR_OPERATION_FAILED;
- }
- crtc_w = crtc->width;
- crtc_h = crtc->height;
- if (crtc_w == 0) {
- TDM_ERR("getting crtc width failed");
- drmModeFreeCrtc(crtc);
- return TDM_ERROR_OPERATION_FAILED;
- }
- drmModeFreeCrtc(crtc);
- }
-
- output_data->mode_changed = 0;
- layer_data->display_buffer_changed = 0;
- layer_data->info_changed = 0;
-
- mode = _tdm_exynos_output_get_mode(output_data);
- if (!mode) {
- TDM_ERR("couldn't find proper mode");
- return TDM_ERROR_BAD_REQUEST;
- }
-
- _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
-
- if (check_hw_restriction_crtc(crtc_w,
- layer_info.src_config.size.h, layer_info.src_config.size.v,
- layer_info.src_config.pos.x, layer_info.src_config.pos.y,
- layer_info.src_config.pos.w, layer_info.src_config.pos.h,
- layer_info.dst_pos.w, layer_info.dst_pos.h,
- &new_x, &new_y) != TDM_ERROR_NONE)
- TDM_WRN("not going to set crtc(%u)", output_data->crtc_id);
-
- if (layer_info.src_config.pos.x != new_x)
- TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x,
- new_x);
- if (layer_info.src_config.pos.y != new_y)
- TDM_DBG("src_y changed: %u => %u", layer_info.src_config.pos.y,
- new_y);
-
- fx = (unsigned int)new_x;
- fy = (unsigned int)new_y;
-
- TDM_DBG("SetCrtc: drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%ux%u, %uhz) pos(%u %u)",
- exynos_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id,
- mode->hdisplay, mode->vdisplay, mode->vrefresh, fx, fy);
-
- if (drmModeSetCrtc(exynos_data->drm_fd, output_data->crtc_id,
- layer_data->display_buffer->fb_id, fx, fy,
- &output_data->connector_id, 1, mode)) {
- TDM_ERR("set crtc failed: %m");
- return TDM_ERROR_OPERATION_FAILED;
- }
-
- tdm_exynos_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED);
-
- *do_waitvblank = 1;
-
- return TDM_ERROR_NONE;
- } else if (layer_data->display_buffer_changed) {
- layer_data->display_buffer_changed = 0;
-
- if (layer_data->display_buffer) {
- tbm_surface_info_s info;
- int ret;
- tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
-
- if (!event_data) {
- TDM_ERR("alloc failed");
- return TDM_ERROR_OUT_OF_MEMORY;
- }
- event_data->type = TDM_EXYNOS_EVENT_TYPE_PAGEFLIP;
- event_data->output_data = output_data;
- event_data->user_data = user_data;
- event_data->hwc_mode = exynos_data->hwc_mode;
-
- TDM_DBG("PageFlip: drm_fd(%d) crtc_id(%u) fb_id(%u)",
- exynos_data->drm_fd, output_data->crtc_id,
- layer_data->display_buffer->fb_id);
-
- ret = tbm_surface_map(layer_data->display_buffer->buffer, TBM_SURF_OPTION_READ, &info);
- if (ret == TBM_SURFACE_ERROR_NONE)
- tbm_surface_unmap(layer_data->display_buffer->buffer);
-
- if (drmModePageFlip(exynos_data->drm_fd, output_data->crtc_id,
- layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) {
- TDM_ERR("pageflip failed: %m");
- free(event_data);
- return TDM_ERROR_OPERATION_FAILED;
- }
- *do_waitvblank = 0;
- } else {
- /* to call a user commit handler whenever committed */
- *do_waitvblank = 1;
- }
- }
-
- return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_output_commit_layer(tdm_exynos_layer_data *layer_data)
-{
- tdm_exynos_data *exynos_data = layer_data->exynos_data;
- tdm_exynos_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, crtc_h;
- tdm_info_layer layer_info = layer_data->info;
-
- if (!layer_data->display_buffer_changed && !layer_data->info_changed)
- return TDM_ERROR_NONE;
-
- if (output_data->current_mode) {
- crtc_w = output_data->current_mode->hdisplay;
- crtc_h = output_data->current_mode->vdisplay;
- } else {
- drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
- if (!crtc) {
- TDM_ERR("getting crtc failed");
- return TDM_ERROR_OPERATION_FAILED;
- }
- crtc_w = crtc->width;
- crtc_h = crtc->height;
- if (crtc_w == 0) {
- TDM_ERR("getting crtc width failed");
- drmModeFreeCrtc(crtc);
- return TDM_ERROR_OPERATION_FAILED;
- }
- drmModeFreeCrtc(crtc);
- }
-
- layer_data->display_buffer_changed = 0;
- layer_data->info_changed = 0;
-
- if (!layer_data->display_buffer) {
- TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
- exynos_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
-
- if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
- output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
- TDM_ERR("unset plane(%u) filed: %m", layer_data->plane_id);
-
- return TDM_ERROR_NONE;
- }
-
- _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
-
- /* check hw restriction*/
- if (check_hw_restriction(crtc_w, crtc_h, layer_data->display_buffer->width,
- layer_info.src_config.pos.x,
- layer_info.src_config.pos.w,
- layer_info.dst_pos.x,
- layer_info.dst_pos.y,
- layer_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(%u)", layer_data->plane_id);
- return TDM_ERROR_NONE;
- }
-
- if (layer_info.src_config.pos.x != new_src_x)
- TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x, new_src_x);
- if (layer_info.src_config.pos.w != new_src_w)
- TDM_DBG("src_w changed: %u => %u", layer_info.src_config.pos.w, new_src_w);
- if (layer_info.dst_pos.x != new_dst_x)
- TDM_DBG("dst_x changed: %u => %u", layer_info.dst_pos.x, new_dst_x);
- if (layer_info.dst_pos.w != new_dst_w)
- TDM_DBG("dst_w changed: %u => %u", layer_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_info.src_config.pos.y) << 16;
- fw = ((unsigned int)new_src_w) << 16;
- fh = ((unsigned int)layer_info.src_config.pos.h) << 16;
-
- TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u)",
- exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
- output_data->crtc_id, layer_data->display_buffer->fb_id,
- new_src_x, layer_info.src_config.pos.y,
- new_src_w, layer_info.src_config.pos.h,
- layer_info.dst_pos.x, layer_info.dst_pos.y,
- layer_info.dst_pos.w, layer_info.dst_pos.h);
-
- if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
- output_data->crtc_id, layer_data->display_buffer->fb_id, 0,
- new_dst_x, layer_info.dst_pos.y,
- new_dst_w, layer_info.dst_pos.h,
- fx, fy, fw, fh) < 0) {
- TDM_ERR("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u) failed: %m",
- exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
- output_data->crtc_id, layer_data->display_buffer->fb_id,
- new_src_x, layer_info.src_config.pos.y,
- new_src_w, layer_info.src_config.pos.h,
- layer_info.dst_pos.x, layer_info.dst_pos.y,
- layer_info.dst_pos.w, layer_info.dst_pos.h);
- return TDM_ERROR_OPERATION_FAILED;
- }
-
- return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_output_cb_event(int fd, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec,
- void *user_data)
-{
- tdm_exynos_event_data *event_data = user_data;
- tdm_exynos_output_data *output_data;
- tdm_exynos_hwc_data *hwc_data;
-
- if (!event_data) {
- TDM_ERR("no event data");
- return;
- }
-
- output_data = event_data->output_data;
- hwc_data = output_data->hwc_data;
-
- switch (event_data->type) {
- case TDM_EXYNOS_EVENT_TYPE_PAGEFLIP:
- case TDM_EXYNOS_EVENT_TYPE_COMMIT:
- if (event_data->hwc_mode && hwc_data) {
- if (hwc_data->commit_func)
- hwc_data->commit_func(hwc_data, sequence, tv_sec, tv_usec,
- event_data->user_data);
- } else {
- if (output_data->commit_func)
- output_data->commit_func(output_data, sequence, tv_sec, tv_usec,
- event_data->user_data);
- }
- break;
- case TDM_EXYNOS_EVENT_TYPE_WAIT:
- if (output_data->vblank_func)
- output_data->vblank_func(output_data, sequence, tv_sec, tv_usec,
- event_data->user_data);
- break;
- default:
- break;
- }
-
- free(event_data);
-}
-
-tdm_error
-tdm_exynos_output_update_status(tdm_exynos_output_data *output_data,
- tdm_output_conn_status status)
-{
- tdm_exynos_layer_data *layer_data = NULL;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- if (output_data->status == status)
- return TDM_ERROR_NONE;
-
- output_data->status = status;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
- if (layer_data->display_buffer)
- layer_data->display_buffer_force_unset = 1;
- } else
- layer_data->display_buffer_force_unset = 0;
- }
-
- if (output_data->status_func)
- output_data->status_func(output_data, status,
- output_data->status_user_data);
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_capability(tdm_output *output, tdm_caps_output *caps)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
- drmModeConnectorPtr connector = NULL;
- drmModeCrtcPtr crtc = NULL;
- drmModeObjectPropertiesPtr props = NULL;
- int i;
- tdm_error ret;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
-
- memset(caps, 0, sizeof(tdm_caps_output));
-
- exynos_data = output_data->exynos_data;
-
- snprintf(caps->maker, TDM_NAME_LEN, "unknown");
- snprintf(caps->model, TDM_NAME_LEN, "unknown");
- snprintf(caps->name, TDM_NAME_LEN, "unknown");
-
- caps->type = output_data->connector_type;
- caps->type_id = output_data->connector_type_id;
-
- connector = drmModeGetConnector(exynos_data->drm_fd, output_data->connector_id);
- RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED);
-
- caps->mode_count = connector->count_modes;
- caps->modes = calloc(1, sizeof(tdm_output_mode) * caps->mode_count);
- if (!caps->modes) {
- ret = TDM_ERROR_OUT_OF_MEMORY;
- TDM_ERR("alloc failed\n");
- goto failed_get;
- }
- if (caps->mode_count != output_data->count_modes) {
- drmModeModeInfoPtr new_drm_modes;
- tdm_output_mode *new_output_modes;
-
- new_drm_modes = calloc(connector->count_modes,
- sizeof(drmModeModeInfo));
- if (!new_drm_modes) {
- ret = TDM_ERROR_OUT_OF_MEMORY;
- TDM_ERR("alloc failed drm_modes\n");
- goto failed_get;
- }
- new_output_modes = calloc(connector->count_modes,
- sizeof(tdm_output_mode));
- if (!new_output_modes) {
- ret = TDM_ERROR_OUT_OF_MEMORY;
- TDM_ERR("alloc failed output_modes\n");
- free(new_drm_modes);
- goto failed_get;
- }
- free(output_data->drm_modes);
- free(output_data->output_modes);
-
- output_data->drm_modes = new_drm_modes;
- output_data->output_modes = new_output_modes;
- output_data->count_modes = caps->mode_count;
- }
- for (i = 0; i < caps->mode_count; i++) {
- output_data->drm_modes[i] = connector->modes[i];
- tdm_exynos_display_to_tdm_mode(&output_data->drm_modes[i],
- &output_data->output_modes[i]);
- caps->modes[i] = output_data->output_modes[i];
- }
-
- if (connector->connection == DRM_MODE_CONNECTED)
- output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
- else
- output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
- caps->status = output_data->status;
-
- if (exynos_screen_prerotation_hint % 180) {
- caps->mmWidth = connector->mmHeight;
- caps->mmHeight = connector->mmWidth;
- caps->min_w = exynos_data->mode_res->min_height;
- caps->min_h = exynos_data->mode_res->min_width;
- caps->max_w = exynos_data->mode_res->max_height;
- caps->max_h = exynos_data->mode_res->max_width;
- } else {
- caps->mmWidth = connector->mmWidth;
- caps->mmHeight = connector->mmHeight;
- caps->min_w = exynos_data->mode_res->min_width;
- caps->min_h = exynos_data->mode_res->min_height;
- caps->max_w = exynos_data->mode_res->max_width;
- caps->max_h = exynos_data->mode_res->max_height;
- }
-
- caps->subpixel = connector->subpixel;
- caps->preferred_align = -1;
-
- caps->cursor_min_w = 32;
- caps->cursor_min_h = 32;
- caps->cursor_max_w = -1;
- caps->cursor_max_h = -1;
- caps->cursor_preferred_align = -1;
-
- crtc = drmModeGetCrtc(exynos_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(exynos_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->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->prop_count = 0;
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
- props->props[i]);
- if (!prop)
- continue;
- snprintf(caps->props[caps->prop_count].name, TDM_NAME_LEN, "%s", prop->name);
- caps->props[caps->prop_count].id = props->props[i];
- caps->prop_count++;
- drmModeFreeProperty(prop);
- }
-
- if (output_data->hwc_enable)
- caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
-
- drmModeFreeObjectProperties(props);
- drmModeFreeCrtc(crtc);
- drmModeFreeConnector(connector);
-
- return TDM_ERROR_NONE;
-failed_get:
- drmModeFreeCrtc(crtc);
- drmModeFreeObjectProperties(props);
- drmModeFreeConnector(connector);
- free(caps->modes);
- free(caps->props);
- memset(caps, 0, sizeof(tdm_caps_output));
- return ret;
-}
-
-tdm_layer **
-exynos_output_get_layers(tdm_output *output, int *count, tdm_error *error)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_layer_data *layer_data = NULL;
- tdm_layer **layers;
- tdm_error ret;
- int i;
-
- RETURN_VAL_IF_FAIL(output_data, NULL);
- RETURN_VAL_IF_FAIL(count, NULL);
-
- if (output_data->hwc_enable) {
- *count = 0;
- ret = TDM_ERROR_NONE;
- goto failed_get;
- }
-
- *count = 0;
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
- (*count)++;
-
- if (*count == 0) {
- ret = TDM_ERROR_NONE;
- goto failed_get;
- }
-
- /* will be freed in frontend */
- layers = calloc(*count, sizeof(tdm_exynos_layer_data *));
- if (!layers) {
- TDM_ERR("failed: alloc memory");
- *count = 0;
- ret = TDM_ERROR_OUT_OF_MEMORY;
- goto failed_get;
- }
-
- i = 0;
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
- layers[i++] = layer_data;
-
- if (error)
- *error = TDM_ERROR_NONE;
-
- return layers;
-failed_get:
- if (error)
- *error = ret;
- return NULL;
-}
-
-tdm_error
-exynos_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_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);
-
- exynos_data = output_data->exynos_data;
- ret = drmModeObjectSetProperty(exynos_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;
-}
-
-tdm_error
-exynos_output_get_property(tdm_output *output, unsigned int id,
- tdm_value *value)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_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);
-
- exynos_data = output_data->exynos_data;
- props = drmModeObjectGetProperties(exynos_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;
-}
-
-tdm_error
-exynos_output_wait_vblank(tdm_output *output, int interval, int sync,
- void *user_data)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
- tdm_exynos_event_data *event_data;
- uint target_msc;
- tdm_error ret;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- event_data = calloc(1, sizeof(tdm_exynos_event_data));
- if (!event_data) {
- TDM_ERR("alloc failed");
- return TDM_ERROR_OUT_OF_MEMORY;
- }
-
- exynos_data = output_data->exynos_data;
-
- ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
- &target_msc);
- if (ret != TDM_ERROR_NONE)
- goto failed_vblank;
-
- target_msc += interval;
-
- event_data->type = TDM_EXYNOS_EVENT_TYPE_WAIT;
- event_data->output_data = output_data;
- event_data->user_data = user_data;
-
- ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
- &target_msc, event_data);
- if (ret != TDM_ERROR_NONE)
- goto failed_vblank;
-
- return TDM_ERROR_NONE;
-failed_vblank:
- free(event_data);
- return ret;
-}
-
-tdm_error
-exynos_output_set_vblank_handler(tdm_output *output,
- tdm_output_vblank_handler func)
-{
- tdm_exynos_output_data *output_data = output;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
- output_data->vblank_func = func;
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_commit(tdm_output *output, int sync, void *user_data)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
- tdm_exynos_layer_data *layer_data = NULL;
- tdm_error ret;
- int do_waitvblank = 1;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- exynos_data = output_data->exynos_data;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (layer_data == output_data->primary_layer) {
- if (!layer_data->display_buffer ||
- (output_data->current_mode->hdisplay == layer_data->info.src_config.pos.w &&
- output_data->current_mode->vdisplay == layer_data->info.src_config.pos.h)) {
- ret = _tdm_exynos_output_commit_primary_layer(layer_data, user_data,
- &do_waitvblank);
- } else
- ret = _tdm_exynos_output_commit_layer(layer_data);
-
- if (ret != TDM_ERROR_NONE)
- return ret;
- } else {
- ret = _tdm_exynos_output_commit_layer(layer_data);
- if (ret != TDM_ERROR_NONE)
- return ret;
- }
- }
-
- if (do_waitvblank == 1) {
- tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
- uint target_msc;
-
- if (!event_data) {
- TDM_ERR("alloc failed");
- return TDM_ERROR_OUT_OF_MEMORY;
- }
-
- ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
- &target_msc);
- if (ret != TDM_ERROR_NONE) {
- free(event_data);
- return ret;
- }
-
- target_msc++;
-
- event_data->type = TDM_EXYNOS_EVENT_TYPE_COMMIT;
- event_data->output_data = output_data;
- event_data->user_data = user_data;
- event_data->hwc_mode = exynos_data->hwc_mode;
-
- ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
- &target_msc, event_data);
- if (ret != TDM_ERROR_NONE) {
- free(event_data);
- return ret;
- }
- }
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_commit_handler(tdm_output *output,
- tdm_output_commit_handler func)
-{
- tdm_exynos_output_data *output_data = output;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
- output_data->commit_func = func;
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
- int ret;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- exynos_data = output_data->exynos_data;
- ret = drmModeObjectSetProperty(exynos_data->drm_fd,
- output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
- output_data->dpms_prop_id, dpms_value);
- if (ret < 0) {
- TDM_ERR("set dpms failed: %m");
- return TDM_ERROR_OPERATION_FAILED;
- }
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
- drmModeObjectPropertiesPtr props;
- int i;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER);
-
- exynos_data = output_data->exynos_data;
- props = drmModeObjectGetProperties(exynos_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;
- }
-
- 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;
- }
-
- drmModeFreeObjectProperties(props);
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_error ret = TDM_ERROR_NONE;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
-
- /* create or replace the target_window when the output mode is set */
- if (output_data->hwc_enable) {
- ret = exynos_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
- if (ret != TDM_ERROR_NONE) {
- TDM_ERR("create target hwc window failed (%d)", ret);
- return ret;
- }
- }
-
- output_data->current_mode = mode;
- output_data->mode_changed = 1;
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
-{
- tdm_exynos_output_data *output_data = output;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
-
- *mode = output_data->current_mode;
-
- return TDM_ERROR_NONE;
-}
-
-tdm_capture*
-exynos_output_create_capture(tdm_output *output, tdm_error *error)
-{
- tdm_exynos_output_data *output_data = output;
- tdm_exynos_data *exynos_data;
-
- RETURN_VAL_IF_FAIL(output_data, NULL);
-
- exynos_data = output_data->exynos_data;
-
- if (exynos_data->use_ippv2)
- return tdm_exynos_capture_create_output(exynos_data, output, error);
- else
- return tdm_exynos_capture_legacy_create_output(exynos_data, output, error);
-}
-
-tdm_error
-exynos_output_set_status_handler(tdm_output *output,
- tdm_output_status_handler func,
- void *user_data)
-{
- tdm_exynos_output_data *output_data = output;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
- output_data->status_func = func;
- output_data->status_user_data = user_data;
-
- return TDM_ERROR_NONE;
-}
-
-tdm_hwc *
-exynos_output_get_hwc(tdm_output *output, tdm_error *error)
-{
- tdm_exynos_hwc_data *hwc_data = NULL;
- tdm_exynos_output_data *output_data = output;
-
- if (!output_data) {
- TDM_ERR("invalid params");
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
- return NULL;
- }
-
- if (output_data->hwc_data) {
- TDM_INFO("hwc_data already exists");
- if (error)
- *error = TDM_ERROR_NONE;
- return output_data->hwc_data;
- }
-
- hwc_data = calloc(1, sizeof(tdm_exynos_hwc_data));
- if (!hwc_data) {
- TDM_ERR("alloc failed");
- if (error)
- *error = TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
- hwc_data->output_data = output_data;
-
- LIST_INITHEAD(&hwc_data->hwc_window_list);
-
- output_data->hwc_data = hwc_data;
-
- if (error)
- *error = TDM_ERROR_NONE;
-
- return hwc_data;
-}