Subversion Repositories Kolibri OS

Rev

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