Subversion Repositories Kolibri OS

Rev

Rev 4104 | Rev 4280 | 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_mode_set     set;
  110.     char *con_name;
  111.     char *enc_name;
  112.     unsigned hdisplay, vdisplay;
  113.     int ret;
  114.  
  115.     mutex_lock(&dev->mode_config.mutex);
  116.  
  117.     list_for_each_entry(tmpmode, &connector->modes, head)
  118.     {
  119.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  120.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  121.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  122.         {
  123.             mode = tmpmode;
  124.             goto do_set;
  125.         }
  126.     };
  127.  
  128.     if( (mode == NULL) && (strict == false) )
  129.     {
  130.         list_for_each_entry(tmpmode, &connector->modes, head)
  131.         {
  132.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  133.                 (drm_mode_height(tmpmode) == reqmode->height) )
  134.             {
  135.                 mode = tmpmode;
  136.                 goto do_set;
  137.             }
  138.         };
  139.     };
  140.  
  141.     DRM_ERROR("%s failed\n", __FUNCTION__);
  142.  
  143.     return -1;
  144.  
  145. do_set:
  146.  
  147.     encoder = connector->encoder;
  148.     crtc = encoder->crtc;
  149.  
  150.     con_name = drm_get_connector_name(connector);
  151.     enc_name = drm_get_encoder_name(encoder);
  152.  
  153.     DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n",
  154.               reqmode->width, reqmode->height, crtc->base.id,
  155.               con_name, enc_name);
  156.  
  157.     drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  158.  
  159.     hdisplay = mode->hdisplay;
  160.     vdisplay = mode->vdisplay;
  161.  
  162.     if (crtc->invert_dimensions)
  163.         swap(hdisplay, vdisplay);
  164.  
  165.     fb = fb_helper->fb;
  166.  
  167.     fb->width  = reqmode->width;
  168.     fb->height = reqmode->height;
  169.     fb->pitches[0]  = ALIGN(reqmode->width * 4, 64);
  170.     fb->pitches[1]  = ALIGN(reqmode->width * 4, 64);
  171.     fb->pitches[2]  = ALIGN(reqmode->width * 4, 64);
  172.     fb->pitches[3]  = ALIGN(reqmode->width * 4, 64);
  173.  
  174.     fb->bits_per_pixel = 32;
  175.     fb->depth = 24;
  176.  
  177.     crtc->fb = fb;
  178.     crtc->enabled = true;
  179.     os_display->crtc = crtc;
  180.  
  181.     set.crtc = crtc;
  182.     set.x = 0;
  183.     set.y = 0;
  184.     set.mode = mode;
  185.     set.connectors = &connector;
  186.     set.num_connectors = 1;
  187.     set.fb = fb;
  188.     ret = crtc->funcs->set_config(&set);
  189.     mutex_unlock(&dev->mode_config.mutex);
  190.  
  191.     if ( !ret )
  192.     {
  193.         os_display->width    = fb->width;
  194.         os_display->height   = fb->height;
  195.         os_display->pitch    = fb->pitches[0];
  196.         os_display->vrefresh = drm_mode_vrefresh(mode);
  197.  
  198.         sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  199.  
  200.         DRM_DEBUG_KMS("new mode %d x %d pitch %d\n",
  201.                        fb->width, fb->height, fb->pitches[0]);
  202.     }
  203.     else
  204.         DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  205.                    fb->width, fb->height, crtc);
  206.  
  207.  
  208.     return ret;
  209. }
  210.  
  211. static int count_connector_modes(struct drm_connector* connector)
  212. {
  213.     struct drm_display_mode  *mode;
  214.     int count = 0;
  215.  
  216.     list_for_each_entry(mode, &connector->modes, head)
  217.     {
  218.         count++;
  219.     };
  220.     return count;
  221. };
  222.  
  223. static struct drm_connector* get_def_connector(struct drm_device *dev)
  224. {
  225.     struct drm_connector  *connector;
  226.     struct drm_connector_helper_funcs *connector_funcs;
  227.  
  228.     struct drm_connector  *def_connector = NULL;
  229.  
  230.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  231.     {
  232.         struct drm_encoder  *encoder;
  233.         struct drm_crtc     *crtc;
  234.  
  235.         if( connector->status != connector_status_connected)
  236.             continue;
  237.  
  238.         connector_funcs = connector->helper_private;
  239.         encoder = connector_funcs->best_encoder(connector);
  240.         if( encoder == NULL)
  241.             continue;
  242.  
  243.         connector->encoder = encoder;
  244.  
  245.         crtc = encoder->crtc;
  246.  
  247.         DRM_DEBUG_KMS("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x",
  248.                    connector, connector->base.id,
  249.                    connector->status, connector->encoder,
  250.                    crtc);
  251.  
  252. //        if (crtc == NULL)
  253. //            continue;
  254.  
  255.         def_connector = connector;
  256.  
  257.         break;
  258.     };
  259.  
  260.     return def_connector;
  261. };
  262.  
  263.  
  264. int init_display_kms(struct drm_device *dev)
  265. {
  266.     struct drm_connector    *connector;
  267.     struct drm_connector_helper_funcs *connector_funcs;
  268.     struct drm_encoder      *encoder;
  269.     struct drm_crtc         *crtc = NULL;
  270.     struct drm_framebuffer  *fb;
  271.  
  272.     cursor_t  *cursor;
  273.     u32_t      ifl;
  274.     int        err;
  275.  
  276.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  277.     {
  278.         if( connector->status != connector_status_connected)
  279.             continue;
  280.  
  281.         connector_funcs = connector->helper_private;
  282.         encoder = connector_funcs->best_encoder(connector);
  283.         if( encoder == NULL)
  284.         {
  285.             DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
  286.                       connector, connector->base.id);
  287.             continue;
  288.         }
  289.         connector->encoder = encoder;
  290.         crtc = encoder->crtc;
  291.  
  292.         DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
  293.                connector, connector->base.id,
  294.                connector->status, connector->encoder,
  295.                crtc, crtc->base.id );
  296.  
  297.         break;
  298.     };
  299.  
  300.     if(connector == NULL)
  301.     {
  302.         DRM_ERROR("No active connectors!\n");
  303.         return -1;
  304.     };
  305.  
  306.     if(crtc == NULL)
  307.     {
  308.         struct drm_crtc *tmp_crtc;
  309.         int crtc_mask = 1;
  310.  
  311.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  312.         {
  313.             if (encoder->possible_crtcs & crtc_mask)
  314.             {
  315.                 crtc = tmp_crtc;
  316.                 encoder->crtc = crtc;
  317.                 break;
  318.             };
  319.             crtc_mask <<= 1;
  320.         };
  321.     };
  322.  
  323.     if(crtc == NULL)
  324.     {
  325.         DRM_ERROR("No CRTC for encoder %d\n", encoder->base.id);
  326.         return -1;
  327.     };
  328.  
  329.  
  330.     DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id);
  331.  
  332.     os_display = GetDisplay();
  333.     os_display->ddev = dev;
  334.     os_display->connector = connector;
  335.     os_display->crtc = crtc;
  336.  
  337.     os_display->supported_modes = count_connector_modes(connector);
  338.  
  339.  
  340.     ifl = safe_cli();
  341.     {
  342.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  343.  
  344.         list_for_each_entry(cursor, &os_display->cursors, list)
  345.         {
  346.             init_cursor(cursor);
  347.         };
  348.  
  349.         os_display->restore_cursor(0,0);
  350.         os_display->init_cursor    = init_cursor;
  351.         os_display->select_cursor  = select_cursor_kms;
  352.         os_display->show_cursor    = NULL;
  353.         os_display->move_cursor    = move_cursor_kms;
  354.         os_display->restore_cursor = restore_cursor;
  355.         os_display->disable_mouse  = disable_mouse;
  356.  
  357.         intel_crtc->cursor_x = os_display->width/2;
  358.         intel_crtc->cursor_y = os_display->height/2;
  359.  
  360.         select_cursor_kms(os_display->cursor);
  361.     };
  362.     safe_sti(ifl);
  363.  
  364. #ifdef __HWA__
  365.     err = init_bitmaps();
  366. #endif
  367.  
  368.     return 0;
  369. };
  370.  
  371.  
  372. int get_videomodes(videomode_t *mode, int *count)
  373. {
  374.     int err = -1;
  375.  
  376. //    dbgprintf("mode %x count %d\n", mode, *count);
  377.  
  378.     if( *count == 0 )
  379.     {
  380.         *count = os_display->supported_modes;
  381.         err = 0;
  382.     }
  383.     else if( mode != NULL )
  384.     {
  385.         struct drm_display_mode  *drmmode;
  386.         int i = 0;
  387.  
  388.         if( *count > os_display->supported_modes)
  389.             *count = os_display->supported_modes;
  390.  
  391.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  392.         {
  393.             if( i < *count)
  394.             {
  395.                 mode->width  = drm_mode_width(drmmode);
  396.                 mode->height = drm_mode_height(drmmode);
  397.                 mode->bpp    = 32;
  398.                 mode->freq   = drm_mode_vrefresh(drmmode);
  399.                 i++;
  400.                 mode++;
  401.             }
  402.             else break;
  403.         };
  404.         *count = i;
  405.         err = 0;
  406.     };
  407.     return err;
  408. };
  409.  
  410. int set_user_mode(videomode_t *mode)
  411. {
  412.     int err = -1;
  413.  
  414. //    dbgprintf("width %d height %d vrefresh %d\n",
  415. //               mode->width, mode->height, mode->freq);
  416.  
  417.     if( (mode->width  != 0)  &&
  418.         (mode->height != 0)  &&
  419.         (mode->freq   != 0 ) &&
  420.         ( (mode->width   != os_display->width)  ||
  421.           (mode->height  != os_display->height) ||
  422.           (mode->freq    != os_display->vrefresh) ) )
  423.     {
  424.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  425.             err = 0;
  426.     };
  427.  
  428.     return err;
  429. };
  430.  
  431. void i915_dpms(struct drm_device *dev, int mode)
  432. {
  433.     struct drm_connector_funcs *f = os_display->connector->funcs;
  434.  
  435.     f->dpms(os_display->connector, mode);
  436. };
  437.  
  438. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  439. {
  440.     list_del(&cursor->list);
  441.  
  442.     i915_gem_object_unpin(cursor->cobj);
  443.  
  444.     mutex_lock(&main_device->struct_mutex);
  445.     drm_gem_object_unreference(&cursor->cobj->base);
  446.     mutex_unlock(&main_device->struct_mutex);
  447.  
  448.     __DestroyObject(cursor);
  449. };
  450.  
  451. int init_cursor(cursor_t *cursor)
  452. {
  453.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  454.     struct drm_i915_gem_object *obj;
  455.     uint32_t *bits;
  456.     uint32_t *src;
  457.     void     *mapped;
  458.  
  459.     int       i,j;
  460.     int       ret;
  461.  
  462.     if (dev_priv->info->cursor_needs_physical)
  463.     {
  464.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  465.         if (unlikely(bits == NULL))
  466.             return ENOMEM;
  467.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  468.     }
  469.     else
  470.     {
  471.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  472.         if (unlikely(obj == NULL))
  473.             return -ENOMEM;
  474.  
  475.         ret = i915_gem_obj_ggtt_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true);
  476.         if (ret) {
  477.             drm_gem_object_unreference(&obj->base);
  478.             return ret;
  479.         }
  480.  
  481.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  482.         if (ret)
  483.         {
  484.             i915_gem_object_unpin(obj);
  485.             drm_gem_object_unreference(&obj->base);
  486.             return ret;
  487.         }
  488. /* You don't need to worry about fragmentation issues.
  489.  * GTT space is continuous. I guarantee it.                           */
  490.  
  491.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  492.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  493.  
  494.         if (unlikely(bits == NULL))
  495.         {
  496.             i915_gem_object_unpin(obj);
  497.             drm_gem_object_unreference(&obj->base);
  498.             return -ENOMEM;
  499.         };
  500.         cursor->cobj = obj;
  501.     };
  502.  
  503.     src = cursor->data;
  504.  
  505.     for(i = 0; i < 32; i++)
  506.     {
  507.         for(j = 0; j < 32; j++)
  508.             *bits++ = *src++;
  509.         for(j = 32; j < CURSOR_WIDTH; j++)
  510.             *bits++ = 0;
  511.     }
  512.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  513.         *bits++ = 0;
  514.  
  515.     FreeKernelSpace(mapped);
  516.  
  517. // release old cursor
  518.  
  519.     KernelFree(cursor->data);
  520.  
  521.     cursor->data = bits;
  522.  
  523.     cursor->header.destroy = destroy_cursor;
  524.  
  525.     return 0;
  526. }
  527.  
  528.  
  529. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  530. {
  531.     struct drm_device *dev = crtc->dev;
  532.     struct drm_i915_private *dev_priv = dev->dev_private;
  533.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  534.     int pipe = intel_crtc->pipe;
  535.     bool visible = base != 0;
  536.  
  537.     if (intel_crtc->cursor_visible != visible) {
  538.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  539.         if (base) {
  540.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  541.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  542.             cntl |= pipe << 28; /* Connect to correct pipe */
  543.         } else {
  544.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  545.             cntl |= CURSOR_MODE_DISABLE;
  546.         }
  547.         I915_WRITE(CURCNTR(pipe), cntl);
  548.  
  549.         intel_crtc->cursor_visible = visible;
  550.     }
  551.     /* and commit changes on next vblank */
  552.     I915_WRITE(CURBASE(pipe), base);
  553. }
  554.  
  555. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  556. {
  557.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  558.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  559.     u32 base, pos;
  560.     bool visible;
  561.  
  562.     int pipe = intel_crtc->pipe;
  563.  
  564.     intel_crtc->cursor_x = x;
  565.     intel_crtc->cursor_y = y;
  566.  
  567.     x = x - cursor->hot_x;
  568.     y = y - cursor->hot_y;
  569.  
  570.  
  571.     pos = 0;
  572.  
  573.     base = intel_crtc->cursor_addr;
  574.     if (x >= os_display->width)
  575.         base = 0;
  576.  
  577.     if (y >= os_display->height)
  578.         base = 0;
  579.  
  580.     if (x < 0)
  581.     {
  582.         if (x + intel_crtc->cursor_width < 0)
  583.             base = 0;
  584.  
  585.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  586.         x = -x;
  587.     }
  588.     pos |= x << CURSOR_X_SHIFT;
  589.  
  590.     if (y < 0)
  591.     {
  592.         if (y + intel_crtc->cursor_height < 0)
  593.             base = 0;
  594.  
  595.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  596.         y = -y;
  597.     }
  598.     pos |= y << CURSOR_Y_SHIFT;
  599.  
  600.     visible = base != 0;
  601.     if (!visible && !intel_crtc->cursor_visible)
  602.         return;
  603.  
  604.     I915_WRITE(CURPOS(pipe), pos);
  605. //    if (IS_845G(dev) || IS_I865G(dev))
  606. //        i845_update_cursor(crtc, base);
  607. //    else
  608.         i9xx_update_cursor(os_display->crtc, base);
  609.  
  610. };
  611.  
  612.  
  613. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  614. {
  615.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  616.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  617.     cursor_t *old;
  618.  
  619.     old = os_display->cursor;
  620.     os_display->cursor = cursor;
  621.  
  622.     if (!dev_priv->info->cursor_needs_physical)
  623.        intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
  624.     else
  625.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  626.  
  627.     intel_crtc->cursor_width = 32;
  628.     intel_crtc->cursor_height = 32;
  629.  
  630.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  631.     return old;
  632. };
  633.  
  634. struct sna_fb
  635. {
  636.     uint32_t  width;
  637.     uint32_t  height;
  638.     uint32_t  pitch;
  639.     uint32_t  tiling;
  640. };
  641.  
  642. int i915_fbinfo(struct sna_fb *fb)
  643. {
  644.     fb->width  = os_display->width;
  645.     fb->height = os_display->height;
  646.     fb->pitch  = os_display->pitch;
  647.     fb->tiling = 0;
  648.  
  649.     return 0;
  650. };
  651.  
  652. typedef struct
  653. {
  654.     int left;
  655.     int top;
  656.     int right;
  657.     int bottom;
  658. }rect_t;
  659.  
  660. struct drm_i915_mask {
  661.     __u32 handle;
  662.     __u32 width;
  663.     __u32 height;
  664.     __u32 bo_size;
  665.     __u32 bo_pitch;
  666.     __u32 bo_map;
  667. };
  668.  
  669. #define CURRENT_TASK             (0x80003000)
  670.  
  671. static u32_t get_display_map()
  672. {
  673.     u32_t   addr;
  674.  
  675.     addr = (u32_t)os_display;
  676.     addr+= sizeof(display_t);            /*  shoot me  */
  677.     return *(u32_t*)addr;
  678. }
  679.  
  680. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  681.  
  682. int i915_mask_update(struct drm_device *dev, void *data,
  683.             struct drm_file *file)
  684. {
  685.     struct drm_i915_mask *mask = data;
  686.     struct drm_gem_object *obj;
  687.     static unsigned int mask_seqno[256];
  688.     rect_t winrc;
  689.     u32    slot;
  690.     int    ret;
  691.  
  692.      if(mask->handle == -2)
  693.      {
  694.         printf("%s handle %d\n", __FUNCTION__, mask->handle);
  695.         return 0;
  696.      }
  697.  
  698.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  699.     if (obj == NULL)
  700.         return -ENOENT;
  701.  
  702.     if (!obj->filp) {
  703.         drm_gem_object_unreference_unlocked(obj);
  704.         return -EINVAL;
  705.     }
  706.  
  707.     GetWindowRect(&winrc);
  708.     {
  709. //        static warn_count;
  710.  
  711.         mask->width    = winrc.right - winrc.left + 1;
  712.         mask->height   = winrc.bottom - winrc.top + 1;
  713.         mask->bo_pitch = (mask->width+15) & ~15;
  714.  
  715. #if 0
  716.         if(warn_count < 1)
  717.         {
  718.             printf("left %d top %d right %d bottom %d\n",
  719.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  720.             printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
  721.             warn_count++;
  722.         };
  723. #endif
  724.  
  725.      };
  726.  
  727.  
  728.     slot = *((u8*)CURRENT_TASK);
  729.  
  730.     if( mask_seqno[slot] != os_display->mask_seqno)
  731.     {
  732.         u8* src_offset;
  733.         u8* dst_offset;
  734.         u32 ifl;
  735.  
  736.         ret = i915_mutex_lock_interruptible(dev);
  737.         if (ret)
  738.             return ret;
  739.  
  740.         ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  741.         if(ret !=0 )
  742.         {
  743.             dbgprintf("%s fail\n", __FUNCTION__);
  744.             return ret;
  745.         };
  746.  
  747. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  748.  
  749. //        slot = 0x01;
  750.  
  751.  
  752.         src_offset = (u8*)( winrc.top*os_display->width + winrc.left);
  753.         src_offset+= get_display_map();
  754.         dst_offset = (u8*)mask->bo_map;
  755.  
  756.         u32_t tmp_h = mask->height;
  757.  
  758.         ifl = safe_cli();
  759.         {
  760.             mask_seqno[slot] = os_display->mask_seqno;
  761.  
  762.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  763.  
  764.             __asm__ __volatile__ (
  765.                 "movd       %[slot],   %%xmm6    \n"
  766.             "punpckldq  %%xmm6, %%xmm6            \n"
  767.             "punpcklqdq %%xmm6, %%xmm6            \n"
  768.             :: [slot]  "m" (slot)
  769.             :"xmm6");
  770.  
  771.             while( tmp_h--)
  772.             {
  773.                 int tmp_w = mask->bo_pitch;
  774.  
  775.                 u8* tmp_src = src_offset;
  776.                 u8* tmp_dst = dst_offset;
  777.  
  778.                 src_offset+= os_display->width;
  779.                 dst_offset+= mask->bo_pitch;
  780.  
  781.                 while(tmp_w >= 64)
  782.                 {
  783.                     __asm__ __volatile__ (
  784.                     "movdqu     (%0),   %%xmm0            \n"
  785.                     "movdqu   16(%0),   %%xmm1            \n"
  786.                     "movdqu   32(%0),   %%xmm2            \n"
  787.                     "movdqu   48(%0),   %%xmm3            \n"
  788.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  789.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  790.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  791.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  792.                     "movdqa     %%xmm0,   (%%edi)         \n"
  793.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  794.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  795.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  796.  
  797.                     :: "r" (tmp_src), "D" (tmp_dst)
  798.                     :"xmm0","xmm1","xmm2","xmm3");
  799.                     tmp_w -= 64;
  800.                     tmp_src += 64;
  801.                     tmp_dst += 64;
  802.                 }
  803.  
  804.                 if( tmp_w >= 32 )
  805.                 {
  806.                     __asm__ __volatile__ (
  807.                     "movdqu     (%0),   %%xmm0            \n"
  808.                     "movdqu   16(%0),   %%xmm1            \n"
  809.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  810.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  811.                     "movdqa     %%xmm0,   (%%edi)         \n"
  812.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  813.  
  814.                     :: "r" (tmp_src), "D" (tmp_dst)
  815.                     :"xmm0","xmm1");
  816.                     tmp_w -= 32;
  817.                     tmp_src += 32;
  818.                     tmp_dst += 32;
  819.                 }
  820.  
  821.                 while( tmp_w > 0 )
  822.                 {
  823.                     __asm__ __volatile__ (
  824.                     "movdqu     (%0),   %%xmm0            \n"
  825.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  826.                     "movdqa     %%xmm0,   (%%edi)         \n"
  827.                     :: "r" (tmp_src), "D" (tmp_dst)
  828.                     :"xmm0");
  829.                     tmp_w -= 16;
  830.                     tmp_src += 16;
  831.                     tmp_dst += 16;
  832.                 }
  833.             };
  834.         };
  835.         safe_sti(ifl);
  836.     }
  837.  
  838.     drm_gem_object_unreference(obj);
  839.  
  840.     mutex_unlock(&dev->struct_mutex);
  841.  
  842.     return 0;
  843. }
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856. #define NSEC_PER_SEC    1000000000L
  857.  
  858. void getrawmonotonic(struct timespec *ts)
  859. {
  860.     u32 tmp = GetTimerTicks();
  861.  
  862.     ts->tv_sec  = tmp/100;
  863.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  864. }
  865.  
  866. void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
  867. {
  868.     while (nsec >= NSEC_PER_SEC) {
  869.         /*
  870.          * The following asm() prevents the compiler from
  871.          * optimising this loop into a modulo operation. See
  872.          * also __iter_div_u64_rem() in include/linux/time.h
  873.          */
  874.         asm("" : "+rm"(nsec));
  875.         nsec -= NSEC_PER_SEC;
  876.         ++sec;
  877.     }
  878.     while (nsec < 0) {
  879.         asm("" : "+rm"(nsec));
  880.         nsec += NSEC_PER_SEC;
  881.         --sec;
  882.     }
  883.     ts->tv_sec = sec;
  884.     ts->tv_nsec = nsec;
  885. }
  886.  
  887. void
  888. prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
  889. {
  890.     unsigned long flags;
  891.  
  892. //    wait->flags &= ~WQ_FLAG_EXCLUSIVE;
  893.     spin_lock_irqsave(&q->lock, flags);
  894.     if (list_empty(&wait->task_list))
  895.             __add_wait_queue(q, wait);
  896.     spin_unlock_irqrestore(&q->lock, flags);
  897. }
  898.  
  899. /**
  900.  * finish_wait - clean up after waiting in a queue
  901.  * @q: waitqueue waited on
  902.  * @wait: wait descriptor
  903.  *
  904.  * Sets current thread back to running state and removes
  905.  * the wait descriptor from the given waitqueue if still
  906.  * queued.
  907.  */
  908. void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
  909. {
  910.     unsigned long flags;
  911.  
  912. //    __set_current_state(TASK_RUNNING);
  913.     /*
  914.      * We can check for list emptiness outside the lock
  915.      * IFF:
  916.      *  - we use the "careful" check that verifies both
  917.      *    the next and prev pointers, so that there cannot
  918.      *    be any half-pending updates in progress on other
  919.      *    CPU's that we haven't seen yet (and that might
  920.      *    still change the stack area.
  921.      * and
  922.      *  - all other users take the lock (ie we can only
  923.      *    have _one_ other CPU that looks at or modifies
  924.      *    the list).
  925.      */
  926.     if (!list_empty_careful(&wait->task_list)) {
  927.             spin_lock_irqsave(&q->lock, flags);
  928.             list_del_init(&wait->task_list);
  929.             spin_unlock_irqrestore(&q->lock, flags);
  930.     }
  931.  
  932.     DestroyEvent(wait->evnt);
  933. }
  934.  
  935. int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
  936. {
  937.     list_del_init(&wait->task_list);
  938.     return 1;
  939. }
  940.  
  941. unsigned int hweight16(unsigned int w)
  942. {
  943.     unsigned int res = w - ((w >> 1) & 0x5555);
  944.     res = (res & 0x3333) + ((res >> 2) & 0x3333);
  945.     res = (res + (res >> 4)) & 0x0F0F;
  946.     return (res + (res >> 8)) & 0x00FF;
  947. }
  948.  
  949.  
  950. unsigned long round_jiffies_up_relative(unsigned long j)
  951. {
  952.     unsigned long j0 = GetTimerTicks();
  953.  
  954.         /* Use j0 because jiffies might change while we run */
  955.     return round_jiffies_common(j + j0, true) - j0;
  956. }
  957.  
  958.  
  959.