Subversion Repositories Kolibri OS

Rev

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