Subversion Repositories Kolibri OS

Rev

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