Subversion Repositories Kolibri OS

Rev

Rev 4398 | Rev 4557 | 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.     const char *con_name;
  112.     const 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->vrefresh = drm_mode_vrefresh(mode);
  201.  
  202.         sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  203.  
  204.         DRM_DEBUG_KMS("new mode %d x %d pitch %d\n",
  205.                        fb->width, fb->height, fb->pitches[0]);
  206.     }
  207.     else
  208.         DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  209.                    fb->width, fb->height, crtc);
  210.  
  211.     return ret;
  212. }
  213.  
  214. static int count_connector_modes(struct drm_connector* connector)
  215. {
  216.     struct drm_display_mode  *mode;
  217.     int count = 0;
  218.  
  219.     list_for_each_entry(mode, &connector->modes, head)
  220.     {
  221.         count++;
  222.     };
  223.     return count;
  224. };
  225.  
  226. static struct drm_connector* get_def_connector(struct drm_device *dev)
  227. {
  228.     struct drm_connector  *connector;
  229.     struct drm_connector_helper_funcs *connector_funcs;
  230.  
  231.     struct drm_connector  *def_connector = NULL;
  232.  
  233.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  234.     {
  235.         struct drm_encoder  *encoder;
  236.         struct drm_crtc     *crtc;
  237.  
  238.         if( connector->status != connector_status_connected)
  239.             continue;
  240.  
  241.         connector_funcs = connector->helper_private;
  242.         encoder = connector_funcs->best_encoder(connector);
  243.         if( encoder == NULL)
  244.             continue;
  245.  
  246.         connector->encoder = encoder;
  247.  
  248.         crtc = encoder->crtc;
  249.  
  250.         DRM_DEBUG_KMS("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x",
  251.                    connector, connector->base.id,
  252.                    connector->status, connector->encoder,
  253.                    crtc);
  254.  
  255. //        if (crtc == NULL)
  256. //            continue;
  257.  
  258.         def_connector = connector;
  259.  
  260.         break;
  261.     };
  262.  
  263.     return def_connector;
  264. };
  265.  
  266. struct drm_connector *get_active_connector(struct drm_device *dev)
  267. {
  268.     struct drm_connector *tmp = NULL;
  269.     struct drm_connector_helper_funcs *connector_funcs;
  270.     struct drm_encoder      *encoder;
  271.  
  272.     list_for_each_entry(tmp, &dev->mode_config.connector_list, head)
  273.     {
  274.         if( tmp->status != connector_status_connected)
  275.             continue;
  276.  
  277.         connector_funcs = tmp->helper_private;
  278.         encoder = connector_funcs->best_encoder(tmp);
  279.         if( encoder == NULL)
  280.         {
  281.             DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
  282.                       tmp, tmp->base.id);
  283.             continue;
  284.         };
  285.  
  286.         tmp->encoder = encoder;
  287.  
  288.         DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %x CRTC %p ID:%d\n",
  289.                tmp, tmp->base.id, tmp->status, tmp->encoder,
  290.                tmp->encoder->crtc, tmp->encoder->crtc->base.id );
  291.  
  292.         return tmp;
  293.     };
  294.  
  295.     return NULL;
  296. }
  297.  
  298. struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder)
  299. {
  300.         struct drm_crtc *tmp_crtc;
  301.         int crtc_mask = 1;
  302.  
  303.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  304.         {
  305.             if (encoder->possible_crtcs & crtc_mask)
  306.             {
  307.             encoder->crtc = tmp_crtc;
  308.             dbgprintf("CRTC %p\n", tmp_crtc);
  309.             return tmp_crtc;
  310.             };
  311.             crtc_mask <<= 1;
  312.         };
  313.     return NULL;
  314. };
  315.  
  316. int get_boot_mode(struct drm_connector *connector, videomode_t *usermode)
  317. {
  318.     struct drm_display_mode *mode;
  319.  
  320.     list_for_each_entry(mode, &connector->modes, head)
  321.     {
  322.         DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n",
  323.                 drm_mode_width(mode), drm_mode_height(mode),
  324.                 drm_mode_vrefresh(mode));
  325.  
  326.         if( os_display->width  == drm_mode_width(mode)  &&
  327.             os_display->height == drm_mode_height(mode) &&
  328.             drm_mode_vrefresh(mode) == 60)
  329.         {
  330.             usermode->width  = os_display->width;
  331.             usermode->height = os_display->height;
  332.             usermode->freq   = 60;
  333.             return 1;
  334.         }
  335.     }
  336.     return 0;
  337. }
  338.  
  339. int init_display_kms(struct drm_device *dev, videomode_t *usermode)
  340. {
  341.     struct drm_connector    *connector;
  342.     struct drm_connector_helper_funcs *connector_funcs;
  343.     struct drm_encoder      *encoder;
  344.     struct drm_crtc         *crtc;
  345.     struct drm_framebuffer  *fb;
  346.  
  347.     cursor_t  *cursor;
  348.     u32_t      ifl;
  349.     int        err;
  350.  
  351.     mutex_lock(&dev->mode_config.mutex);
  352.  
  353.     connector = get_active_connector(dev) ;
  354.     if(connector == NULL)
  355.     {
  356.         DRM_DEBUG_KMS("No active connectors!\n");
  357.         mutex_unlock(&dev->mode_config.mutex);
  358.         return -1;
  359.     };
  360.  
  361.     encoder = connector->encoder;
  362.     crtc = encoder->crtc;
  363.  
  364.     if(crtc == NULL)
  365.         crtc = get_possible_crtc(dev, encoder);
  366.  
  367.     if(crtc == NULL)
  368.     {
  369.         DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
  370.         mutex_unlock(&dev->mode_config.mutex);
  371.         return -1;
  372.     };
  373.  
  374.     DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id);
  375.  
  376.     os_display = GetDisplay();
  377.     os_display->ddev = dev;
  378.     os_display->connector = connector;
  379.     os_display->crtc = crtc;
  380.  
  381.     os_display->supported_modes = count_connector_modes(connector);
  382.  
  383.  
  384.     ifl = safe_cli();
  385.     {
  386.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  387.  
  388.         list_for_each_entry(cursor, &os_display->cursors, list)
  389.         {
  390.             init_cursor(cursor);
  391.         };
  392.  
  393.         os_display->restore_cursor(0,0);
  394.         os_display->init_cursor    = init_cursor;
  395.         os_display->select_cursor  = select_cursor_kms;
  396.         os_display->show_cursor    = NULL;
  397.         os_display->move_cursor    = move_cursor_kms;
  398.         os_display->restore_cursor = restore_cursor;
  399.         os_display->disable_mouse  = disable_mouse;
  400.  
  401.         intel_crtc->cursor_x = os_display->width/2;
  402.         intel_crtc->cursor_y = os_display->height/2;
  403.  
  404.         select_cursor_kms(os_display->cursor);
  405.     };
  406.     safe_sti(ifl);
  407.  
  408.     if( (usermode->width == 0) ||
  409.         (usermode->height == 0))
  410.     {
  411.         if( !get_boot_mode(connector, usermode))
  412.         {
  413.         struct drm_display_mode *mode;
  414.  
  415.             mode = list_entry(connector->modes.next, typeof(*mode), head);
  416.             usermode->width  = drm_mode_width(mode);
  417.             usermode->height = drm_mode_height(mode);
  418.             usermode->freq   = drm_mode_vrefresh(mode);
  419.         };
  420.     };
  421.  
  422.     mutex_unlock(&dev->mode_config.mutex);
  423.  
  424.     set_mode(dev, os_display->connector, usermode, false);
  425.  
  426. #ifdef __HWA__
  427.     err = init_bitmaps();
  428. #endif
  429.  
  430.     LEAVE();
  431.  
  432.     return 0;
  433. };
  434.  
  435.  
  436. int get_videomodes(videomode_t *mode, int *count)
  437. {
  438.     int err = -1;
  439.  
  440. //    dbgprintf("mode %x count %d\n", mode, *count);
  441.  
  442.     if( *count == 0 )
  443.     {
  444.         *count = os_display->supported_modes;
  445.         err = 0;
  446.     }
  447.     else if( mode != NULL )
  448.     {
  449.         struct drm_display_mode  *drmmode;
  450.         int i = 0;
  451.  
  452.         if( *count > os_display->supported_modes)
  453.             *count = os_display->supported_modes;
  454.  
  455.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  456.         {
  457.             if( i < *count)
  458.             {
  459.                 mode->width  = drm_mode_width(drmmode);
  460.                 mode->height = drm_mode_height(drmmode);
  461.                 mode->bpp    = 32;
  462.                 mode->freq   = drm_mode_vrefresh(drmmode);
  463.                 i++;
  464.                 mode++;
  465.             }
  466.             else break;
  467.         };
  468.         *count = i;
  469.         err = 0;
  470.     };
  471.     return err;
  472. };
  473.  
  474. int set_user_mode(videomode_t *mode)
  475. {
  476.     int err = -1;
  477.  
  478. //    dbgprintf("width %d height %d vrefresh %d\n",
  479. //               mode->width, mode->height, mode->freq);
  480.  
  481.     if( (mode->width  != 0)  &&
  482.         (mode->height != 0)  &&
  483.         (mode->freq   != 0 ) &&
  484.         ( (mode->width   != os_display->width)  ||
  485.           (mode->height  != os_display->height) ||
  486.           (mode->freq    != os_display->vrefresh) ) )
  487.     {
  488.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  489.             err = 0;
  490.     };
  491.  
  492.     return err;
  493. };
  494.  
  495. void i915_dpms(struct drm_device *dev, int mode)
  496. {
  497.     const struct drm_connector_funcs *f = os_display->connector->funcs;
  498.  
  499.     f->dpms(os_display->connector, mode);
  500. };
  501.  
  502. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  503. {
  504.     list_del(&cursor->list);
  505.  
  506.     i915_gem_object_unpin(cursor->cobj);
  507.  
  508.     mutex_lock(&main_device->struct_mutex);
  509.     drm_gem_object_unreference(&cursor->cobj->base);
  510.     mutex_unlock(&main_device->struct_mutex);
  511.  
  512.     __DestroyObject(cursor);
  513. };
  514.  
  515. int init_cursor(cursor_t *cursor)
  516. {
  517.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  518.     struct drm_i915_gem_object *obj;
  519.     uint32_t *bits;
  520.     uint32_t *src;
  521.     void     *mapped;
  522.  
  523.     int       i,j;
  524.     int       ret;
  525.  
  526.     if (dev_priv->info->cursor_needs_physical)
  527.     {
  528.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  529.         if (unlikely(bits == NULL))
  530.             return ENOMEM;
  531.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  532.     }
  533.     else
  534.     {
  535.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  536.         if (unlikely(obj == NULL))
  537.             return -ENOMEM;
  538.  
  539.         ret = i915_gem_obj_ggtt_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true);
  540.         if (ret) {
  541.             drm_gem_object_unreference(&obj->base);
  542.             return ret;
  543.         }
  544.  
  545.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  546.         if (ret)
  547.         {
  548.             i915_gem_object_unpin(obj);
  549.             drm_gem_object_unreference(&obj->base);
  550.             return ret;
  551.         }
  552. /* You don't need to worry about fragmentation issues.
  553.  * GTT space is continuous. I guarantee it.                           */
  554.  
  555.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  556.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  557.  
  558.         if (unlikely(bits == NULL))
  559.         {
  560.             i915_gem_object_unpin(obj);
  561.             drm_gem_object_unreference(&obj->base);
  562.             return -ENOMEM;
  563.         };
  564.         cursor->cobj = obj;
  565.     };
  566.  
  567.     src = cursor->data;
  568.  
  569.     for(i = 0; i < 32; i++)
  570.     {
  571.         for(j = 0; j < 32; j++)
  572.             *bits++ = *src++;
  573.         for(j = 32; j < CURSOR_WIDTH; j++)
  574.             *bits++ = 0;
  575.     }
  576.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  577.         *bits++ = 0;
  578.  
  579.     FreeKernelSpace(mapped);
  580.  
  581. // release old cursor
  582.  
  583.     KernelFree(cursor->data);
  584.  
  585.     cursor->data = bits;
  586.  
  587.     cursor->header.destroy = destroy_cursor;
  588.  
  589.     return 0;
  590. }
  591.  
  592.  
  593. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  594. {
  595.     struct drm_device *dev = crtc->dev;
  596.     struct drm_i915_private *dev_priv = dev->dev_private;
  597.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  598.     int pipe = intel_crtc->pipe;
  599.     bool visible = base != 0;
  600.  
  601.     if (intel_crtc->cursor_visible != visible) {
  602.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  603.         if (base) {
  604.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  605.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  606.             cntl |= pipe << 28; /* Connect to correct pipe */
  607.         } else {
  608.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  609.             cntl |= CURSOR_MODE_DISABLE;
  610.         }
  611.         I915_WRITE(CURCNTR(pipe), cntl);
  612.  
  613.         intel_crtc->cursor_visible = visible;
  614.     }
  615.     /* and commit changes on next vblank */
  616.     I915_WRITE(CURBASE(pipe), base);
  617. }
  618.  
  619. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  620. {
  621.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  622.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  623.     u32 base, pos;
  624.     bool visible;
  625.  
  626.     int pipe = intel_crtc->pipe;
  627.  
  628.     intel_crtc->cursor_x = x;
  629.     intel_crtc->cursor_y = y;
  630.  
  631.     x = x - cursor->hot_x;
  632.     y = y - cursor->hot_y;
  633.  
  634.  
  635.     pos = 0;
  636.  
  637.     base = intel_crtc->cursor_addr;
  638.     if (x >= os_display->width)
  639.         base = 0;
  640.  
  641.     if (y >= os_display->height)
  642.         base = 0;
  643.  
  644.     if (x < 0)
  645.     {
  646.         if (x + intel_crtc->cursor_width < 0)
  647.             base = 0;
  648.  
  649.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  650.         x = -x;
  651.     }
  652.     pos |= x << CURSOR_X_SHIFT;
  653.  
  654.     if (y < 0)
  655.     {
  656.         if (y + intel_crtc->cursor_height < 0)
  657.             base = 0;
  658.  
  659.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  660.         y = -y;
  661.     }
  662.     pos |= y << CURSOR_Y_SHIFT;
  663.  
  664.     visible = base != 0;
  665.     if (!visible && !intel_crtc->cursor_visible)
  666.         return;
  667.  
  668.     I915_WRITE(CURPOS(pipe), pos);
  669. //    if (IS_845G(dev) || IS_I865G(dev))
  670. //        i845_update_cursor(crtc, base);
  671. //    else
  672.         i9xx_update_cursor(os_display->crtc, base);
  673.  
  674. };
  675.  
  676.  
  677. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  678. {
  679.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  680.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  681.     cursor_t *old;
  682.  
  683.     old = os_display->cursor;
  684.     os_display->cursor = cursor;
  685.  
  686.     if (!dev_priv->info->cursor_needs_physical)
  687.        intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
  688.     else
  689.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  690.  
  691.     intel_crtc->cursor_width = 32;
  692.     intel_crtc->cursor_height = 32;
  693.  
  694.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  695.     return old;
  696. };
  697.  
  698. int i915_fbinfo(struct drm_i915_fb_info *fb)
  699. {
  700.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  701.     struct intel_crtc *crtc = to_intel_crtc(os_display->crtc);
  702.  
  703.     struct drm_i915_gem_object *obj = get_fb_obj();
  704.  
  705.     fb->name   = obj->base.name;
  706.     fb->width  = os_display->width;
  707.     fb->height = os_display->height;
  708.     fb->pitch  = obj->stride;
  709.     fb->tiling = obj->tiling_mode;
  710.     fb->crtc   = crtc->base.base.id;
  711.     fb->pipe   = crtc->pipe;
  712.  
  713.     return 0;
  714. }
  715.  
  716.  
  717. typedef struct
  718. {
  719.     int left;
  720.     int top;
  721.     int right;
  722.     int bottom;
  723. }rect_t;
  724.  
  725.  
  726. #define CURRENT_TASK             (0x80003000)
  727.  
  728. static u32_t get_display_map()
  729. {
  730.     u32_t   addr;
  731.  
  732.     addr = (u32_t)os_display;
  733.     addr+= sizeof(display_t);            /*  shoot me  */
  734.     return *(u32_t*)addr;
  735. }
  736.  
  737. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  738.  
  739. int i915_mask_update(struct drm_device *dev, void *data,
  740.             struct drm_file *file)
  741. {
  742.     struct drm_i915_mask *mask = data;
  743.     struct drm_gem_object *obj;
  744.     static unsigned int mask_seqno[256];
  745.     rect_t winrc;
  746.     u32    slot;
  747.     int    ret=0;
  748.  
  749.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  750.     if (obj == NULL)
  751.         return -ENOENT;
  752.  
  753.     if (!obj->filp) {
  754.         drm_gem_object_unreference_unlocked(obj);
  755.         return -EINVAL;
  756.     }
  757.  
  758.     GetWindowRect(&winrc);
  759.     {
  760. //        static warn_count;
  761.  
  762.         mask->width    = winrc.right - winrc.left + 1;
  763.         mask->height   = winrc.bottom - winrc.top + 1;
  764.         mask->bo_pitch = (mask->width+15) & ~15;
  765.  
  766. #if 0
  767.         if(warn_count < 1)
  768.         {
  769.             printf("left %d top %d right %d bottom %d\n",
  770.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  771.             printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
  772.             warn_count++;
  773.         };
  774. #endif
  775.  
  776.      };
  777.  
  778.  
  779.     slot = *((u8*)CURRENT_TASK);
  780.  
  781.     if( mask_seqno[slot] != os_display->mask_seqno)
  782.     {
  783.         u8* src_offset;
  784.         u8* dst_offset;
  785.         u32 ifl;
  786.  
  787.         ret = i915_mutex_lock_interruptible(dev);
  788.         if (ret)
  789.             goto err1;
  790.  
  791.         ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  792.         if(ret != 0 )
  793.         {
  794.             dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__);
  795.             goto err2;
  796.         };
  797.  
  798. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  799.  
  800. //        slot = 0x01;
  801.  
  802.  
  803.         src_offset = (u8*)( winrc.top*os_display->width + winrc.left);
  804.         src_offset+= get_display_map();
  805.         dst_offset = (u8*)mask->bo_map;
  806.  
  807.         u32_t tmp_h = mask->height;
  808.  
  809.         ifl = safe_cli();
  810.         {
  811.             mask_seqno[slot] = os_display->mask_seqno;
  812.  
  813.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  814.  
  815.             __asm__ __volatile__ (
  816.                 "movd       %[slot],   %%xmm6    \n"
  817.             "punpckldq  %%xmm6, %%xmm6            \n"
  818.             "punpcklqdq %%xmm6, %%xmm6            \n"
  819.             :: [slot]  "m" (slot)
  820.             :"xmm6");
  821.  
  822.             while( tmp_h--)
  823.             {
  824.                 int tmp_w = mask->width;
  825.  
  826.                 u8* tmp_src = src_offset;
  827.                 u8* tmp_dst = dst_offset;
  828.  
  829.                 src_offset+= os_display->width;
  830.                 dst_offset+= mask->bo_pitch;
  831.  
  832.                 while(tmp_w >= 64)
  833.                 {
  834.                     __asm__ __volatile__ (
  835.                     "movdqu     (%0),   %%xmm0            \n"
  836.                     "movdqu   16(%0),   %%xmm1            \n"
  837.                     "movdqu   32(%0),   %%xmm2            \n"
  838.                     "movdqu   48(%0),   %%xmm3            \n"
  839.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  840.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  841.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  842.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  843.                     "movdqa     %%xmm0,   (%%edi)         \n"
  844.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  845.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  846.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  847.  
  848.                     :: "r" (tmp_src), "D" (tmp_dst)
  849.                     :"xmm0","xmm1","xmm2","xmm3");
  850.                     tmp_w -= 64;
  851.                     tmp_src += 64;
  852.                     tmp_dst += 64;
  853.                 }
  854.  
  855.                 if( tmp_w >= 32 )
  856.                 {
  857.                     __asm__ __volatile__ (
  858.                     "movdqu     (%0),   %%xmm0            \n"
  859.                     "movdqu   16(%0),   %%xmm1            \n"
  860.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  861.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  862.                     "movdqa     %%xmm0,   (%%edi)         \n"
  863.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  864.  
  865.                     :: "r" (tmp_src), "D" (tmp_dst)
  866.                     :"xmm0","xmm1");
  867.                     tmp_w -= 32;
  868.                     tmp_src += 32;
  869.                     tmp_dst += 32;
  870.                 }
  871.  
  872.                 if( tmp_w >= 16 )
  873.                 {
  874.                     __asm__ __volatile__ (
  875.                     "movdqu     (%0),   %%xmm0            \n"
  876.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  877.                     "movdqa     %%xmm0,   (%%edi)         \n"
  878.                     :: "r" (tmp_src), "D" (tmp_dst)
  879.                     :"xmm0");
  880.                     tmp_w -= 16;
  881.                     tmp_src += 16;
  882.                     tmp_dst += 16;
  883.                 }
  884.  
  885.                 if( tmp_w >= 8 )
  886.                 {
  887.                     __asm__ __volatile__ (
  888.                     "movq       (%0),   %%xmm0            \n"
  889.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  890.                     "movq       %%xmm0,   (%%edi)         \n"
  891.                     :: "r" (tmp_src), "D" (tmp_dst)
  892.                     :"xmm0");
  893.                     tmp_w -= 8;
  894.                     tmp_src += 8;
  895.                     tmp_dst += 8;
  896.                 }
  897.                 if( tmp_w >= 4 )
  898.                 {
  899.                     __asm__ __volatile__ (
  900.                     "movd       (%0),   %%xmm0            \n"
  901.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  902.                     "movd       %%xmm0,   (%%edi)         \n"
  903.                     :: "r" (tmp_src), "D" (tmp_dst)
  904.                     :"xmm0");
  905.                     tmp_w -= 4;
  906.                     tmp_src += 4;
  907.                     tmp_dst += 4;
  908.                 }
  909.                 while(tmp_w--)
  910.                     *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
  911.             };
  912.         };
  913.         safe_sti(ifl);
  914.  
  915.         ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
  916.     }
  917.  
  918. err2:
  919.     mutex_unlock(&dev->struct_mutex);
  920. err1:
  921.     drm_gem_object_unreference(obj);
  922.  
  923.     return ret;
  924. }
  925.  
  926. int i915_mask_update_ex(struct drm_device *dev, void *data,
  927.             struct drm_file *file)
  928. {
  929.     struct drm_i915_mask_update *mask = data;
  930.     struct drm_gem_object *obj;
  931.     static unsigned int mask_seqno[256];
  932.     static warn_count;
  933.  
  934.     rect_t win;
  935.     u32    winw,winh;
  936.     u32    ml,mt,mr,mb;
  937.     u32    slot;
  938.     int    ret = 0;
  939.     slot = *((u8*)CURRENT_TASK);
  940.  
  941.     if( mask_seqno[slot] == os_display->mask_seqno)
  942.         return 0;
  943.  
  944.     GetWindowRect(&win);
  945.     win.right+= 1;
  946.     win.bottom+=  1;
  947.  
  948.     winw = win.right - win.left;
  949.     winh = win.bottom - win.top;
  950.  
  951.     if(mask->dx >= winw ||
  952.        mask->dy >= winh)
  953.        return 1;
  954.  
  955.     ml = win.left + mask->dx;
  956.     mt = win.top  + mask->dy;
  957.     mr = ml + mask->width;
  958.     mb = mt + mask->height;
  959.  
  960.     if( ml >= win.right || mt >= win.bottom ||
  961.         mr < win.left   || mb < win.top )
  962.         return 1;
  963.  
  964.     if( mr > win.right )
  965.         mr = win.right;
  966.  
  967.     if( mb > win.bottom )
  968.         mb = win.bottom;
  969.  
  970.     mask->width  = mr - ml;
  971.     mask->height = mb - mt;
  972.  
  973.     if( mask->width == 0 ||
  974.         mask->height== 0 )
  975.         return 1;
  976.  
  977.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  978.     if (obj == NULL)
  979.         return -ENOENT;
  980.  
  981.     if (!obj->filp) {
  982.         drm_gem_object_unreference_unlocked(obj);
  983.         return -EINVAL;
  984.     }
  985.  
  986. #if 1
  987.     if(warn_count < 1000)
  988.     {
  989.         printf("left %d top %d right %d bottom %d\n",
  990.                 ml, mt, mr, mb);
  991.         warn_count++;
  992.     };
  993. #endif
  994.  
  995.  
  996. #if 1
  997.  
  998.     {
  999.         u8* src_offset;
  1000.         u8* dst_offset;
  1001.         u32 ifl;
  1002.  
  1003.         ret = i915_mutex_lock_interruptible(dev);
  1004.         if (ret)
  1005.             goto err1;
  1006.  
  1007.         i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  1008.  
  1009.         src_offset = (u8*)( mt*os_display->width + ml);
  1010.         src_offset+= get_display_map();
  1011.         dst_offset = (u8*)mask->bo_map;
  1012.  
  1013.         u32_t tmp_h = mask->height;
  1014.  
  1015.         ifl = safe_cli();
  1016.         {
  1017.             mask_seqno[slot] = os_display->mask_seqno;
  1018.  
  1019.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  1020.  
  1021.             __asm__ __volatile__ (
  1022.             "movd       %[slot],   %%xmm6         \n"
  1023.             "punpckldq  %%xmm6, %%xmm6            \n"
  1024.             "punpcklqdq %%xmm6, %%xmm6            \n"
  1025.             :: [slot]  "m" (slot)
  1026.             :"xmm6");
  1027.  
  1028.             while( tmp_h--)
  1029.             {
  1030.                 int tmp_w = mask->width;
  1031.  
  1032.                 u8* tmp_src = src_offset;
  1033.                 u8* tmp_dst = dst_offset;
  1034.  
  1035.                 src_offset+= os_display->width;
  1036.                 dst_offset+= mask->bo_pitch;
  1037.  
  1038.                 while(tmp_w >= 64)
  1039.                 {
  1040.                     __asm__ __volatile__ (
  1041.                     "movdqu     (%0),   %%xmm0            \n"
  1042.                     "movdqu   16(%0),   %%xmm1            \n"
  1043.                     "movdqu   32(%0),   %%xmm2            \n"
  1044.                     "movdqu   48(%0),   %%xmm3            \n"
  1045.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1046.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  1047.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  1048.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  1049.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1050.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  1051.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  1052.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  1053.  
  1054.                     :: "r" (tmp_src), "D" (tmp_dst)
  1055.                     :"xmm0","xmm1","xmm2","xmm3");
  1056.                     tmp_w -= 64;
  1057.                     tmp_src += 64;
  1058.                     tmp_dst += 64;
  1059.                 }
  1060.  
  1061.                 if( tmp_w >= 32 )
  1062.                 {
  1063.                     __asm__ __volatile__ (
  1064.                     "movdqu     (%0),   %%xmm0            \n"
  1065.                     "movdqu   16(%0),   %%xmm1            \n"
  1066.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1067.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  1068.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1069.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  1070.  
  1071.                     :: "r" (tmp_src), "D" (tmp_dst)
  1072.                     :"xmm0","xmm1");
  1073.                     tmp_w -= 32;
  1074.                     tmp_src += 32;
  1075.                     tmp_dst += 32;
  1076.                 }
  1077.  
  1078.                 if( tmp_w >= 16 )
  1079.                 {
  1080.                     __asm__ __volatile__ (
  1081.                     "movdqu     (%0),   %%xmm0            \n"
  1082.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1083.                     "movdqa     %%xmm0,   (%%edi)         \n"
  1084.                     :: "r" (tmp_src), "D" (tmp_dst)
  1085.                     :"xmm0");
  1086.                     tmp_w -= 16;
  1087.                     tmp_src += 16;
  1088.                     tmp_dst += 16;
  1089.                 }
  1090.  
  1091.                 if( tmp_w >= 8 )
  1092.                 {
  1093.                     __asm__ __volatile__ (
  1094.                     "movq       (%0),   %%xmm0            \n"
  1095.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1096.                     "movq       %%xmm0,   (%%edi)         \n"
  1097.                     :: "r" (tmp_src), "D" (tmp_dst)
  1098.                     :"xmm0");
  1099.                     tmp_w -= 8;
  1100.                     tmp_src += 8;
  1101.                     tmp_dst += 8;
  1102.                 }
  1103.                 if( tmp_w >= 4 )
  1104.         {
  1105.                     __asm__ __volatile__ (
  1106.                     "movd       (%0),   %%xmm0            \n"
  1107.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  1108.                     "movd       %%xmm0,   (%%edi)         \n"
  1109.                     :: "r" (tmp_src), "D" (tmp_dst)
  1110.                     :"xmm0");
  1111.                     tmp_w -= 4;
  1112.                     tmp_src += 4;
  1113.                     tmp_dst += 4;
  1114.                 }
  1115.                 while(tmp_w--)
  1116.                     *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
  1117.             };
  1118.         };
  1119.         safe_sti(ifl);
  1120.  
  1121.         i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
  1122.     }
  1123. #endif
  1124.  
  1125. err2:
  1126.     mutex_unlock(&dev->struct_mutex);
  1127. err1:
  1128.     drm_gem_object_unreference(obj);
  1129.  
  1130.     return ret;
  1131. }
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143. #define NSEC_PER_SEC    1000000000L
  1144.  
  1145. void getrawmonotonic(struct timespec *ts)
  1146. {
  1147.     u32 tmp = GetTimerTicks();
  1148.  
  1149.     ts->tv_sec  = tmp/100;
  1150.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  1151. }
  1152.  
  1153. void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
  1154. {
  1155.     while (nsec >= NSEC_PER_SEC) {
  1156.         /*
  1157.          * The following asm() prevents the compiler from
  1158.          * optimising this loop into a modulo operation. See
  1159.          * also __iter_div_u64_rem() in include/linux/time.h
  1160.          */
  1161.         asm("" : "+rm"(nsec));
  1162.         nsec -= NSEC_PER_SEC;
  1163.         ++sec;
  1164.     }
  1165.     while (nsec < 0) {
  1166.         asm("" : "+rm"(nsec));
  1167.         nsec += NSEC_PER_SEC;
  1168.         --sec;
  1169.     }
  1170.     ts->tv_sec = sec;
  1171.     ts->tv_nsec = nsec;
  1172. }
  1173.  
  1174. void
  1175. prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
  1176. {
  1177.     unsigned long flags;
  1178.  
  1179. //    wait->flags &= ~WQ_FLAG_EXCLUSIVE;
  1180.     spin_lock_irqsave(&q->lock, flags);
  1181.     if (list_empty(&wait->task_list))
  1182.             __add_wait_queue(q, wait);
  1183.     spin_unlock_irqrestore(&q->lock, flags);
  1184. }
  1185.  
  1186. /**
  1187.  * finish_wait - clean up after waiting in a queue
  1188.  * @q: waitqueue waited on
  1189.  * @wait: wait descriptor
  1190.  *
  1191.  * Sets current thread back to running state and removes
  1192.  * the wait descriptor from the given waitqueue if still
  1193.  * queued.
  1194.  */
  1195. void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
  1196. {
  1197.     unsigned long flags;
  1198.  
  1199. //    __set_current_state(TASK_RUNNING);
  1200.     /*
  1201.      * We can check for list emptiness outside the lock
  1202.      * IFF:
  1203.      *  - we use the "careful" check that verifies both
  1204.      *    the next and prev pointers, so that there cannot
  1205.      *    be any half-pending updates in progress on other
  1206.      *    CPU's that we haven't seen yet (and that might
  1207.      *    still change the stack area.
  1208.      * and
  1209.      *  - all other users take the lock (ie we can only
  1210.      *    have _one_ other CPU that looks at or modifies
  1211.      *    the list).
  1212.      */
  1213.     if (!list_empty_careful(&wait->task_list)) {
  1214.             spin_lock_irqsave(&q->lock, flags);
  1215.             list_del_init(&wait->task_list);
  1216.             spin_unlock_irqrestore(&q->lock, flags);
  1217.     }
  1218.  
  1219.     DestroyEvent(wait->evnt);
  1220. }
  1221.  
  1222. int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
  1223. {
  1224.     list_del_init(&wait->task_list);
  1225.     return 1;
  1226. }
  1227.  
  1228. unsigned int hweight16(unsigned int w)
  1229. {
  1230.     unsigned int res = w - ((w >> 1) & 0x5555);
  1231.     res = (res & 0x3333) + ((res >> 2) & 0x3333);
  1232.     res = (res + (res >> 4)) & 0x0F0F;
  1233.     return (res + (res >> 8)) & 0x00FF;
  1234. }
  1235.  
  1236.  
  1237. unsigned long round_jiffies_up_relative(unsigned long j)
  1238. {
  1239.     unsigned long j0 = GetTimerTicks();
  1240.  
  1241.         /* Use j0 because jiffies might change while we run */
  1242.     return round_jiffies_common(j + j0, true) - j0;
  1243. }
  1244.  
  1245.  
  1246.