Subversion Repositories Kolibri OS

Rev

Rev 6131 | Rev 6296 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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