Subversion Repositories Kolibri OS

Rev

Rev 3266 | Rev 3290 | 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 "hmm.h"
  19. #include "bitmap.h"
  20.  
  21. extern struct drm_device *main_device;
  22.  
  23.  
  24. typedef struct
  25. {
  26.     kobj_t     header;
  27.  
  28.     uint32_t  *data;
  29.     uint32_t   hot_x;
  30.     uint32_t   hot_y;
  31.  
  32.     struct list_head   list;
  33.     struct drm_i915_gem_object  *cobj;
  34. }cursor_t;
  35.  
  36. #define CURSOR_WIDTH 64
  37. #define CURSOR_HEIGHT 64
  38.  
  39.  
  40. struct tag_display
  41. {
  42.     int  x;
  43.     int  y;
  44.     int  width;
  45.     int  height;
  46.     int  bpp;
  47.     int  vrefresh;
  48.     int  pitch;
  49.     int  lfb;
  50.  
  51.     int  supported_modes;
  52.     struct drm_device    *ddev;
  53.     struct drm_connector *connector;
  54.     struct drm_crtc      *crtc;
  55.  
  56.     struct list_head   cursors;
  57.  
  58.     cursor_t   *cursor;
  59.     int       (*init_cursor)(cursor_t*);
  60.     cursor_t* (__stdcall *select_cursor)(cursor_t*);
  61.     void      (*show_cursor)(int show);
  62.     void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
  63.     void      (__stdcall *restore_cursor)(int x, int y);
  64.     void      (*disable_mouse)(void);
  65.     u32  mask_seqno;
  66.     u32  check_mouse;
  67.     u32  check_m_pixel;
  68.  
  69. };
  70.  
  71.  
  72. static display_t *os_display;
  73.  
  74. u32_t cmd_buffer;
  75. u32_t cmd_offset;
  76.  
  77. void init_render();
  78. int  sna_init();
  79.  
  80. int init_cursor(cursor_t *cursor);
  81. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  82. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  83.  
  84. void __stdcall restore_cursor(int x, int y)
  85. {};
  86.  
  87. void disable_mouse(void)
  88. {};
  89.  
  90. static char *manufacturer_name(unsigned char *x)
  91. {
  92.     static char name[4];
  93.  
  94.     name[0] = ((x[0] & 0x7C) >> 2) + '@';
  95.     name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
  96.     name[2] = (x[1] & 0x1F) + '@';
  97.     name[3] = 0;
  98.  
  99.     return name;
  100. }
  101.  
  102. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  103.               videomode_t *reqmode, bool strict)
  104. {
  105.     drm_i915_private_t      *dev_priv   = dev->dev_private;
  106.     struct drm_fb_helper    *fb_helper  = &dev_priv->fbdev->helper;
  107.  
  108.     struct drm_mode_config  *config     = &dev->mode_config;
  109.     struct drm_display_mode *mode       = NULL, *tmpmode;
  110.     struct drm_framebuffer  *fb         = NULL;
  111.     struct drm_crtc         *crtc;
  112.     struct drm_encoder      *encoder;
  113.     struct drm_mode_set     set;
  114.     char *con_name;
  115.     char *enc_name;
  116.     unsigned hdisplay, vdisplay;
  117.     int ret;
  118.  
  119.     mutex_lock(&dev->mode_config.mutex);
  120.  
  121.     list_for_each_entry(tmpmode, &connector->modes, head)
  122.     {
  123.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  124.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  125.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  126.         {
  127.             mode = tmpmode;
  128.             goto do_set;
  129.         }
  130.     };
  131.  
  132.     if( (mode == NULL) && (strict == false) )
  133.     {
  134.         list_for_each_entry(tmpmode, &connector->modes, head)
  135.         {
  136.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  137.                 (drm_mode_height(tmpmode) == reqmode->height) )
  138.             {
  139.                 mode = tmpmode;
  140.                 goto do_set;
  141.             }
  142.         };
  143.     };
  144.  
  145.     DRM_ERROR("%s failed\n", __FUNCTION__);
  146.  
  147.     return -1;
  148.  
  149. do_set:
  150.  
  151.  
  152.     encoder = connector->encoder;
  153.     crtc = encoder->crtc;
  154.  
  155.     con_name = drm_get_connector_name(connector);
  156.     enc_name = drm_get_encoder_name(encoder);
  157.  
  158.     DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n",
  159.               reqmode->width, reqmode->height, crtc->base.id,
  160.               con_name, enc_name);
  161.  
  162.     drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  163.  
  164.     hdisplay = mode->hdisplay;
  165.     vdisplay = mode->vdisplay;
  166.  
  167.     if (crtc->invert_dimensions)
  168.         swap(hdisplay, vdisplay);
  169.  
  170.     fb = fb_helper->fb;
  171.  
  172.     fb->width  = reqmode->width;
  173.     fb->height = reqmode->height;
  174.     fb->pitches[0]  = ALIGN(reqmode->width * 4, 64);
  175.     fb->pitches[1]  = ALIGN(reqmode->width * 4, 64);
  176.     fb->pitches[2]  = ALIGN(reqmode->width * 4, 64);
  177.     fb->pitches[3]  = ALIGN(reqmode->width * 4, 64);
  178.  
  179.     fb->bits_per_pixel = 32;
  180.     fb->depth = 24;
  181.  
  182.     crtc->fb = fb;
  183.     crtc->enabled = true;
  184.     os_display->crtc = crtc;
  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)
  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.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  282.     {
  283.         if( connector->status != connector_status_connected)
  284.             continue;
  285.  
  286.         connector_funcs = connector->helper_private;
  287.         encoder = connector_funcs->best_encoder(connector);
  288.         if( encoder == NULL)
  289.         {
  290.             DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
  291.                       connector, connector->base.id);
  292.             continue;
  293.         }
  294.         connector->encoder = encoder;
  295.         crtc = encoder->crtc;
  296.  
  297.         DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
  298.                connector, connector->base.id,
  299.                connector->status, connector->encoder,
  300.                crtc, crtc->base.id );
  301.  
  302.         break;
  303.     };
  304.  
  305.     if(connector == NULL)
  306.     {
  307.         DRM_ERROR("No active connectors!\n");
  308.         return -1;
  309.     };
  310.  
  311.     if(crtc == NULL)
  312.     {
  313.         struct drm_crtc *tmp_crtc;
  314.         int crtc_mask = 1;
  315.  
  316.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  317.         {
  318.             if (encoder->possible_crtcs & crtc_mask)
  319.             {
  320.                 crtc = tmp_crtc;
  321.                 encoder->crtc = crtc;
  322.                 break;
  323.             };
  324.             crtc_mask <<= 1;
  325.         };
  326.     };
  327.  
  328.     if(crtc == NULL)
  329.     {
  330.         DRM_ERROR("No CRTC for encoder %d\n", encoder->base.id);
  331.         return -1;
  332.     };
  333.  
  334.  
  335.     DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id);
  336.  
  337.     os_display = GetDisplay();
  338.     os_display->ddev = dev;
  339.     os_display->connector = connector;
  340.     os_display->crtc = crtc;
  341.  
  342.     os_display->supported_modes = count_connector_modes(connector);
  343.  
  344.  
  345.     ifl = safe_cli();
  346.     {
  347.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  348.  
  349.         list_for_each_entry(cursor, &os_display->cursors, list)
  350.         {
  351.             init_cursor(cursor);
  352.         };
  353.  
  354.         os_display->restore_cursor(0,0);
  355.         os_display->init_cursor    = init_cursor;
  356.         os_display->select_cursor  = select_cursor_kms;
  357.         os_display->show_cursor    = NULL;
  358.         os_display->move_cursor    = move_cursor_kms;
  359.         os_display->restore_cursor = restore_cursor;
  360.         os_display->disable_mouse  = disable_mouse;
  361.  
  362.         intel_crtc->cursor_x = os_display->width/2;
  363.         intel_crtc->cursor_y = os_display->height/2;
  364.  
  365.         select_cursor_kms(os_display->cursor);
  366.     };
  367.     safe_sti(ifl);
  368.  
  369.     main_device = dev;
  370.  
  371. #ifdef __HWA__
  372.     err = init_bitmaps();
  373. #endif
  374.  
  375.     return 0;
  376. };
  377.  
  378.  
  379. int get_videomodes(videomode_t *mode, int *count)
  380. {
  381.     int err = -1;
  382.  
  383. //    dbgprintf("mode %x count %d\n", mode, *count);
  384.  
  385.     if( *count == 0 )
  386.     {
  387.         *count = os_display->supported_modes;
  388.         err = 0;
  389.     }
  390.     else if( mode != NULL )
  391.     {
  392.         struct drm_display_mode  *drmmode;
  393.         int i = 0;
  394.  
  395.         if( *count > os_display->supported_modes)
  396.             *count = os_display->supported_modes;
  397.  
  398.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  399.         {
  400.             if( i < *count)
  401.             {
  402.                 mode->width  = drm_mode_width(drmmode);
  403.                 mode->height = drm_mode_height(drmmode);
  404.                 mode->bpp    = 32;
  405.                 mode->freq   = drm_mode_vrefresh(drmmode);
  406.                 i++;
  407.                 mode++;
  408.             }
  409.             else break;
  410.         };
  411.         *count = i;
  412.         err = 0;
  413.     };
  414.     return err;
  415. };
  416.  
  417. int set_user_mode(videomode_t *mode)
  418. {
  419.     int err = -1;
  420.  
  421. //    dbgprintf("width %d height %d vrefresh %d\n",
  422. //               mode->width, mode->height, mode->freq);
  423.  
  424.     if( (mode->width  != 0)  &&
  425.         (mode->height != 0)  &&
  426.         (mode->freq   != 0 ) &&
  427.         ( (mode->width   != os_display->width)  ||
  428.           (mode->height  != os_display->height) ||
  429.           (mode->freq    != os_display->vrefresh) ) )
  430.     {
  431.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  432.             err = 0;
  433.     };
  434.  
  435.     return err;
  436. };
  437.  
  438. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  439. {
  440.     list_del(&cursor->list);
  441.  
  442.     i915_gem_object_unpin(cursor->cobj);
  443.  
  444.     mutex_lock(&main_device->struct_mutex);
  445.     drm_gem_object_unreference(&cursor->cobj->base);
  446.     mutex_unlock(&main_device->struct_mutex);
  447.  
  448.     __DestroyObject(cursor);
  449. };
  450.  
  451. int init_cursor(cursor_t *cursor)
  452. {
  453.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  454.     struct drm_i915_gem_object *obj;
  455.     uint32_t *bits;
  456.     uint32_t *src;
  457.     void     *mapped;
  458.  
  459.     int       i,j;
  460.     int       ret;
  461.  
  462.     if (dev_priv->info->cursor_needs_physical)
  463.     {
  464.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  465.         if (unlikely(bits == NULL))
  466.             return ENOMEM;
  467.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  468.     }
  469.     else
  470.     {
  471.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  472.         if (unlikely(obj == NULL))
  473.             return -ENOMEM;
  474.  
  475.         ret = i915_gem_object_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true);
  476.         if (ret) {
  477.             drm_gem_object_unreference(&obj->base);
  478.             return ret;
  479.         }
  480.  
  481. /* You don't need to worry about fragmentation issues.
  482.  * GTT space is continuous. I guarantee it.                           */
  483.  
  484.         mapped = bits = (u32*)MapIoMem(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset,
  485.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  486.  
  487.         if (unlikely(bits == NULL))
  488.         {
  489.             i915_gem_object_unpin(obj);
  490.             drm_gem_object_unreference(&obj->base);
  491.             return -ENOMEM;
  492.         };
  493.         cursor->cobj = obj;
  494.     };
  495.  
  496.     src = cursor->data;
  497.  
  498.     for(i = 0; i < 32; i++)
  499.     {
  500.         for(j = 0; j < 32; j++)
  501.             *bits++ = *src++;
  502.         for(j = 32; j < CURSOR_WIDTH; j++)
  503.             *bits++ = 0;
  504.     }
  505.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  506.         *bits++ = 0;
  507.  
  508.     FreeKernelSpace(mapped);
  509.  
  510. // release old cursor
  511.  
  512.     KernelFree(cursor->data);
  513.  
  514.     cursor->data = bits;
  515.  
  516.     cursor->header.destroy = destroy_cursor;
  517.  
  518.     return 0;
  519. }
  520.  
  521.  
  522. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  523. {
  524.     struct drm_device *dev = crtc->dev;
  525.     struct drm_i915_private *dev_priv = dev->dev_private;
  526.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  527.     int pipe = intel_crtc->pipe;
  528.     bool visible = base != 0;
  529.  
  530.     if (intel_crtc->cursor_visible != visible) {
  531.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  532.         if (base) {
  533.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  534.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  535.             cntl |= pipe << 28; /* Connect to correct pipe */
  536.         } else {
  537.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  538.             cntl |= CURSOR_MODE_DISABLE;
  539.         }
  540.         I915_WRITE(CURCNTR(pipe), cntl);
  541.  
  542.         intel_crtc->cursor_visible = visible;
  543.     }
  544.     /* and commit changes on next vblank */
  545.     I915_WRITE(CURBASE(pipe), base);
  546. }
  547.  
  548. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  549. {
  550.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  551.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  552.     u32 base, pos;
  553.     bool visible;
  554.  
  555.     int pipe = intel_crtc->pipe;
  556.  
  557.     intel_crtc->cursor_x = x;
  558.     intel_crtc->cursor_y = y;
  559.  
  560.     x = x - cursor->hot_x;
  561.     y = y - cursor->hot_y;
  562.  
  563.  
  564.     pos = 0;
  565.  
  566.     base = intel_crtc->cursor_addr;
  567.     if (x >= os_display->width)
  568.         base = 0;
  569.  
  570.     if (y >= os_display->height)
  571.         base = 0;
  572.  
  573.     if (x < 0)
  574.     {
  575.         if (x + intel_crtc->cursor_width < 0)
  576.             base = 0;
  577.  
  578.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  579.         x = -x;
  580.     }
  581.     pos |= x << CURSOR_X_SHIFT;
  582.  
  583.     if (y < 0)
  584.     {
  585.         if (y + intel_crtc->cursor_height < 0)
  586.             base = 0;
  587.  
  588.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  589.         y = -y;
  590.     }
  591.     pos |= y << CURSOR_Y_SHIFT;
  592.  
  593.     visible = base != 0;
  594.     if (!visible && !intel_crtc->cursor_visible)
  595.         return;
  596.  
  597.     I915_WRITE(CURPOS(pipe), pos);
  598. //    if (IS_845G(dev) || IS_I865G(dev))
  599. //        i845_update_cursor(crtc, base);
  600. //    else
  601.         i9xx_update_cursor(os_display->crtc, base);
  602.  
  603. };
  604.  
  605.  
  606. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  607. {
  608.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  609.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  610.     cursor_t *old;
  611.  
  612.     old = os_display->cursor;
  613.     os_display->cursor = cursor;
  614.  
  615.     if (!dev_priv->info->cursor_needs_physical)
  616.        intel_crtc->cursor_addr = cursor->cobj->gtt_offset;
  617.     else
  618.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  619.  
  620.     intel_crtc->cursor_width = 32;
  621.     intel_crtc->cursor_height = 32;
  622.  
  623.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  624.     return old;
  625. };
  626.  
  627. struct sna_fb
  628. {
  629.     uint32_t  width;
  630.     uint32_t  height;
  631.     uint32_t  pitch;
  632.     uint32_t  tiling;
  633. };
  634.  
  635. int i915_fbinfo(struct sna_fb *fb)
  636. {
  637.     fb->width  = os_display->width;
  638.     fb->height = os_display->height;
  639.     fb->pitch  = os_display->pitch;
  640.     fb->tiling = 0;
  641.  
  642.     return 0;
  643. };
  644.  
  645. typedef struct
  646. {
  647.     int left;
  648.     int top;
  649.     int right;
  650.     int bottom;
  651. }rect_t;
  652.  
  653. struct drm_i915_mask {
  654.     __u32 handle;
  655.     __u32 bo_size;
  656.     __u32 bo_pitch;
  657.     __u32 bo_map;
  658. };
  659.  
  660. #define CURRENT_TASK             (0x80003000)
  661.  
  662. static u32_t get_display_map()
  663. {
  664.     u32_t   addr;
  665.  
  666.     addr = (u32_t)os_display;
  667.     addr+= sizeof(display_t);            /*  shoot me  */
  668.     return *(u32_t*)addr;
  669. }
  670.  
  671. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  672.  
  673. int i915_mask_update(struct drm_device *dev, void *data,
  674.             struct drm_file *file)
  675. {
  676.     struct drm_i915_mask *mask = data;
  677.     struct drm_gem_object *obj;
  678.     static unsigned int mask_seqno[256];
  679.     rect_t winrc;
  680.     u32    slot;
  681.     int    ret;
  682.  
  683.     obj = drm_gem_object_lookup(dev, file, mask->handle);
  684.     if (obj == NULL)
  685.         return -ENOENT;
  686.  
  687.     if (!obj->filp) {
  688.         drm_gem_object_unreference_unlocked(obj);
  689.         return -EINVAL;
  690.     }
  691.  
  692.     GetWindowRect(&winrc);
  693.     {
  694.         static warn_count;
  695.  
  696.         if(warn_count < 1)
  697.         {
  698.             printf("left %d top %d right %d bottom %d\n",
  699.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  700.             printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
  701.             warn_count++;
  702.         };
  703.     };
  704.  
  705.     slot = *((u8*)CURRENT_TASK);
  706.  
  707.     if( mask_seqno[slot] != os_display->mask_seqno)
  708.     {
  709.         u8* src_offset;
  710.         u8* dst_offset;
  711.         u32 ifl;
  712.  
  713.         ret = i915_mutex_lock_interruptible(dev);
  714.         if (ret)
  715.             return ret;
  716.  
  717.         ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
  718.         if(ret !=0 )
  719.         {
  720.             dbgprintf("%s fail\n", __FUNCTION__);
  721.             return ret;
  722.         };
  723.  
  724. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  725.  
  726. //        slot = 0x01;
  727.  
  728.  
  729.         src_offset = (u8*)( winrc.top*os_display->width + winrc.left);
  730.         src_offset+= get_display_map();
  731.         dst_offset = (u8*)mask->bo_map;
  732.  
  733.         u32_t tmp_h = winrc.bottom - winrc.top;
  734.  
  735.         ifl = safe_cli();
  736.         {
  737.             mask_seqno[slot] = os_display->mask_seqno;
  738.  
  739.             slot|= (slot<<8)|(slot<<16)|(slot<<24);
  740.  
  741.             __asm__ __volatile__ (
  742.                 "movd       %[slot],   %%xmm6    \n"
  743.             "punpckldq  %%xmm6, %%xmm6            \n"
  744.             "punpcklqdq %%xmm6, %%xmm6            \n"
  745.             :: [slot]  "m" (slot)
  746.             :"xmm6");
  747.  
  748.             while( tmp_h--)
  749.             {
  750.                 int tmp_w = mask->bo_pitch;
  751.  
  752.                 u8* tmp_src = src_offset;
  753.                 u8* tmp_dst = dst_offset;
  754.  
  755.                 src_offset+= os_display->width;
  756.                 dst_offset+= mask->bo_pitch;
  757.  
  758. //            while( tmp_w--)
  759. //            {
  760. //                *(tmp_src) = (*tmp_dst==slot)?0x1:0x00;
  761. //                tmp_src++;
  762. //                tmp_dst++;
  763. //            };
  764.                 while(tmp_w >= 64)
  765.                 {
  766.                     __asm__ __volatile__ (
  767.                     "movdqu     (%0),   %%xmm0            \n"
  768.                     "movdqu   16(%0),   %%xmm1            \n"
  769.                     "movdqu   32(%0),   %%xmm2            \n"
  770.                     "movdqu   48(%0),   %%xmm3            \n"
  771.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  772.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  773.                     "pcmpeqb    %%xmm6, %%xmm2            \n"
  774.                     "pcmpeqb    %%xmm6, %%xmm3            \n"
  775.                     "movdqa     %%xmm0,   (%%edi)         \n"
  776.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  777.                     "movdqa     %%xmm2, 32(%%edi)         \n"
  778.                     "movdqa     %%xmm3, 48(%%edi)         \n"
  779.  
  780.                     :: "r" (tmp_src), "D" (tmp_dst)
  781.                     :"xmm0","xmm1","xmm2","xmm3");
  782.                     tmp_w -= 64;
  783.                     tmp_src += 64;
  784.                     tmp_dst += 64;
  785.                 }
  786.  
  787.                 if( tmp_w >= 32 )
  788.                 {
  789.                     __asm__ __volatile__ (
  790.                     "movdqu     (%0),   %%xmm0            \n"
  791.                     "movdqu   16(%0),   %%xmm1            \n"
  792.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  793.                     "pcmpeqb    %%xmm6, %%xmm1            \n"
  794.                     "movdqa     %%xmm0,   (%%edi)         \n"
  795.                     "movdqa     %%xmm1, 16(%%edi)         \n"
  796.  
  797.                     :: "r" (tmp_src), "D" (tmp_dst)
  798.                     :"xmm0","xmm1");
  799.                     tmp_w -= 32;
  800.                     tmp_src += 32;
  801.                     tmp_dst += 32;
  802.                 }
  803.  
  804.                 while( tmp_w > 0 )
  805.                 {
  806.                     __asm__ __volatile__ (
  807.                     "movdqu     (%0),   %%xmm0            \n"
  808.                     "pcmpeqb    %%xmm6, %%xmm0            \n"
  809.                     "movdqa     %%xmm0,   (%%edi)         \n"
  810.                     :: "r" (tmp_src), "D" (tmp_dst)
  811.                     :"xmm0");
  812.                     tmp_w -= 16;
  813.                     tmp_src += 16;
  814.                     tmp_dst += 16;
  815.                 }
  816.             };
  817.         };
  818.         safe_sti(ifl);
  819.     }
  820.  
  821.     drm_gem_object_unreference(obj);
  822.  
  823.     mutex_unlock(&dev->struct_mutex);
  824.  
  825.     return 0;
  826. }
  827.  
  828.  
  829.  
  830. #ifdef __HWA__
  831.  
  832. extern struct hmm bm_mm;
  833.  
  834.  
  835. typedef struct
  836. {
  837.     int left;
  838.     int top;
  839.     int right;
  840.     int bottom;
  841. }rect_t;
  842.  
  843.  
  844. #include "clip.inc"
  845.  
  846. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  847.  
  848. #define CURRENT_TASK             (0x80003000)
  849.  
  850. static u32_t get_display_map()
  851. {
  852.     u32_t   addr;
  853.  
  854.     addr = (u32_t)os_display;
  855.     addr+= sizeof(display_t);            /*  shoot me  */
  856.     return *(u32_t*)addr;
  857. }
  858.  
  859. #define XY_COLOR_BLT                ((2<<29)|(0x50<<22)|(0x4))
  860. #define XY_SRC_COPY_BLT_CMD         ((2<<29)|(0x53<<22)|6)
  861. #define XY_SRC_COPY_CHROMA_CMD      ((2<<29)|(0x73<<22)|8)
  862. #define ROP_COPY_SRC                0xCC
  863. #define FORMAT8888                  3
  864.  
  865. #define BLT_WRITE_ALPHA             (1<<21)
  866. #define BLT_WRITE_RGB               (1<<20)
  867.  
  868.  
  869.  
  870. typedef int v4si __attribute__ ((vector_size (16)));
  871.  
  872.  
  873.  
  874. static void
  875. i915_gem_execbuffer_retire_commands(struct drm_device *dev,
  876.                     struct drm_file *file,
  877.                     struct intel_ring_buffer *ring)
  878. {
  879.     /* Unconditionally force add_request to emit a full flush. */
  880.     ring->gpu_caches_dirty = true;
  881.  
  882.     /* Add a breadcrumb for the completion of the batch buffer */
  883.     (void)i915_add_request(ring, file, NULL);
  884. }
  885.  
  886. int srv_blit_bitmap(u32 hbitmap, int  dst_x, int dst_y,
  887.                int src_x, int src_y, u32 w, u32 h)
  888. {
  889.     drm_i915_private_t *dev_priv = main_device->dev_private;
  890.     struct intel_ring_buffer *ring;
  891.     struct context *context;
  892.  
  893.     bitmap_t  *bitmap;
  894.     rect_t     winrc;
  895.     clip_t     dst_clip;
  896.     clip_t     src_clip;
  897.     u32_t      width;
  898.     u32_t      height;
  899.  
  900.     u32_t      br13, cmd, slot_mask, *b;
  901.     u32_t      offset;
  902.     u8         slot;
  903.     int        n=0;
  904.     int        ret;
  905.  
  906.     if(unlikely(hbitmap==0))
  907.         return -1;
  908.  
  909.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, hbitmap);
  910.  
  911.     if(unlikely(bitmap==NULL))
  912.         return -1;
  913.  
  914.     context = get_context(main_device);
  915.     if(unlikely(context == NULL))
  916.         return -1;
  917.  
  918.     GetWindowRect(&winrc);
  919.     {
  920.         static warn_count;
  921.  
  922.         if(warn_count < 1)
  923.         {
  924.             printf("left %d top %d right %d bottom %d\n",
  925.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  926.             printf("bitmap width %d height %d\n", w, h);
  927.             warn_count++;
  928.         };
  929.     };
  930.  
  931.  
  932.     dst_clip.xmin   = 0;
  933.     dst_clip.ymin   = 0;
  934.     dst_clip.xmax   = winrc.right-winrc.left;
  935.     dst_clip.ymax   = winrc.bottom -winrc.top;
  936.  
  937.     src_clip.xmin   = 0;
  938.     src_clip.ymin   = 0;
  939.     src_clip.xmax   = bitmap->width  - 1;
  940.     src_clip.ymax   = bitmap->height - 1;
  941.  
  942.     width  = w;
  943.     height = h;
  944.  
  945.     if( blit_clip(&dst_clip, &dst_x, &dst_y,
  946.                   &src_clip, &src_x, &src_y,
  947.                   &width, &height) )
  948.         return 0;
  949.  
  950.     dst_x+= winrc.left;
  951.     dst_y+= winrc.top;
  952.  
  953.     slot = *((u8*)CURRENT_TASK);
  954.  
  955.     slot_mask = (u32_t)slot<<24;
  956.  
  957.     {
  958. #if 0
  959.         static v4si write_mask = {0xFF000000, 0xFF000000,
  960.                                   0xFF000000, 0xFF000000};
  961.  
  962.         u8* src_offset;
  963.         u8* dst_offset;
  964.  
  965.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  966.         src_offset += (u32)bitmap->uaddr;
  967.  
  968.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  969.         dst_offset+= get_display_map();
  970.  
  971.         u32_t tmp_h = height;
  972.  
  973.         __asm__ __volatile__ (
  974.         "movdqa     %[write_mask],  %%xmm7    \n"
  975.         "movd       %[slot_mask],   %%xmm6    \n"
  976.         "punpckldq  %%xmm6, %%xmm6            \n"
  977.         "punpcklqdq %%xmm6, %%xmm6            \n"
  978.         :: [write_mask] "m" (write_mask),
  979.            [slot_mask]  "g" (slot_mask)
  980.         :"xmm7", "xmm6");
  981.  
  982.         while( tmp_h--)
  983.         {
  984.             u32_t tmp_w = width;
  985.  
  986.             u8* tmp_src = src_offset;
  987.             u8* tmp_dst = dst_offset;
  988.  
  989.             src_offset+= bitmap->pitch;
  990.             dst_offset+= os_display->width;
  991.  
  992.             while( tmp_w >= 8 )
  993.             {
  994.                 __asm__ __volatile__ (
  995.                 "movq       (%0),   %%xmm0            \n"
  996.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  997.                 "movdqa     %%xmm0, %%xmm1            \n"
  998.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  999.                 "punpckhwd  %%xmm1, %%xmm1            \n"
  1000.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1001.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  1002.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  1003.                 "addl       $16, %%edi                \n"
  1004.                 "maskmovdqu %%xmm7, %%xmm1            \n"
  1005.                 :: "r" (tmp_dst), "D" (tmp_src)
  1006.                 :"xmm0", "xmm1");
  1007.                 __asm__ __volatile__ ("":::"edi");
  1008.                 tmp_w -= 8;
  1009.                 tmp_src += 32;
  1010.                 tmp_dst += 8;
  1011.             };
  1012.  
  1013.             if( tmp_w >= 4 )
  1014.             {
  1015.                 __asm__ __volatile__ (
  1016.                 "movd       (%0),   %%xmm0            \n"
  1017.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  1018.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  1019.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1020.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  1021.                 :: "r" (tmp_dst), "D" (tmp_src)
  1022.                 :"xmm0");
  1023.                 tmp_w -= 4;
  1024.                 tmp_src += 16;
  1025.                 tmp_dst += 4;
  1026.             };
  1027.  
  1028.             while( tmp_w--)
  1029.             {
  1030.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  1031.                 tmp_src+=4;
  1032.                 tmp_dst++;
  1033.             };
  1034.         };
  1035. #else
  1036.         u8* src_offset;
  1037.         u8* dst_offset;
  1038.         u32 ifl;
  1039.  
  1040.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  1041.         src_offset += (u32)bitmap->uaddr;
  1042.  
  1043.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  1044.         dst_offset+= get_display_map();
  1045.  
  1046.         u32_t tmp_h = height;
  1047.  
  1048.       ifl = safe_cli();
  1049.         while( tmp_h--)
  1050.         {
  1051.             u32_t tmp_w = width;
  1052.  
  1053.             u8* tmp_src = src_offset;
  1054.             u8* tmp_dst = dst_offset;
  1055.  
  1056.             src_offset+= bitmap->pitch;
  1057.             dst_offset+= os_display->width;
  1058.  
  1059.             while( tmp_w--)
  1060.             {
  1061.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  1062.                 tmp_src+=4;
  1063.                 tmp_dst++;
  1064.             };
  1065.         };
  1066.       safe_sti(ifl);
  1067.     }
  1068. #endif
  1069.  
  1070.     {
  1071.         static warn_count;
  1072.  
  1073.         if(warn_count < 1)
  1074.         {
  1075.             printf("blit width %d height %d\n",
  1076.                     width, height);
  1077.             warn_count++;
  1078.         };
  1079.     };
  1080.  
  1081.  
  1082.     if((context->cmd_buffer & 0xFC0)==0xFC0)
  1083.         context->cmd_buffer&= 0xFFFFF000;
  1084.  
  1085.     b = (u32_t*)ALIGN(context->cmd_buffer,16);
  1086.  
  1087.     offset = context->cmd_offset + ((u32_t)b & 0xFFF);
  1088.  
  1089.     cmd = XY_SRC_COPY_CHROMA_CMD | BLT_WRITE_RGB | BLT_WRITE_ALPHA;
  1090.     cmd |= 3 << 17;
  1091.  
  1092.     br13 = os_display->pitch;
  1093.     br13|= ROP_COPY_SRC << 16;
  1094.     br13|= FORMAT8888   << 24;
  1095.  
  1096.     b[n++] = cmd;
  1097.     b[n++] = br13;
  1098.     b[n++] = (dst_y << 16) | dst_x;                   // left, top
  1099.     b[n++] = ((dst_y+height)<< 16)|(dst_x+width); // bottom, right
  1100.     b[n++] = 0;                          // destination
  1101.     b[n++] = (src_y << 16) | src_x;      // source left & top
  1102.     b[n++] = bitmap->pitch;              // source pitch
  1103.     b[n++] = bitmap->gaddr;              // source
  1104.  
  1105.     b[n++] = 0;                          // Transparency Color Low
  1106.     b[n++] = 0x00FFFFFF;                 // Transparency Color High
  1107.  
  1108.     b[n++] = MI_BATCH_BUFFER_END;
  1109.     if( n & 1)
  1110.         b[n++] = MI_NOOP;
  1111.  
  1112.     context->cmd_buffer+= n*4;
  1113.  
  1114.     context->obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
  1115.  
  1116.  
  1117.     mutex_lock(&main_device->struct_mutex);
  1118.  
  1119.     i915_gem_object_set_to_gtt_domain(bitmap->obj, false);
  1120.  
  1121.     if (HAS_BLT(main_device))
  1122.     {
  1123.         u32 seqno;
  1124.         int i;
  1125.  
  1126.         ring = &dev_priv->ring[BCS];
  1127. //        printf("dispatch...  ");
  1128.  
  1129.         i915_gem_object_sync(bitmap->obj, ring);
  1130.         intel_ring_invalidate_all_caches(ring);
  1131.  
  1132.         seqno = i915_gem_next_request_seqno(ring);
  1133. //        printf("seqno = %d\n", seqno);
  1134.  
  1135.         for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
  1136.             if (seqno < ring->sync_seqno[i]) {
  1137.             /* The GPU can not handle its semaphore value wrapping,
  1138.              * so every billion or so execbuffers, we need to stall
  1139.              * the GPU in order to reset the counters.
  1140.              */
  1141.                 DRM_DEBUG("wrap seqno\n");
  1142.  
  1143.                 ret = i915_gpu_idle(main_device);
  1144.                 if (ret)
  1145.                     goto fail;
  1146.                 i915_gem_retire_requests(main_device);
  1147.  
  1148.                 BUG_ON(ring->sync_seqno[i]);
  1149.             }
  1150.         }
  1151.  
  1152.         ret = ring->dispatch_execbuffer(ring, offset, n*4);
  1153.         if (ret)
  1154.             goto fail;
  1155. //        printf("done\n");
  1156.  
  1157.         bitmap->obj->base.read_domains = bitmap->obj->base.pending_read_domains;
  1158.         bitmap->obj->base.write_domain = bitmap->obj->base.pending_write_domain;
  1159.         bitmap->obj->fenced_gpu_access = bitmap->obj->pending_fenced_gpu_access;
  1160.  
  1161.         i915_gem_object_move_to_active(bitmap->obj, ring, seqno);
  1162.  
  1163.         i915_gem_execbuffer_retire_commands(main_device, NULL, ring);
  1164. //        printf("retire\n");
  1165.     }
  1166.     else
  1167.     {
  1168.         ring = &dev_priv->ring[RCS];
  1169.         ring->dispatch_execbuffer(ring, offset, n*4);
  1170.         ring->flush(ring, 0, I915_GEM_DOMAIN_RENDER);
  1171.     };
  1172.  
  1173. //    bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU;
  1174. //    bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  1175.  
  1176.     mutex_unlock(&main_device->struct_mutex);
  1177. fail:
  1178.     return ret;
  1179. };
  1180.  
  1181.  
  1182. #if 0
  1183.  
  1184.     i915_gem_execbuffer_retire_commands(dev, ring);
  1185. /* For display hotplug interrupt */
  1186. static void
  1187. ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
  1188. {
  1189.     if ((dev_priv->irq_mask & mask) != 0) {
  1190.         dev_priv->irq_mask &= ~mask;
  1191.         I915_WRITE(DEIMR, dev_priv->irq_mask);
  1192.         POSTING_READ(DEIMR);
  1193.     }
  1194. }
  1195.  
  1196. static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
  1197. {
  1198.     drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  1199.     unsigned long irqflags;
  1200.  
  1201. //    if (!i915_pipe_enabled(dev, pipe))
  1202. //        return -EINVAL;
  1203.  
  1204.     spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
  1205.     ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
  1206.                     DE_PIPEA_VBLANK : DE_PIPEB_VBLANK);
  1207.     spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  1208.  
  1209.     return 0;
  1210. }
  1211.  
  1212.  
  1213.  
  1214. static int i915_interrupt_info(struct drm_device *dev)
  1215. {
  1216.     drm_i915_private_t *dev_priv = dev->dev_private;
  1217.     int ret, i, pipe;
  1218.  
  1219.     if (!HAS_PCH_SPLIT(dev)) {
  1220.         dbgprintf("Interrupt enable:    %08x\n",
  1221.                I915_READ(IER));
  1222.         dbgprintf("Interrupt identity:  %08x\n",
  1223.                I915_READ(IIR));
  1224.         dbgprintf("Interrupt mask:      %08x\n",
  1225.                I915_READ(IMR));
  1226.         for_each_pipe(pipe)
  1227.             dbgprintf("Pipe %c stat:         %08x\n",
  1228.                    pipe_name(pipe),
  1229.                    I915_READ(PIPESTAT(pipe)));
  1230.     } else {
  1231.         dbgprintf("North Display Interrupt enable:      %08x\n",
  1232.            I915_READ(DEIER));
  1233.         dbgprintf("North Display Interrupt identity:    %08x\n",
  1234.            I915_READ(DEIIR));
  1235.         dbgprintf("North Display Interrupt mask:        %08x\n",
  1236.            I915_READ(DEIMR));
  1237.         dbgprintf("South Display Interrupt enable:      %08x\n",
  1238.            I915_READ(SDEIER));
  1239.         dbgprintf("South Display Interrupt identity:    %08x\n",
  1240.            I915_READ(SDEIIR));
  1241.         dbgprintf("South Display Interrupt mask:        %08x\n",
  1242.            I915_READ(SDEIMR));
  1243.         dbgprintf("Graphics Interrupt enable:           %08x\n",
  1244.            I915_READ(GTIER));
  1245.         dbgprintf("Graphics Interrupt identity:         %08x\n",
  1246.            I915_READ(GTIIR));
  1247.         dbgprintf("Graphics Interrupt mask:             %08x\n",
  1248.                I915_READ(GTIMR));
  1249.     }
  1250.     dbgprintf("Interrupts received: %d\n",
  1251.            atomic_read(&dev_priv->irq_received));
  1252.     for (i = 0; i < I915_NUM_RINGS; i++) {
  1253.         if (IS_GEN6(dev) || IS_GEN7(dev)) {
  1254.             printf("Graphics Interrupt mask (%s):       %08x\n",
  1255.                    dev_priv->ring[i].name,
  1256.                    I915_READ_IMR(&dev_priv->ring[i]));
  1257.         }
  1258. //        i915_ring_seqno_info(m, &dev_priv->ring[i]);
  1259.     }
  1260.  
  1261.     return 0;
  1262. }
  1263.  
  1264. void execute_buffer (struct drm_i915_gem_object *buffer, uint32_t offset,
  1265.                      int size)
  1266. {
  1267.     struct intel_ring_buffer *ring;
  1268.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1269.     u32 invalidate;
  1270.     u32 seqno = 2;
  1271.  
  1272.     offset += buffer->gtt_offset;
  1273. //    dbgprintf("execute %x size %d\n", offset, size);
  1274.  
  1275. //    asm volatile(
  1276. //    "mfence \n"
  1277. //    "wbinvd \n"
  1278. //    "mfence  \n"
  1279. //    :::"memory");
  1280.  
  1281.     ring = &dev_priv->ring[RCS];
  1282.     ring->dispatch_execbuffer(ring, offset, size);
  1283.  
  1284.     invalidate = I915_GEM_DOMAIN_COMMAND;
  1285.     if (INTEL_INFO(main_device)->gen >= 4)
  1286.         invalidate |= I915_GEM_DOMAIN_SAMPLER;
  1287.     if (ring->flush(ring, invalidate, 0))
  1288.         i915_gem_next_request_seqno(ring);
  1289.  
  1290.     ring->irq_get(ring);
  1291.  
  1292.     ring->add_request(ring, &seqno);
  1293.  
  1294. //    i915_interrupt_info(main_device);
  1295.  
  1296. };
  1297.  
  1298.  
  1299. int blit_textured(u32 hbitmap, int  dst_x, int dst_y,
  1300.                int src_x, int src_y, u32 w, u32 h)
  1301. {
  1302.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1303.  
  1304.     bitmap_t  *src_bitmap, *dst_bitmap;
  1305.     bitmap_t   screen;
  1306.  
  1307.     rect_t     winrc;
  1308.  
  1309. //    dbgprintf("  handle: %d dx %d dy %d sx %d sy %d w %d h %d\n",
  1310. //              hbitmap, dst_x, dst_y, src_x, src_y, w, h);
  1311.  
  1312.     if(unlikely(hbitmap==0))
  1313.         return -1;
  1314.  
  1315.     src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  1316. //    dbgprintf("bitmap %x\n", src_bitmap);
  1317.  
  1318.     if(unlikely(src_bitmap==NULL))
  1319.         return -1;
  1320.  
  1321.     GetWindowRect(&winrc);
  1322.  
  1323.     screen.pitch  = os_display->pitch;
  1324.     screen.gaddr  = 0;
  1325.     screen.width  = os_display->width;
  1326.     screen.height = os_display->height;
  1327.     screen.obj    = (void*)-1;
  1328.  
  1329.     dst_bitmap = &screen;
  1330.  
  1331.     dst_x+= winrc.left;
  1332.     dst_y+= winrc.top;
  1333.  
  1334.     sna_blit_copy(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y);
  1335.  
  1336. };
  1337.  
  1338. int sna_blit_tex(bitmap_t *dst_bitmap, int dst_x, int dst_y,
  1339.                   int w, int h, bitmap_t *src_bitmap, int src_x, int src_y,
  1340.                   bitmap_t *mask_bitmap);
  1341.  
  1342.  
  1343. int blit_tex(u32 hbitmap, int  dst_x, int dst_y,
  1344.              int src_x, int src_y, u32 w, u32 h)
  1345. {
  1346.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1347.     struct context *ctx;
  1348.  
  1349.     bitmap_t  *src_bitmap, *dst_bitmap;
  1350.     bitmap_t   screen;
  1351.     int        ret;
  1352.  
  1353.     bitmap_t *mask_bitmap;
  1354.     rect_t     winrc;
  1355.  
  1356. //    dbgprintf("  handle: %d dx %d dy %d sx %d sy %d w %d h %d\n",
  1357. //              hbitmap, dst_x, dst_y, src_x, src_y, w, h);
  1358.  
  1359.     if(unlikely(hbitmap==0))
  1360.         return -1;
  1361.  
  1362.     src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  1363. //    dbgprintf("bitmap %x\n", src_bitmap);
  1364.  
  1365.     if(unlikely(src_bitmap==NULL))
  1366.         return -1;
  1367.  
  1368.     ctx = get_context();
  1369.     if(unlikely(ctx==NULL))
  1370.     {
  1371.         ret = create_context();
  1372.         if(ret!=0)
  1373.             return -1;
  1374.  
  1375.         ctx = get_context();
  1376.     };
  1377.  
  1378.     mask_bitmap = ctx->mask;
  1379.  
  1380.     GetWindowRect(&winrc);
  1381.     dst_x+= winrc.left;
  1382.     dst_y+= winrc.top;
  1383.  
  1384.  
  1385.     if(ctx->seqno != os_display->mask_seqno)
  1386.     {
  1387.         u8* src_offset;
  1388.         u8* dst_offset;
  1389.         u32 slot;
  1390.         u32 ifl;
  1391.  
  1392.         ret = gem_object_lock(mask_bitmap->obj);
  1393.         if(ret !=0 )
  1394.         {
  1395.             dbgprintf("%s fail\n", __FUNCTION__);
  1396.             return ret;
  1397.         };
  1398.  
  1399. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  1400.  
  1401.         mask_bitmap->width  = winrc.right;
  1402.         mask_bitmap->height = winrc.bottom;
  1403.         mask_bitmap->pitch =  ALIGN(w,64);
  1404.  
  1405.         slot = *((u8*)CURRENT_TASK);
  1406. //        slot = 0x01;
  1407.  
  1408.         slot|= (slot<<8)|(slot<<16)|(slot<<24);
  1409.  
  1410.  
  1411.         __asm__ __volatile__ (
  1412.         "movd       %[slot],   %%xmm6    \n"
  1413.         "punpckldq  %%xmm6, %%xmm6            \n"
  1414.         "punpcklqdq %%xmm6, %%xmm6            \n"
  1415.         :: [slot]  "m" (slot)
  1416.         :"xmm6");
  1417.  
  1418.         src_offset = mask_bitmap->uaddr;
  1419.  
  1420.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  1421.         dst_offset+= get_display_map();
  1422.  
  1423.         u32_t tmp_h = mask_bitmap->height;
  1424.  
  1425.       ifl = safe_cli();
  1426.         while( tmp_h--)
  1427.         {
  1428.             int tmp_w = mask_bitmap->width;
  1429.  
  1430.             u8* tmp_src = src_offset;
  1431.             u8* tmp_dst = dst_offset;
  1432.  
  1433.             src_offset+= mask_bitmap->pitch;
  1434.             dst_offset+= os_display->width;
  1435.  
  1436. //            while( tmp_w--)
  1437. //            {
  1438. //                *(tmp_src) = (*tmp_dst==slot)?0x1:0x00;
  1439. //                tmp_src++;
  1440. //                tmp_dst++;
  1441. //            };
  1442.             while(tmp_w >= 64)
  1443.             {
  1444.                 __asm__ __volatile__ (
  1445.                 "movdqu     (%0),   %%xmm0            \n"
  1446.                 "movdqu   16(%0),   %%xmm1            \n"
  1447.                 "movdqu   32(%0),   %%xmm2            \n"
  1448.                 "movdqu   48(%0),   %%xmm3            \n"
  1449.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1450.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  1451.                 "pcmpeqb    %%xmm6, %%xmm2            \n"
  1452.                 "pcmpeqb    %%xmm6, %%xmm3            \n"
  1453.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1454.                 "movdqa     %%xmm1, 16(%%edi)         \n"
  1455.                 "movdqa     %%xmm2, 32(%%edi)         \n"
  1456.                 "movdqa     %%xmm3, 48(%%edi)         \n"
  1457.  
  1458.                 :: "r" (tmp_dst), "D" (tmp_src)
  1459.                 :"xmm0","xmm1","xmm2","xmm3");
  1460.                 tmp_w -= 64;
  1461.                 tmp_src += 64;
  1462.                 tmp_dst += 64;
  1463.             }
  1464.  
  1465.             if( tmp_w >= 32 )
  1466.             {
  1467.                 __asm__ __volatile__ (
  1468.                 "movdqu     (%0),   %%xmm0            \n"
  1469.                 "movdqu   16(%0),   %%xmm1            \n"
  1470.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1471.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  1472.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1473.                 "movdqa     %%xmm1, 16(%%edi)         \n"
  1474.  
  1475.                 :: "r" (tmp_dst), "D" (tmp_src)
  1476.                 :"xmm0","xmm1");
  1477.                 tmp_w -= 32;
  1478.                 tmp_src += 32;
  1479.                 tmp_dst += 32;
  1480.             }
  1481.  
  1482.             while( tmp_w > 0 )
  1483.             {
  1484.                 __asm__ __volatile__ (
  1485.                 "movdqu     (%0),   %%xmm0            \n"
  1486.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1487.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1488.                 :: "r" (tmp_dst), "D" (tmp_src)
  1489.                 :"xmm0");
  1490.                 tmp_w -= 16;
  1491.                 tmp_src += 16;
  1492.                 tmp_dst += 16;
  1493.             }
  1494.         };
  1495.       safe_sti(ifl);
  1496.       ctx->seqno = os_display->mask_seqno;
  1497.     }
  1498.  
  1499.     screen.pitch  = os_display->pitch;
  1500.     screen.gaddr  = 0;
  1501.     screen.width  = os_display->width;
  1502.     screen.height = os_display->height;
  1503.     screen.obj    = (void*)-1;
  1504.  
  1505.     dst_bitmap = &screen;
  1506.  
  1507.  
  1508.     sna_blit_tex(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y,
  1509.                  mask_bitmap);
  1510.  
  1511. //    asm volatile ("int3");
  1512. };
  1513.  
  1514.  
  1515. #endif
  1516.  
  1517.  
  1518. #endif
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524. void __stdcall run_workqueue(struct workqueue_struct *cwq)
  1525. {
  1526.     unsigned long irqflags;
  1527.  
  1528. //    dbgprintf("wq: %x head %x, next %x\n",
  1529. //               cwq, &cwq->worklist, cwq->worklist.next);
  1530.  
  1531.     spin_lock_irqsave(&cwq->lock, irqflags);
  1532.  
  1533.     while (!list_empty(&cwq->worklist))
  1534.     {
  1535.         struct work_struct *work = list_entry(cwq->worklist.next,
  1536.                                         struct work_struct, entry);
  1537.         work_func_t f = work->func;
  1538.         list_del_init(cwq->worklist.next);
  1539. //        dbgprintf("head %x, next %x\n",
  1540. //                  &cwq->worklist, cwq->worklist.next);
  1541.  
  1542.         spin_unlock_irqrestore(&cwq->lock, irqflags);
  1543.         f(work);
  1544.         spin_lock_irqsave(&cwq->lock, irqflags);
  1545.     }
  1546.  
  1547.     spin_unlock_irqrestore(&cwq->lock, irqflags);
  1548. }
  1549.  
  1550.  
  1551. static inline
  1552. int __queue_work(struct workqueue_struct *wq,
  1553.                          struct work_struct *work)
  1554. {
  1555.     unsigned long flags;
  1556.  
  1557. //    dbgprintf("wq: %x, work: %x\n",
  1558. //               wq, work );
  1559.  
  1560.     if(!list_empty(&work->entry))
  1561.         return 0;
  1562.  
  1563.     spin_lock_irqsave(&wq->lock, flags);
  1564.  
  1565.     if(list_empty(&wq->worklist))
  1566.         TimerHs(0,0, run_workqueue, wq);
  1567.  
  1568.     list_add_tail(&work->entry, &wq->worklist);
  1569.  
  1570.     spin_unlock_irqrestore(&wq->lock, flags);
  1571. //    dbgprintf("wq: %x head %x, next %x\n",
  1572. //               wq, &wq->worklist, wq->worklist.next);
  1573.  
  1574.     return 1;
  1575. };
  1576.  
  1577. void __stdcall delayed_work_timer_fn(unsigned long __data)
  1578. {
  1579.     struct delayed_work *dwork = (struct delayed_work *)__data;
  1580.     struct workqueue_struct *wq = dwork->work.data;
  1581.  
  1582. //    dbgprintf("wq: %x, work: %x\n",
  1583. //               wq, &dwork->work );
  1584.  
  1585.     __queue_work(wq, &dwork->work);
  1586. }
  1587.  
  1588.  
  1589. int queue_delayed_work_on(struct workqueue_struct *wq,
  1590.                         struct delayed_work *dwork, unsigned long delay)
  1591. {
  1592.     struct work_struct *work = &dwork->work;
  1593.  
  1594.     work->data = wq;
  1595.     TimerHs(0,0, delayed_work_timer_fn, dwork);
  1596.     return 1;
  1597. }
  1598.  
  1599. int queue_delayed_work(struct workqueue_struct *wq,
  1600.                         struct delayed_work *dwork, unsigned long delay)
  1601. {
  1602.     u32  flags;
  1603.  
  1604. //    dbgprintf("wq: %x, work: %x\n",
  1605. //               wq, &dwork->work );
  1606.  
  1607.     if (delay == 0)
  1608.         return __queue_work(wq, &dwork->work);
  1609.  
  1610.     return queue_delayed_work_on(wq, dwork, delay);
  1611. }
  1612.  
  1613.  
  1614. struct workqueue_struct *alloc_workqueue(const char *fmt,
  1615.                            unsigned int flags,
  1616.                            int max_active)
  1617. {
  1618.     struct workqueue_struct *wq;
  1619.  
  1620.     wq = kzalloc(sizeof(*wq),0);
  1621.     if (!wq)
  1622.         goto err;
  1623.  
  1624.     INIT_LIST_HEAD(&wq->worklist);
  1625.  
  1626.     return wq;
  1627. err:
  1628.     return NULL;
  1629. }
  1630.  
  1631. #define NSEC_PER_SEC    1000000000L
  1632.  
  1633. void getrawmonotonic(struct timespec *ts)
  1634. {
  1635.     u32 tmp = GetTimerTicks();
  1636.  
  1637.     ts->tv_sec  = tmp/100;
  1638.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  1639. }
  1640.  
  1641. void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
  1642. {
  1643.         while (nsec >= NSEC_PER_SEC) {
  1644.                 nsec -= NSEC_PER_SEC;
  1645.                 ++sec;
  1646.         }
  1647.         while (nsec < 0) {
  1648.                 nsec += NSEC_PER_SEC;
  1649.                 --sec;
  1650.         }
  1651.         ts->tv_sec = sec;
  1652.         ts->tv_nsec = nsec;
  1653. }
  1654.  
  1655.  
  1656.  
  1657.