2 * Copyright © 2007 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Dave Airlie <airlied@redhat.com>
33 #include <sys/types.h>
41 #include <X11/extensions/dpmsconst.h>
42 #include <xorgVersion.h>
43 #include <X11/Xatom.h>
50 #include "sec_output.h"
51 #include "sec_plane.h"
52 #include "sec_display.h"
53 #include "sec_video_fourcc.h"
55 #include "sec_converter.h"
57 #include "sec_xberc.h"
58 #include <xf86RandR12.h>
60 #include "sec_dummy.h"
62 static Bool SECCrtcConfigResize(ScrnInfoPtr pScrn, int width, int height);
63 static void SECModeVblankHandler(int fd, unsigned int frame, unsigned int tv_sec,
64 unsigned int tv_usec, void *event);
65 static void SECModePageFlipHandler(int fd, unsigned int frame, unsigned int tv_sec,
66 unsigned int tv_usec, void *event_data);
67 static void SECModeG2dHandler(int fd, unsigned int cmdlist_no, unsigned int tv_sec,
68 unsigned int tv_usec, void *event_data);
69 static void SECModeIppHandler(int fd, unsigned int prop_id, unsigned int *buf_idx, unsigned int tv_sec,
70 unsigned int tv_usec, void *event_data);
72 static const xf86CrtcConfigFuncsRec sec_xf86crtc_config_funcs =
78 _secDisplaySetDrmEventCtx(SECModePtr pSecMode)
80 pSecMode->event_context.vblank_handler = SECModeVblankHandler;
81 pSecMode->event_context.page_flip_handler = SECModePageFlipHandler;
82 pSecMode->event_context.g2d_handler = SECModeG2dHandler;
83 pSecMode->event_context.ipp_handler = SECModeIppHandler;
87 _secSetMainMode (ScrnInfoPtr pScrn, SECModePtr pSecMode)
89 xf86CrtcConfigPtr pXf86CrtcConfig;
90 pXf86CrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
93 for (i = 0; i < pXf86CrtcConfig->num_output; i++)
95 xf86OutputPtr pOutput = pXf86CrtcConfig->output[i];
96 SECOutputPrivPtr pOutputPriv = pOutput->driver_private;
99 if (pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_LVDS ||
100 pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_Unknown)
102 memcpy (&pSecMode->main_lcd_mode, pOutputPriv->mode_output->modes, sizeof(drmModeModeInfo));
106 if (pSecMode->main_lcd_mode.hdisplay == 0 ||
107 pSecMode->main_lcd_mode.vdisplay == 0)
109 pSecMode->main_lcd_mode.hdisplay = 640;
110 pSecMode->main_lcd_mode.vdisplay = 480;
117 _secDisplayRemoveFlipPixmaps (ScrnInfoPtr pScrn)
119 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
122 for (c = 0; c < pCrtcConfig->num_crtc; c++)
124 xf86CrtcPtr pCrtc = pCrtcConfig->crtc[c];
125 int conn_type = secCrtcGetConnectType (pCrtc);
126 if (conn_type == DRM_MODE_CONNECTOR_Unknown)
127 secCrtcRemoveFlipPixmap (pCrtc);
132 _saveFrameBuffer (ScrnInfoPtr pScrn, tbm_bo bo, int w, int h)
134 SECPtr pSec = SECPTR(pScrn);
136 SECFbBoDataPtr bo_data;
138 if (!pSec->dump_info)
141 tbm_bo_get_user_data (bo, TBM_BO_DATA_FB, (void * *)&bo_data);
142 XDBG_RETURN_IF_FAIL(bo_data != NULL);
144 snprintf (file, sizeof(file), "%03d_fb_%d.bmp", pSec->flip_cnt, bo_data->fb_id);
145 secUtilDoDumpBmps (pSec->dump_info, bo, w, h, NULL, file);
150 secHandleEvent (int fd, secDrmEventContextPtr evctx)
152 #define MAX_BUF_SIZE 1024
154 char buffer[MAX_BUF_SIZE];
158 /* The DRM read semantics guarantees that we always get only
159 * complete events. */
160 len = read (fd, buffer, sizeof buffer);
163 XDBG_WARNING (MDISP, "warning: the size of the drm_event is 0.\n");
168 XDBG_WARNING (MDISP, "warning: the size of the drm_event is less than drm_event structure.\n");
171 if (len > MAX_BUF_SIZE - sizeof (struct drm_exynos_ipp_event))
173 XDBG_WARNING (MDISP, "warning: the size of the drm_event can be over the maximum size.\n");
180 e = (struct drm_event *) &buffer[i];
183 case DRM_EVENT_VBLANK:
185 struct drm_event_vblank *vblank;
187 if (evctx->vblank_handler == NULL)
190 vblank = (struct drm_event_vblank *) e;
191 evctx->vblank_handler (fd,
195 (void *)((unsigned long)vblank->user_data));
198 case DRM_EVENT_FLIP_COMPLETE:
200 struct drm_event_vblank *vblank;
202 if (evctx->page_flip_handler == NULL)
205 vblank = (struct drm_event_vblank *) e;
206 evctx->page_flip_handler (fd,
210 (void *)((unsigned long)vblank->user_data));
213 case DRM_EXYNOS_G2D_EVENT:
215 struct drm_exynos_g2d_event *g2d;
217 if (evctx->g2d_handler == NULL)
220 g2d = (struct drm_exynos_g2d_event *) e;
221 evctx->g2d_handler (fd,
225 (void *)((unsigned long)g2d->user_data));
228 case DRM_EXYNOS_IPP_EVENT:
230 struct drm_exynos_ipp_event *ipp;
232 if (evctx->ipp_handler == NULL)
235 ipp = (struct drm_exynos_ipp_event *) e;
236 evctx->ipp_handler (fd,
241 (void *)((unsigned long)ipp->user_data));
254 SECCrtcConfigResize(ScrnInfoPtr pScrn, int width, int height)
256 ScreenPtr pScreen = pScrn->pScreen;
257 SECPtr pSec = SECPTR (pScrn);
259 XDBG_DEBUG(MDISP, "Resize cur(%dx%d) new(%d,%d)\n",
264 pSec->isCrtcOn = secCrtcCheckInUseAll(pScrn);
266 if (pScrn->virtualX == width &&
267 pScrn->virtualY == height)
271 secFbResize(pSec->pFb, width, height);
273 /* set the new size of pScrn */
274 pScrn->virtualX = width;
275 pScrn->virtualY = height;
276 pScrn->displayWidth = width;
277 secExaScreenSetScrnPixmap (pScreen);
279 secOutputDrmUpdate (pScrn);
281 _secDisplayRemoveFlipPixmaps (pScrn);
287 SECModeVblankHandler(int fd, unsigned int frame, unsigned int tv_sec,
288 unsigned int tv_usec, void *event)
290 SECVBlankInfoPtr pVblankInfo = event;
291 SECVBlankInfoType vblank_type;
294 XDBG_RETURN_IF_FAIL (pVblankInfo != NULL);
296 vblank_type = pVblankInfo->type;
297 data = pVblankInfo->data;
300 xDbgLogDrmEventRemoveVblank (pVblankInfo->xdbg_log_vblank);
303 if (vblank_type == VBLANK_INFO_SWAP)
305 XDBG_TRACE (MDISP, "vblank handler (%p, %ld, %ld)\n",
306 pVblankInfo, pVblankInfo->time, GetTimeInMillis () - pVblankInfo->time);
307 secDri2FrameEventHandler (frame, tv_sec, tv_usec, data);
309 else if (vblank_type == VBLANK_INFO_PLANE)
310 secLayerVBlankEventHandler (frame, tv_sec, tv_usec, data);
311 else if (vblank_type == VBLANK_INFO_PRESENT)
313 XDBG_TRACE (MDISP, "vblank handler (%p, %ld, %ld)\n",
314 pVblankInfo, pVblankInfo->time, GetTimeInMillis () - pVblankInfo->time);
315 secPresentVblankHandler(frame, tv_sec, tv_usec, data);
318 XDBG_ERROR (MDISP, "unknown the vblank type\n");
325 SECModePageFlipHandler(int fd, unsigned int frame, unsigned int tv_sec,
326 unsigned int tv_usec, void *event_data)
328 SECPageFlipPtr flip = event_data;
330 SECCrtcPrivPtr pCrtcPriv;
334 XDBG_ERROR (MDISP, "flip is null\n");
338 XDBG_TRACE (MDISP, "pageflip handler (%p, %ld, %ld)\n",
339 flip, flip->time, GetTimeInMillis () - flip->time);
342 if( flip->xdbg_log_pageflip != NULL )
343 xDbgLogDrmEventRemovePageflip (flip->xdbg_log_pageflip);
347 pCrtcPriv = pCrtc->driver_private;
348 pCrtcPriv->is_flipping = FALSE;
349 pCrtcPriv->is_fb_blit_flipping = FALSE;
350 pCrtcPriv->flip_count--; /* check flipping completed */
352 /* Is this the event whose info shall be delivered to higher level? */
353 /* Yes: Cache msc, ust for later delivery. */
354 pCrtcPriv->fe_frame = frame;
355 pCrtcPriv->fe_tv_sec = tv_sec;
356 pCrtcPriv->fe_tv_usec = tv_usec;
358 if (pCrtcPriv->bAccessibility || pCrtcPriv->screen_rotate_degree > 0)
359 if (pCrtcPriv->accessibility_front_bo && pCrtcPriv->accessibility_back_bo)
362 temp = pCrtcPriv->accessibility_front_bo;
363 pCrtcPriv->accessibility_front_bo = pCrtcPriv->accessibility_back_bo;
364 pCrtcPriv->accessibility_back_bo = temp;
368 if (flip->accessibility_back_bo)
370 secRenderBoUnref(flip->accessibility_back_bo);
371 flip->accessibility_back_bo = NULL;
374 /* if accessibility is diabled, remove the accessibility_bo
375 when the pageflip is occurred once after the accessibility is disabled */
376 if (!pCrtcPriv->bAccessibility && pCrtcPriv->screen_rotate_degree == 0)
378 if (pCrtcPriv->accessibility_front_bo)
380 secRenderBoUnref (pCrtcPriv->accessibility_front_bo);
381 pCrtcPriv->accessibility_front_bo = NULL;
383 if (pCrtcPriv->accessibility_back_bo)
385 secRenderBoUnref (pCrtcPriv->accessibility_back_bo);
386 pCrtcPriv->accessibility_back_bo = NULL;
390 /* Release back framebuffer */
393 secRenderBoUnref(flip->back_bo);
394 flip->back_bo = NULL;
397 if (pCrtcPriv->flip_info == NULL)
400 * If pCrtcPriv->flip_info is failed and secCrtcGetFirstPendingFlip (pCrtc) has data,
401 * ModePageFlipHandler is triggered by secDisplayUpdateRequest(). - Maybe FB_BLIT or FB is updated by CPU.
402 * In this case we should call _secDri2ProcessPending().
404 DRI2FrameEventPtr pending_flip;
405 pending_flip = secCrtcGetFirstPendingFlip (pCrtc);
406 if( pending_flip != NULL )
408 XDBG_DEBUG (MDISP, "FB_BLIT or FB is updated by CPU. But there's secCrtcGetFirstPendingFlip(). So trigger it manually\n");
409 flip->dispatch_me = TRUE;
410 pCrtcPriv->flip_info = pending_flip;
416 XDBG_DEBUG(MDISP, "ModePageFlipHandler ctrc_id:%d dispatch_me:%d, frame:%d, flip_count=%d is_pending=%p\n",
417 secCrtcID(pCrtcPriv), flip->dispatch_me, frame, pCrtcPriv->flip_count, secCrtcGetFirstPendingFlip (pCrtc));
419 /* Last crtc completed flip? */
420 if (flip->dispatch_me)
422 secCrtcCountFps(pCrtc);
424 /* Deliver cached msc, ust from reference crtc to flip event handler */
426 flip->handler(pCrtcPriv->fe_frame, pCrtcPriv->fe_tv_sec,
427 pCrtcPriv->fe_tv_usec, pCrtcPriv->flip_info, flip->flip_failed);
433 if (flip->accessibility_back_bo)
435 secRenderBoUnref(flip->accessibility_back_bo);
436 flip->accessibility_back_bo = NULL;
441 secRenderBoUnref(flip->back_bo);
442 flip->back_bo = NULL;
449 SECModeG2dHandler(int fd, unsigned int cmdlist_no, unsigned int tv_sec,
450 unsigned int tv_usec, void *event_data)
455 SECModeIppHandler(int fd, unsigned int prop_id, unsigned int *buf_idx,
456 unsigned int tv_sec, unsigned int tv_usec, void *event_data)
458 XDBG_DEBUG (MDRM, "wb_prop_id(%d) prop_id(%d), buf_idx(%d, %d) \n",
459 secWbGetPropID(), prop_id, buf_idx[0], buf_idx[1]);
461 if (secWbGetPropID () == prop_id)
462 secWbHandleIppEvent (fd, buf_idx, event_data);
464 secCvtHandleIppEvent (fd, buf_idx, event_data, FALSE);
468 SECModeWakeupHanlder(pointer data, int err, pointer p)
473 if (data == NULL || err < 0)
478 if (FD_ISSET (pSecMode->fd, read_mask))
479 secHandleEvent (pSecMode->fd, &pSecMode->event_context);
483 secModePreInit (ScrnInfoPtr pScrn, int drm_fd)
485 SECPtr pSec = SECPTR (pScrn);
490 // secLogSetLevel(MDISP, 0);
492 pSecMode = calloc (1, sizeof *pSecMode);
496 pSecMode->fd = drm_fd;
497 xorg_list_init (&pSecMode->crtcs);
498 xorg_list_init (&pSecMode->outputs);
499 xorg_list_init (&pSecMode->planes);
501 xf86CrtcConfigInit (pScrn, &sec_xf86crtc_config_funcs);
503 cpp = pScrn->bitsPerPixel /8;
506 pSecMode->mode_res = drmModeGetResources (pSecMode->fd);
507 if (!pSecMode->mode_res)
509 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
510 "failed to get resources: %s\n", strerror (errno));
515 pSecMode->plane_res = drmModeGetPlaneResources (pSecMode->fd);
516 if (!pSecMode->plane_res)
518 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
519 "failed to get plane resources: %s\n", strerror (errno));
520 drmModeFreeResources (pSecMode->mode_res);
525 xf86CrtcSetSizeRange (pScrn, 320, 200, pSecMode->mode_res->max_width,
526 pSecMode->mode_res->max_height);
528 for (i = 0; i < pSecMode->mode_res->count_crtcs; i++)
529 secCrtcInit (pScrn, pSecMode, i);
531 for (i = 0; i < pSecMode->mode_res->count_connectors; i++)
532 secOutputInit (pScrn, pSecMode, i);
534 for (i = 0; i < pSecMode->plane_res->count_planes; i++)
535 secPlaneInit (pScrn, pSecMode, i);
537 secDummyOutputInit(pScrn, pSecMode, FALSE);
538 #endif //NO_CRTC_MODE
539 _secSetMainMode (pScrn, pSecMode);
541 /* virtaul x and virtual y of the screen is ones from main lcd mode */
542 pScrn->virtualX = pSecMode->main_lcd_mode.hdisplay;
543 pScrn->virtualY = pSecMode->main_lcd_mode.vdisplay;
544 xf86InitialConfiguration (pScrn, TRUE);
547 * we assume that kernel always support the pageflipping
550 /* set the drm event context */
551 _secDisplaySetDrmEventCtx(pSecMode);
553 pSec->pSecMode = pSecMode;
555 /* virtaul x and virtual y of the screen is ones from main lcd mode */
556 pScrn->virtualX = pSecMode->main_lcd_mode.hdisplay;
557 pScrn->virtualY = pSecMode->main_lcd_mode.vdisplay;
560 xDbgLogDrmEventInit();
567 secModeInit (ScrnInfoPtr pScrn)
569 SECPtr pSec = SECPTR (pScrn);
570 SECModePtr pSecMode = pSec->pSecMode;
572 /* We need to re-register the mode->fd for the synchronisation
573 * feedback on every server generation, so perform the
574 * registration within ScreenInit and not PreInit.
576 //pSecMode->flip_count = 0;
577 AddGeneralSocket(pSecMode->fd);
578 RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
579 SECModeWakeupHanlder, pSecMode);
584 secModeDeinit (ScrnInfoPtr pScrn)
586 SECPtr pSec = SECPTR (pScrn);
587 SECModePtr pSecMode = (SECModePtr) pSec->pSecMode;
588 xf86CrtcPtr pCrtc = NULL;
589 xf86OutputPtr pOutput = NULL;
591 secDisplayDeinitDispMode (pScrn);
593 SECCrtcPrivPtr crtc_ref=NULL, crtc_next=NULL;
594 xorg_list_for_each_entry_safe (crtc_ref, crtc_next, &pSecMode->crtcs, link)
596 pCrtc = crtc_ref->pCrtc;
597 xf86CrtcDestroy (pCrtc);
600 SECOutputPrivPtr output_ref, output_next;
601 xorg_list_for_each_entry_safe (output_ref, output_next, &pSecMode->outputs, link)
603 pOutput = output_ref->pOutput;
604 xf86OutputDestroy (pOutput);
607 SECPlanePrivPtr plane_ref, plane_next;
608 xorg_list_for_each_entry_safe (plane_ref, plane_next, &pSecMode->planes, link)
610 secPlaneDeinit (pScrn, plane_ref);
613 if (pSecMode->mode_res)
614 drmModeFreeResources (pSecMode->mode_res);
616 if (pSecMode->plane_res)
617 drmModeFreePlaneResources (pSecMode->plane_res);
619 /* mode->rotate_fb_id should have been destroyed already */
622 if (pSecMode->num_dummy_output > 0)
624 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
626 for (i = 0; i < xf86_config->num_crtc; i++)
628 xf86CrtcPtr pCrtc = xf86_config->crtc[i];
629 xf86CrtcDestroy (pCrtc);
632 for (i = 0; i < xf86_config->num_output; i++)
634 xf86OutputPtr pOutput = xf86_config->output[i];
635 xf86OutputDestroy(pOutput);
638 #endif //NO_CRTC_MODE
641 pSec->pSecMode = NULL;
645 * Return the crtc covering 'box'. If two crtcs cover a portion of
646 * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
647 * with greater coverage
650 secModeCoveringCrtc (ScrnInfoPtr pScrn, BoxPtr pBox, xf86CrtcPtr pDesiredCrtc, BoxPtr pBoxCrtc)
652 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
653 xf86CrtcPtr pCrtc, pBestCrtc;
654 int coverage, best_coverage;
656 BoxRec crtc_box, cover_box;
658 XDBG_RETURN_VAL_IF_FAIL (pBox != NULL, NULL);
671 for (c = 0; c < pCrtcConfig->num_crtc; c++)
673 pCrtc = pCrtcConfig->crtc[c];
675 /* If the CRTC is off, treat it as not covering */
676 if(!secCrtcOn(pCrtc))
679 crtc_box.x1 = pCrtc->x;
680 crtc_box.x2 = pCrtc->x + xf86ModeWidth (&pCrtc->mode, pCrtc->rotation);
681 crtc_box.y1 = pCrtc->y;
682 crtc_box.y2 = pCrtc->y + xf86ModeHeight (&pCrtc->mode, pCrtc->rotation);
684 secUtilBoxIntersect(&cover_box, &crtc_box, pBox);
685 coverage = secUtilBoxArea(&cover_box);
687 if (coverage && pCrtc == pDesiredCrtc)
690 *pBoxCrtc = crtc_box;
694 if (coverage > best_coverage)
697 *pBoxCrtc = crtc_box;
699 best_coverage = coverage;
706 int secModeGetCrtcPipe (xf86CrtcPtr pCrtc)
708 SECCrtcPrivPtr pCrtcPriv = pCrtc->driver_private;
709 if (pCrtcPriv == NULL)
711 return pCrtcPriv->pipe;
715 secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe, tbm_bo back_bo,
716 RegionPtr pFlipRegion, unsigned int client_idx, XID drawable_id,
717 SECFlipEventHandler handler)
719 SECPageFlipPtr pPageFlip = NULL;
720 SECFbBoDataPtr bo_data;
721 SECCrtcPrivPtr pCrtcPriv;
723 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
724 xf86CrtcPtr pCurCrtc;
725 SECPtr pSec = SECPTR(pScrn);
733 tbm_bo_get_user_data (back_bo, TBM_BO_DATA_FB, (void * *)&bo_data);
734 XDBG_RETURN_VAL_IF_FAIL(bo_data != NULL, FALSE);
736 for (i = 0; i < pCrtcConfig->num_crtc; i++)
738 pCurCrtc = pCrtcConfig->crtc[i];
739 if (!pCurCrtc->enabled)
741 pCrtcPriv = pCurCrtc->driver_private;
742 pSecMode = pCrtcPriv->pSecMode;
746 b1.x2 = pCurCrtc->x + pCurCrtc->mode.HDisplay;
747 b1.y2 = pCurCrtc->y + pCurCrtc->mode.VDisplay;
749 retBox = secUtilBoxInBox(&bo_data->pos, &b1);
750 if(retBox == rgnSAME || retBox == rgnIN)
752 pPageFlip = calloc (1, sizeof (SECPageFlipRec));
753 if (pPageFlip == NULL)
755 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "Page flip alloc failed\n");
759 /* Only the reference crtc will finally deliver its page flip
760 * completion event. All other crtc's events will be discarded.
762 pPageFlip->dispatch_me = 0;
763 pPageFlip->pCrtc = pCurCrtc;
764 pPageFlip->clone = TRUE;
765 pPageFlip->back_bo = secRenderBoRef (back_bo);
766 pPageFlip->data = flip_info;
767 pPageFlip->flip_failed = FALSE;
768 pPageFlip->handler = handler;
771 if (pCrtcPriv->bAccessibility || pCrtcPriv->screen_rotate_degree > 0)
773 tbm_bo accessibility_bo = pCrtcPriv->accessibility_back_bo;
774 SECFbBoDataPtr accessibility_bo_data;
776 tbm_bo_get_user_data (accessibility_bo, TBM_BO_DATA_FB, (void * *)&accessibility_bo_data);
777 XDBG_GOTO_IF_FAIL (accessibility_bo_data != NULL, fail);
779 fb_id = accessibility_bo_data->fb_id;
781 /*Buffer is already changed by bo_swap*/
782 if (!secCrtcExecAccessibility (pCurCrtc, back_bo, accessibility_bo))
785 pPageFlip->accessibility_back_bo = secRenderBoRef(accessibility_bo);
789 fb_id = bo_data->fb_id;
791 tbm_bo_map(pPageFlip->back_bo, TBM_DEVICE_2D, TBM_OPTION_READ);
792 tbm_bo_unmap(pPageFlip->back_bo);
795 pCrtcPriv->is_flipping = TRUE;
797 if (!pCrtcPriv->onoff && !pCrtcPriv->onoff_always)
798 secCrtcTurn (pCrtcPriv->pCrtc, TRUE, FALSE, FALSE);
801 pPageFlip->xdbg_log_pageflip = xDbgLogDrmEventAddPageflip (pipe, client_idx, drawable_id);
804 XDBG_DEBUG (MSEC, "dump_mode(%x)\n", pSec->dump_mode);
806 if (pSec->dump_mode & XBERC_DUMP_MODE_FB)
807 _saveFrameBuffer (pScrn, back_bo,
808 bo_data->pos.x2 - bo_data->pos.x1,
809 bo_data->pos.y2 - bo_data->pos.y1);
811 pPageFlip->time = GetTimeInMillis ();
814 if(pSec->use_partial_update && pFlipRegion)
818 RegionRec new_region;
819 RegionPtr pRegion = pFlipRegion;
821 for (nBox = RegionNumRects(pRegion),
822 pBox = RegionRects(pRegion); nBox--; pBox++)
824 XDBG_DEBUG (MDISP, "dirtfb region(%d): (%d,%d %dx%d)\n", nBox,
825 pBox->x1, pBox->y1, pBox->x2-pBox->x1, pBox->y2-pBox->y1);
828 if (pCrtcPriv->screen_rotate_degree > 0)
830 RegionCopy (&new_region, pFlipRegion);
831 secUtilRotateRegion (pCrtc->mode.HDisplay, pCrtc->mode.VDisplay,
832 &new_region, pCrtcPriv->screen_rotate_degree);
833 pRegion = &new_region;
835 for (nBox = RegionNumRects(pRegion),
836 pBox = RegionRects(pRegion); nBox--; pBox++)
838 XDBG_DEBUG (MDISP, "(R)dirtfb region(%d): (%d,%d %dx%d)\n", nBox,
839 pBox->x1, pBox->y1, pBox->x2-pBox->x1, pBox->y2-pBox->y1);
843 drmModeDirtyFB (pSec->drm_fd, fb_id,
844 (drmModeClipPtr)RegionRects (pRegion),
845 (uint32_t)RegionNumRects (pRegion));
850 ret = drmModePageFlip (pSec->drm_fd, secCrtcID(pCrtcPriv), fb_id,
851 DRM_MODE_PAGE_FLIP_EVENT, pPageFlip);
854 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", strerror (errno));
858 XDBG_TRACE (MDISP, "pageflip do (%p, %ld)\n", pPageFlip, pPageFlip->time);
860 pCrtcPriv->flip_count++; /* check flipping completed */
861 pCrtcPriv->flip_info = (DRI2FrameEventPtr)flip_info;
864 XDBG_DEBUG(MDISP, "ModePageFlip crtc_id:%d, fb_id:%d, back_fb_id:%d, back_name:%d, accessibility:%d\n",
865 secCrtcID(pCrtcPriv), fb_id, bo_data->fb_id,
866 tbm_bo_export (back_bo), pCrtcPriv->bAccessibility);
872 XDBG_WARNING(MDISP, "Cannot find CRTC in (%d,%d)-(%d,%d)\n",
873 bo_data->pos.x1, bo_data->pos.y1, bo_data->pos.x2, bo_data->pos.y2);
877 /* Set dispatch_me to last pageflip */
878 pPageFlip->dispatch_me = 1;
883 pCrtcPriv->flip_count++; /* check flipping completed */
884 pCrtcPriv->flip_info = (DRI2FrameEventPtr)flip_info;
885 pPageFlip->dispatch_me = 1;
886 pPageFlip->flip_failed = TRUE;
888 SECModePageFlipHandler(pSecMode->fd, 0, 0, 0, pPageFlip);
890 XDBG_ERROR(MDISP, "drmModePageFlip error(crtc:%d, fb_id:%d, back_fb_id:%d, back_name:%d, accessibility:%d)\n",
891 secCrtcID(pCrtcPriv), fb_id, bo_data->fb_id, tbm_bo_export (back_bo), pCrtcPriv->bAccessibility);
896 /* load palette per a crtc */
898 secModeLoadPalette (ScrnInfoPtr pScrn, int numColors, int* indices,
899 LOCO* colors, VisualPtr pVisual)
901 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
904 uint16_t lut_r[256], lut_g[256], lut_b[256];
906 for (p = 0; p < pCrtcConfig->num_crtc; p++)
908 xf86CrtcPtr pCrtc = pCrtcConfig->crtc[p];
910 switch (pScrn->depth)
913 for (i = 0; i < numColors; i++)
918 for (j = 0; j < 8; j++)
920 lut_r[index * 8 + j] = colors[index].red << 8;
921 lut_b[index * 8 + j] = colors[index].blue << 8;
924 for (j = 0; j < 4; j++)
926 lut_g[index * 4 + j] = colors[index].green << 8;
931 for (i = 0; i < numColors; i++)
934 lut_r[index] = colors[index].red << 8;
935 lut_g[index] = colors[index].green << 8;
936 lut_b[index] = colors[index].blue << 8;
942 /* make the change through RandR */
943 RRCrtcGammaSet (pCrtc->randr_crtc, lut_r, lut_g, lut_b);
948 secDisplaySwapModeFromKmode(ScrnInfoPtr pScrn,
949 drmModeModeInfoPtr kmode,
950 DisplayModePtr pMode)
952 char fake_name[32] = "fake_mode";
954 memset (pMode, 0, sizeof (DisplayModeRec));
955 pMode->status = MODE_OK;
957 pMode->Clock = kmode->clock;
959 pMode->HDisplay = kmode->vdisplay;
960 pMode->HSyncStart = kmode->vsync_start;
961 pMode->HSyncEnd = kmode->vsync_end;
962 pMode->HTotal = kmode->vtotal;
963 pMode->HSkew = kmode->vscan;
965 pMode->VDisplay = kmode->hdisplay;
966 pMode->VSyncStart = kmode->hsync_start;
967 pMode->VSyncEnd = kmode->hsync_end;
968 pMode->VTotal = kmode->htotal;
969 pMode->VScan = kmode->hskew;
971 pMode->Flags = kmode->flags; //& FLAG_BITS;
972 pMode->name = strdup (fake_name);
974 if (kmode->type & DRM_MODE_TYPE_DRIVER)
975 pMode->type = M_T_DRIVER;
976 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
977 pMode->type |= M_T_PREFERRED;
979 xf86SetModeCrtc (pMode, pScrn->adjustFlags);
986 secDisplayModeFromKmode(ScrnInfoPtr pScrn,
987 drmModeModeInfoPtr kmode,
988 DisplayModePtr pMode)
990 memset (pMode, 0, sizeof (DisplayModeRec));
991 pMode->status = MODE_OK;
993 pMode->Clock = kmode->clock;
995 pMode->HDisplay = kmode->hdisplay;
996 pMode->HSyncStart = kmode->hsync_start;
997 pMode->HSyncEnd = kmode->hsync_end;
998 pMode->HTotal = kmode->htotal;
999 pMode->HSkew = kmode->hskew;
1001 pMode->VDisplay = kmode->vdisplay;
1002 pMode->VSyncStart = kmode->vsync_start;
1003 pMode->VSyncEnd = kmode->vsync_end;
1004 pMode->VTotal = kmode->vtotal;
1005 pMode->VScan = kmode->vscan;
1007 pMode->Flags = kmode->flags; //& FLAG_BITS;
1008 pMode->name = strdup (kmode->name);
1009 pMode->VRefresh = kmode->vrefresh;
1011 if (kmode->type & DRM_MODE_TYPE_DRIVER)
1012 pMode->type = M_T_DRIVER;
1013 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
1014 pMode->type |= M_T_PREFERRED;
1016 xf86SetModeCrtc (pMode, pScrn->adjustFlags);
1021 secDisplaySwapModeToKmode(ScrnInfoPtr pScrn,
1022 drmModeModeInfoPtr kmode,
1023 DisplayModePtr pMode)
1025 memset (kmode, 0, sizeof (*kmode));
1027 kmode->clock = pMode->Clock;
1028 kmode->hdisplay = pMode->VDisplay;
1029 kmode->hsync_start = pMode->VSyncStart;
1030 kmode->hsync_end = pMode->VSyncEnd;
1031 kmode->htotal = pMode->VTotal;
1032 kmode->hskew = pMode->VScan;
1034 kmode->vdisplay = pMode->HDisplay;
1035 kmode->vsync_start = pMode->HSyncStart;
1036 kmode->vsync_end = pMode->HSyncEnd;
1037 kmode->vtotal = pMode->HTotal;
1038 kmode->vscan = pMode->HSkew;
1039 kmode->vrefresh = xf86ModeVRefresh (pMode);
1041 kmode->flags = pMode->Flags; //& FLAG_BITS;
1043 strncpy (kmode->name, pMode->name, DRM_DISPLAY_MODE_LEN);
1044 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1049 secDisplayModeToKmode(ScrnInfoPtr pScrn,
1050 drmModeModeInfoPtr kmode,
1051 DisplayModePtr pMode)
1053 memset (kmode, 0, sizeof (*kmode));
1055 kmode->clock = pMode->Clock;
1056 kmode->hdisplay = pMode->HDisplay;
1057 kmode->hsync_start = pMode->HSyncStart;
1058 kmode->hsync_end = pMode->HSyncEnd;
1059 kmode->htotal = pMode->HTotal;
1060 kmode->hskew = pMode->HSkew;
1062 kmode->vdisplay = pMode->VDisplay;
1063 kmode->vsync_start = pMode->VSyncStart;
1064 kmode->vsync_end = pMode->VSyncEnd;
1065 kmode->vtotal = pMode->VTotal;
1066 kmode->vscan = pMode->VScan;
1067 kmode->vrefresh = xf86ModeVRefresh (pMode);
1069 kmode->flags = pMode->Flags; //& FLAG_BITS;
1071 strncpy (kmode->name, pMode->name, DRM_DISPLAY_MODE_LEN);
1073 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1077 static uint32_t crtc_id;
1078 static tbm_bo hdmi_bo;
1080 static Bool connect_crtc;
1083 _secDisplayGetAvailableCrtcID (ScrnInfoPtr pScrn)
1085 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
1089 for (i = 0; i < pSecMode->mode_res->count_crtcs; i++)
1091 drmModeCrtcPtr kcrtc = NULL;
1092 kcrtc = drmModeGetCrtc (pSecMode->fd, pSecMode->mode_res->crtcs[i]);
1095 XDBG_ERROR (MSEC, "fail to get kcrtc. \n");
1099 if (kcrtc->buffer_id > 0)
1101 drmModeFreeCrtc (kcrtc);
1105 crtc_id = kcrtc->crtc_id;
1106 drmModeFreeCrtc (kcrtc);
1115 _secDisplayWbCloseFunc (SECWb *wb, SECWbNotify noti, void *noti_data, void *user_data)
1117 ScrnInfoPtr pScrn = (ScrnInfoPtr)user_data;
1123 pSec = SECPTR (pScrn);
1125 pSec->wb_clone = NULL;
1129 secDisplayInitDispMode (ScrnInfoPtr pScrn, SECDisplayConnMode conn_mode)
1131 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
1133 uint32_t *output_ids = NULL;
1136 drmModeModeInfoPtr pKmode = NULL;
1137 drmModeCrtcPtr kcrtc = NULL;
1138 SECFbBoDataPtr bo_data = NULL;
1139 SECOutputPrivPtr pOutputPriv=NULL, pNext=NULL;
1140 int connector_type = -1;
1146 /* get output ids */
1147 output_ids = calloc (output_cnt, sizeof (uint32_t));
1148 XDBG_RETURN_VAL_IF_FAIL (output_ids != NULL, FALSE);
1150 xorg_list_for_each_entry_safe (pOutputPriv, pNext, &pSecMode->outputs, link)
1152 if (conn_mode == DISPLAY_CONN_MODE_HDMI)
1154 if (pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
1155 pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_HDMIB)
1157 output_ids[0] = pOutputPriv->mode_output->connector_id;
1158 pKmode = &pSecMode->ext_connector_mode;
1159 connector_type = pOutputPriv->mode_output->connector_type;
1163 else if (conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1165 if (pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_VIRTUAL)
1167 output_ids[0] = pOutputPriv->mode_output->connector_id;
1168 pKmode = &pSecMode->ext_connector_mode;
1169 connector_type = pOutputPriv->mode_output->connector_type;
1176 XDBG_NEVER_GET_HERE (MTVO);
1180 XDBG_GOTO_IF_FAIL (output_ids[0] > 0, fail_to_init);
1181 XDBG_GOTO_IF_FAIL (pKmode != NULL, fail_to_init);
1183 width = pKmode->hdisplay;
1184 height = pKmode->vdisplay;
1186 pOutputPriv = secOutputGetPrivateForConnType (pScrn, connector_type);
1187 if (pOutputPriv && pOutputPriv->mode_encoder)
1188 XDBG_GOTO_IF_FAIL (pOutputPriv->mode_encoder->crtc_id == 0, fail_to_init);
1190 crtc_id = _secDisplayGetAvailableCrtcID (pScrn);
1191 XDBG_GOTO_IF_FAIL (crtc_id > 0, fail_to_init);
1194 kcrtc = drmModeGetCrtc (pSecMode->fd, crtc_id);
1195 XDBG_GOTO_IF_FAIL (kcrtc != NULL, fail_to_init);
1197 if (kcrtc->buffer_id > 0)
1199 XDBG_ERROR (MTVO, "crtc(%d) already has buffer(%d) \n",
1200 crtc_id, kcrtc->buffer_id);
1205 hdmi_bo = secRenderBoCreate (pScrn, width, height);
1206 XDBG_GOTO_IF_FAIL (hdmi_bo != NULL, fail_to_init);
1208 tbm_bo_get_user_data(hdmi_bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1209 XDBG_GOTO_IF_FAIL (bo_data != NULL, fail_to_init);
1211 fb_id = bo_data->fb_id;
1214 if (drmModeSetCrtc (pSecMode->fd, crtc_id, fb_id, 0, 0, output_ids, output_cnt, pKmode))
1216 XDBG_ERRNO (MTVO, "drmModeSetCrtc failed. \n");
1224 secUtilSetDrmProperty (pSecMode, crtc_id, DRM_MODE_OBJECT_CRTC, "mode", 1);
1226 secOutputDrmUpdate (pScrn);
1228 XDBG_INFO (MDISP, "** ModeSet : (%dx%d) %dHz !!\n", pKmode->hdisplay, pKmode->vdisplay, pKmode->vrefresh);
1230 connect_crtc = TRUE;
1235 drmModeFreeCrtc (kcrtc);
1241 secDisplayDeinitDispMode (ScrnInfoPtr pScrn)
1243 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
1248 XDBG_INFO (MDISP, "** ModeUnset. !!\n");
1250 secUtilSetDrmProperty (pSecMode, crtc_id, DRM_MODE_OBJECT_CRTC, "mode", 0);
1254 secRenderBoUnref (hdmi_bo);
1258 secOutputDrmUpdate (pScrn);
1261 connect_crtc = FALSE;
1265 secDisplaySetDispSetMode (ScrnInfoPtr pScrn, SECDisplaySetMode set_mode)
1267 SECPtr pSec = SECPTR (pScrn);
1268 SECModePtr pSecMode = pSec->pSecMode;
1272 if (pSecMode->set_mode == set_mode)
1274 XDBG_INFO (MDISP, "set_mode(%d) is already set\n", set_mode);
1278 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_NONE)
1280 XDBG_WARNING (MDISP, "set_mode(%d) is failed : output is not connected yet\n", set_mode);
1286 case DISPLAY_SET_MODE_OFF:
1287 if (secWbIsOpened ())
1289 SECWb *wb = secWbGet ();
1292 secDisplayDeinitDispMode (pScrn);
1294 case DISPLAY_SET_MODE_CLONE:
1295 /* In case of DISPLAY_CONN_MODE_VIRTUAL, we will open writeback
1298 if (pSecMode->conn_mode != DISPLAY_CONN_MODE_VIRTUAL)
1304 XDBG_ERROR (MWB, "Fail : wb_clone(%p) already exists.\n", pSec->wb_clone);
1308 if (secWbIsOpened ())
1310 XDBG_ERROR (MWB, "Fail : wb(%p) already opened.\n", secWbGet ());
1314 wb_hz = (pSec->wb_hz > 0)? pSec->wb_hz : pSecMode->ext_connector_mode.vrefresh;
1316 XDBG_TRACE (MWB, "wb_hz(%d) vrefresh(%d)\n", pSec->wb_hz, pSecMode->ext_connector_mode.vrefresh);
1318 pSec->wb_clone = secWbOpen (pScrn, FOURCC_SN12, 0, 0, (pSec->scanout)?TRUE:FALSE, wb_hz, TRUE);
1321 secWbAddNotifyFunc (pSec->wb_clone, WB_NOTI_CLOSED,
1322 _secDisplayWbCloseFunc, pScrn);
1323 secWbSetRotate (pSec->wb_clone, pSecMode->rotate);
1324 secWbSetTvout (pSec->wb_clone, TRUE);
1325 if (!secWbStart (pSec->wb_clone))
1327 secWbClose (pSec->wb_clone);
1333 case DISPLAY_SET_MODE_EXT:
1334 if (secWbIsOpened ())
1336 SECWb *wb = secWbGet ();
1339 secDisplayDeinitDispMode (pScrn);
1345 pSecMode->set_mode = set_mode;
1351 secDisplayGetDispSetMode (ScrnInfoPtr pScrn)
1353 SECDisplaySetMode set_mode;
1354 SECPtr pSec = SECPTR (pScrn);
1355 SECModePtr pSecMode = pSec->pSecMode;
1357 set_mode = pSecMode->set_mode;
1363 secDisplaySetDispRotate (ScrnInfoPtr pScrn, int rotate)
1365 SECPtr pSec = SECPTR (pScrn);
1366 SECModePtr pSecMode = pSec->pSecMode;
1368 if (pSecMode->rotate == rotate)
1371 pSecMode->rotate = rotate;
1374 secWbSetRotate (pSec->wb_clone, rotate);
1380 secDisplayGetDispRotate (ScrnInfoPtr pScrn)
1383 SECPtr pSec = SECPTR (pScrn);
1384 SECModePtr pSecMode = pSec->pSecMode;
1386 rotate = pSecMode->rotate;
1392 secDisplaySetDispConnMode (ScrnInfoPtr pScrn, SECDisplayConnMode conn_mode)
1394 SECPtr pSec = SECPTR (pScrn);
1395 SECModePtr pSecMode = pSec->pSecMode;
1397 if (pSecMode->conn_mode == conn_mode)
1399 XDBG_DEBUG (MDISP, "conn_mode(%d) is already set\n", conn_mode);
1405 case DISPLAY_CONN_MODE_NONE:
1407 case DISPLAY_CONN_MODE_HDMI:
1409 case DISPLAY_CONN_MODE_VIRTUAL:
1415 pSecMode->conn_mode = conn_mode;
1421 secDisplayGetDispConnMode (ScrnInfoPtr pScrn)
1423 SECDisplayConnMode conn_mode;
1425 SECPtr pSec = SECPTR (pScrn);
1426 SECModePtr pSecMode = pSec->pSecMode;
1428 conn_mode = pSecMode->conn_mode;
1434 secDisplayGetCurMSC (ScrnInfoPtr pScrn, int pipe, CARD64 *ust, CARD64 *msc)
1438 SECPtr pSec = SECPTR (pScrn);
1439 SECModePtr pSecMode = pSec->pSecMode;
1441 /* if lcd is off, return true with msc = 0 */
1443 if (pSec->isCrtcOn == FALSE)
1449 #endif //NO_CRTC_MODE
1458 /* if pipe is -1, return the current msc of the main crtc */
1462 vbl.request.type = DRM_VBLANK_RELATIVE;
1466 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1467 vbl.request.type |= _DRM_VBLANK_EXYNOS_VIDI;
1469 vbl.request.type |= DRM_VBLANK_SECONDARY;
1472 vbl.request.sequence = 0;
1473 ret = drmWaitVBlank (pSec->drm_fd, &vbl);
1478 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1479 "first get vblank counter failed: %s\n",
1484 *ust = ((CARD64) vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
1485 *msc = vbl.reply.sequence;
1491 secDisplayVBlank (ScrnInfoPtr pScrn, int pipe, CARD64 *target_msc, int flip,
1492 SECVBlankInfoType type, void *vblank_info)
1496 SECPtr pSec = SECPTR (pScrn);
1497 SECVBlankInfoPtr pVblankInfo = NULL;
1498 SECModePtr pSecMode = pSec->pSecMode;
1500 pVblankInfo = calloc (1, sizeof (SECVBlankInfoRec));
1501 if (pVblankInfo == NULL)
1503 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "vblank_info alloc failed\n");
1507 pVblankInfo->type = type;
1508 pVblankInfo->data = vblank_info;
1509 pVblankInfo->time = GetTimeInMillis ();
1511 vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
1515 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1516 vbl.request.type |= _DRM_VBLANK_EXYNOS_VIDI;
1518 vbl.request.type |= DRM_VBLANK_SECONDARY;
1521 /* If non-pageflipping, but blitting/exchanging, we need to use
1522 * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later
1527 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL && pipe > 0)
1528 ; /* do not set the DRM_VBLANK_NEXTMISS */
1530 vbl.request.type |= DRM_VBLANK_NEXTONMISS;
1533 vbl.request.sequence = *target_msc;
1534 vbl.request.signal = (unsigned long) pVblankInfo;
1537 DRI2FrameEventPtr pEvent = (DRI2FrameEventPtr) vblank_info;
1538 if (type == VBLANK_INFO_SWAP)
1539 pVblankInfo->xdbg_log_vblank = xDbgLogDrmEventAddVblank (pipe, pEvent->client_idx, pEvent->drawable_id, type);
1541 pVblankInfo->xdbg_log_vblank = xDbgLogDrmEventAddVblank (pipe, 0, 0, type);
1543 ret = drmWaitVBlank (pSec->drm_fd, &vbl);
1547 xDbgLogDrmEventRemoveVblank (pVblankInfo->xdbg_log_vblank);
1554 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1555 "divisor 0 get vblank counter failed: %s\n",
1560 XDBG_TRACE (MDISP, "vblank do (%p, %ld)\n", pVblankInfo, pVblankInfo->time);
1562 /* Adjust returned value for 1 fame pageflip offset of flip > 0 */
1563 *target_msc = vbl.reply.sequence + flip;
1569 secDisplayDrawablePipe (DrawablePtr pDraw)
1571 ScreenPtr pScreen = pDraw->pScreen;
1572 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1573 BoxRec box, crtc_box;
1579 box.x2 = box.x1 + pDraw->width;
1580 box.y2 = box.y1 + pDraw->height;
1582 pCrtc = secModeCoveringCrtc (pScrn, &box, NULL, &crtc_box);
1584 if (pCrtc != NULL && !pCrtc->rotatedData)
1585 pipe = secModeGetCrtcPipe (pCrtc);
1591 secDisplayCrtcPipe (ScrnInfoPtr pScrn, int crtc_id)
1593 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (pScrn);
1596 for (c = 0; c < pCrtcConfig->num_crtc; c++)
1598 xf86CrtcPtr pCrtc = pCrtcConfig->crtc[c];
1599 SECCrtcPrivPtr pCrtcPriv = pCrtc->driver_private;
1600 if (pCrtcPriv->mode_crtc->crtc_id == crtc_id)
1601 return pCrtcPriv->pipe;
1604 XDBG_ERROR (MDISP, "%s(%d): crtc(%d) not found.\n", __func__, __LINE__, crtc_id);
1606 for (c = 0; c < pCrtcConfig->num_crtc; c++)
1608 xf86CrtcPtr pCrtc = pCrtcConfig->crtc[c];
1609 SECCrtcPrivPtr pCrtcPriv = pCrtc->driver_private;
1610 XDBG_ERROR (MDISP, "%s(%d) : crtc(%d) != crtc(%d)\n", __func__, __LINE__,
1611 pCrtcPriv->mode_crtc->crtc_id, crtc_id);
1617 Bool secDisplayUpdateRequest(ScrnInfoPtr pScrn)
1619 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, FALSE);
1621 SECPtr pSec = SECPTR(pScrn);
1622 xf86CrtcPtr pCrtc = xf86CompatCrtc (pScrn);
1623 SECCrtcPrivPtr pCrtcPriv;
1626 SECPageFlipPtr pPageFlip = NULL;
1632 XDBG_RETURN_VAL_IF_FAIL (pCrtc != NULL, FALSE);
1634 pCrtcPriv = pCrtc->driver_private;
1636 if (pCrtcPriv == NULL)
1639 XDBG_RETURN_VAL_IF_FAIL (pCrtcPriv != NULL, FALSE);
1642 bo = pCrtcPriv->front_bo;
1644 if( pCrtcPriv->is_fb_blit_flipping || pCrtcPriv->is_flipping || secCrtcGetFirstPendingFlip (pCrtc) )
1646 XDBG_DEBUG (MDISP, "drmModePageFlip is already requested!\n");
1650 // Without buffer swap, we need to request drmModePageFlip().
1653 SECFbBoDataPtr bo_data;
1656 tbm_bo_get_user_data (bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1657 XDBG_RETURN_VAL_IF_FAIL(bo_data != NULL, FALSE);
1659 fb_id = bo_data->fb_id;
1661 pPageFlip = calloc (1, sizeof (SECPageFlipRec));
1662 if (pPageFlip == NULL)
1664 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "Page flip alloc failed\n");
1668 /* Only the reference crtc will finally deliver its page flip
1669 * completion event. All other crtc's events will be discarded.
1671 pPageFlip->dispatch_me = 0;
1672 pPageFlip->pCrtc = pCrtc;
1673 pPageFlip->clone = TRUE;
1674 pPageFlip->back_bo = secRenderBoRef (bo);
1675 pPageFlip->data = NULL;
1676 pPageFlip->flip_failed = FALSE;
1677 pPageFlip->xdbg_log_pageflip = NULL;
1678 pPageFlip->time = GetTimeInMillis ();
1679 pPageFlip->handler = secDri2FlipEventHandler;
1682 if (pCrtcPriv->bAccessibility || pCrtcPriv->screen_rotate_degree > 0)
1684 tbm_bo accessibility_bo = pCrtcPriv->accessibility_back_bo;
1685 SECFbBoDataPtr accessibility_bo_data;
1687 tbm_bo_get_user_data (accessibility_bo, TBM_BO_DATA_FB, (void * *)&accessibility_bo_data);
1688 XDBG_GOTO_IF_FAIL (accessibility_bo_data != NULL, fail);
1690 fb_id = accessibility_bo_data->fb_id;
1692 /*Buffer is already changed by bo_swap*/
1693 if (!secCrtcExecAccessibility (pCrtc, bo, accessibility_bo))
1696 pPageFlip->accessibility_back_bo = secRenderBoRef(accessibility_bo);
1701 * If pPageFlip->dispatch_me is NULL, then in SECModePageFlipHandler, nothing to happen.
1702 * That means only LCD buffer is updated.
1703 * Frame buffer is not swapped. Because these request is only for FB_BLIT case!
1705 ret = drmModePageFlip (pSec->drm_fd, secCrtcID(pCrtcPriv), fb_id,
1706 DRM_MODE_PAGE_FLIP_EVENT, pPageFlip);
1709 XDBG_ERRNO (MDISP, "Page flip failed: %s\n", strerror (errno));
1713 pCrtcPriv->flip_info = NULL;
1714 pCrtcPriv->flip_count++;
1715 pCrtcPriv->is_fb_blit_flipping = TRUE;
1719 XDBG_DEBUG (MDISP, "pCrtcPriv->front_bo is NULL!\n");
1729 if( pPageFlip != NULL )
1731 if (pPageFlip->accessibility_back_bo)
1733 secRenderBoUnref(pPageFlip->accessibility_back_bo);
1734 pPageFlip->accessibility_back_bo = NULL;
1737 if (pPageFlip->back_bo)
1739 secRenderBoUnref(pPageFlip->back_bo);
1740 pPageFlip->back_bo = NULL;
1751 secDisplayChangeMode (ScrnInfoPtr pScrn)
1753 SECPtr pSec = SECPTR(pScrn);
1754 SECModePtr pSecMode = pSec->pSecMode;
1755 xf86CrtcPtr pCrtc = NULL;
1756 xf86OutputPtr pOutput = NULL;
1757 int temp = 99, i = 0;
1758 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1759 for (i = 0; i < config->num_crtc; i++)
1761 if (config->crtc[i]->active == TRUE)
1767 SECOutputPrivPtr output_ref, output_next;
1768 /* Priority LVDS > HDMI > Virtual */
1769 xorg_list_for_each_entry_safe (output_ref, output_next, &pSecMode->outputs, link)
1771 if (output_ref->pOutput->crtc == NULL)
1773 if (output_ref->mode_output == NULL)
1775 if (output_ref->mode_output->connector_type == DRM_MODE_CONNECTOR_Unknown)
1777 if (output_ref->mode_output->connector_type < temp)
1779 pOutput = output_ref->pOutput;
1780 pCrtc = output_ref->pOutput->crtc;
1781 temp = (int) output_ref->mode_output->connector_type;
1785 if (pCrtc != NULL && pOutput != NULL && pCrtc->active == FALSE)
1787 DisplayModePtr max_mode = xf86CVTMode( 4096, 4096, 60, 0, 0);
1788 DisplayModePtr mode =
1789 xf86OutputFindClosestMode(pOutput, max_mode);
1793 "Can't find display mode for output: %s\n", pOutput->name);
1798 if (!RRScreenSizeSet(pScrn->pScreen,
1799 mode->HDisplay, mode->VDisplay,
1800 pOutput->mm_width, pOutput->mm_height))
1803 "Can't setup screen size H:%d V:%d for output: %s\n", mode->HDisplay, mode->VDisplay);
1808 if (!xf86CrtcSetModeTransform(pCrtc, mode, RR_Rotate_0, NULL, 0, 0))
1811 "Can't transform Crtc to mode: %s\n", pCrtc, mode->name);
1814 RRScreenSizeSet(pScrn->pScreen, 640, 480, 0, 0);
1819 pSec->enableCursor = TRUE;
1820 secCrtcCursorEnable (pScrn, TRUE);
1821 // xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1822 // for (temp = 0; temp < config->num_output; temp++)
1824 // if (config->output[temp] == pOutput)
1826 // config->compat_output = temp;
1830 xf86SetScrnInfoModes(pScrn);
1831 xf86RandR12TellChanged(pScrn->pScreen);
1834 if (pSec->isCrtcOn == FALSE)
1836 pSec->enableCursor = FALSE;
1837 secCrtcCursorEnable (pScrn, FALSE);
1842 RRScreenSizeSet(pScrn->pScreen, 640, 480, 0, 0);
1843 xf86SetScrnInfoModes(pScrn);
1844 xf86RandR12TellChanged(pScrn->pScreen);