Subversion Repositories Kolibri OS

Rev

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