Merge branch 'devel/dri3' into devel/tizen
[platform/adaptation/samsung_exynos/xf86-video-exynos.git] / src / sec.c
1 /**************************************************************************
2
3 xserver-xorg-video-exynos
4
5 Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 #include <sys/stat.h>
35 #include <fcntl.h>
36
37 /* all driver need this */
38 #include "xf86.h"
39 #include "xf86_OSproc.h"
40
41 #include "fb.h"
42 #include "mipointer.h"
43 #include "micmap.h"
44 #include "colormapst.h"
45 #include "xf86cmap.h"
46 #include "xf86xv.h"
47 #include "xf86Crtc.h"
48 #include "sec.h"
49 #include "sec_display.h"
50 #include "sec_plane.h"
51 #include "sec_accel.h"
52 #include "sec_xberc.h"
53 #include "sec_util.h"
54 #include "sec_wb.h"
55 #include "sec_crtc.h"
56 #include <tbm_bufmgr.h>
57 #include "fimg2d.h"
58 #include "sec_output.h"
59
60 #define OPTION_FLIP_BUFFERS 0
61
62 /* prototypes */
63 static const OptionInfoRec* SECAvailableOptions (int chipid, int busid);
64 static void SECIdentify (int flags);
65 static Bool SECProbe (DriverPtr pDrv, int flags);
66 static Bool SECPreInit (ScrnInfoPtr pScrn, int flags);
67 static Bool SECScreenInit (ScreenPtr pScreen, int argc, char **argv);
68 static Bool SECSwitchMode (ScrnInfoPtr pScrn, DisplayModePtr pMode);
69 static void SECAdjustFrame (ScrnInfoPtr pScrn, int x, int y);
70 static Bool SECEnterVT (ScrnInfoPtr pScrn);
71 static void SECLeaveVT (ScrnInfoPtr pScrn);
72 static ModeStatus SECValidMode (ScrnInfoPtr pScrn, DisplayModePtr pMode, Bool verbose, int flags);
73 static Bool SECCloseScreen (ScreenPtr pScreen);
74 static Bool SECCreateScreenResources (ScreenPtr pScreen);
75 #if HAVE_UDEV
76 static void SECUdevEventsHandler (int fd, void *closure);
77 #endif
78
79 /* This DriverRec must be defined in the driver for Xserver to load this driver */
80 _X_EXPORT DriverRec SEC =
81 {
82     SEC_VERSION,
83     SEC_DRIVER_NAME,
84     SECIdentify,
85     SECProbe,
86     SECAvailableOptions,
87     NULL,
88     0,
89     NULL,
90 };
91
92 /* Supported "chipsets" */
93 static SymTabRec SECChipsets[] =
94 {
95     { 0, "exynos" },
96     {-1, NULL }
97 };
98
99 /* Supported options */
100 typedef enum
101 {
102     OPTION_DRI2,
103     OPTION_EXA,
104     OPTION_SWEXA,
105     OPTION_ROTATE,
106     OPTION_SNAPSHOT,
107     OPTION_WB,
108 #if OPTION_FLIP_BUFFERS
109     OPTION_FLIPBUFS,
110 #endif
111     OPTION_CACHABLE,
112     OPTION_SCANOUT,
113     OPTION_ACCEL2D,
114     OPTION_PRESENT,
115     OPTION_DRI3,
116     OPTION_PARTIAL_UPDATE,
117 } SECOpts;
118
119 static const OptionInfoRec SECOptions[] =
120 {
121     { OPTION_DRI2,     "dri2",       OPTV_BOOLEAN, {0}, FALSE },
122     { OPTION_EXA,      "exa",        OPTV_BOOLEAN, {0}, FALSE },
123     { OPTION_SWEXA,    "sw_exa",     OPTV_BOOLEAN, {0}, FALSE },
124     { OPTION_ROTATE,   "rotate",     OPTV_STRING,  {0}, FALSE },
125     { OPTION_SNAPSHOT, "snapshot",   OPTV_STRING,  {0}, FALSE },
126     { OPTION_WB,       "wb",         OPTV_BOOLEAN, {0}, FALSE },
127 #if OPTION_FLIP_BUFFERS
128     { OPTION_FLIPBUFS, "flip_bufs",  OPTV_INTEGER, {0}, 3 },
129 #endif
130     { OPTION_CACHABLE, "cachable",   OPTV_BOOLEAN, {0}, FALSE },
131     { OPTION_SCANOUT,  "scanout",    OPTV_BOOLEAN, {0}, FALSE },
132     { OPTION_ACCEL2D,  "accel_2d",   OPTV_BOOLEAN, {0}, FALSE },
133     { OPTION_PRESENT,  "present",    OPTV_BOOLEAN, {0}, FALSE },
134     { OPTION_DRI3,         "dri3",       OPTV_BOOLEAN, {0}, FALSE },
135     { OPTION_PARTIAL_UPDATE,  "partial_update",    OPTV_BOOLEAN, {0}, FALSE },
136     { -1,              NULL,         OPTV_NONE,    {0}, FALSE }
137 };
138
139 /* -------------------------------------------------------------------- */
140 #ifdef XFree86LOADER
141
142 MODULESETUPPROTO (SECSetup);
143
144 static XF86ModuleVersionInfo SECVersRec =
145 {
146     "exynos",
147     MODULEVENDORSTRING,
148     MODINFOSTRING1,
149     MODINFOSTRING2,
150     XORG_VERSION_CURRENT,
151     PACKAGE_VERSION_MAJOR,
152     PACKAGE_VERSION_MINOR,
153     PACKAGE_VERSION_PATCHLEVEL,
154     ABI_CLASS_VIDEODRV,
155     ABI_VIDEODRV_VERSION,
156     NULL,
157     {0,0,0,0}
158 };
159
160 _X_EXPORT XF86ModuleData exynosModuleData = { &SECVersRec, SECSetup, NULL };
161
162 pointer
163 SECSetup (pointer module, pointer opts, int *errmaj, int *errmin)
164 {
165     static Bool setupDone = FALSE;
166
167     if (!setupDone)
168     {
169         setupDone = TRUE;
170         xf86AddDriver (&SEC, module, HaveDriverFuncs);
171         return (pointer) 1;
172     }
173     else
174     {
175         if (errmaj) *errmaj = LDR_ONCEONLY;
176         return NULL;
177     }
178 }
179
180 #endif /* XFree86LOADER */
181 /* -------------------------------------------------------------------- */
182
183 /* TODO:::check the fimd_drm */
184 static Bool
185 _has_drm_mode_setting()
186 {
187     /* TODO:: check the sysfs dri2 device name */
188     return TRUE;
189 }
190
191 /*
192  * Probing the device with the device node, this probing depend on the specific hw.
193  * This function just verify whether the display hw is avaliable or not.
194  */
195 static Bool
196 _secHwProbe (struct pci_device * pPci, char *device,char **namep)
197 {
198     if (!_has_drm_mode_setting())
199         return FALSE;
200
201     return TRUE;
202 }
203
204 static tbm_bufmgr
205 _secInitBufmgr (int drm_fd, void * arg)
206 {
207     tbm_bufmgr bufmgr = NULL;
208
209     /* get buffer manager */
210     setenv("BUFMGR_LOCK_TYPE", "once", 1);
211     setenv("BUFMGR_MAP_CACHE", "true", 1);
212     bufmgr = tbm_bufmgr_init (drm_fd);
213
214     if (bufmgr == NULL)
215         return NULL;
216
217     return bufmgr;
218 }
219
220 static void
221 _secDeInitBufmgr (tbm_bufmgr bufmgr)
222 {
223     if (bufmgr)
224         tbm_bufmgr_deinit (bufmgr);
225 }
226
227 /* open drm */
228 static Bool
229 _openDrmMaster (ScrnInfoPtr pScrn)
230 {
231     SECPtr pSec = SECPTR (pScrn);
232     int ret;
233
234     /* open drm */
235     pSec->drm_fd = drmOpen ("exynos", NULL);
236     if (pSec->drm_fd < 0)
237     {
238         struct udev *udev;
239         struct udev_enumerate *e;
240         struct udev_list_entry *entry;
241         struct udev_device *device, *drm_device;
242         const char *path, *device_seat;
243         const char *filename;
244
245         xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "[DRM] Cannot open drm device.. search by udev\n");
246
247         /* STEP 1: Find drm device */
248         udev = udev_new();
249         if (udev == NULL)
250         {
251             xf86DrvMsg (pScrn->scrnIndex, X_ERROR,"[DRM] fail to initialize udev context\n");
252             goto fail_to_open_drm_master;
253         }
254
255         e = udev_enumerate_new(udev);
256         udev_enumerate_add_match_subsystem(e, "drm");
257         udev_enumerate_add_match_sysname(e, "card[0-9]*");
258         udev_enumerate_scan_devices(e);
259
260         drm_device = NULL;
261         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e))
262         {
263             path = udev_list_entry_get_name(entry);
264             device = udev_device_new_from_syspath(udev, path);
265             device_seat = udev_device_get_property_value(device, "ID_SEAT");
266             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] drm info: device:%p, patch:%s, seat:%s\n", device, path, device_seat);
267
268             if(!device_seat)
269                 device_seat = "seat0";
270
271             if(strcmp(device_seat, "seat0") == 0)
272             {
273                 drm_device = device;
274                 break;
275             }
276             udev_device_unref(device);
277         }
278
279         if(drm_device == NULL)
280         {
281             xf86DrvMsg (pScrn->scrnIndex, X_ERROR,"[DRM] fail to find drm device\n");
282             goto fail_to_open_drm_master;
283         }
284
285         filename = udev_device_get_devnode(drm_device);
286
287         pSec->drm_fd  = open(filename, O_RDWR|O_CLOEXEC);
288         if (pSec->drm_fd < 0)
289         {
290             xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "[DRM] Cannot open drm device(%s)\n", filename);
291
292             udev_device_unref(drm_device);
293             udev_enumerate_unref(e);
294             udev_unref(udev);
295
296             goto fail_to_open_drm_master;
297         }
298         else
299         {
300             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed to open drm device(%s)\n", filename);
301         }
302
303         udev_device_unref(drm_device);
304         udev_enumerate_unref(e);
305         udev_unref(udev);
306     }
307     else
308     {
309         xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed to open drm device\n");
310     }
311
312     pSec->drm_device_name = drmGetDeviceNameFromFd (pSec->drm_fd);
313     xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed get drm device name:%s\n",
314                 pSec->drm_device_name);
315
316     /* enable drm vblank */
317     ret = drmCtlInstHandler (pSec->drm_fd, 217);
318     if (ret)
319     {
320         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
321                     "[DRM] Fail to enable drm VBlank(%d)\n", ret);
322         goto fail_to_open_drm_master;
323     }
324
325     xf86DrvMsg (pScrn->scrnIndex, X_CONFIG,
326                 "[DRM] Enable drm VBlank(%d)\n", ret);
327
328     /* initialize drm bufmgr */
329     pSec->tbm_bufmgr = _secInitBufmgr (pSec->drm_fd, NULL);
330     if (pSec->tbm_bufmgr == NULL)
331     {
332         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
333                     "[DRM] Error : bufmgr initialization failed\n");
334         goto fail_to_open_drm_master;
335     }
336
337     xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
338                 , "[DRM] Enable buffer manager\n");
339
340     return TRUE;
341
342 fail_to_open_drm_master:
343
344     if (pSec->tbm_bufmgr)
345     {
346         _secDeInitBufmgr (pSec->tbm_bufmgr);
347         pSec->tbm_bufmgr = NULL;
348     }
349
350     if (pSec->drm_device_name)
351     {
352         free (pSec->drm_device_name);
353         pSec->drm_device_name = NULL;
354     }
355
356     if (pSec->drm_fd >= 0)
357     {
358         drmClose (pSec->drm_fd);
359         pSec->drm_fd = -1;
360     }
361
362     return FALSE;
363 }
364
365 /* close drm */
366 static void
367 _closeDrmMaster (ScrnInfoPtr pScrn)
368 {
369     SECPtr pSec = SECPTR (pScrn);
370
371     if (pSec->tbm_bufmgr)
372     {
373         _secDeInitBufmgr (pSec->tbm_bufmgr);
374         pSec->tbm_bufmgr = NULL;
375     }
376
377     if (pSec->drm_fd >= 0)
378     {
379         drmClose (pSec->drm_fd);
380         pSec->drm_fd = -1;
381     }
382
383     if (pSec->drm_device_name)
384     {
385         free (pSec->drm_device_name);
386         pSec->drm_device_name = NULL;
387     }
388 }
389
390 /*
391  * Initialize the device Probing the device with the device node,
392  * this probing depend on the specific hw.
393  * This function just verify whether the display hw is avaliable or not.
394  */
395 static Bool
396 _secHwInit (ScrnInfoPtr pScrn, struct pci_device *pPci, char *device)
397 {
398     SECPtr pSec = SECPTR (pScrn);
399
400     /* init drm master */
401     if (_openDrmMaster (pScrn) == TRUE)
402         xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
403                     , "DRM BLANK is enabled\n");
404     else
405         xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
406                     , "DRM BLANK is disabled\n");
407
408
409     if(g2d_init (pSec->drm_fd))
410     {
411         xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
412                     , "G2D is enabled\n");
413         pSec->is_accel_2d = TRUE;
414     }
415     else
416         xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
417                     , "G2D is disabled\n");
418 #ifdef NO_CRTC_MODE 
419    /*** Temporary disable G2D acceleration for using PIXMAN ***/
420     pSec->is_accel_2d = FALSE;
421 #endif
422     return TRUE;
423 }
424
425 /* SigHook */
426 OsSigWrapperPtr old_sig_wrapper;
427 int
428 _secOsSigWrapper (int sig)
429 {
430     XDBG_KLOG(MSEC,"Catch SIG: %d\n", sig);
431
432     return old_sig_wrapper(sig); /*Contiue*/
433 }
434
435 /*
436  * DeInitialize the hw
437  */
438 static void
439 _secHwDeinit (ScrnInfoPtr pScrn)
440 {
441     g2d_fini ();
442
443     /* deinit drm master */
444     _closeDrmMaster (pScrn);
445
446     return;
447 }
448
449 static Bool
450 _allocScrnPrivRec (ScrnInfoPtr pScrn)
451 {
452     if (pScrn->driverPrivate != NULL)
453         return TRUE;
454
455     pScrn->driverPrivate = calloc (sizeof (SECRec), 1);
456     if (!pScrn->driverPrivate)
457         return FALSE;
458
459     return TRUE;
460 }
461
462 static void
463 _freeScrnPrivRec (ScrnInfoPtr pScrn)
464 {
465     if (pScrn->driverPrivate == NULL)
466         return;
467     free (pScrn->driverPrivate);
468     pScrn->driverPrivate = NULL;
469 }
470
471 /*
472  * Check the driver option.
473  * Set the option flags to the driver private
474  */
475 static void
476 _checkDriverOptions (ScrnInfoPtr pScrn)
477 {
478     SECPtr pSec = SECPTR (pScrn);
479     const char *s;
480     int flip_bufs = 3;
481
482     /* exa */
483     if (xf86ReturnOptValBool (pSec->Options, OPTION_EXA, FALSE))
484         pSec->is_exa = TRUE;
485
486     /* sw exa */
487     if (pSec->is_exa)
488     {
489         if (xf86ReturnOptValBool (pSec->Options, OPTION_SWEXA, TRUE))
490             pSec->is_sw_exa = TRUE;
491     }
492
493     /* dri2 */
494     if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI2, FALSE))
495     {
496         pSec->is_dri2 = TRUE;
497
498         /* number of the flip buffers */
499 #if OPTION_FLIP_BUFFERS
500         if (xf86GetOptValInteger (pSec->Options, OPTION_FLIPBUFS, &flip_bufs))
501             pSec->flip_bufs = flip_bufs;
502         else
503 #endif
504         {
505             /* default is 3 */
506             flip_bufs = 3;
507             pSec->flip_bufs = flip_bufs;
508         }
509     }
510
511     /* present */
512     if (xf86ReturnOptValBool (pSec->Options, OPTION_PRESENT, FALSE))
513     {
514         pSec->is_present = TRUE;
515     }
516     
517     /* dri3 */
518     if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI3, FALSE))
519     {
520         pSec->is_dri3 = TRUE;
521     }
522
523     /* rotate */
524     pSec->rotate = RR_Rotate_0;
525     if (( s= xf86GetOptValString (pSec->Options, OPTION_ROTATE)))
526     {
527         if (!xf86NameCmp (s, "CW"))
528         {
529             pSec->rotate = RR_Rotate_90;
530             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen clockwise\n");
531         }
532         else if (!xf86NameCmp (s, "CCW"))
533         {
534             pSec->rotate = RR_Rotate_270;
535             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen counter-clockwise\n");
536         }
537         else if (!xf86NameCmp (s, "UD"))
538         {
539             pSec->rotate = RR_Rotate_180;
540             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen upside-down\n");
541         }
542         else
543         {
544             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "\"%s\" is not valid option", s);
545         }
546     }
547
548     /* wb */
549     if (xf86ReturnOptValBool (pSec->Options, OPTION_WB, FALSE))
550     {
551         if (xf86ReturnOptValBool (pSec->Options, OPTION_WB, TRUE))
552             pSec->is_wb_clone = TRUE;
553     }
554
555     /* cachable */
556     if (xf86ReturnOptValBool (pSec->Options, OPTION_CACHABLE, FALSE))
557     {
558         if (xf86ReturnOptValBool (pSec->Options, OPTION_CACHABLE, TRUE))
559         {
560             pSec->cachable = TRUE;
561             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use cachable buffer.\n");
562         }
563     }
564
565     /* scanout */
566     if (xf86ReturnOptValBool (pSec->Options, OPTION_SCANOUT, FALSE))
567     {
568         if (xf86ReturnOptValBool (pSec->Options, OPTION_SCANOUT, TRUE))
569         {
570             pSec->scanout = TRUE;
571             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use scanout buffer.\n");
572         }
573     }
574
575     /* hw_2d */
576     if (xf86ReturnOptValBool (pSec->Options, OPTION_ACCEL2D, FALSE))
577     {
578         if (xf86ReturnOptValBool (pSec->Options, OPTION_ACCEL2D, TRUE))
579         {
580             pSec->is_accel_2d = TRUE;
581             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use 2d accelerator.\n");
582         }
583     }
584
585     /* use_partial_update */
586     if (xf86ReturnOptValBool (pSec->Options, OPTION_PARTIAL_UPDATE, FALSE))
587     {
588         if (xf86ReturnOptValBool (pSec->Options, OPTION_PARTIAL_UPDATE, TRUE))
589         {
590             pSec->use_partial_update = TRUE;
591             xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use partial update.\n");
592         }
593     }
594 }
595
596 #if HAVE_UDEV
597 static void
598 _secUdevInit (ScrnInfoPtr pScrn)
599 {
600     SECPtr pSec = SECPTR (pScrn);
601     struct udev *u;
602     struct udev_monitor *mon;
603
604     xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "hotplug detection\n");
605
606     u = udev_new();
607     if(!u)
608         return;
609
610     mon = udev_monitor_new_from_netlink(u, "udev");
611     if(!mon)
612     {
613         udev_unref(u);
614         return;
615     }
616
617     if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") > 0 ||
618             udev_monitor_enable_receiving(mon) < 0)
619     {
620         udev_monitor_unref(mon);
621         udev_unref(u);
622         return;
623     }
624
625     pSec->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), SECUdevEventsHandler, pScrn);
626     if (!pSec->uevent_handler)
627     {
628         udev_monitor_unref(mon);
629         udev_unref(u);
630         return;
631     }
632
633     pSec->uevent_monitor = mon;
634 }
635
636 static void
637 _secUdevDeinit (ScrnInfoPtr pScrn)
638 {
639     SECPtr pSec = SECPTR (pScrn);
640
641     if (pSec->uevent_handler)
642     {
643         struct udev *u = udev_monitor_get_udev(pSec->uevent_monitor);
644
645         udev_monitor_unref(pSec->uevent_monitor);
646         udev_unref(u);
647         pSec->uevent_handler = NULL;
648         pSec->uevent_monitor = NULL;
649     }
650
651 }
652
653 static Bool
654 SECSaveScreen (ScreenPtr pScreen, int mode)
655 {
656     /* dummpy save screen */
657     return TRUE;
658 }
659
660 static void
661 SECUdevEventsHandler (int fd, void *closure)
662 {
663     ScrnInfoPtr pScrn = closure;
664     SECPtr pSec = SECPTR (pScrn);
665     struct udev_device *dev;
666     const char *hotplug;
667     struct stat s;
668     dev_t udev_devnum;
669     int ret;
670
671     dev = udev_monitor_receive_device (pSec->uevent_monitor);
672     if (!dev)
673         return;
674
675     udev_devnum = udev_device_get_devnum(dev);
676
677     ret = fstat (pSec->drm_fd, &s);
678     if (ret == -1)
679         return;
680
681     /*
682      * Check to make sure this event is directed at our
683      * device (by comparing dev_t values), then make
684      * sure it's a hotplug event (HOTPLUG=1)
685      */
686     hotplug = udev_device_get_property_value (dev, "HOTPLUG");
687
688     if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 &&
689             hotplug && atoi(hotplug) == 1)
690     {
691         XDBG_INFO(MSEC, "SEC-UDEV: HotPlug\n");
692         RRGetInfo (xf86ScrnToScreen(pScrn), TRUE);
693 #ifdef NO_CRTC_MODE
694         secOutputDrmUpdate (pScrn);
695         secDisplayChangeMode(pScrn);
696 #endif
697     }
698
699     udev_device_unref(dev);
700 }
701 #endif /* UDEV_HAVE */
702
703 static const OptionInfoRec *
704 SECAvailableOptions (int chipid, int busid)
705 {
706     return SECOptions;
707 }
708
709 static void
710 SECIdentify (int flags)
711 {
712     xf86PrintChipsets (SEC_NAME, "driver for Exynos Chipsets", SECChipsets);
713 }
714
715
716 /* The purpose of this function is to identify all instances of hardware supported
717  * by the driver. The probe must find the active device sections that match the driver
718  * by calling xf86MatchDevice().
719  */
720 static Bool
721 SECProbe (DriverPtr pDrv, int flags)
722 {
723     int i;
724     ScrnInfoPtr pScrn;
725     GDevPtr *ppDevSections;
726     int numDevSections;
727     int entity;
728     Bool foundScreen = FALSE;
729
730     /* check the drm mode setting */
731     if (!_secHwProbe (NULL, NULL, NULL))
732     {
733         return FALSE;
734     }
735
736     /* For now, just bail out for PROBE_DETECT. */
737     if (flags & PROBE_DETECT)
738         return FALSE;
739
740     if ((numDevSections = xf86MatchDevice (SEC_DRIVER_NAME, &ppDevSections)) <= 0)
741         return FALSE;
742
743     for (i = 0; i < numDevSections; i++)
744     {
745         entity = xf86ClaimNoSlot (pDrv, 0, ppDevSections[i], TRUE);
746
747         pScrn = xf86AllocateScreen (pDrv, flags);
748         xf86AddEntityToScreen (pScrn, entity);
749
750         if (pScrn)
751         {
752             foundScreen = TRUE;
753
754             pScrn->driverVersion  = SEC_VERSION;
755             pScrn->driverName     = SEC_DRIVER_NAME;
756             pScrn->name           = SEC_NAME;
757             pScrn->Probe          = SECProbe;
758             pScrn->PreInit        = SECPreInit;
759             pScrn->ScreenInit     = SECScreenInit;
760             pScrn->SwitchMode     = SECSwitchMode;
761             pScrn->AdjustFrame    = SECAdjustFrame;
762             pScrn->EnterVT        = SECEnterVT;
763             pScrn->LeaveVT        = SECLeaveVT;
764             pScrn->ValidMode      = SECValidMode;
765
766             xf86DrvMsg (pScrn->scrnIndex, X_INFO,
767                         "using drm mode setting device\n");
768         }
769     }
770     free (ppDevSections);
771
772     return foundScreen;
773 }
774
775 /*
776  * This is called before ScreenInit to probe the screen configuration.
777  * The main tasks to do in this funtion are probing, module loading, option handling,
778  * card mapping, and mode setting setup.
779  */
780 static Bool
781 SECPreInit (ScrnInfoPtr pScrn, int flags)
782 {
783     SECPtr pSec;
784     Gamma defualt_gamma = {0.0, 0.0, 0.0};
785     rgb default_weight = {0, 0, 0};
786     int flag24;
787
788     if (flags & PROBE_DETECT)
789         return FALSE;
790
791     /* allocate private */
792     if (!_allocScrnPrivRec (pScrn))
793         return FALSE;
794     pSec = SECPTR (pScrn);
795
796     /* Check the number of entities, and fail if it isn't one. */
797     if (pScrn->numEntities != 1)
798         return FALSE;
799
800     pSec->pEnt = xf86GetEntityInfo (pScrn->entityList[0]);
801
802     /* initialize the hardware specifics */
803     if (!_secHwInit (pScrn, NULL, NULL))
804     {
805         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
806                     "fail to initialize hardware\n");
807         goto bail1;
808     }
809
810     pScrn->displayWidth = 640; /*default width */
811     pScrn->monitor = pScrn->confScreen->monitor;
812     pScrn->progClock = TRUE;
813     pScrn->rgbBits   = 8;
814
815     /* set the depth and the bpp to pScrn */
816     flag24 = Support24bppFb | Support32bppFb;
817     if (!xf86SetDepthBpp (pScrn, 0, 0, 0, flag24))
818     {
819         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
820                     "fail to find the depth\n");
821         goto bail1;
822     }
823     xf86PrintDepthBpp (pScrn); /* just print out the depth and the bpp */
824
825     /* color weight */
826     if (!xf86SetWeight (pScrn, default_weight, default_weight))
827     {
828         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
829                     "fail to set the color weight of RGB\n");
830         goto bail1;
831     }
832
833     /* visual init, make a TrueColor, -1 */
834     if (!xf86SetDefaultVisual (pScrn, -1))
835     {
836         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
837                     "fail to initialize the default visual\n");
838         goto bail1;
839     }
840
841     /* Collect all the option flags (fill in pScrn->options) */
842     xf86CollectOptions (pScrn, NULL);
843
844     /*
845      * Process the options based on the information SECOptions.
846      * The results are written to pSec->Options. If all the options
847      * processing is done within this fuction a local variable "options"
848      * can be used instead of pSec->Options
849      */
850     if (!(pSec->Options = malloc (sizeof (SECOptions))))
851         goto bail1;
852     memcpy (pSec->Options, SECOptions, sizeof (SECOptions));
853     xf86ProcessOptions (pScrn->scrnIndex, pSec->pEnt->device->options,
854                         pSec->Options);
855
856     /* Check with the driver options */
857     _checkDriverOptions (pScrn);
858
859     /* use a fake root pixmap when rotation angle is 90 or 270 */
860     pSec->fake_root = ((pSec->rotate &(RR_Rotate_90|RR_Rotate_270)) != 0);
861
862     /* drm mode init:: Set the Crtc,  the default Output, and the current Mode */
863     if (!secModePreInit (pScrn, pSec->drm_fd))
864     {
865         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
866                     "fail to initialize drm mode setting\n");
867         goto bail1;
868     }
869
870     /* set gamma */
871     if (!xf86SetGamma (pScrn,defualt_gamma))
872     {
873         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
874                     "fail to set the gamma\n");
875         goto bail1;
876     }
877 #ifdef NO_CRTC_MODE
878     if (pScrn->modes == NULL)
879     {
880         pScrn->modes = xf86ModesAdd(pScrn->modes,
881                                     xf86CVTMode(pScrn->virtualX,
882                                                 pScrn->virtualY,
883                                                 60, 0, 0));
884     }
885 #endif
886     pScrn->currentMode = pScrn->modes;
887
888     pScrn->displayWidth = pScrn->virtualX;
889     xf86PrintModes (pScrn); /* just print the current mode */
890
891     /* set dpi */
892     xf86SetDpi (pScrn, 0, 0);
893
894     /* Load modules */
895     if (!xf86LoadSubModule (pScrn, "fb"))
896     {
897         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
898                     "fail to load fb module\n");
899         goto bail1;
900     }
901
902     if (!xf86LoadSubModule (pScrn, "exa"))
903     {
904         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
905                     "fail to load exa module\n");
906         goto bail1;
907     }
908
909     if (!xf86LoadSubModule (pScrn, "dri2"))
910     {
911         xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
912                     "fail to load dri2 module\n");
913         goto bail1;
914     }
915
916     old_sig_wrapper = OsRegisterSigWrapper(_secOsSigWrapper);
917     return TRUE;
918
919 bail1:
920     _freeScrnPrivRec (pScrn);
921     _secHwDeinit (pScrn);
922     return FALSE;
923 }
924
925
926
927
928 static Bool
929 SECScreenInit (ScreenPtr pScreen, int argc, char **argv)
930 {
931     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
932     SECPtr pSec = SECPTR (pScrn);
933     VisualPtr visual;
934     int init_picture = 0;
935     SECFbPtr pFb = NULL;
936
937     xf86DrvMsg (pScrn->scrnIndex,X_INFO,
938                 "Infomation of Visual is \n\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
939                 "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
940                 pScrn->bitsPerPixel,
941                 pScrn->depth,
942                 xf86GetVisualName (pScrn->defaultVisual),
943                 (unsigned int) pScrn->mask.red,
944                 (unsigned int) pScrn->mask.green,
945                 (unsigned int) pScrn->mask.blue,
946                 (int) pScrn->offset.red,
947                 (int) pScrn->offset.green,
948                 (int) pScrn->offset.blue);
949
950     /* initialize the framebuffer */
951     /* soolim :: think rotations */
952
953     pFb = secFbAllocate (pScrn, pScrn->virtualX, pScrn->virtualY);
954     if  (!pFb)
955     {
956         xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "cannot allocate framebuffer\n");
957         return FALSE;
958     }
959     pSec->pFb = pFb;
960
961     /* mi layer */
962     miClearVisualTypes();
963     if (!miSetVisualTypes (pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor))
964     {
965         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
966                     "visual type setup failed for %d bits per pixel [1]\n",
967                     pScrn->bitsPerPixel);
968         return FALSE;
969     }
970
971     if (!miSetPixmapDepths())
972     {
973         xf86DrvMsg (pScrn->scrnIndex,X_ERROR ,
974                     "pixmap depth setup failed\n");
975         return FALSE;
976     }
977
978     switch (pScrn->bitsPerPixel)
979     {
980     case 16:
981     case 24:
982     case 32:
983         if (! fbScreenInit (pScreen, (void*)ROOT_FB_ADDR,
984                             pScrn->virtualX, pScrn->virtualY,
985                             pScrn->xDpi, pScrn->yDpi,
986                             pScrn->virtualX, /*Pixel width for framebuffer*/
987                             pScrn->bitsPerPixel))
988             return FALSE;
989
990         init_picture = 1;
991
992         break;
993     default:
994         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
995                     "internal error: invalid number of bits per pixel (%d) encountered\n",
996                     pScrn->bitsPerPixel);
997         break;
998     }
999
1000     if (pScrn->bitsPerPixel > 8)
1001     {
1002         /* Fixup RGB ordering */
1003         visual = pScreen->visuals + pScreen->numVisuals;
1004         while (--visual >= pScreen->visuals)
1005         {
1006             if ((visual->class | DynamicClass) == DirectColor)
1007             {
1008                 visual->offsetRed   = pScrn->offset.red;
1009                 visual->offsetGreen = pScrn->offset.green;
1010                 visual->offsetBlue  = pScrn->offset.blue;
1011                 visual->redMask     = pScrn->mask.red;
1012                 visual->greenMask   = pScrn->mask.green;
1013                 visual->blueMask    = pScrn->mask.blue;
1014             }
1015         }
1016     }
1017
1018     /* must be after RGB ordering fixed */
1019     if (init_picture && !fbPictureInit (pScreen, NULL, 0))
1020     {
1021         xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1022                     "Render extension initialisation failed\n");
1023     }
1024
1025     /* init the exa */
1026     if (pSec->is_exa)
1027     {
1028         if (!secExaInit (pScreen))
1029         {
1030             xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1031                         "EXA initialization failed\n");
1032         }
1033         else
1034         {
1035             /* init the dri2 */
1036             if (pSec->is_dri2)
1037             {
1038                 if (!secDri2Init (pScreen))
1039                 {
1040                     xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1041                                 "DRI2 initialization failed\n");
1042                 }
1043             }
1044             
1045             if (pSec->is_present)
1046             {
1047                 if(!secPresentScreenInit(pScreen))
1048                 {
1049                     xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1050                                 "Present initialization failed\n");
1051                 }
1052             }
1053
1054             /* init the dri3 */
1055             if (pSec->is_dri3)
1056             {
1057                 if (!secDri3ScreenInit (pScreen))
1058                 {
1059                     xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1060                                 "DRI3 initialization failed\n");
1061                 }
1062             }
1063         }
1064     }
1065
1066     /* XVideo Initiailization here */
1067     if (!secVideoInit (pScreen))
1068         xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
1069                     "XVideo extention initialization failed\n");
1070
1071     xf86SetBlackWhitePixels (pScreen);
1072     xf86SetBackingStore (pScreen);
1073
1074     /* use dummy hw_cursro instead of sw_cursor */
1075     miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
1076     xf86DrvMsg (pScrn->scrnIndex, X_INFO
1077                 , "Initializing HW Cursor\n");
1078 #if 1
1079     if (!xf86_cursors_init (pScreen, SEC_CURSOR_W, SEC_CURSOR_H,
1080                             (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
1081                              HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
1082                              HARDWARE_CURSOR_INVERT_MASK |
1083                              HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
1084                              HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1085                              HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
1086                              HARDWARE_CURSOR_ARGB)))
1087     {
1088         xf86DrvMsg (pScrn->scrnIndex, X_ERROR
1089                     , "Hardware cursor initialization failed\n");
1090     }
1091 #endif
1092     /* crtc init */
1093     if (!xf86CrtcScreenInit (pScreen))
1094         return FALSE;
1095
1096     /* set the desire mode : set the mode to xf86crtc here */
1097     xf86SetDesiredModes (pScrn);
1098
1099     /* colormap */
1100     if (!miCreateDefColormap (pScreen))
1101     {
1102         xf86DrvMsg (pScrn->scrnIndex, X_ERROR
1103                     , "internal error: miCreateDefColormap failed \n");
1104         return FALSE;
1105     }
1106
1107     if (!xf86HandleColormaps (pScreen, 256, 8, secModeLoadPalette, NULL,
1108                               CMAP_PALETTED_TRUECOLOR))
1109         return FALSE;
1110
1111     /* dpms */
1112     xf86DPMSInit (pScreen, xf86DPMSSet, 0);
1113
1114     /* screen saver */
1115     pScreen->SaveScreen = SECSaveScreen;
1116
1117     secModeInit(pScrn);
1118
1119     /* Wrap the current CloseScreen function */
1120     pSec->CloseScreen = pScreen->CloseScreen;
1121     pScreen->CloseScreen = SECCloseScreen;
1122
1123     /* Wrap the current CloseScreen function */
1124     pSec->CreateScreenResources = pScreen->CreateScreenResources;
1125     pScreen->CreateScreenResources = SECCreateScreenResources;
1126
1127 #if HAVE_UDEV
1128     _secUdevInit(pScrn);
1129 #endif
1130
1131 #if 0
1132     /* Init Hooks for memory flush */
1133     secMemoryInstallHooks();
1134 #endif
1135
1136 #if USE_XDBG
1137     xDbgLogPListInit (pScreen);
1138 #endif
1139 #ifdef NO_CRTC_MODE
1140     pSec->isCrtcOn = secCrtcCheckInUseAll(pScrn);
1141 #endif
1142     XDBG_KLOG(MSEC, "Init Screen\n");
1143     return TRUE;
1144 }
1145
1146 static Bool
1147 SECSwitchMode (ScrnInfoPtr pScrn, DisplayModePtr pMode)
1148 {
1149     return xf86SetSingleMode (pScrn, pMode, RR_Rotate_0);
1150 }
1151
1152 static void
1153 SECAdjustFrame (ScrnInfoPtr pScrn, int x, int y)
1154 {
1155 }
1156
1157 static Bool
1158 SECEnterVT (ScrnInfoPtr pScrn)
1159 {
1160     xf86DrvMsg (pScrn->scrnIndex, X_INFO
1161                 , "EnterVT::Hardware state at EnterVT:\n");
1162
1163     return TRUE;
1164 }
1165
1166 static void
1167 SECLeaveVT (ScrnInfoPtr pScrn)
1168 {
1169     xf86DrvMsg (pScrn->scrnIndex, X_INFO
1170                 , "LeaveVT::Hardware state at LeaveVT:\n");
1171 }
1172
1173 static ModeStatus
1174 SECValidMode (ScrnInfoPtr pScrn, DisplayModePtr pMode, Bool verbose, int flags)
1175 {
1176     return MODE_OK;
1177 }
1178
1179
1180 /**
1181  * Adjust the screen pixmap for the current location of the front buffer.
1182  * This is done at EnterVT when buffers are bound as long as the resources
1183  * have already been created, but the first EnterVT happens before
1184  * CreateScreenResources.
1185  */
1186 static Bool
1187 SECCreateScreenResources (ScreenPtr pScreen)
1188 {
1189     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1190     SECPtr pSec = SECPTR (pScrn);
1191
1192     pScreen->CreateScreenResources = pSec->CreateScreenResources;
1193     if (!(*pScreen->CreateScreenResources) (pScreen))
1194         return FALSE;
1195
1196     /*
1197      * [TODO]:::::
1198      * create screen resources
1199      * set the bo to the screen pixamp private here
1200      * or create the shadow pixmap for the screen pixamp here
1201      * or set the fake rotated screen infomation here.
1202      */
1203
1204     return TRUE;
1205 }
1206
1207 static Bool
1208 SECCloseScreen (ScreenPtr pScreen)
1209 {
1210     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1211     SECPtr pSec = SECPTR (pScrn);
1212
1213     secWbDestroy ();
1214
1215 #if HAVE_UDEV
1216     _secUdevDeinit(pScrn);
1217 #endif
1218
1219     secVideoFini (pScreen);
1220     secExaDeinit (pScreen);
1221     secModeDeinit (pScrn);
1222
1223     if (pSec->pFb)
1224     {
1225         secFbFree (pSec->pFb);
1226         pSec->pFb = NULL;
1227     }
1228
1229     _secHwDeinit (pScrn);
1230
1231     pScrn->vtSema = FALSE;
1232
1233     pScreen->CreateScreenResources = pSec->CreateScreenResources;
1234     pScreen->CloseScreen = pSec->CloseScreen;
1235
1236     XDBG_KLOG(MSEC, "Close Screen\n");
1237     return (*pScreen->CloseScreen) (pScreen);
1238 }
1239
1240
1241 #define CONV_POINT_TO_KEY(x, y, key)    key = (unsigned long)((((unsigned short)(x&0xFFFF)) << 16) | ((unsigned short)(y&0xFFFF )))
1242 #define CONT_KEY_TO_POINT(key, x, y)    x = (unsigned short)((key&0xFFFF0000)>>16); y=(unsigned short)(key&0xFFFF)
1243
1244 typedef struct{
1245     tbm_bo bo;
1246     struct xorg_list link;
1247 }SecFbBoItem, *SecFbBoItemPtr;
1248
1249 static void
1250 _secFbFreeBoData(void* data)
1251 {
1252     XDBG_RETURN_IF_FAIL(data != NULL);
1253
1254     ScrnInfoPtr pScrn;
1255     SECPtr pSec;
1256     SECFbBoDataPtr bo_data = (SECFbBoDataPtr)data;
1257
1258     pScrn = bo_data->pScrn;
1259     pSec = SECPTR (pScrn);
1260
1261     XDBG_DEBUG (MFB, "FreeRender bo_data gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1262                 bo_data->gem_handle, bo_data->fb_id,
1263                 bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1264                 bo_data->pos.x1, bo_data->pos.y1);
1265
1266     if (bo_data->fb_id)
1267     {
1268         drmModeRmFB (pSec->drm_fd, bo_data->fb_id);
1269         bo_data->fb_id = 0;
1270     }
1271
1272     if (bo_data->pPixmap)
1273     {
1274         pScrn->pScreen->DestroyPixmap (bo_data->pPixmap);
1275         bo_data->pPixmap = NULL;
1276     }
1277
1278     free (bo_data);
1279     bo_data = NULL;
1280 }
1281
1282 static tbm_bo
1283 _secFbCreateBo2 (SECFbPtr pFb, int x, int y, int width, int height, tbm_bo prev_bo)
1284 {
1285     XDBG_RETURN_VAL_IF_FAIL ((pFb != NULL), NULL);
1286     XDBG_RETURN_VAL_IF_FAIL ((width > 0), NULL);
1287     XDBG_RETURN_VAL_IF_FAIL ((height > 0), NULL);
1288
1289     SECPtr pSec = SECPTR (pFb->pScrn);
1290
1291     tbm_bo bo = NULL;
1292     tbm_bo_handle bo_handle1, bo_handle2;
1293     SECFbBoDataPtr bo_data=NULL;
1294     unsigned int pitch;
1295     unsigned int fb_id = 0;
1296     int ret;
1297     int flag;
1298
1299     pitch = width * 4;
1300
1301     if (!pSec->cachable)
1302         flag = TBM_BO_WC;
1303     else
1304         flag = TBM_BO_DEFAULT;
1305
1306     bo = tbm_bo_alloc (pSec->tbm_bufmgr, pitch*height, flag);
1307     XDBG_GOTO_IF_FAIL (bo != NULL, fail);
1308     
1309     if (prev_bo != NULL)
1310     {
1311         tbm_bo_swap(bo, prev_bo);
1312         
1313         //delete prev bo(naw _bo contains an old GEM object)
1314         tbm_bo_unref(bo);
1315         //delete TBM_BO_DATA_FB if present, because the new will be created in here
1316         tbm_bo_delete_user_data(prev_bo, TBM_BO_DATA_FB);
1317         
1318         bo = prev_bo;
1319     }
1320
1321     /* memset 0x0 */
1322     bo_handle1 = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1323     XDBG_RETURN_VAL_IF_FAIL (bo_handle1.ptr != NULL, NULL);
1324
1325     memset (bo_handle1.ptr, 0x0, pitch*height);
1326     tbm_bo_unmap (bo);
1327
1328     bo_handle2 = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT);
1329
1330     /* Create drm fb */
1331     ret = drmModeAddFB(pSec->drm_fd
1332                        , width, height
1333                        , pFb->pScrn->bitsPerPixel
1334                        , pFb->pScrn->bitsPerPixel
1335                        , pitch
1336                        , bo_handle2.u32
1337                        , &fb_id);
1338     XDBG_GOTO_IF_ERRNO(ret == Success, fail, -ret);
1339
1340     if(x == -1) x = 0;
1341     if(y == -1) y = 0;
1342
1343     /* Set bo user data */
1344     bo_data = calloc(1, sizeof(SECFbBoDataRec));
1345     bo_data->pFb = pFb;
1346     bo_data->gem_handle = bo_handle2.u32;
1347     bo_data->pitch = pitch;
1348     bo_data->fb_id = fb_id;
1349     bo_data->pos.x1 = x;
1350     bo_data->pos.y1 = y;
1351     bo_data->pos.x2 = x+width;
1352     bo_data->pos.y2 = y+height;
1353     bo_data->size = tbm_bo_size(bo);
1354     bo_data->pScrn = pFb->pScrn;
1355     XDBG_GOTO_IF_FAIL(tbm_bo_add_user_data(bo, TBM_BO_DATA_FB, _secFbFreeBoData), fail);
1356     XDBG_GOTO_IF_FAIL(tbm_bo_set_user_data(bo, TBM_BO_DATA_FB, (void *)bo_data), fail);
1357
1358     XDBG_DEBUG (MFB, "CreateRender bo(name:%d, gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1359                 tbm_bo_export (bo), bo_data->gem_handle, bo_data->fb_id,
1360                 bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1361                 bo_data->pos.x1, bo_data->pos.y1);
1362
1363     return bo;
1364 fail:
1365     if (bo)
1366     {
1367         secRenderBoUnref(bo);
1368     }
1369
1370     if (fb_id)
1371     {
1372         drmModeRmFB(pSec->drm_fd, fb_id);
1373     }
1374
1375     if (bo_data)
1376     {
1377         free (bo_data);
1378         bo_data = NULL;
1379     }
1380
1381     return NULL;
1382 }
1383
1384 static tbm_bo
1385 _secFbCreateBo (SECFbPtr pFb, int x, int y, int width, int height)
1386 {
1387         return _secFbCreateBo2 (pFb, x, y, width, height, NULL);
1388 }
1389
1390 static tbm_bo
1391 _secFbRefBo (tbm_bo bo)
1392 {
1393     return tbm_bo_ref(bo);
1394 }
1395
1396 static int
1397 _secFbUnrefBo(tbm_bo bo)
1398 {
1399     tbm_bo_unref(bo);
1400     bo = NULL;
1401
1402     return TRUE;
1403 }
1404
1405 SECFbPtr
1406 secFbAllocate (ScrnInfoPtr pScrn, int width, int height)
1407 {
1408     //secLogSetLevel(MFB, 0);
1409
1410     XDBG_RETURN_VAL_IF_FAIL((pScrn != NULL), NULL);
1411     XDBG_RETURN_VAL_IF_FAIL((width > 0), NULL);
1412     XDBG_RETURN_VAL_IF_FAIL((height > 0), NULL);
1413
1414     SECFbPtr  pFb = calloc (1, sizeof(SECFbRec));
1415     XDBG_GOTO_IF_FAIL ((pFb != NULL), fail);
1416
1417     pFb->pScrn = pScrn;
1418     pFb->num_bo = 0;
1419     pFb->width = width;
1420     pFb->height = height;
1421
1422     xorg_list_init(&pFb->list_bo);
1423
1424     /* Create default buffer */
1425     pFb->default_bo = _secFbCreateBo(pFb, 0, 0, width, height);
1426
1427     XDBG_TRACE (MFB,"Allocate %dx%d\n", width, height);
1428
1429     return pFb;
1430
1431 fail:
1432
1433     return NULL;
1434 }
1435
1436 void
1437 secFbFree (SECFbPtr pFb)
1438 {
1439     XDBG_RETURN_IF_FAIL(pFb != NULL);
1440
1441     XDBG_TRACE (MFB,"Free %dx%d, num:%d\n", pFb->width, pFb->height, pFb->num_bo);
1442
1443     if (!xorg_list_is_empty(&pFb->list_bo))
1444     {
1445         SecFbBoItemPtr item = NULL, tmp = NULL;
1446
1447         xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1448         {
1449             xorg_list_del(&item->link);
1450             _secFbUnrefBo(item->bo);
1451             free(item);
1452             item=NULL;
1453         }
1454     }
1455
1456     if (pFb->default_bo)
1457     {
1458         secRenderBoUnref(pFb->default_bo);
1459         pFb->default_bo = NULL;
1460     }
1461
1462     free (pFb);
1463     pFb = NULL;
1464 }
1465
1466 tbm_bo
1467 secFbGetBo (SECFbPtr pFb, int x, int y, int width, int height, Bool onlyIfExists)
1468 {
1469     SECFbBoDataPtr bo_data=NULL;
1470     tbm_bo bo = NULL;
1471     _X_UNUSED unsigned long key;
1472     BoxRec box;
1473     BoxPtr b1, b2;
1474     int ret = rgnOUT;
1475
1476     box.x1 = x;
1477     box.y1 = y;
1478     box.x2 = x+width;
1479     box.y2 = y+height;
1480     b2 = &box;
1481
1482     if(!xorg_list_is_empty(&pFb->list_bo))
1483     {
1484         SecFbBoItemPtr item = NULL, tmp = NULL;
1485         xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1486         {
1487             bo = item->bo;
1488
1489             tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1490             b1 = &bo_data->pos;
1491
1492             ret = secUtilBoxInBox(b1, b2);
1493
1494             if(ret == rgnIN || ret == rgnSAME)
1495             {
1496                 return bo;
1497             }
1498             else if(ret == rgnPART)
1499             {
1500                 if (!onlyIfExists) continue;
1501
1502                 int r2 = secUtilBoxInBox(b2, b1);
1503                 if(r2 == rgnIN)
1504                 {
1505                     xorg_list_del(&item->link);
1506                     _secFbUnrefBo(bo);
1507                     free(item);
1508                     item=NULL;
1509                     pFb->num_bo--;
1510                     ret = rgnOUT;
1511                     break;
1512                 }
1513             }
1514             else if(ret == rgnOUT)
1515             {
1516                 continue;
1517             }
1518             else
1519             {
1520                 return NULL;
1521             }
1522         }
1523     }
1524
1525     if (ret == rgnOUT && !onlyIfExists)
1526     {
1527         SecFbBoItemPtr item;
1528         CONV_POINT_TO_KEY(x, y, key);
1529
1530         item = calloc(1, sizeof(SecFbBoItem));
1531         if(width == pFb->width &&
1532            height == pFb->height &&
1533            x == 0 &&
1534            y == 0)
1535         {
1536             bo = _secFbRefBo(pFb->default_bo);
1537         }
1538         else
1539         {
1540             bo = _secFbCreateBo(pFb, x, y, width, height);
1541             if (!bo)
1542             {
1543                 free (item);
1544                 item = NULL;
1545                 return NULL;
1546             }
1547         }
1548
1549         item->bo = bo;
1550         xorg_list_add(&item->link, &pFb->list_bo);
1551         pFb->num_bo++;
1552
1553         XDBG_TRACE (MFB, "GetBO num:%d bo:%p name:%d, %dx%d+%d+%d\n",
1554                     pFb->num_bo, bo, tbm_bo_export (bo), width, height, x,y);
1555         return bo;
1556     }
1557
1558     return NULL;
1559 }
1560
1561 tbm_bo
1562 secFbSwapBo (SECFbPtr pFb, tbm_bo back_bo)
1563 {
1564     SECFbBoDataPtr back_bo_data = NULL;
1565     SECFbBoDataPtr bo_data = NULL;
1566     SECFbBoDataRec tmp_bo_data;
1567     tbm_bo bo;
1568     BoxPtr b1, b2;
1569     SecFbBoItemPtr item = NULL, tmp = NULL;
1570
1571     XDBG_RETURN_VAL_IF_FAIL(pFb != NULL, NULL);
1572     XDBG_RETURN_VAL_IF_FAIL(FALSE == xorg_list_is_empty(&pFb->list_bo), NULL);
1573     XDBG_RETURN_VAL_IF_FAIL(tbm_bo_get_user_data(back_bo, TBM_BO_DATA_FB, (void * *)&back_bo_data), NULL);
1574     XDBG_RETURN_VAL_IF_FAIL(back_bo_data, NULL);
1575
1576     b2 = &back_bo_data->pos;
1577
1578     xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1579     {
1580         bo = item->bo;
1581
1582         tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1583         b1 = &bo_data->pos;
1584         if(rgnSAME == secUtilBoxInBox(b1, b2))
1585         {
1586             XDBG_DEBUG(MFB, "SwapBO(Back:%d, Front:%d)\n",
1587                        tbm_bo_export (back_bo), tbm_bo_export (bo));
1588
1589             if(tbm_bo_swap(bo, back_bo))
1590             {
1591                 memcpy(&tmp_bo_data, bo_data, sizeof(SECFbBoDataRec));
1592                 memcpy(bo_data, back_bo_data, sizeof(SECFbBoDataRec));
1593                 memcpy(back_bo_data, &tmp_bo_data, sizeof(SECFbBoDataRec));
1594             }
1595             else
1596                 return NULL;
1597
1598             return bo;
1599         }
1600     }
1601
1602     return NULL;
1603 }
1604
1605 void
1606 secFbResize (SECFbPtr pFb, int width, int height)
1607 {
1608     XDBG_RETURN_IF_FAIL(pFb != NULL);
1609
1610     SECFbBoDataPtr bo_data=NULL;
1611     tbm_bo bo, old_bo;
1612     int ret;
1613     BoxRec box;
1614     BoxPtr b1, b2;
1615
1616     if (pFb->width == width && pFb->height == height)
1617         return;
1618
1619     old_bo = pFb->default_bo;
1620
1621     pFb->width = width;
1622     pFb->height = height;
1623     XDBG_TRACE (MFB,"Resize %dx%d, num:%d\n", pFb->width, pFb->height, pFb->num_bo);
1624
1625     box.x1=0;
1626     box.y1=0;
1627     box.x2=width;
1628     box.y2=height;
1629     b1 = &box;
1630
1631     if (!xorg_list_is_empty (&pFb->list_bo))
1632     {
1633         SecFbBoItemPtr item = NULL, tmp = NULL;
1634
1635         xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1636         {
1637             bo = item->bo;
1638
1639             tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1640             b2 = &bo_data->pos;
1641             ret = secUtilBoxInBox(b1, b2);
1642
1643             if(ret == rgnIN || ret ==rgnSAME)
1644                 continue;
1645
1646             /* Remove bo */
1647             XDBG_DEBUG (MFB, "\t unref bo(name:%d, gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1648                         tbm_bo_export (bo), bo_data->gem_handle, bo_data->fb_id,
1649                         bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1650                         bo_data->pos.x1, bo_data->pos.y1);
1651
1652             xorg_list_del(&item->link);
1653             secRenderBoUnref(bo);
1654             pFb->num_bo--;
1655             free(item);
1656             item=NULL;
1657         }
1658     }
1659
1660     pFb->default_bo = _secFbCreateBo(pFb, 0, 0, width, height);
1661     if(old_bo)
1662         secRenderBoUnref(old_bo);
1663 }
1664
1665 int
1666 secFbFindBo (SECFbPtr pFb, int x, int y, int width, int height, int *num_bo, tbm_bo** bos)
1667 {
1668     SECFbBoDataPtr bo_data=NULL;
1669     int num=0;
1670     tbm_bo *l=NULL;
1671     tbm_bo bo;
1672     int ret = rgnOUT;
1673     BoxRec box;
1674     BoxPtr b1, b2;
1675     SecFbBoItemPtr item = NULL, tmp = NULL;
1676
1677     if(xorg_list_is_empty(&pFb->list_bo))
1678     {
1679         return rgnOUT;
1680     }
1681
1682     box.x1=x;
1683     box.y1=y;
1684     box.x2=x+width;
1685     box.y2=y+height;
1686     b2 = &box;
1687
1688     l = calloc(pFb->num_bo, sizeof(tbm_bo));
1689
1690     xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1691     {
1692         bo = item->bo;
1693
1694         tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1695         if (bo_data == NULL)
1696         {
1697             free (l);
1698             return rgnOUT;
1699         }
1700
1701         b1 = &bo_data->pos;
1702         ret = secUtilBoxInBox(b1, b2);
1703         XDBG_DEBUG(MFB, "[%d/%d] ret:%d bo(%d,%d,%d,%d) fb(%d,%d,%d,%d)\n",
1704                    num+1, pFb->num_bo, ret,
1705                    b1->x1,b1->y1,b1->x2,b1->y2,
1706                    b2->x1,b2->y1,b2->x2,b2->y2);
1707
1708         if(ret == rgnSAME || ret == rgnIN)
1709         {
1710             l[num++] = bo;
1711             break;
1712         }
1713         else if(ret == rgnPART)
1714         {
1715             l[num++] = bo;
1716         }
1717         else
1718         {
1719             ;
1720         }
1721     }
1722
1723     if(num_bo) *num_bo = num;
1724     if(bos)
1725     {
1726         *bos = l;
1727     }
1728     else
1729     {
1730         free(l);
1731     }
1732
1733     return ret;
1734 }
1735
1736 tbm_bo
1737 secFbFindBoByPoint (SECFbPtr pFb, int x, int y)
1738 {
1739     SECFbBoDataPtr bo_data=NULL;
1740     tbm_bo bo;
1741     SecFbBoItemPtr item = NULL, tmp = NULL;
1742
1743     if(xorg_list_is_empty(&pFb->list_bo))
1744     {
1745         return NULL;
1746     }
1747
1748     xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1749     {
1750         bo = item->bo;
1751         tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1752         if ((x >= bo_data->pos.x1) &&
1753             (x < bo_data->pos.x2) &&
1754             (y >= bo_data->pos.y1) &&
1755             (y < bo_data->pos.y2))
1756         {
1757             return bo;
1758         }
1759     }
1760
1761     return NULL;
1762 }
1763
1764 PixmapPtr
1765 secRenderBoGetPixmap (SECFbPtr pFb, tbm_bo bo)
1766 {
1767     ScreenPtr pScreen = pFb->pScrn->pScreen;
1768     PixmapPtr pPixmap;
1769     SECFbBoDataPtr bo_data;
1770     int ret;
1771
1772     XDBG_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
1773     XDBG_RETURN_VAL_IF_FAIL(tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void**)&bo_data), NULL);
1774
1775     if(bo_data->pPixmap == NULL)
1776     {
1777         pPixmap = pScreen->CreatePixmap(pFb->pScrn->pScreen, 0,0,
1778                                         pFb->pScrn->depth,
1779                                         CREATE_PIXMAP_USAGE_SUB_FB);
1780         XDBG_GOTO_IF_FAIL(pPixmap != NULL, fail);
1781
1782         ret = pScreen->ModifyPixmapHeader(pPixmap,
1783                                           bo_data->pos.x2 - bo_data->pos.x1,
1784                                           bo_data->pos.y2 - bo_data->pos.y1,
1785                                           pFb->pScrn->depth,
1786                                           pFb->pScrn->bitsPerPixel,
1787                                           bo_data->pitch, (void*)bo);
1788         XDBG_GOTO_IF_FAIL(ret != FALSE, fail);
1789         bo_data->pPixmap = pPixmap;
1790         XDBG_DEBUG(MFB, "CreateRenderPixmap:%p\n", pPixmap);
1791     }
1792
1793     return bo_data->pPixmap;
1794
1795 fail:
1796     XDBG_ERROR(MFB, "ERR: CreateRenderPixmap\n");
1797     if(pPixmap)
1798     {
1799         pScreen->DestroyPixmap(pPixmap);
1800     }
1801     return NULL;
1802 }
1803
1804 tbm_bo
1805 secRenderBoCreate (ScrnInfoPtr pScrn, int width, int height)
1806 {
1807     SECPtr pSec = SECPTR (pScrn);
1808
1809     return _secFbCreateBo(pSec->pFb, -1, -1, width, height);
1810 }
1811
1812 int
1813 secSwapToRenderBo(ScrnInfoPtr pScrn, int width, int height, tbm_bo carr_bo)
1814 {
1815     SECPtr pSec = SECPTR (pScrn);
1816
1817     return _secFbCreateBo2(pSec->pFb, -1, -1, width, height, carr_bo);
1818 }
1819
1820 tbm_bo
1821 secRenderBoRef (tbm_bo bo)
1822 {
1823         return _secFbRefBo (bo);
1824 }
1825
1826 void
1827 secRenderBoUnref (tbm_bo bo)
1828 {
1829     _secFbUnrefBo(bo);
1830 }
1831
1832 void
1833 secRenderBoSetPos (tbm_bo bo, int x, int y)
1834 {
1835     SECFbBoDataPtr bo_data;
1836     int width, height;
1837
1838     XDBG_RETURN_IF_FAIL(bo != NULL);
1839     XDBG_RETURN_IF_FAIL(x >= 0);
1840     XDBG_RETURN_IF_FAIL(y >= 0);
1841     XDBG_RETURN_IF_FAIL(tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void**)&bo_data));
1842
1843     width = bo_data->pos.x2 - bo_data->pos.x1;
1844     height = bo_data->pos.y2 - bo_data->pos.y1;
1845
1846     bo_data->pos.x1 = x;
1847     bo_data->pos.y1 = y;
1848     bo_data->pos.x2 = x+width;
1849     bo_data->pos.y2 = y+height;
1850 }