Subversion Repositories Kolibri OS

Rev

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