Subversion Repositories Kolibri OS

Rev

Rev 6088 | Rev 6131 | 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.     }
  378.  
  379.     crtc = encoder->crtc;
  380.     if(crtc == NULL)
  381.         crtc = get_possible_crtc(dev, encoder);
  382.  
  383.     if(crtc != NULL)
  384.     {
  385.         encoder->crtc = crtc;
  386.         return 0;
  387.     }
  388.     else
  389.         DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
  390.     return -EINVAL;
  391. }
  392.  
  393. static struct drm_connector* get_cmdline_connector(struct drm_device *dev, const char *cmdline)
  394. {
  395.     struct drm_connector *connector;
  396.  
  397.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  398.     {
  399.         int name_len = __builtin_strlen(connector->name);
  400.  
  401.         if (name_len == 0)
  402.             continue;
  403.  
  404.         if (__builtin_strncmp(connector->name, cmdline, name_len))
  405.             continue;
  406.  
  407.         if(check_connector(dev, connector) == 0)
  408.             return connector;
  409.     }
  410.     return NULL;
  411. }
  412.  
  413.  
  414. static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector,
  415.                   struct drm_crtc **boot_crtc)
  416. {
  417.     struct drm_connector *connector;
  418.  
  419.     if((i915.cmdline_mode != NULL) && (*i915.cmdline_mode != 0))
  420.     {
  421.         connector = get_cmdline_connector(dev, i915.cmdline_mode);
  422.         if(connector != NULL)
  423.         {
  424.             *boot_connector = connector;
  425.             *boot_crtc = connector->encoder->crtc;
  426.             return 0;
  427.         }
  428.     }
  429.  
  430.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  431.     {
  432.         if(check_connector(dev, connector) == 0)
  433.         {
  434.             *boot_connector = connector;
  435.             *boot_crtc = connector->encoder->crtc;
  436.             return 0;
  437.         };
  438.     };
  439.  
  440.     return -ENOENT;
  441. };
  442.  
  443.  
  444. static int get_boot_mode(struct drm_connector *connector, videomode_t *usermode)
  445. {
  446.     struct drm_display_mode *mode;
  447.  
  448.     list_for_each_entry(mode, &connector->modes, head)
  449.     {
  450.         if( os_display->width  == mode->hdisplay &&
  451.             os_display->height == mode->vdisplay &&
  452.             drm_mode_vrefresh(mode) == 60)
  453.         {
  454.             usermode->width  = os_display->width;
  455.             usermode->height = os_display->height;
  456.             usermode->freq   = 60;
  457.             return 1;
  458.         }
  459.     }
  460.     return 0;
  461. }
  462.  
  463. int init_display_kms(struct drm_device *dev, videomode_t *usermode)
  464. {
  465.     struct drm_connector_helper_funcs *connector_funcs;
  466.     struct drm_connector    *connector = NULL;
  467.     struct drm_crtc         *crtc = NULL;
  468.     struct drm_framebuffer  *fb;
  469.  
  470.     cursor_t  *cursor;
  471.     u32      ifl;
  472.     int       ret;
  473.  
  474.     mutex_lock(&dev->mode_config.mutex);
  475.     ret = choose_config(dev, &connector, &crtc);
  476.     if(ret)
  477.     {
  478.         mutex_unlock(&dev->mode_config.mutex);
  479.         DRM_DEBUG_KMS("No active connectors!\n");
  480.         return -1;
  481.     };
  482.  
  483.     mutex_lock(&dev->object_name_lock);
  484.     idr_preload(GFP_KERNEL);
  485.  
  486.     if (!main_fb_obj->base.name) {
  487.         ret = idr_alloc(&dev->object_name_idr, &main_fb_obj->base, 1, 0, GFP_NOWAIT);
  488.  
  489.         main_fb_obj->base.name = ret;
  490.         main_fb_obj->base.handle_count++;
  491.         DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->base.name );
  492.     }
  493.  
  494.     idr_preload_end();
  495.     mutex_unlock(&dev->object_name_lock);
  496.  
  497.     os_display = GetDisplay();
  498.     os_display->ddev = dev;
  499.     os_display->connector = connector;
  500.     os_display->crtc = crtc;
  501.     os_display->supported_modes = count_connector_modes(connector);
  502.     mutex_unlock(&dev->mode_config.mutex);
  503.  
  504.     mutex_init(&cursor_lock);
  505.     mutex_lock(&dev->struct_mutex);
  506.  
  507.     ifl = safe_cli();
  508.     {
  509.         list_for_each_entry(cursor, &os_display->cursors, list)
  510.         {
  511.             init_cursor(cursor);
  512.         };
  513.  
  514.         os_display->restore_cursor(0,0);
  515.         os_display->init_cursor    = init_cursor;
  516.         os_display->select_cursor  = select_cursor_kms;
  517.         os_display->show_cursor    = NULL;
  518.         os_display->move_cursor    = move_cursor_kms;
  519.         os_display->restore_cursor = restore_cursor;
  520.         os_display->disable_mouse  = disable_mouse;
  521.  
  522.         crtc->cursor_x = os_display->width/2;
  523.         crtc->cursor_y = os_display->height/2;
  524.  
  525.         select_cursor_kms(os_display->cursor);
  526.     };
  527.     safe_sti(ifl);
  528.  
  529.     mutex_unlock(&dev->struct_mutex);
  530.  
  531.     ret = -1;
  532.  
  533.     if(connector->cmdline_mode.specified == true)
  534.         ret = set_cmdline_mode(dev, connector);
  535.  
  536.     if(ret !=0)
  537.     {
  538.         mutex_lock(&dev->mode_config.mutex);
  539.  
  540.         if( (usermode->width == 0) ||
  541.             (usermode->height == 0))
  542.         {
  543.             if( !get_boot_mode(connector, usermode))
  544.             {
  545.                 struct drm_display_mode *mode;
  546.  
  547.                 mode = list_entry(connector->modes.next, typeof(*mode), head);
  548.                 usermode->width  = mode->hdisplay;
  549.                 usermode->height = mode->vdisplay;
  550.                 usermode->freq   = drm_mode_vrefresh(mode);
  551.             };
  552.         };
  553.         mutex_unlock(&dev->mode_config.mutex);
  554.  
  555.         set_mode(dev, os_display->connector, os_display->crtc, usermode, false);
  556.     };
  557.  
  558. #ifdef __HWA__
  559.     err = init_bitmaps();
  560. #endif
  561.  
  562.     return ret;
  563. };
  564.  
  565.  
  566. int set_cmdline_mode_ext(struct drm_device *dev, const char *cmdline)
  567. {
  568.     struct drm_connector_helper_funcs *connector_funcs;
  569.     struct drm_connector    *connector;
  570.     struct drm_cmdline_mode cmd_mode = {0};
  571.     struct drm_display_mode *mode;
  572.     char *mode_option;
  573.     int retval = 0;
  574.     char  con_edid[128];
  575.  
  576.     if((cmdline == NULL) || (*cmdline == 0))
  577.         return EINVAL;
  578.  
  579.     mutex_lock(&dev->mode_config.mutex);
  580.     connector = get_cmdline_connector(dev, cmdline);
  581.     mutex_unlock(&dev->mode_config.mutex);
  582.  
  583.     if(connector == NULL)
  584.         return EINVAL;
  585.  
  586.     mode_option = __builtin_strchr(cmdline,':');
  587.     if(mode_option == NULL)
  588.         return EINVAL;
  589.  
  590.     mode_option++;
  591.  
  592.     if( !drm_mode_parse_command_line_for_connector(mode_option, connector, &cmd_mode))
  593.         return EINVAL;
  594.  
  595.     DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
  596.                    connector->name,
  597.                    cmd_mode.xres, cmd_mode.yres,
  598.                    cmd_mode.refresh_specified ? cmd_mode.refresh : 60,
  599.                    cmd_mode.rb ? " reduced blanking" : "",
  600.                    cmd_mode.margins ? " with margins" : "",
  601.                    cmd_mode.interlace ?  " interlaced" : "");
  602.  
  603.     mode = drm_mode_create_from_cmdline_mode(dev, &cmd_mode);
  604.     if(mode == NULL)
  605.         return EINVAL;
  606.  
  607.     memcpy(con_edid, connector->edid_blob_ptr->data, 128);
  608.     DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n",
  609.             connector->name,
  610.             manufacturer_name(con_edid + 0x08),
  611.             (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
  612.             (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
  613.             + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
  614.  
  615.     retval = set_mode_ex(dev, connector, mode);
  616.  
  617.     drm_mode_destroy(dev, mode);
  618.  
  619.     return retval;
  620. }
  621.  
  622. void list_connectors(struct drm_device *dev)
  623. {
  624.     struct drm_connector *connector;
  625.     char  con_edid[128];
  626.  
  627.     mutex_lock(&dev->mode_config.mutex);
  628.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  629.     {
  630.         if( connector->status != connector_status_connected)
  631.             continue;
  632.  
  633.         memcpy(con_edid, connector->edid_blob_ptr->data, 128);
  634.  
  635.         if(connector ==  os_display->connector)
  636.         {
  637.             printf("%s mode %dx%d connected %s model %x serial number %u\n",
  638.                    connector->name, os_display->width, os_display->height,
  639.                    manufacturer_name(con_edid + 0x08),
  640.                    (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
  641.                    (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
  642.                    + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
  643.             continue;
  644.         }
  645.         else
  646.         {
  647.             printf("%s connected: %s model %x serial number %u\n",
  648.                 connector->name, manufacturer_name(con_edid + 0x08),
  649.                 (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
  650.                 (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
  651.                 + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
  652.         }
  653.     };
  654.     mutex_unlock(&dev->mode_config.mutex);
  655. }
  656.  
  657. int list_connector_modes(struct drm_device *dev, const char* name)
  658. {
  659.     struct drm_connector *connector;
  660.     struct drm_display_mode  *drmmode;
  661.  
  662.     mutex_lock(&dev->mode_config.mutex);
  663.  
  664.     connector = get_cmdline_connector(dev, name);
  665.     if(connector == NULL)
  666.     {
  667.         mutex_unlock(&dev->mode_config.mutex);
  668.         return EINVAL;
  669.     };
  670.  
  671.     printf("connector %s probed modes :\n", connector->name);
  672.  
  673.     list_for_each_entry(drmmode, &connector->modes, head)
  674.     {
  675.         printf("%dx%d@%d\n", drmmode->hdisplay, drmmode->vdisplay, drm_mode_vrefresh(drmmode));
  676.     };
  677.  
  678.     mutex_unlock(&dev->mode_config.mutex);
  679.     return 0;
  680. };
  681.  
  682. int get_videomodes(videomode_t *mode, int *count)
  683. {
  684.     int err = -1;
  685.  
  686. //    dbgprintf("mode %x count %d\n", mode, *count);
  687.  
  688.     if( *count == 0 )
  689.     {
  690.         *count = os_display->supported_modes;
  691.         err = 0;
  692.     }
  693.     else if( mode != NULL )
  694.     {
  695.         struct drm_display_mode  *drmmode;
  696.         int i = 0;
  697.  
  698.         if( *count > os_display->supported_modes)
  699.             *count = os_display->supported_modes;
  700.  
  701.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  702.         {
  703.             if( i < *count)
  704.             {
  705.                 mode->width  = drmmode->hdisplay;
  706.                 mode->height = drmmode->vdisplay;
  707.                 mode->bpp    = 32;
  708.                 mode->freq   = drm_mode_vrefresh(drmmode);
  709.                 i++;
  710.                 mode++;
  711.             }
  712.             else break;
  713.         };
  714.         *count = i;
  715.         err = 0;
  716.     };
  717.     return err;
  718. };
  719.  
  720. int set_user_mode(videomode_t *mode)
  721. {
  722.  
  723. //    dbgprintf("width %d height %d vrefresh %d\n",
  724. //               mode->width, mode->height, mode->freq);
  725.  
  726.     if( (mode->width  != 0)  &&
  727.         (mode->height != 0)  &&
  728.         (mode->freq   != 0 ) &&
  729.         ( (mode->width   != os_display->width)  ||
  730.           (mode->height  != os_display->height) ||
  731.           (mode->freq    != os_display->vrefresh) ) )
  732.     {
  733.         return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true);
  734.     };
  735.  
  736.     return -1;
  737. };
  738.  
  739. void i915_dpms(struct drm_device *dev, int mode)
  740. {
  741.     const struct drm_connector_funcs *f = os_display->connector->funcs;
  742.  
  743.     f->dpms(os_display->connector, mode);
  744. };
  745.  
  746. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  747. {
  748.     struct drm_i915_gem_object *obj = cursor->cobj;
  749.     list_del(&cursor->list);
  750.  
  751.     i915_gem_object_ggtt_unpin(cursor->cobj);
  752.  
  753.     mutex_lock(&main_device->struct_mutex);
  754.     drm_gem_object_unreference(&obj->base);
  755.     mutex_unlock(&main_device->struct_mutex);
  756.  
  757.     __DestroyObject(cursor);
  758. };
  759.  
  760. int init_cursor(cursor_t *cursor)
  761. {
  762.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  763.     struct drm_i915_gem_object *obj;
  764.     uint32_t *bits;
  765.     uint32_t *src;
  766.     void     *mapped;
  767.  
  768.     int       i,j;
  769.     int       ret;
  770.  
  771.     if (dev_priv->info.cursor_needs_physical)
  772.     {
  773.         bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
  774.         if (unlikely(bits == NULL))
  775.             return ENOMEM;
  776.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  777.     }
  778.     else
  779.     {
  780.         obj = i915_gem_alloc_object(os_display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
  781.         if (unlikely(obj == NULL))
  782.             return -ENOMEM;
  783.  
  784.         ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
  785.         if (ret) {
  786.             drm_gem_object_unreference(&obj->base);
  787.             return ret;
  788.         }
  789.  
  790.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  791.         if (ret)
  792.         {
  793.             i915_gem_object_ggtt_unpin(obj);
  794.             drm_gem_object_unreference(&obj->base);
  795.             return ret;
  796.         }
  797. /* You don't need to worry about fragmentation issues.
  798.  * GTT space is continuous. I guarantee it.                           */
  799.  
  800.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  801.                     KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
  802.  
  803.         if (unlikely(bits == NULL))
  804.         {
  805.             i915_gem_object_ggtt_unpin(obj);
  806.             drm_gem_object_unreference(&obj->base);
  807.             return -ENOMEM;
  808.         };
  809.         cursor->cobj = obj;
  810.     };
  811.  
  812.     src = cursor->data;
  813.  
  814.     for(i = 0; i < 32; i++)
  815.     {
  816.         for(j = 0; j < 32; j++)
  817.             *bits++ = *src++;
  818.         for(j = 32; j < KMS_CURSOR_WIDTH; j++)
  819.             *bits++ = 0;
  820.     }
  821.     for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
  822.         *bits++ = 0;
  823.  
  824.     FreeKernelSpace(mapped);
  825.  
  826. // release old cursor
  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.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  1157.     if (obj == NULL)
  1158.         return -ENOENT;
  1159.  
  1160.     if (!obj->filp) {
  1161.         drm_gem_object_unreference_unlocked(obj);
  1162.         return -EINVAL;
  1163.     }
  1164.  
  1165. #if 0
  1166.     if(warn_count < 100)
  1167.     {
  1168.         printf("left %d top %d right %d bottom %d\n",
  1169.                 ml, mt, mr, mb);
  1170.         warn_count++;
  1171.     };
  1172. #endif
  1173.  
  1174.  
  1175. #if 1
  1176.  
  1177.     {
  1178.         u8* src_offset;
  1179.         u8* dst_offset;
  1180.         u32 ifl;
  1181.  
  1182.         ret = i915_mutex_lock_interruptible(dev);
  1183.         if (ret)
  1184.             goto err1;
  1185.  
  1186.         i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  1187.  
  1188.         src_offset = os_display->win_map;
  1189.         src_offset+= mt*os_display->width + ml;
  1190.         dst_offset = (u8*)mask->bo_map;
  1191.  
  1192.         u32 tmp_h = mask->height;
  1193.  
  1194.         ifl = safe_cli();
  1195.         {
  1196.             mask_seqno[slot] = os_display->mask_seqno;
  1197.  
  1198.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  1199.  
  1200.             __asm__ __volatile__ (
  1201.             "movd       %[slot],   %%xmm6         \n"
  1202.             "punpckldq  %%xmm6, %%xmm6            \n"
  1203.             "punpcklqdq %%xmm6, %%xmm6            \n"
  1204.             :: [slot]  "m" (slot)
  1205.             :"xmm6");
  1206.  
  1207.             while( tmp_h--)
  1208.             {
  1209.                 int tmp_w = mask->width;
  1210.  
  1211.                 u8* tmp_src = src_offset;
  1212.                 u8* tmp_dst = dst_offset;
  1213.  
  1214.                 src_offset+= os_display->width;
  1215.                 dst_offset+= mask->bo_pitch;
  1216.  
  1217.                 while(tmp_w >= 64)
  1218.                 {
  1219.                     __asm__ __volatile__ (
  1220.                     "movdqu     (%0),   %%xmm0            \n"
  1221.                     "movdqu   16(%0),   %%xmm1            \n"
  1222.                     "movdqu   32(%0),   %%xmm2            \n"
  1223.                     "movdqu   48(%0),   %%xmm3            \n"
  1224.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1225.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  1226.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  1227.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  1228.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1229.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  1230.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  1231.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  1232.  
  1233.                     :: "r" (tmp_src), "D" (tmp_dst)
  1234.                     :"xmm0","xmm1","xmm2","xmm3");
  1235.                     tmp_w -= 64;
  1236.                     tmp_src += 64;
  1237.                     tmp_dst += 64;
  1238.                 }
  1239.  
  1240.                 if( tmp_w >= 32 )
  1241.                 {
  1242.                     __asm__ __volatile__ (
  1243.                     "movdqu     (%0),   %%xmm0            \n"
  1244.                     "movdqu   16(%0),   %%xmm1            \n"
  1245.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1246.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  1247.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1248.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  1249.  
  1250.                     :: "r" (tmp_src), "D" (tmp_dst)
  1251.                     :"xmm0","xmm1");
  1252.                     tmp_w -= 32;
  1253.                     tmp_src += 32;
  1254.                     tmp_dst += 32;
  1255.                 }
  1256.  
  1257.                 if( tmp_w >= 16 )
  1258.                 {
  1259.                     __asm__ __volatile__ (
  1260.                     "movdqu     (%0),   %%xmm0            \n"
  1261.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1262.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1263.                     :: "r" (tmp_src), "D" (tmp_dst)
  1264.                     :"xmm0");
  1265.                     tmp_w -= 16;
  1266.                     tmp_src += 16;
  1267.                     tmp_dst += 16;
  1268.                 }
  1269.  
  1270.                 if( tmp_w >= 8 )
  1271.                 {
  1272.                     __asm__ __volatile__ (
  1273.                     "movq       (%0),   %%xmm0            \n"
  1274.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1275.                     "movq       %%xmm0,   (%%edi)         \n"
  1276.                     :: "r" (tmp_src), "D" (tmp_dst)
  1277.                     :"xmm0");
  1278.                     tmp_w -= 8;
  1279.                     tmp_src += 8;
  1280.                     tmp_dst += 8;
  1281.                 }
  1282.                 if( tmp_w >= 4 )
  1283.                 {
  1284.                     __asm__ __volatile__ (
  1285.                     "movd       (%0),   %%xmm0            \n"
  1286.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1287.                     "movd       %%xmm0,   (%%edi)         \n"
  1288.                     :: "r" (tmp_src), "D" (tmp_dst)
  1289.                     :"xmm0");
  1290.                     tmp_w -= 4;
  1291.                     tmp_src += 4;
  1292.                     tmp_dst += 4;
  1293.                 }
  1294.                 while(tmp_w--)
  1295.                     *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
  1296.             };
  1297.         };
  1298.         safe_sti(ifl);
  1299.  
  1300.         i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
  1301.     }
  1302. #endif
  1303.  
  1304. err2:
  1305.     mutex_unlock(&dev->struct_mutex);
  1306. err1:
  1307.     drm_gem_object_unreference(obj);
  1308.  
  1309.     return ret;
  1310. }
  1311.  
  1312.  
  1313.  
  1314.  
  1315. #define NSEC_PER_SEC    1000000000L
  1316.  
  1317. void getrawmonotonic(struct timespec *ts)
  1318. {
  1319.     u32 tmp = GetTimerTicks();
  1320.  
  1321.     ts->tv_sec  = tmp/100;
  1322.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  1323. }
  1324.  
  1325. void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
  1326. {
  1327.     unsigned long flags;
  1328.  
  1329. //    wait->flags &= ~WQ_FLAG_EXCLUSIVE;
  1330.     spin_lock_irqsave(&q->lock, flags);
  1331.     if (list_empty(&wait->task_list))
  1332.             __add_wait_queue(q, wait);
  1333.     spin_unlock_irqrestore(&q->lock, flags);
  1334. }
  1335.  
  1336. /**
  1337.  * finish_wait - clean up after waiting in a queue
  1338.  * @q: waitqueue waited on
  1339.  * @wait: wait descriptor
  1340.  *
  1341.  * Sets current thread back to running state and removes
  1342.  * the wait descriptor from the given waitqueue if still
  1343.  * queued.
  1344.  */
  1345. void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
  1346. {
  1347.     unsigned long flags;
  1348.  
  1349. //    __set_current_state(TASK_RUNNING);
  1350.     /*
  1351.      * We can check for list emptiness outside the lock
  1352.      * IFF:
  1353.      *  - we use the "careful" check that verifies both
  1354.      *    the next and prev pointers, so that there cannot
  1355.      *    be any half-pending updates in progress on other
  1356.      *    CPU's that we haven't seen yet (and that might
  1357.      *    still change the stack area.
  1358.      * and
  1359.      *  - all other users take the lock (ie we can only
  1360.      *    have _one_ other CPU that looks at or modifies
  1361.      *    the list).
  1362.      */
  1363.     if (!list_empty_careful(&wait->task_list)) {
  1364.             spin_lock_irqsave(&q->lock, flags);
  1365.             list_del_init(&wait->task_list);
  1366.             spin_unlock_irqrestore(&q->lock, flags);
  1367.     }
  1368.  
  1369.     DestroyEvent(wait->evnt);
  1370. }
  1371.  
  1372. int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
  1373. {
  1374.     list_del_init(&wait->task_list);
  1375.     return 1;
  1376. }
  1377.  
  1378.  
  1379.  
  1380.