Subversion Repositories Kolibri OS

Rev

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