Subversion Repositories Kolibri OS

Rev

Rev 2351 | Rev 2360 | 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. extern struct drm_device *main_device;
  21.  
  22.  
  23. typedef struct
  24. {
  25.     kobj_t     header;
  26.  
  27.     uint32_t  *data;
  28.     uint32_t   hot_x;
  29.     uint32_t   hot_y;
  30.  
  31.     struct list_head   list;
  32.     struct drm_i915_gem_object  *cobj;
  33. }cursor_t;
  34.  
  35. #define CURSOR_WIDTH 64
  36. #define CURSOR_HEIGHT 64
  37.  
  38.  
  39. struct tag_display
  40. {
  41.     int  x;
  42.     int  y;
  43.     int  width;
  44.     int  height;
  45.     int  bpp;
  46.     int  vrefresh;
  47.     int  pitch;
  48.     int  lfb;
  49.  
  50.     int  supported_modes;
  51.     struct drm_device    *ddev;
  52.     struct drm_connector *connector;
  53.     struct drm_crtc      *crtc;
  54.  
  55.     struct list_head   cursors;
  56.  
  57.     cursor_t   *cursor;
  58.     int       (*init_cursor)(cursor_t*);
  59.     cursor_t* (__stdcall *select_cursor)(cursor_t*);
  60.     void      (*show_cursor)(int show);
  61.     void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
  62.     void      (__stdcall *restore_cursor)(int x, int y);
  63.     void      (*disable_mouse)(void);
  64. };
  65.  
  66.  
  67. static display_t *os_display;
  68.  
  69. u32_t cmd_buffer;
  70. u32_t cmd_offset;
  71.  
  72. void init_render();
  73. int  sna_init();
  74.  
  75. int init_cursor(cursor_t *cursor);
  76. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  77. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  78.  
  79. void __stdcall restore_cursor(int x, int y)
  80. {};
  81.  
  82. void disable_mouse(void)
  83. {};
  84.  
  85. static int count_connector_modes(struct drm_connector* connector)
  86. {
  87.     struct drm_display_mode  *mode;
  88.     int count = 0;
  89.  
  90.     list_for_each_entry(mode, &connector->modes, head)
  91.     {
  92.         count++;
  93.     };
  94.     return count;
  95. };
  96.  
  97. int init_display_kms(struct drm_device *dev)
  98. {
  99.     struct drm_connector    *connector;
  100.     struct drm_connector_helper_funcs *connector_funcs;
  101.     struct drm_encoder      *encoder;
  102.     struct drm_crtc         *crtc = NULL;
  103.     struct drm_framebuffer  *fb;
  104.  
  105.     cursor_t  *cursor;
  106.     u32_t      ifl;
  107.  
  108.     ENTER();
  109.  
  110.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  111.     {
  112.         if( connector->status != connector_status_connected)
  113.             continue;
  114.  
  115.         connector_funcs = connector->helper_private;
  116.         encoder = connector_funcs->best_encoder(connector);
  117.         if( encoder == NULL)
  118.         {
  119.             dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
  120.                       connector, connector->base.id);
  121.             continue;
  122.         }
  123.         connector->encoder = encoder;
  124.  
  125.         dbgprintf("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x\n",
  126.                connector, connector->base.id,
  127.                connector->status, connector->encoder,
  128.                encoder->crtc);
  129.  
  130.         crtc = encoder->crtc;
  131.         break;
  132.     };
  133.  
  134.     if(connector == NULL)
  135.     {
  136.         dbgprintf("No active connectors!\n");
  137.         return -1;
  138.     };
  139.  
  140.     if(crtc == NULL)
  141.     {
  142.         struct drm_crtc *tmp_crtc;
  143.         int crtc_mask = 1;
  144.  
  145.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  146.         {
  147.             if (encoder->possible_crtcs & crtc_mask)
  148.             {
  149.                 crtc = tmp_crtc;
  150.                 encoder->crtc = crtc;
  151.                 break;
  152.             };
  153.             crtc_mask <<= 1;
  154.         };
  155.     };
  156.  
  157.     if(crtc == NULL)
  158.     {
  159.         dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
  160.         return -1;
  161.     };
  162.  
  163.  
  164.     DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id);
  165.  
  166.     os_display = GetDisplay();
  167.  
  168.     os_display->ddev = dev;
  169.     os_display->connector = connector;
  170.     os_display->crtc = crtc;
  171.  
  172.     os_display->supported_modes = count_connector_modes(connector);
  173.  
  174.  
  175.     ifl = safe_cli();
  176.     {
  177.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  178.  
  179.         list_for_each_entry(cursor, &os_display->cursors, list)
  180.         {
  181.             init_cursor(cursor);
  182.         };
  183.  
  184.         os_display->restore_cursor(0,0);
  185.         os_display->init_cursor    = init_cursor;
  186.         os_display->select_cursor  = select_cursor_kms;
  187.         os_display->show_cursor    = NULL;
  188.         os_display->move_cursor    = move_cursor_kms;
  189.         os_display->restore_cursor = restore_cursor;
  190.         os_display->disable_mouse  = disable_mouse;
  191.  
  192.         intel_crtc->cursor_x = os_display->width/2;
  193.         intel_crtc->cursor_y = os_display->height/2;
  194.  
  195.         select_cursor_kms(os_display->cursor);
  196.     };
  197.     safe_sti(ifl);
  198.  
  199. #define XY_COLOR_BLT        ((2<<29)|(0x50<<22)|(0x4))
  200. #define BLT_WRITE_ALPHA     (1<<21)
  201. #define BLT_WRITE_RGB       (1<<20)
  202.  
  203. #if 1
  204.     {
  205.  
  206.         drm_i915_private_t *dev_priv = dev->dev_private;
  207.         struct drm_i915_gem_object *obj;
  208.         struct intel_ring_buffer *ring;
  209.  
  210.         obj = i915_gem_alloc_object(dev, 4096);
  211.         i915_gem_object_pin(obj, 4096, true);
  212.  
  213.         cmd_buffer = MapIoMem((addr_t)obj->pages[0], 4096, PG_SW|PG_NOCACHE);
  214.         cmd_offset = obj->gtt_offset;
  215.     };
  216. #endif
  217.  
  218.     main_device = dev;
  219.  
  220.     int err;
  221.  
  222.     err = init_bitmaps();
  223.     if( !err )
  224.     {
  225.         printf("Initialize bitmap manager\n");
  226.     };
  227.  
  228.     sna_init();
  229.  
  230.     LEAVE();
  231.  
  232.     return 0;
  233. };
  234.  
  235.  
  236. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  237.               videomode_t *reqmode, bool strict)
  238. {
  239.     struct drm_display_mode  *mode = NULL, *tmpmode;
  240.     drm_i915_private_t *dev_priv = dev->dev_private;
  241.     struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper;
  242.  
  243.     bool ret = false;
  244.  
  245.     ENTER();
  246.  
  247.     dbgprintf("width %d height %d vrefresh %d\n",
  248.                reqmode->width, reqmode->height, reqmode->freq);
  249.  
  250.     list_for_each_entry(tmpmode, &connector->modes, head)
  251.     {
  252.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  253.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  254.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  255.         {
  256.             mode = tmpmode;
  257.             goto do_set;
  258.         }
  259.     };
  260.  
  261.     if( (mode == NULL) && (strict == false) )
  262.     {
  263.         list_for_each_entry(tmpmode, &connector->modes, head)
  264.         {
  265.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  266.                 (drm_mode_height(tmpmode) == reqmode->height) )
  267.             {
  268.                 mode = tmpmode;
  269.                 goto do_set;
  270.             }
  271.         };
  272.     };
  273.  
  274. do_set:
  275.  
  276.     if( mode != NULL )
  277.     {
  278.         struct drm_framebuffer   *fb;
  279.         struct drm_encoder       *encoder;
  280.         struct drm_crtc          *crtc;
  281.  
  282.         char *con_name;
  283.         char *enc_name;
  284.  
  285.         encoder = connector->encoder;
  286.         crtc = encoder->crtc;
  287.  
  288.         con_name = drm_get_connector_name(connector);
  289.         enc_name = drm_get_encoder_name(encoder);
  290.  
  291.         dbgprintf("set mode %d %d connector %s encoder %s\n",
  292.                    reqmode->width, reqmode->height, con_name, enc_name);
  293.  
  294.         fb = fb_helper->fb;
  295.  
  296.         fb->width  = reqmode->width;
  297.         fb->height = reqmode->height;
  298.         fb->pitches[0]  = ALIGN(reqmode->width * 4, 64);
  299.         fb->pitches[1]  = ALIGN(reqmode->width * 4, 64);
  300.         fb->pitches[2]  = ALIGN(reqmode->width * 4, 64);
  301.         fb->pitches[3]  = ALIGN(reqmode->width * 4, 64);
  302.  
  303.         fb->bits_per_pixel = 32;
  304.         fb->depth == 24;
  305.  
  306.         crtc->fb = fb;
  307.         crtc->enabled = true;
  308.         os_display->crtc = crtc;
  309.  
  310.         ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
  311.  
  312. //        select_cursor_kms(rdisplay->cursor);
  313. //        radeon_show_cursor_kms(crtc);
  314.  
  315.         if (ret == true)
  316.         {
  317.             os_display->width    = fb->width;
  318.             os_display->height   = fb->height;
  319.             os_display->pitch    = fb->pitches[0];
  320.             os_display->vrefresh = drm_mode_vrefresh(mode);
  321.  
  322.             sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  323.  
  324.             dbgprintf("new mode %d x %d pitch %d\n",
  325.                        fb->width, fb->height, fb->pitches[0]);
  326.         }
  327.         else
  328.             DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  329.                        fb->width, fb->height, crtc);
  330.     }
  331.  
  332.     LEAVE();
  333.     return ret;
  334. };
  335.  
  336.  
  337.  
  338. int get_videomodes(videomode_t *mode, int *count)
  339. {
  340.     int err = -1;
  341.  
  342.     ENTER();
  343.  
  344.     dbgprintf("mode %x count %d\n", mode, *count);
  345.  
  346.     if( *count == 0 )
  347.     {
  348.         *count = os_display->supported_modes;
  349.         err = 0;
  350.     }
  351.     else if( mode != NULL )
  352.     {
  353.         struct drm_display_mode  *drmmode;
  354.         int i = 0;
  355.  
  356.         if( *count > os_display->supported_modes)
  357.             *count = os_display->supported_modes;
  358.  
  359.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  360.         {
  361.             if( i < *count)
  362.             {
  363.                 mode->width  = drm_mode_width(drmmode);
  364.                 mode->height = drm_mode_height(drmmode);
  365.                 mode->bpp    = 32;
  366.                 mode->freq   = drm_mode_vrefresh(drmmode);
  367.                 i++;
  368.                 mode++;
  369.             }
  370.             else break;
  371.         };
  372.         *count = i;
  373.         err = 0;
  374.     };
  375.     LEAVE();
  376.     return err;
  377. };
  378.  
  379. int set_user_mode(videomode_t *mode)
  380. {
  381.     int err = -1;
  382.  
  383.     ENTER();
  384.  
  385.     dbgprintf("width %d height %d vrefresh %d\n",
  386.                mode->width, mode->height, mode->freq);
  387.  
  388.     if( (mode->width  != 0)  &&
  389.         (mode->height != 0)  &&
  390.         (mode->freq   != 0 ) &&
  391.         ( (mode->width   != os_display->width)  ||
  392.           (mode->height  != os_display->height) ||
  393.           (mode->freq    != os_display->vrefresh) ) )
  394.     {
  395.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  396.             err = 0;
  397.     };
  398.  
  399.     LEAVE();
  400.     return err;
  401. };
  402.  
  403. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  404. {
  405. /*  FIXME    synchronization */
  406.  
  407.     list_del(&cursor->list);
  408. //    radeon_bo_unpin(cursor->robj);
  409. //    KernelFree(cursor->data);
  410.     __DestroyObject(cursor);
  411. };
  412.  
  413. int init_cursor(cursor_t *cursor)
  414. {
  415.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  416.     struct drm_i915_gem_object *obj;
  417.     uint32_t *bits;
  418.     uint32_t *src;
  419.  
  420.     int       i,j;
  421.     int       ret;
  422.  
  423.     ENTER();
  424.  
  425.     if (dev_priv->info->cursor_needs_physical)
  426.     {
  427.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  428.         if (unlikely(bits == NULL))
  429.             return ENOMEM;
  430.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  431.     }
  432.     else
  433.     {
  434.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  435.         if (unlikely(obj == NULL))
  436.             return -ENOMEM;
  437.  
  438.         ret = i915_gem_object_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true);
  439.         if (ret) {
  440.             drm_gem_object_unreference(&obj->base);
  441.             return ret;
  442.         }
  443.  
  444. /* You don't need to worry about fragmentation issues.
  445.  * GTT space is continuous. I guarantee it.                           */
  446.  
  447.         bits = (u32*)MapIoMem(get_bus_addr() + obj->gtt_offset,
  448.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  449.  
  450.         if (unlikely(bits == NULL))
  451.         {
  452.             i915_gem_object_unpin(obj);
  453.             drm_gem_object_unreference(&obj->base);
  454.             return -ENOMEM;
  455.         };
  456.         cursor->cobj = obj;
  457.     };
  458.  
  459.     src = cursor->data;
  460.  
  461.     for(i = 0; i < 32; i++)
  462.     {
  463.         for(j = 0; j < 32; j++)
  464.             *bits++ = *src++;
  465.         for(j = 32; j < CURSOR_WIDTH; j++)
  466.             *bits++ = 0;
  467.     }
  468.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  469.         *bits++ = 0;
  470.  
  471. // release old cursor
  472.  
  473.     KernelFree(cursor->data);
  474.  
  475.     cursor->data = bits;
  476.  
  477.     cursor->header.destroy = destroy_cursor;
  478.     LEAVE();
  479.  
  480.     return 0;
  481. }
  482.  
  483.  
  484. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  485. {
  486.     struct drm_device *dev = crtc->dev;
  487.     struct drm_i915_private *dev_priv = dev->dev_private;
  488.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  489.     int pipe = intel_crtc->pipe;
  490.     bool visible = base != 0;
  491.  
  492.     if (intel_crtc->cursor_visible != visible) {
  493.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  494.         if (base) {
  495.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  496.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  497.             cntl |= pipe << 28; /* Connect to correct pipe */
  498.         } else {
  499.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  500.             cntl |= CURSOR_MODE_DISABLE;
  501.         }
  502.         I915_WRITE(CURCNTR(pipe), cntl);
  503.  
  504.         intel_crtc->cursor_visible = visible;
  505.     }
  506.     /* and commit changes on next vblank */
  507.     I915_WRITE(CURBASE(pipe), base);
  508. }
  509.  
  510. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  511. {
  512.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  513.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  514.     u32 base, pos;
  515.     bool visible;
  516.  
  517.     int pipe = intel_crtc->pipe;
  518.  
  519.     intel_crtc->cursor_x = x;
  520.     intel_crtc->cursor_y = y;
  521.  
  522.     x = x - cursor->hot_x;
  523.     y = y - cursor->hot_y;
  524.  
  525.  
  526.     pos = 0;
  527.  
  528.     base = intel_crtc->cursor_addr;
  529.     if (x >= os_display->width)
  530.         base = 0;
  531.  
  532.     if (y >= os_display->height)
  533.         base = 0;
  534.  
  535.     if (x < 0)
  536.     {
  537.         if (x + intel_crtc->cursor_width < 0)
  538.             base = 0;
  539.  
  540.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  541.         x = -x;
  542.     }
  543.     pos |= x << CURSOR_X_SHIFT;
  544.  
  545.     if (y < 0)
  546.     {
  547.         if (y + intel_crtc->cursor_height < 0)
  548.             base = 0;
  549.  
  550.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  551.         y = -y;
  552.     }
  553.     pos |= y << CURSOR_Y_SHIFT;
  554.  
  555.     visible = base != 0;
  556.     if (!visible && !intel_crtc->cursor_visible)
  557.         return;
  558.  
  559.     I915_WRITE(CURPOS(pipe), pos);
  560. //    if (IS_845G(dev) || IS_I865G(dev))
  561. //        i845_update_cursor(crtc, base);
  562. //    else
  563.         i9xx_update_cursor(os_display->crtc, base);
  564.  
  565. };
  566.  
  567.  
  568. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  569. {
  570.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  571.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  572.     cursor_t *old;
  573.  
  574.     old = os_display->cursor;
  575.     os_display->cursor = cursor;
  576.  
  577.     if (!dev_priv->info->cursor_needs_physical)
  578.        intel_crtc->cursor_addr = cursor->cobj->gtt_offset;
  579.     else
  580.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  581.  
  582.     intel_crtc->cursor_width = 32;
  583.     intel_crtc->cursor_height = 32;
  584.  
  585.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  586.     return old;
  587. };
  588.  
  589.  
  590. #define XY_SRC_COPY_BLT_CMD     ((2<<29)|(0x53<<22)|6)
  591.  
  592.  
  593. typedef struct
  594. {
  595.     int left;
  596.     int top;
  597.     int right;
  598.     int bottom;
  599. }rect_t;
  600.  
  601.  
  602. #include "clip.inc"
  603.  
  604. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  605.  
  606. #define CURRENT_TASK             (0x80003000)
  607.  
  608. static u32_t get_display_map()
  609. {
  610.     u32_t   addr;
  611.  
  612.     addr = (u32_t)os_display;
  613.     addr+= sizeof(display_t);            /*  shoot me  */
  614.     return *(u32_t*)addr;
  615. }
  616.  
  617. #define XY_SRC_COPY_CHROMA_CMD     ((2<<29)|(0x73<<22)|8)
  618. #define ROP_COPY_SRC               0xCC
  619. #define FORMAT8888                 3
  620.  
  621. typedef int v4si __attribute__ ((vector_size (16)));
  622.  
  623.  
  624. int blit_video(u32 hbitmap, int  dst_x, int dst_y,
  625.                int src_x, int src_y, u32 w, u32 h)
  626. {
  627.     drm_i915_private_t *dev_priv = main_device->dev_private;
  628.     struct intel_ring_buffer *ring;
  629.  
  630.     bitmap_t  *bitmap;
  631.     rect_t     winrc;
  632.     clip_t     dst_clip;
  633.     clip_t     src_clip;
  634.     u32_t      width;
  635.     u32_t      height;
  636.  
  637.     u32_t      br13, cmd, slot_mask, *b;
  638.     u32_t      offset;
  639.     u8         slot;
  640.     int      n=0;
  641.  
  642.     if(unlikely(hbitmap==0))
  643.         return -1;
  644.  
  645.     bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  646.  
  647.     if(unlikely(bitmap==NULL))
  648.         return -1;
  649.  
  650.  
  651.     GetWindowRect(&winrc);
  652.  
  653.     dst_clip.xmin   = 0;
  654.     dst_clip.ymin   = 0;
  655.     dst_clip.xmax   = winrc.right-winrc.left-1;
  656.     dst_clip.ymax   = winrc.bottom -winrc.top -1;
  657.  
  658.     src_clip.xmin   = 0;
  659.     src_clip.ymin   = 0;
  660.     src_clip.xmax   = bitmap->width  - 1;
  661.     src_clip.ymax   = bitmap->height - 1;
  662.  
  663.     width  = w;
  664.     height = h;
  665.  
  666.     if( blit_clip(&dst_clip, &dst_x, &dst_y,
  667.                   &src_clip, &src_x, &src_y,
  668.                   &width, &height) )
  669.         return 0;
  670.  
  671.     dst_x+= winrc.left;
  672.     dst_y+= winrc.top;
  673.  
  674.     slot = *((u8*)CURRENT_TASK);
  675.  
  676.     slot_mask = (u32_t)slot<<24;
  677.  
  678.     {
  679. #if 0
  680.         static v4si write_mask = {0xFF000000, 0xFF000000,
  681.                                   0xFF000000, 0xFF000000};
  682.  
  683.         u8* src_offset;
  684.         u8* dst_offset;
  685.  
  686.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  687.         src_offset += (u32)bitmap->uaddr;
  688.  
  689.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  690.         dst_offset+= get_display_map();
  691.  
  692.         u32_t tmp_h = height;
  693.  
  694.         __asm__ __volatile__ (
  695.         "movdqa     %[write_mask],  %%xmm7    \n"
  696.         "movd       %[slot_mask],   %%xmm6    \n"
  697.         "punpckldq  %%xmm6, %%xmm6            \n"
  698.         "punpcklqdq %%xmm6, %%xmm6            \n"
  699.         :: [write_mask] "m" (write_mask),
  700.            [slot_mask]  "g" (slot_mask)
  701.         :"xmm7", "xmm6");
  702.  
  703.         while( tmp_h--)
  704.         {
  705.             u32_t tmp_w = width;
  706.  
  707.             u8* tmp_src = src_offset;
  708.             u8* tmp_dst = dst_offset;
  709.  
  710.             src_offset+= bitmap->pitch;
  711.             dst_offset+= os_display->width;
  712.  
  713.             while( tmp_w >= 8 )
  714.             {
  715.                 __asm__ __volatile__ (
  716.                 "movq       (%0),   %%xmm0            \n"
  717.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  718.                 "movdqa     %%xmm0, %%xmm1            \n"
  719.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  720.                 "punpckhwd  %%xmm1, %%xmm1            \n"
  721.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  722.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  723.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  724.                 "addl       $16, %%edi                \n"
  725.                 "maskmovdqu %%xmm7, %%xmm1            \n"
  726.                 :: "r" (tmp_dst), "D" (tmp_src)
  727.                 :"xmm0", "xmm1");
  728.                 __asm__ __volatile__ ("":::"edi");
  729.                 tmp_w -= 8;
  730.                 tmp_src += 32;
  731.                 tmp_dst += 8;
  732.             };
  733.  
  734.             if( tmp_w >= 4 )
  735.             {
  736.                 __asm__ __volatile__ (
  737.                 "movd       (%0),   %%xmm0            \n"
  738.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  739.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  740.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  741.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  742.                 :: "r" (tmp_dst), "D" (tmp_src)
  743.                 :"xmm0");
  744.                 tmp_w -= 4;
  745.                 tmp_src += 16;
  746.                 tmp_dst += 4;
  747.             };
  748.  
  749.             while( tmp_w--)
  750.             {
  751.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  752.                 tmp_src+=4;
  753.                 tmp_dst++;
  754.             };
  755.         };
  756. #else
  757.         u8* src_offset;
  758.         u8* dst_offset;
  759.         u32 ifl;
  760.  
  761.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  762.         src_offset += (u32)bitmap->uaddr;
  763.  
  764.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  765.         dst_offset+= get_display_map();
  766.  
  767.         u32_t tmp_h = height;
  768.  
  769.       ifl = safe_cli();
  770.         while( tmp_h--)
  771.         {
  772.             u32_t tmp_w = width;
  773.  
  774.             u8* tmp_src = src_offset;
  775.             u8* tmp_dst = dst_offset;
  776.  
  777.             src_offset+= bitmap->pitch;
  778.             dst_offset+= os_display->width;
  779.  
  780.             while( tmp_w--)
  781.             {
  782.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  783.                 tmp_src+=4;
  784.                 tmp_dst++;
  785.             };
  786.         };
  787.       safe_sti(ifl);
  788.     }
  789. #endif
  790.  
  791.     if((cmd_buffer & 0xFC0)==0xFC0)
  792.         cmd_buffer&= 0xFFFFF000;
  793.  
  794.     b = (u32_t*)ALIGN(cmd_buffer,16);
  795.  
  796.     offset = cmd_offset + ((u32_t)b & 0xFFF);
  797.  
  798.     cmd = XY_SRC_COPY_CHROMA_CMD | BLT_WRITE_RGB | BLT_WRITE_ALPHA;
  799.     cmd |= 3 << 17;
  800.  
  801.     br13 = os_display->pitch;
  802.     br13|= ROP_COPY_SRC << 16;
  803.     br13|= FORMAT8888   << 24;
  804.  
  805.     b[n++] = cmd;
  806.     b[n++] = br13;
  807.     b[n++] = (dst_y << 16) | dst_x;                   // left, top
  808.     b[n++] = ((dst_y+height-1)<< 16)|(dst_x+width-1); // bottom, right
  809.     b[n++] = 0;                          // destination
  810.     b[n++] = (src_y << 16) | src_x;      // source left & top
  811.     b[n++] = bitmap->pitch;              // source pitch
  812.     b[n++] = bitmap->gaddr;              // source
  813.  
  814.     b[n++] = 0;                          // Transparency Color Low
  815.     b[n++] = 0x00FFFFFF;                 // Transparency Color High
  816.  
  817.     b[n++] = MI_BATCH_BUFFER_END;
  818.     if( n & 1)
  819.         b[n++] = MI_NOOP;
  820.  
  821.     i915_gem_object_set_to_gtt_domain(bitmap->obj, false);
  822.  
  823.     if (HAS_BLT(main_device))
  824.     {
  825.         int ret;
  826.  
  827.         ring = &dev_priv->ring[BCS];
  828.         ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  829.  
  830.         ret = intel_ring_begin(ring, 4);
  831.         if (ret)
  832.             return ret;
  833.  
  834.         intel_ring_emit(ring, MI_FLUSH_DW);
  835.         intel_ring_emit(ring, 0);
  836.         intel_ring_emit(ring, 0);
  837.         intel_ring_emit(ring, MI_NOOP);
  838.         intel_ring_advance(ring);
  839.     }
  840.     else
  841.     {
  842.         ring = &dev_priv->ring[RCS];
  843.         ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  844.         ring->flush(ring, 0, I915_GEM_DOMAIN_RENDER);
  845.     };
  846.  
  847.     bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU;
  848.     bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  849.  
  850.     return 0;
  851. fail:
  852.     return -1;
  853. };
  854.  
  855.  
  856. /* For display hotplug interrupt */
  857. static void
  858. ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
  859. {
  860.     if ((dev_priv->irq_mask & mask) != 0) {
  861.         dev_priv->irq_mask &= ~mask;
  862.         I915_WRITE(DEIMR, dev_priv->irq_mask);
  863.         POSTING_READ(DEIMR);
  864.     }
  865. }
  866.  
  867. static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
  868. {
  869.     drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  870.     unsigned long irqflags;
  871.  
  872. //    if (!i915_pipe_enabled(dev, pipe))
  873. //        return -EINVAL;
  874.  
  875.     spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
  876.     ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
  877.                     DE_PIPEA_VBLANK : DE_PIPEB_VBLANK);
  878.     spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  879.  
  880.     return 0;
  881. }
  882.  
  883.  
  884.  
  885. static int i915_interrupt_info(struct drm_device *dev)
  886. {
  887.     drm_i915_private_t *dev_priv = dev->dev_private;
  888.     int ret, i, pipe;
  889.  
  890.     if (!HAS_PCH_SPLIT(dev)) {
  891.         dbgprintf("Interrupt enable:    %08x\n",
  892.                I915_READ(IER));
  893.         dbgprintf("Interrupt identity:  %08x\n",
  894.                I915_READ(IIR));
  895.         dbgprintf("Interrupt mask:      %08x\n",
  896.                I915_READ(IMR));
  897.         for_each_pipe(pipe)
  898.             dbgprintf("Pipe %c stat:         %08x\n",
  899.                    pipe_name(pipe),
  900.                    I915_READ(PIPESTAT(pipe)));
  901.     } else {
  902.         dbgprintf("North Display Interrupt enable:      %08x\n",
  903.            I915_READ(DEIER));
  904.         dbgprintf("North Display Interrupt identity:    %08x\n",
  905.            I915_READ(DEIIR));
  906.         dbgprintf("North Display Interrupt mask:        %08x\n",
  907.            I915_READ(DEIMR));
  908.         dbgprintf("South Display Interrupt enable:      %08x\n",
  909.            I915_READ(SDEIER));
  910.         dbgprintf("South Display Interrupt identity:    %08x\n",
  911.            I915_READ(SDEIIR));
  912.         dbgprintf("South Display Interrupt mask:        %08x\n",
  913.            I915_READ(SDEIMR));
  914.         dbgprintf("Graphics Interrupt enable:           %08x\n",
  915.            I915_READ(GTIER));
  916.         dbgprintf("Graphics Interrupt identity:         %08x\n",
  917.            I915_READ(GTIIR));
  918.         dbgprintf("Graphics Interrupt mask:             %08x\n",
  919.                I915_READ(GTIMR));
  920.     }
  921.     dbgprintf("Interrupts received: %d\n",
  922.            atomic_read(&dev_priv->irq_received));
  923.     for (i = 0; i < I915_NUM_RINGS; i++) {
  924.         if (IS_GEN6(dev) || IS_GEN7(dev)) {
  925.             printf("Graphics Interrupt mask (%s):       %08x\n",
  926.                    dev_priv->ring[i].name,
  927.                    I915_READ_IMR(&dev_priv->ring[i]));
  928.         }
  929. //        i915_ring_seqno_info(m, &dev_priv->ring[i]);
  930.     }
  931.  
  932.     return 0;
  933. }
  934.  
  935. void execute_buffer (struct drm_i915_gem_object *buffer, uint32_t offset,
  936.                      int size)
  937. {
  938.     struct intel_ring_buffer *ring;
  939.     drm_i915_private_t *dev_priv = main_device->dev_private;
  940.     u32 invalidate;
  941.     u32 seqno = 2;
  942.  
  943.     offset += buffer->gtt_offset;
  944. //    dbgprintf("execute %x size %d\n", offset, size);
  945.  
  946. //    asm volatile(
  947. //    "mfence \n"
  948. //    "wbinvd \n"
  949. //    "mfence  \n"
  950. //    :::"memory");
  951.  
  952.     ring = &dev_priv->ring[RCS];
  953.     ring->dispatch_execbuffer(ring, offset, size);
  954.  
  955.     invalidate = I915_GEM_DOMAIN_COMMAND;
  956.     if (INTEL_INFO(main_device)->gen >= 4)
  957.         invalidate |= I915_GEM_DOMAIN_SAMPLER;
  958.     if (ring->flush(ring, invalidate, 0))
  959.         i915_gem_next_request_seqno(ring);
  960.  
  961.     ring->irq_get(ring);
  962.  
  963.     ring->add_request(ring, &seqno);
  964.  
  965. //    i915_interrupt_info(main_device);
  966.  
  967. //    ironlake_enable_vblank(main_device, 0);
  968. };
  969.  
  970.  
  971. int blit_textured(u32 hbitmap, int  dst_x, int dst_y,
  972.                int src_x, int src_y, u32 w, u32 h)
  973. {
  974.     drm_i915_private_t *dev_priv = main_device->dev_private;
  975.  
  976.     bitmap_t  *src_bitmap, *dst_bitmap;
  977.     bitmap_t   screen;
  978.  
  979.     rect_t     winrc;
  980.  
  981. //    dbgprintf("  handle: %d dx %d dy %d sx %d sy %d w %d h %d\n",
  982. //              hbitmap, dst_x, dst_y, src_x, src_y, w, h);
  983.  
  984.     if(unlikely(hbitmap==0))
  985.         return -1;
  986.  
  987.     src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  988. //    dbgprintf("bitmap %x\n", src_bitmap);
  989.  
  990.     if(unlikely(src_bitmap==NULL))
  991.         return -1;
  992.  
  993.     GetWindowRect(&winrc);
  994.  
  995.     screen.pitch  = os_display->pitch;
  996.     screen.gaddr  = 0;
  997.     screen.width  = os_display->width;
  998.     screen.height = os_display->height;
  999.     screen.obj    = (void*)-1;
  1000.  
  1001.     dst_bitmap = &screen;
  1002.  
  1003.     dst_x+= winrc.left;
  1004.     dst_y+= winrc.top;
  1005.  
  1006.     sna_blit_copy(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y);
  1007.  
  1008. };
  1009.  
  1010.