Subversion Repositories Kolibri OS

Rev

Rev 4539 | Rev 4560 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #define iowrite32(v, addr)      writel((v), (addr))
  3.  
  4. #include "drmP.h"
  5. #include "drm.h"
  6. #include "i915_drm.h"
  7. #include "i915_drv.h"
  8. #include "intel_drv.h"
  9.  
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/mod_devicetable.h>
  13. #include <errno-base.h>
  14. #include <linux/pci.h>
  15.  
  16. #include <syscall.h>
  17.  
  18. #include "bitmap.h"
  19.  
  20. typedef struct
  21. {
  22.     kobj_t     header;
  23.  
  24.     uint32_t  *data;
  25.     uint32_t   hot_x;
  26.     uint32_t   hot_y;
  27.  
  28.     struct list_head   list;
  29.     struct drm_i915_gem_object  *cobj;
  30. }cursor_t;
  31.  
  32. #define CURSOR_WIDTH 64
  33. #define CURSOR_HEIGHT 64
  34.  
  35.  
  36. struct tag_display
  37. {
  38.     int  x;
  39.     int  y;
  40.     int  width;
  41.     int  height;
  42.     int  bpp;
  43.     int  vrefresh;
  44.     int  pitch;
  45.     int  lfb;
  46.  
  47.     int  supported_modes;
  48.     struct drm_device    *ddev;
  49.     struct drm_connector *connector;
  50.     struct drm_crtc      *crtc;
  51.  
  52.     struct list_head   cursors;
  53.  
  54.     cursor_t   *cursor;
  55.     int       (*init_cursor)(cursor_t*);
  56.     cursor_t* (__stdcall *select_cursor)(cursor_t*);
  57.     void      (*show_cursor)(int show);
  58.     void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
  59.     void      (__stdcall *restore_cursor)(int x, int y);
  60.     void      (*disable_mouse)(void);
  61.     u32  mask_seqno;
  62.     u32  check_mouse;
  63.     u32  check_m_pixel;
  64.  
  65. };
  66.  
  67.  
  68. static display_t *os_display;
  69.  
  70. u32_t cmd_buffer;
  71. u32_t cmd_offset;
  72.  
  73. void init_render();
  74. int  sna_init();
  75.  
  76. int init_cursor(cursor_t *cursor);
  77. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  78. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  79.  
  80. void __stdcall restore_cursor(int x, int y)
  81. {};
  82.  
  83. void disable_mouse(void)
  84. {};
  85.  
  86. static char *manufacturer_name(unsigned char *x)
  87. {
  88.     static char name[4];
  89.  
  90.     name[0] = ((x[0] & 0x7C) >> 2) + '@';
  91.     name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
  92.     name[2] = (x[1] & 0x1F) + '@';
  93.     name[3] = 0;
  94.  
  95.     return name;
  96. }
  97.  
  98. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  99.               videomode_t *reqmode, bool strict)
  100. {
  101.     drm_i915_private_t      *dev_priv   = dev->dev_private;
  102.     struct drm_fb_helper    *fb_helper  = &dev_priv->fbdev->helper;
  103.  
  104.     struct drm_mode_config  *config     = &dev->mode_config;
  105.     struct drm_display_mode *mode       = NULL, *tmpmode;
  106.     struct drm_framebuffer  *fb         = NULL;
  107.     struct drm_crtc         *crtc;
  108.     struct drm_encoder      *encoder;
  109.     struct drm_i915_gem_object *fb_obj;
  110.     struct drm_mode_set     set;
  111.     const char *con_name;
  112.     const char *enc_name;
  113.     unsigned hdisplay, vdisplay;
  114.     int stride;
  115.     int ret;
  116.  
  117.     mutex_lock(&dev->mode_config.mutex);
  118.  
  119.     list_for_each_entry(tmpmode, &connector->modes, head)
  120.     {
  121.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  122.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  123.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  124.         {
  125.             mode = tmpmode;
  126.             goto do_set;
  127.         }
  128.     };
  129.  
  130.     if( (mode == NULL) && (strict == false) )
  131.     {
  132.         list_for_each_entry(tmpmode, &connector->modes, head)
  133.         {
  134.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  135.                 (drm_mode_height(tmpmode) == reqmode->height) )
  136.             {
  137.                 mode = tmpmode;
  138.                 goto do_set;
  139.             }
  140.         };
  141.     };
  142.  
  143.     DRM_ERROR("%s failed\n", __FUNCTION__);
  144.  
  145.     return -1;
  146.  
  147. do_set:
  148.  
  149.     encoder = connector->encoder;
  150.     crtc = encoder->crtc;
  151.  
  152.     con_name = drm_get_connector_name(connector);
  153.     enc_name = drm_get_encoder_name(encoder);
  154.  
  155.     DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n",
  156.               reqmode->width, reqmode->height, crtc->base.id,
  157.               con_name, enc_name);
  158.  
  159.     drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  160.  
  161.     hdisplay = mode->hdisplay;
  162.     vdisplay = mode->vdisplay;
  163.  
  164.     if (crtc->invert_dimensions)
  165.         swap(hdisplay, vdisplay);
  166.  
  167.     fb_obj = get_fb_obj();
  168.     fb = fb_helper->fb;
  169.  
  170.     fb->width  = reqmode->width;
  171.     fb->height = reqmode->height;
  172.  
  173.     if(dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_NONE)
  174.     {
  175.         fb_obj->tiling_mode = I915_TILING_X;
  176.  
  177.         if(IS_GEN3(dev))
  178.             for (stride = 512; stride < reqmode->width * 4; stride <<= 1);
  179.         else
  180.             stride = ALIGN(reqmode->width * 4, 512);
  181.     }
  182.     else
  183.     {
  184.         fb_obj->tiling_mode = I915_TILING_NONE;
  185.         stride = ALIGN(reqmode->width * 4, 64);
  186.     }
  187.  
  188.     fb->pitches[0]  =
  189.     fb->pitches[1]  =
  190.     fb->pitches[2]  =
  191.     fb->pitches[3]  = stride;
  192.  
  193.     fb_obj->stride  = stride;
  194.  
  195.     fb->bits_per_pixel = 32;
  196.     fb->depth = 24;
  197.  
  198.     crtc->fb = fb;
  199.     crtc->enabled = true;
  200.     os_display->crtc = crtc;
  201.  
  202.     i915_gem_object_put_fence(fb_obj);
  203.  
  204.     set.crtc = crtc;
  205.     set.x = 0;
  206.     set.y = 0;
  207.     set.mode = mode;
  208.     set.connectors = &connector;
  209.     set.num_connectors = 1;
  210.     set.fb = fb;
  211.     ret = crtc->funcs->set_config(&set);
  212.     mutex_unlock(&dev->mode_config.mutex);
  213.  
  214.     if ( !ret )
  215.     {
  216.         os_display->width    = fb->width;
  217.         os_display->height   = fb->height;
  218.         os_display->vrefresh = drm_mode_vrefresh(mode);
  219.  
  220.         sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  221.  
  222.         DRM_DEBUG_KMS("new mode %d x %d pitch %d\n",
  223.                        fb->width, fb->height, fb->pitches[0]);
  224.     }
  225.     else
  226.         DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  227.                    fb->width, fb->height, crtc);
  228.  
  229.     return ret;
  230. }
  231.  
  232. static int count_connector_modes(struct drm_connector* connector)
  233. {
  234.     struct drm_display_mode  *mode;
  235.     int count = 0;
  236.  
  237.     list_for_each_entry(mode, &connector->modes, head)
  238.     {
  239.         count++;
  240.     };
  241.     return count;
  242. };
  243.  
  244. static struct drm_connector* get_def_connector(struct drm_device *dev)
  245. {
  246.     struct drm_connector  *connector;
  247.     struct drm_connector_helper_funcs *connector_funcs;
  248.  
  249.     struct drm_connector  *def_connector = NULL;
  250.  
  251.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  252.     {
  253.         struct drm_encoder  *encoder;
  254.         struct drm_crtc     *crtc;
  255.  
  256.         if( connector->status != connector_status_connected)
  257.             continue;
  258.  
  259.         connector_funcs = connector->helper_private;
  260.         encoder = connector_funcs->best_encoder(connector);
  261.         if( encoder == NULL)
  262.             continue;
  263.  
  264.         connector->encoder = encoder;
  265.  
  266.         crtc = encoder->crtc;
  267.  
  268.         DRM_DEBUG_KMS("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x",
  269.                    connector, connector->base.id,
  270.                    connector->status, connector->encoder,
  271.                    crtc);
  272.  
  273. //        if (crtc == NULL)
  274. //            continue;
  275.  
  276.         def_connector = connector;
  277.  
  278.         break;
  279.     };
  280.  
  281.     return def_connector;
  282. };
  283.  
  284. struct drm_connector *get_active_connector(struct drm_device *dev)
  285. {
  286.     struct drm_connector *tmp = NULL;
  287.     struct drm_connector_helper_funcs *connector_funcs;
  288.     struct drm_encoder      *encoder;
  289.  
  290.     list_for_each_entry(tmp, &dev->mode_config.connector_list, head)
  291.     {
  292.         if( tmp->status != connector_status_connected)
  293.             continue;
  294.  
  295.         connector_funcs = tmp->helper_private;
  296.         encoder = connector_funcs->best_encoder(tmp);
  297.         if( encoder == NULL)
  298.         {
  299.             DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
  300.                       tmp, tmp->base.id);
  301.             continue;
  302.         };
  303.  
  304.         tmp->encoder = encoder;
  305.  
  306.         DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %x CRTC %p ID:%d\n",
  307.                tmp, tmp->base.id, tmp->status, tmp->encoder,
  308.                tmp->encoder->crtc, tmp->encoder->crtc->base.id );
  309.  
  310.         return tmp;
  311.     };
  312.  
  313.     return NULL;
  314. }
  315.  
  316. struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder)
  317. {
  318.         struct drm_crtc *tmp_crtc;
  319.         int crtc_mask = 1;
  320.  
  321.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  322.         {
  323.             if (encoder->possible_crtcs & crtc_mask)
  324.             {
  325.             encoder->crtc = tmp_crtc;
  326.             dbgprintf("CRTC %p\n", tmp_crtc);
  327.             return tmp_crtc;
  328.             };
  329.             crtc_mask <<= 1;
  330.         };
  331.     return NULL;
  332. };
  333.  
  334. int get_boot_mode(struct drm_connector *connector, videomode_t *usermode)
  335. {
  336.     struct drm_display_mode *mode;
  337.  
  338.     list_for_each_entry(mode, &connector->modes, head)
  339.     {
  340.         DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n",
  341.                 drm_mode_width(mode), drm_mode_height(mode),
  342.                 drm_mode_vrefresh(mode));
  343.  
  344.         if( os_display->width  == drm_mode_width(mode)  &&
  345.             os_display->height == drm_mode_height(mode) &&
  346.             drm_mode_vrefresh(mode) == 60)
  347.         {
  348.             usermode->width  = os_display->width;
  349.             usermode->height = os_display->height;
  350.             usermode->freq   = 60;
  351.             return 1;
  352.         }
  353.     }
  354.     return 0;
  355. }
  356.  
  357. int init_display_kms(struct drm_device *dev, videomode_t *usermode)
  358. {
  359.     struct drm_connector    *connector;
  360.     struct drm_connector_helper_funcs *connector_funcs;
  361.     struct drm_encoder      *encoder;
  362.     struct drm_crtc         *crtc;
  363.     struct drm_framebuffer  *fb;
  364.  
  365.     cursor_t  *cursor;
  366.     u32_t      ifl;
  367.     int        err;
  368.  
  369.     mutex_lock(&dev->mode_config.mutex);
  370.  
  371.     connector = get_active_connector(dev) ;
  372.     if(connector == NULL)
  373.     {
  374.         DRM_DEBUG_KMS("No active connectors!\n");
  375.         mutex_unlock(&dev->mode_config.mutex);
  376.         return -1;
  377.     };
  378.  
  379.     encoder = connector->encoder;
  380.     crtc = encoder->crtc;
  381.  
  382.     if(crtc == NULL)
  383.         crtc = get_possible_crtc(dev, encoder);
  384.  
  385.     if(crtc == NULL)
  386.     {
  387.         DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
  388.         mutex_unlock(&dev->mode_config.mutex);
  389.         return -1;
  390.     };
  391.  
  392.     DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id);
  393.  
  394.     os_display = GetDisplay();
  395.     os_display->ddev = dev;
  396.     os_display->connector = connector;
  397.     os_display->crtc = crtc;
  398.  
  399.     os_display->supported_modes = count_connector_modes(connector);
  400.  
  401.  
  402.     ifl = safe_cli();
  403.     {
  404.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  405.  
  406.         list_for_each_entry(cursor, &os_display->cursors, list)
  407.         {
  408.             init_cursor(cursor);
  409.         };
  410.  
  411.         os_display->restore_cursor(0,0);
  412.         os_display->init_cursor    = init_cursor;
  413.         os_display->select_cursor  = select_cursor_kms;
  414.         os_display->show_cursor    = NULL;
  415.         os_display->move_cursor    = move_cursor_kms;
  416.         os_display->restore_cursor = restore_cursor;
  417.         os_display->disable_mouse  = disable_mouse;
  418.  
  419.         intel_crtc->cursor_x = os_display->width/2;
  420.         intel_crtc->cursor_y = os_display->height/2;
  421.  
  422.         select_cursor_kms(os_display->cursor);
  423.     };
  424.     safe_sti(ifl);
  425.  
  426.     if( (usermode->width == 0) ||
  427.         (usermode->height == 0))
  428.     {
  429.         if( !get_boot_mode(connector, usermode))
  430.         {
  431.         struct drm_display_mode *mode;
  432.  
  433.             mode = list_entry(connector->modes.next, typeof(*mode), head);
  434.             usermode->width  = drm_mode_width(mode);
  435.             usermode->height = drm_mode_height(mode);
  436.             usermode->freq   = drm_mode_vrefresh(mode);
  437.         };
  438.     };
  439.  
  440.     mutex_unlock(&dev->mode_config.mutex);
  441.  
  442.     set_mode(dev, os_display->connector, usermode, false);
  443.  
  444. #ifdef __HWA__
  445.     err = init_bitmaps();
  446. #endif
  447.  
  448.     LEAVE();
  449.  
  450.     return 0;
  451. };
  452.  
  453.  
  454. int get_videomodes(videomode_t *mode, int *count)
  455. {
  456.     int err = -1;
  457.  
  458. //    dbgprintf("mode %x count %d\n", mode, *count);
  459.  
  460.     if( *count == 0 )
  461.     {
  462.         *count = os_display->supported_modes;
  463.         err = 0;
  464.     }
  465.     else if( mode != NULL )
  466.     {
  467.         struct drm_display_mode  *drmmode;
  468.         int i = 0;
  469.  
  470.         if( *count > os_display->supported_modes)
  471.             *count = os_display->supported_modes;
  472.  
  473.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  474.         {
  475.             if( i < *count)
  476.             {
  477.                 mode->width  = drm_mode_width(drmmode);
  478.                 mode->height = drm_mode_height(drmmode);
  479.                 mode->bpp    = 32;
  480.                 mode->freq   = drm_mode_vrefresh(drmmode);
  481.                 i++;
  482.                 mode++;
  483.             }
  484.             else break;
  485.         };
  486.         *count = i;
  487.         err = 0;
  488.     };
  489.     return err;
  490. };
  491.  
  492. int set_user_mode(videomode_t *mode)
  493. {
  494.     int err = -1;
  495.  
  496. //    dbgprintf("width %d height %d vrefresh %d\n",
  497. //               mode->width, mode->height, mode->freq);
  498.  
  499.     if( (mode->width  != 0)  &&
  500.         (mode->height != 0)  &&
  501.         (mode->freq   != 0 ) &&
  502.         ( (mode->width   != os_display->width)  ||
  503.           (mode->height  != os_display->height) ||
  504.           (mode->freq    != os_display->vrefresh) ) )
  505.     {
  506.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  507.             err = 0;
  508.     };
  509.  
  510.     return err;
  511. };
  512.  
  513. void i915_dpms(struct drm_device *dev, int mode)
  514. {
  515.     const struct drm_connector_funcs *f = os_display->connector->funcs;
  516.  
  517.     f->dpms(os_display->connector, mode);
  518. };
  519.  
  520. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  521. {
  522.     list_del(&cursor->list);
  523.  
  524.     i915_gem_object_unpin(cursor->cobj);
  525.  
  526.     mutex_lock(&main_device->struct_mutex);
  527.     drm_gem_object_unreference(&cursor->cobj->base);
  528.     mutex_unlock(&main_device->struct_mutex);
  529.  
  530.     __DestroyObject(cursor);
  531. };
  532.  
  533. int init_cursor(cursor_t *cursor)
  534. {
  535.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  536.     struct drm_i915_gem_object *obj;
  537.     uint32_t *bits;
  538.     uint32_t *src;
  539.     void     *mapped;
  540.  
  541.     int       i,j;
  542.     int       ret;
  543.  
  544.     if (dev_priv->info->cursor_needs_physical)
  545.     {
  546.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  547.         if (unlikely(bits == NULL))
  548.             return ENOMEM;
  549.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  550.     }
  551.     else
  552.     {
  553.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  554.         if (unlikely(obj == NULL))
  555.             return -ENOMEM;
  556.  
  557.         ret = i915_gem_obj_ggtt_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true);
  558.         if (ret) {
  559.             drm_gem_object_unreference(&obj->base);
  560.             return ret;
  561.         }
  562.  
  563.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  564.         if (ret)
  565.         {
  566.             i915_gem_object_unpin(obj);
  567.             drm_gem_object_unreference(&obj->base);
  568.             return ret;
  569.         }
  570. /* You don't need to worry about fragmentation issues.
  571.  * GTT space is continuous. I guarantee it.                           */
  572.  
  573.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  574.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  575.  
  576.         if (unlikely(bits == NULL))
  577.         {
  578.             i915_gem_object_unpin(obj);
  579.             drm_gem_object_unreference(&obj->base);
  580.             return -ENOMEM;
  581.         };
  582.         cursor->cobj = obj;
  583.     };
  584.  
  585.     src = cursor->data;
  586.  
  587.     for(i = 0; i < 32; i++)
  588.     {
  589.         for(j = 0; j < 32; j++)
  590.             *bits++ = *src++;
  591.         for(j = 32; j < CURSOR_WIDTH; j++)
  592.             *bits++ = 0;
  593.     }
  594.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  595.         *bits++ = 0;
  596.  
  597.     FreeKernelSpace(mapped);
  598.  
  599. // release old cursor
  600.  
  601.     KernelFree(cursor->data);
  602.  
  603.     cursor->data = bits;
  604.  
  605.     cursor->header.destroy = destroy_cursor;
  606.  
  607.     return 0;
  608. }
  609.  
  610.  
  611. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  612. {
  613.     struct drm_crtc *crtc = os_display->crtc;
  614.     x-= cursor->hot_x;
  615.     y-= cursor->hot_y;
  616.  
  617.     if (crtc->funcs->cursor_move)
  618.         crtc->funcs->cursor_move(crtc, x, y);
  619.  
  620. };
  621.  
  622.  
  623. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  624. {
  625.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  626.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  627.     cursor_t *old;
  628.  
  629.     old = os_display->cursor;
  630.     os_display->cursor = cursor;
  631.  
  632.     intel_crtc->cursor_bo = cursor->cobj;
  633.  
  634.     if (!dev_priv->info->cursor_needs_physical)
  635.        intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
  636.     else
  637.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  638.  
  639.     intel_crtc->cursor_width = 32;
  640.     intel_crtc->cursor_height = 32;
  641.  
  642.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  643.     return old;
  644. };
  645.  
  646. int i915_fbinfo(struct drm_i915_fb_info *fb)
  647. {
  648.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  649.     struct intel_crtc *crtc = to_intel_crtc(os_display->crtc);
  650.  
  651.     struct drm_i915_gem_object *obj = get_fb_obj();
  652.  
  653.     fb->name   = obj->base.name;
  654.     fb->width  = os_display->width;
  655.     fb->height = os_display->height;
  656.     fb->pitch  = obj->stride;
  657.     fb->tiling = obj->tiling_mode;
  658.     fb->crtc   = crtc->base.base.id;
  659.     fb->pipe   = crtc->pipe;
  660.  
  661.     return 0;
  662. }
  663.  
  664.  
  665. typedef struct
  666. {
  667.     int left;
  668.     int top;
  669.     int right;
  670.     int bottom;
  671. }rect_t;
  672.  
  673.  
  674. #define CURRENT_TASK             (0x80003000)
  675.  
  676. static u32_t get_display_map()
  677. {
  678.     u32_t   addr;
  679.  
  680.     addr = (u32_t)os_display;
  681.     addr+= sizeof(display_t);            /*  shoot me  */
  682.     return *(u32_t*)addr;
  683. }
  684.  
  685. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  686.  
  687. int i915_mask_update(struct drm_device *dev, void *data,
  688.             struct drm_file *file)
  689. {
  690.     struct drm_i915_mask *mask = data;
  691.     struct drm_gem_object *obj;
  692.     static unsigned int mask_seqno[256];
  693.     rect_t winrc;
  694.     u32    slot;
  695.     int    ret=0;
  696.  
  697.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  698.     if (obj == NULL)
  699.         return -ENOENT;
  700.  
  701.     if (!obj->filp) {
  702.         drm_gem_object_unreference_unlocked(obj);
  703.         return -EINVAL;
  704.     }
  705.  
  706.     GetWindowRect(&winrc);
  707.     {
  708. //        static warn_count;
  709.  
  710.         mask->width    = winrc.right - winrc.left + 1;
  711.         mask->height   = winrc.bottom - winrc.top + 1;
  712.         mask->bo_pitch = (mask->width+15) & ~15;
  713.  
  714. #if 0
  715.         if(warn_count < 1)
  716.         {
  717.             printf("left %d top %d right %d bottom %d\n",
  718.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  719.             printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
  720.             warn_count++;
  721.         };
  722. #endif
  723.  
  724.      };
  725.  
  726.  
  727.     slot = *((u8*)CURRENT_TASK);
  728.  
  729.     if( mask_seqno[slot] != os_display->mask_seqno)
  730.     {
  731.         u8* src_offset;
  732.         u8* dst_offset;
  733.         u32 ifl;
  734.  
  735.         ret = i915_mutex_lock_interruptible(dev);
  736.         if (ret)
  737.             goto err1;
  738.  
  739.         ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  740.         if(ret != 0 )
  741.         {
  742.             dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__);
  743.             goto err2;
  744.         };
  745.  
  746. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  747.  
  748. //        slot = 0x01;
  749.  
  750.  
  751.         src_offset = (u8*)( winrc.top*os_display->width + winrc.left);
  752.         src_offset+= get_display_map();
  753.         dst_offset = (u8*)mask->bo_map;
  754.  
  755.         u32_t tmp_h = mask->height;
  756.  
  757.         ifl = safe_cli();
  758.         {
  759.             mask_seqno[slot] = os_display->mask_seqno;
  760.  
  761.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  762.  
  763.             __asm__ __volatile__ (
  764.                 "movd       %[slot],   %%xmm6    \n"
  765.             "punpckldq  %%xmm6, %%xmm6            \n"
  766.             "punpcklqdq %%xmm6, %%xmm6            \n"
  767.             :: [slot]  "m" (slot)
  768.             :"xmm6");
  769.  
  770.             while( tmp_h--)
  771.             {
  772.                 int tmp_w = mask->width;
  773.  
  774.                 u8* tmp_src = src_offset;
  775.                 u8* tmp_dst = dst_offset;
  776.  
  777.                 src_offset+= os_display->width;
  778.                 dst_offset+= mask->bo_pitch;
  779.  
  780.                 while(tmp_w >= 64)
  781.                 {
  782.                     __asm__ __volatile__ (
  783.                     "movdqu     (%0),   %%xmm0            \n"
  784.                     "movdqu   16(%0),   %%xmm1            \n"
  785.                     "movdqu   32(%0),   %%xmm2            \n"
  786.                     "movdqu   48(%0),   %%xmm3            \n"
  787.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  788.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  789.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  790.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  791.                     "movdqa     %%xmm0,   (%%edi)         \n"
  792.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  793.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  794.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  795.  
  796.                     :: "r" (tmp_src), "D" (tmp_dst)
  797.                     :"xmm0","xmm1","xmm2","xmm3");
  798.                     tmp_w -= 64;
  799.                     tmp_src += 64;
  800.                     tmp_dst += 64;
  801.                 }
  802.  
  803.                 if( tmp_w >= 32 )
  804.                 {
  805.                     __asm__ __volatile__ (
  806.                     "movdqu     (%0),   %%xmm0            \n"
  807.                     "movdqu   16(%0),   %%xmm1            \n"
  808.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  809.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  810.                     "movdqa     %%xmm0,   (%%edi)         \n"
  811.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  812.  
  813.                     :: "r" (tmp_src), "D" (tmp_dst)
  814.                     :"xmm0","xmm1");
  815.                     tmp_w -= 32;
  816.                     tmp_src += 32;
  817.                     tmp_dst += 32;
  818.                 }
  819.  
  820.                 if( tmp_w >= 16 )
  821.                 {
  822.                     __asm__ __volatile__ (
  823.                     "movdqu     (%0),   %%xmm0            \n"
  824.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  825.                     "movdqa     %%xmm0,   (%%edi)         \n"
  826.                     :: "r" (tmp_src), "D" (tmp_dst)
  827.                     :"xmm0");
  828.                     tmp_w -= 16;
  829.                     tmp_src += 16;
  830.                     tmp_dst += 16;
  831.                 }
  832.  
  833.                 if( tmp_w >= 8 )
  834.                 {
  835.                     __asm__ __volatile__ (
  836.                     "movq       (%0),   %%xmm0            \n"
  837.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  838.                     "movq       %%xmm0,   (%%edi)         \n"
  839.                     :: "r" (tmp_src), "D" (tmp_dst)
  840.                     :"xmm0");
  841.                     tmp_w -= 8;
  842.                     tmp_src += 8;
  843.                     tmp_dst += 8;
  844.                 }
  845.                 if( tmp_w >= 4 )
  846.                 {
  847.                     __asm__ __volatile__ (
  848.                     "movd       (%0),   %%xmm0            \n"
  849.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  850.                     "movd       %%xmm0,   (%%edi)         \n"
  851.                     :: "r" (tmp_src), "D" (tmp_dst)
  852.                     :"xmm0");
  853.                     tmp_w -= 4;
  854.                     tmp_src += 4;
  855.                     tmp_dst += 4;
  856.                 }
  857.                 while(tmp_w--)
  858.                     *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
  859.             };
  860.         };
  861.         safe_sti(ifl);
  862.  
  863.         ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
  864.     }
  865.  
  866. err2:
  867.     mutex_unlock(&dev->struct_mutex);
  868. err1:
  869.     drm_gem_object_unreference(obj);
  870.  
  871.     return ret;
  872. }
  873.  
  874. int i915_mask_update_ex(struct drm_device *dev, void *data,
  875.             struct drm_file *file)
  876. {
  877.     struct drm_i915_mask_update *mask = data;
  878.     struct drm_gem_object *obj;
  879.     static unsigned int mask_seqno[256];
  880.     static warn_count;
  881.  
  882.     rect_t win;
  883.     u32    winw,winh;
  884.     u32    ml,mt,mr,mb;
  885.     u32    slot;
  886.     int    ret = 0;
  887.     slot = *((u8*)CURRENT_TASK);
  888.  
  889.     if( mask_seqno[slot] == os_display->mask_seqno)
  890.         return 0;
  891.  
  892.     GetWindowRect(&win);
  893.     win.right+= 1;
  894.     win.bottom+=  1;
  895.  
  896.     winw = win.right - win.left;
  897.     winh = win.bottom - win.top;
  898.  
  899.     if(mask->dx >= winw ||
  900.        mask->dy >= winh)
  901.        return 1;
  902.  
  903.     ml = win.left + mask->dx;
  904.     mt = win.top  + mask->dy;
  905.     mr = ml + mask->width;
  906.     mb = mt + mask->height;
  907.  
  908.     if( ml >= win.right || mt >= win.bottom ||
  909.         mr < win.left   || mb < win.top )
  910.         return 1;
  911.  
  912.     if( mr > win.right )
  913.         mr = win.right;
  914.  
  915.     if( mb > win.bottom )
  916.         mb = win.bottom;
  917.  
  918.     mask->width  = mr - ml;
  919.     mask->height = mb - mt;
  920.  
  921.     if( mask->width == 0 ||
  922.         mask->height== 0 )
  923.         return 1;
  924.  
  925.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  926.     if (obj == NULL)
  927.         return -ENOENT;
  928.  
  929.     if (!obj->filp) {
  930.         drm_gem_object_unreference_unlocked(obj);
  931.         return -EINVAL;
  932.     }
  933.  
  934. #if 1
  935.     if(warn_count < 1000)
  936.     {
  937.         printf("left %d top %d right %d bottom %d\n",
  938.                 ml, mt, mr, mb);
  939.         warn_count++;
  940.     };
  941. #endif
  942.  
  943.  
  944. #if 1
  945.  
  946.     {
  947.         u8* src_offset;
  948.         u8* dst_offset;
  949.         u32 ifl;
  950.  
  951.         ret = i915_mutex_lock_interruptible(dev);
  952.         if (ret)
  953.             goto err1;
  954.  
  955.         i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  956.  
  957.         src_offset = (u8*)( mt*os_display->width + ml);
  958.         src_offset+= get_display_map();
  959.         dst_offset = (u8*)mask->bo_map;
  960.  
  961.         u32_t tmp_h = mask->height;
  962.  
  963.         ifl = safe_cli();
  964.         {
  965.             mask_seqno[slot] = os_display->mask_seqno;
  966.  
  967.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  968.  
  969.             __asm__ __volatile__ (
  970.             "movd       %[slot],   %%xmm6         \n"
  971.             "punpckldq  %%xmm6, %%xmm6            \n"
  972.             "punpcklqdq %%xmm6, %%xmm6            \n"
  973.             :: [slot]  "m" (slot)
  974.             :"xmm6");
  975.  
  976.             while( tmp_h--)
  977.             {
  978.                 int tmp_w = mask->width;
  979.  
  980.                 u8* tmp_src = src_offset;
  981.                 u8* tmp_dst = dst_offset;
  982.  
  983.                 src_offset+= os_display->width;
  984.                 dst_offset+= mask->bo_pitch;
  985.  
  986.                 while(tmp_w >= 64)
  987.                 {
  988.                     __asm__ __volatile__ (
  989.                     "movdqu     (%0),   %%xmm0            \n"
  990.                     "movdqu   16(%0),   %%xmm1            \n"
  991.                     "movdqu   32(%0),   %%xmm2            \n"
  992.                     "movdqu   48(%0),   %%xmm3            \n"
  993.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  994.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  995.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  996.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  997.                     "movdqa     %%xmm0,   (%%edi)         \n"
  998.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  999.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  1000.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  1001.  
  1002.                     :: "r" (tmp_src), "D" (tmp_dst)
  1003.                     :"xmm0","xmm1","xmm2","xmm3");
  1004.                     tmp_w -= 64;
  1005.                     tmp_src += 64;
  1006.                     tmp_dst += 64;
  1007.                 }
  1008.  
  1009.                 if( tmp_w >= 32 )
  1010.                 {
  1011.                     __asm__ __volatile__ (
  1012.                     "movdqu     (%0),   %%xmm0            \n"
  1013.                     "movdqu   16(%0),   %%xmm1            \n"
  1014.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1015.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  1016.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1017.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  1018.  
  1019.                     :: "r" (tmp_src), "D" (tmp_dst)
  1020.                     :"xmm0","xmm1");
  1021.                     tmp_w -= 32;
  1022.                     tmp_src += 32;
  1023.                     tmp_dst += 32;
  1024.                 }
  1025.  
  1026.                 if( tmp_w >= 16 )
  1027.                 {
  1028.                     __asm__ __volatile__ (
  1029.                     "movdqu     (%0),   %%xmm0            \n"
  1030.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1031.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1032.                     :: "r" (tmp_src), "D" (tmp_dst)
  1033.                     :"xmm0");
  1034.                     tmp_w -= 16;
  1035.                     tmp_src += 16;
  1036.                     tmp_dst += 16;
  1037.                 }
  1038.  
  1039.                 if( tmp_w >= 8 )
  1040.                 {
  1041.                     __asm__ __volatile__ (
  1042.                     "movq       (%0),   %%xmm0            \n"
  1043.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1044.                     "movq       %%xmm0,   (%%edi)         \n"
  1045.                     :: "r" (tmp_src), "D" (tmp_dst)
  1046.                     :"xmm0");
  1047.                     tmp_w -= 8;
  1048.                     tmp_src += 8;
  1049.                     tmp_dst += 8;
  1050.                 }
  1051.                 if( tmp_w >= 4 )
  1052.         {
  1053.                     __asm__ __volatile__ (
  1054.                     "movd       (%0),   %%xmm0            \n"
  1055.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1056.                     "movd       %%xmm0,   (%%edi)         \n"
  1057.                     :: "r" (tmp_src), "D" (tmp_dst)
  1058.                     :"xmm0");
  1059.                     tmp_w -= 4;
  1060.                     tmp_src += 4;
  1061.                     tmp_dst += 4;
  1062.                 }
  1063.                 while(tmp_w--)
  1064.                     *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
  1065.             };
  1066.         };
  1067.         safe_sti(ifl);
  1068.  
  1069.         i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
  1070.     }
  1071. #endif
  1072.  
  1073. err2:
  1074.     mutex_unlock(&dev->struct_mutex);
  1075. err1:
  1076.     drm_gem_object_unreference(obj);
  1077.  
  1078.     return ret;
  1079. }
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091. #define NSEC_PER_SEC    1000000000L
  1092.  
  1093. void getrawmonotonic(struct timespec *ts)
  1094. {
  1095.     u32 tmp = GetTimerTicks();
  1096.  
  1097.     ts->tv_sec  = tmp/100;
  1098.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  1099. }
  1100.  
  1101. void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
  1102. {
  1103.     while (nsec >= NSEC_PER_SEC) {
  1104.         /*
  1105.          * The following asm() prevents the compiler from
  1106.          * optimising this loop into a modulo operation. See
  1107.          * also __iter_div_u64_rem() in include/linux/time.h
  1108.          */
  1109.         asm("" : "+rm"(nsec));
  1110.         nsec -= NSEC_PER_SEC;
  1111.         ++sec;
  1112.     }
  1113.     while (nsec < 0) {
  1114.         asm("" : "+rm"(nsec));
  1115.         nsec += NSEC_PER_SEC;
  1116.         --sec;
  1117.     }
  1118.     ts->tv_sec = sec;
  1119.     ts->tv_nsec = nsec;
  1120. }
  1121.  
  1122. void
  1123. prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
  1124. {
  1125.     unsigned long flags;
  1126.  
  1127. //    wait->flags &= ~WQ_FLAG_EXCLUSIVE;
  1128.     spin_lock_irqsave(&q->lock, flags);
  1129.     if (list_empty(&wait->task_list))
  1130.             __add_wait_queue(q, wait);
  1131.     spin_unlock_irqrestore(&q->lock, flags);
  1132. }
  1133.  
  1134. /**
  1135.  * finish_wait - clean up after waiting in a queue
  1136.  * @q: waitqueue waited on
  1137.  * @wait: wait descriptor
  1138.  *
  1139.  * Sets current thread back to running state and removes
  1140.  * the wait descriptor from the given waitqueue if still
  1141.  * queued.
  1142.  */
  1143. void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
  1144. {
  1145.     unsigned long flags;
  1146.  
  1147. //    __set_current_state(TASK_RUNNING);
  1148.     /*
  1149.      * We can check for list emptiness outside the lock
  1150.      * IFF:
  1151.      *  - we use the "careful" check that verifies both
  1152.      *    the next and prev pointers, so that there cannot
  1153.      *    be any half-pending updates in progress on other
  1154.      *    CPU's that we haven't seen yet (and that might
  1155.      *    still change the stack area.
  1156.      * and
  1157.      *  - all other users take the lock (ie we can only
  1158.      *    have _one_ other CPU that looks at or modifies
  1159.      *    the list).
  1160.      */
  1161.     if (!list_empty_careful(&wait->task_list)) {
  1162.             spin_lock_irqsave(&q->lock, flags);
  1163.             list_del_init(&wait->task_list);
  1164.             spin_unlock_irqrestore(&q->lock, flags);
  1165.     }
  1166.  
  1167.     DestroyEvent(wait->evnt);
  1168. }
  1169.  
  1170. int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
  1171. {
  1172.     list_del_init(&wait->task_list);
  1173.     return 1;
  1174. }
  1175.  
  1176. unsigned int hweight16(unsigned int w)
  1177. {
  1178.     unsigned int res = w - ((w >> 1) & 0x5555);
  1179.     res = (res & 0x3333) + ((res >> 2) & 0x3333);
  1180.     res = (res + (res >> 4)) & 0x0F0F;
  1181.     return (res + (res >> 8)) & 0x00FF;
  1182. }
  1183.  
  1184.  
  1185. unsigned long round_jiffies_up_relative(unsigned long j)
  1186. {
  1187.     unsigned long j0 = GetTimerTicks();
  1188.  
  1189.         /* Use j0 because jiffies might change while we run */
  1190.     return round_jiffies_common(j + j0, true) - j0;
  1191. }
  1192.  
  1193.  
  1194.