Subversion Repositories Kolibri OS

Rev

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