Subversion Repositories Kolibri OS

Rev

Rev 2338 | Rev 2342 | 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.  
  21. typedef struct
  22. {
  23.     kobj_t     header;
  24.  
  25.     uint32_t  *data;
  26.     uint32_t   hot_x;
  27.     uint32_t   hot_y;
  28.  
  29.     struct list_head   list;
  30.     struct drm_i915_gem_object  *cobj;
  31. }cursor_t;
  32.  
  33. #define CURSOR_WIDTH 64
  34. #define CURSOR_HEIGHT 64
  35.  
  36.  
  37. struct tag_display
  38. {
  39.     int  x;
  40.     int  y;
  41.     int  width;
  42.     int  height;
  43.     int  bpp;
  44.     int  vrefresh;
  45.     int  pitch;
  46.     int  lfb;
  47.  
  48.     int  supported_modes;
  49.     struct drm_device    *ddev;
  50.     struct drm_connector *connector;
  51.     struct drm_crtc      *crtc;
  52.  
  53.     struct list_head   cursors;
  54.  
  55.     cursor_t   *cursor;
  56.     int       (*init_cursor)(cursor_t*);
  57.     cursor_t* (__stdcall *select_cursor)(cursor_t*);
  58.     void      (*show_cursor)(int show);
  59.     void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
  60.     void      (__stdcall *restore_cursor)(int x, int y);
  61.     void      (*disable_mouse)(void);
  62. };
  63.  
  64.  
  65. static display_t *os_display;
  66.  
  67. u32_t cmd_buffer;
  68. u32_t cmd_offset;
  69.  
  70. int init_cursor(cursor_t *cursor);
  71. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  72. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  73.  
  74. void __stdcall restore_cursor(int x, int y)
  75. {};
  76.  
  77. void disable_mouse(void)
  78. {};
  79.  
  80. static int count_connector_modes(struct drm_connector* connector)
  81. {
  82.     struct drm_display_mode  *mode;
  83.     int count = 0;
  84.  
  85.     list_for_each_entry(mode, &connector->modes, head)
  86.     {
  87.         count++;
  88.     };
  89.     return count;
  90. };
  91.  
  92. int init_display_kms(struct drm_device *dev)
  93. {
  94.     struct drm_connector    *connector;
  95.     struct drm_connector_helper_funcs *connector_funcs;
  96.     struct drm_encoder      *encoder;
  97.     struct drm_crtc         *crtc = NULL;
  98.     struct drm_framebuffer  *fb;
  99.  
  100.     cursor_t  *cursor;
  101.     u32_t      ifl;
  102.  
  103.     ENTER();
  104.  
  105.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  106.     {
  107.         if( connector->status != connector_status_connected)
  108.             continue;
  109.  
  110.         connector_funcs = connector->helper_private;
  111.         encoder = connector_funcs->best_encoder(connector);
  112.         if( encoder == NULL)
  113.         {
  114.             dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
  115.                       connector, connector->base.id);
  116.             continue;
  117.         }
  118.         connector->encoder = encoder;
  119.  
  120.         dbgprintf("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x\n",
  121.                connector, connector->base.id,
  122.                connector->status, connector->encoder,
  123.                encoder->crtc);
  124.  
  125.         crtc = encoder->crtc;
  126.         break;
  127.     };
  128.  
  129.     if(connector == NULL)
  130.     {
  131.         dbgprintf("No active connectors!\n");
  132.         return -1;
  133.     };
  134.  
  135.     if(crtc == NULL)
  136.     {
  137.         struct drm_crtc *tmp_crtc;
  138.         int crtc_mask = 1;
  139.  
  140.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  141.         {
  142.             if (encoder->possible_crtcs & crtc_mask)
  143.             {
  144.                 crtc = tmp_crtc;
  145.                 encoder->crtc = crtc;
  146.                 break;
  147.             };
  148.             crtc_mask <<= 1;
  149.         };
  150.     };
  151.  
  152.     if(crtc == NULL)
  153.     {
  154.         dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
  155.         return -1;
  156.     };
  157.  
  158.  
  159.     DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id);
  160.  
  161.     os_display = GetDisplay();
  162.  
  163.     os_display->ddev = dev;
  164.     os_display->connector = connector;
  165.     os_display->crtc = crtc;
  166.  
  167.     os_display->supported_modes = count_connector_modes(connector);
  168.  
  169.  
  170.     ifl = safe_cli();
  171.     {
  172.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  173.  
  174.         list_for_each_entry(cursor, &os_display->cursors, list)
  175.         {
  176.             init_cursor(cursor);
  177.         };
  178.  
  179.         os_display->restore_cursor(0,0);
  180.         os_display->init_cursor    = init_cursor;
  181.         os_display->select_cursor  = select_cursor_kms;
  182.         os_display->show_cursor    = NULL;
  183.         os_display->move_cursor    = move_cursor_kms;
  184.         os_display->restore_cursor = restore_cursor;
  185.         os_display->disable_mouse  = disable_mouse;
  186.  
  187.         intel_crtc->cursor_x = os_display->width/2;
  188.         intel_crtc->cursor_y = os_display->height/2;
  189.  
  190.         select_cursor_kms(os_display->cursor);
  191.     };
  192.     safe_sti(ifl);
  193.  
  194.     {
  195. #define XY_COLOR_BLT        ((2<<29)|(0x50<<22)|(0x4))
  196. #define BLT_WRITE_ALPHA     (1<<21)
  197. #define BLT_WRITE_RGB       (1<<20)
  198.  
  199.         drm_i915_private_t *dev_priv = dev->dev_private;
  200.         struct drm_i915_gem_object *obj;
  201.         struct intel_ring_buffer *ring;
  202.  
  203.         u32_t br13, cmd, *b;
  204.  
  205.         int      n=0;
  206.  
  207.         cmd =  XY_COLOR_BLT | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
  208.         br13 = os_display->pitch;
  209.         br13 |= 0xF0 << 16;
  210.         br13 |= 3 << 24;
  211.  
  212.         obj = i915_gem_alloc_object(dev, 4096);
  213.         i915_gem_object_pin(obj, 4096, true);
  214.  
  215.         cmd_buffer = MapIoMem(obj->pages[0], 4096, PG_SW|PG_NOCACHE);
  216.         cmd_offset = obj->gtt_offset;
  217.  
  218.         b = (u32_t*)cmd_buffer;
  219.         b[n++] = cmd;
  220.         b[n++] = br13;
  221.         b[n++] = 0; // top, left
  222.         b[n++] = (128 << 16) | 128; // bottom, right
  223.         b[n++] = 0; // dst
  224.         b[n++] = 0x0000FF00;
  225.         b[n++] = MI_BATCH_BUFFER_END;
  226.         if( n & 1)
  227.             b[n++] = MI_NOOP;
  228.  
  229. //        cmd_buffer = (u32_t)&b[n];
  230. //        i915_gem_object_set_to_gtt_domain(obj, false);
  231.  
  232.  
  233.         ring = &dev_priv->ring[BCS];
  234.         ring->dispatch_execbuffer(ring,cmd_offset, n*4);
  235.  
  236.     };
  237.  
  238.     LEAVE();
  239.  
  240.     return 0;
  241. };
  242.  
  243.  
  244. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  245.               videomode_t *reqmode, bool strict)
  246. {
  247.     struct drm_display_mode  *mode = NULL, *tmpmode;
  248.     drm_i915_private_t *dev_priv = dev->dev_private;
  249.     struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper;
  250.  
  251.     bool ret = false;
  252.  
  253.     ENTER();
  254.  
  255.     dbgprintf("width %d height %d vrefresh %d\n",
  256.                reqmode->width, reqmode->height, reqmode->freq);
  257.  
  258.     list_for_each_entry(tmpmode, &connector->modes, head)
  259.     {
  260.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  261.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  262.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  263.         {
  264.             mode = tmpmode;
  265.             goto do_set;
  266.         }
  267.     };
  268.  
  269.     if( (mode == NULL) && (strict == false) )
  270.     {
  271.         list_for_each_entry(tmpmode, &connector->modes, head)
  272.         {
  273.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  274.                 (drm_mode_height(tmpmode) == reqmode->height) )
  275.             {
  276.                 mode = tmpmode;
  277.                 goto do_set;
  278.             }
  279.         };
  280.     };
  281.  
  282. do_set:
  283.  
  284.     if( mode != NULL )
  285.     {
  286.         struct drm_framebuffer   *fb;
  287.         struct drm_encoder       *encoder;
  288.         struct drm_crtc          *crtc;
  289.  
  290.         char *con_name;
  291.         char *enc_name;
  292.  
  293.         encoder = connector->encoder;
  294.         crtc = encoder->crtc;
  295.  
  296.         con_name = drm_get_connector_name(connector);
  297.         enc_name = drm_get_encoder_name(encoder);
  298.  
  299.         dbgprintf("set mode %d %d connector %s encoder %s\n",
  300.                    reqmode->width, reqmode->height, con_name, enc_name);
  301.  
  302.         fb = fb_helper->fb;
  303.  
  304.         fb->width  = reqmode->width;
  305.         fb->height = reqmode->height;
  306.         fb->pitch  = ALIGN(reqmode->width * 4, 64);
  307.         fb->bits_per_pixel = 32;
  308.         fb->depth == 24;
  309.  
  310.         crtc->fb = fb;
  311.         crtc->enabled = true;
  312.         os_display->crtc = crtc;
  313.  
  314.         ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
  315.  
  316. //        select_cursor_kms(rdisplay->cursor);
  317. //        radeon_show_cursor_kms(crtc);
  318.  
  319.         if (ret == true)
  320.         {
  321.             os_display->width    = fb->width;
  322.             os_display->height   = fb->height;
  323.             os_display->pitch    = fb->pitch;
  324.             os_display->vrefresh = drm_mode_vrefresh(mode);
  325.  
  326.             sysSetScreen(fb->width, fb->height, fb->pitch);
  327.  
  328.             dbgprintf("new mode %d x %d pitch %d\n",
  329.                        fb->width, fb->height, fb->pitch);
  330.         }
  331.         else
  332.             DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  333.                        fb->width, fb->height, crtc);
  334.     }
  335.  
  336.     LEAVE();
  337.     return ret;
  338. };
  339.  
  340.  
  341.  
  342. int get_videomodes(videomode_t *mode, int *count)
  343. {
  344.     int err = -1;
  345.  
  346.     ENTER();
  347.  
  348.     dbgprintf("mode %x count %d\n", mode, *count);
  349.  
  350.     if( *count == 0 )
  351.     {
  352.         *count = os_display->supported_modes;
  353.         err = 0;
  354.     }
  355.     else if( mode != NULL )
  356.     {
  357.         struct drm_display_mode  *drmmode;
  358.         int i = 0;
  359.  
  360.         if( *count > os_display->supported_modes)
  361.             *count = os_display->supported_modes;
  362.  
  363.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  364.         {
  365.             if( i < *count)
  366.             {
  367.                 mode->width  = drm_mode_width(drmmode);
  368.                 mode->height = drm_mode_height(drmmode);
  369.                 mode->bpp    = 32;
  370.                 mode->freq   = drm_mode_vrefresh(drmmode);
  371.                 i++;
  372.                 mode++;
  373.             }
  374.             else break;
  375.         };
  376.         *count = i;
  377.         err = 0;
  378.     };
  379.     LEAVE();
  380.     return err;
  381. };
  382.  
  383. int set_user_mode(videomode_t *mode)
  384. {
  385.     int err = -1;
  386.  
  387.     ENTER();
  388.  
  389.     dbgprintf("width %d height %d vrefresh %d\n",
  390.                mode->width, mode->height, mode->freq);
  391.  
  392.     if( (mode->width  != 0)  &&
  393.         (mode->height != 0)  &&
  394.         (mode->freq   != 0 ) &&
  395.         ( (mode->width   != os_display->width)  ||
  396.           (mode->height  != os_display->height) ||
  397.           (mode->freq    != os_display->vrefresh) ) )
  398.     {
  399.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  400.             err = 0;
  401.     };
  402.  
  403.     LEAVE();
  404.     return err;
  405. };
  406.  
  407. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  408. {
  409.     list_del(&cursor->list);
  410. //    radeon_bo_unpin(cursor->robj);
  411. //    KernelFree(cursor->data);
  412.     __DestroyObject(cursor);
  413. };
  414.  
  415. int init_cursor(cursor_t *cursor)
  416. {
  417.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  418.     struct drm_i915_gem_object *obj;
  419.     uint32_t *bits;
  420.     uint32_t *src;
  421.  
  422.     int       i,j;
  423.     int       ret;
  424.  
  425.     ENTER();
  426.  
  427.     if (dev_priv->info->cursor_needs_physical)
  428.     {
  429.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  430.         if (unlikely(bits == NULL))
  431.             return ENOMEM;
  432.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  433.     }
  434.     else
  435.     {
  436.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  437.         if (unlikely(obj == NULL))
  438.             return -ENOMEM;
  439.  
  440.         ret = i915_gem_object_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true);
  441.         if (ret) {
  442. //           drm_gem_object_unreference(&obj->base);
  443.             return ret;
  444.         }
  445.  
  446. /* You don't need to worry about fragmentation issues.
  447.  * GTT space is continuous. I guarantee it.                           */
  448.  
  449.         bits = (u32*)MapIoMem(get_bus_addr() + obj->gtt_offset,
  450.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  451.  
  452.         if (unlikely(bits == NULL))
  453.         {
  454. //          i915_gem_object_unpin(obj);
  455. //           drm_gem_object_unreference(&obj->base);
  456.             return -ENOMEM;
  457.         };
  458.         cursor->cobj = obj;
  459.     };
  460.  
  461.     src = cursor->data;
  462.  
  463.     for(i = 0; i < 32; i++)
  464.     {
  465.         for(j = 0; j < 32; j++)
  466.             *bits++ = *src++;
  467.         for(j = 32; j < CURSOR_WIDTH; j++)
  468.             *bits++ = 0;
  469.     }
  470.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  471.         *bits++ = 0;
  472.  
  473. // release old cursor
  474.  
  475.     KernelFree(cursor->data);
  476.  
  477.     cursor->data = bits;
  478.  
  479.     cursor->header.destroy = destroy_cursor;
  480.     LEAVE();
  481.  
  482.     return 0;
  483. }
  484.  
  485.  
  486. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  487. {
  488.     struct drm_device *dev = crtc->dev;
  489.     struct drm_i915_private *dev_priv = dev->dev_private;
  490.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  491.     int pipe = intel_crtc->pipe;
  492.     bool visible = base != 0;
  493.  
  494.     if (intel_crtc->cursor_visible != visible) {
  495.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  496.         if (base) {
  497.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  498.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  499.             cntl |= pipe << 28; /* Connect to correct pipe */
  500.         } else {
  501.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  502.             cntl |= CURSOR_MODE_DISABLE;
  503.         }
  504.         I915_WRITE(CURCNTR(pipe), cntl);
  505.  
  506.         intel_crtc->cursor_visible = visible;
  507.     }
  508.     /* and commit changes on next vblank */
  509.     I915_WRITE(CURBASE(pipe), base);
  510. }
  511.  
  512. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  513. {
  514.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  515.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  516.     u32 base, pos;
  517.     bool visible;
  518.  
  519.     int pipe = intel_crtc->pipe;
  520.  
  521.     intel_crtc->cursor_x = x;
  522.     intel_crtc->cursor_y = y;
  523.  
  524.     x = x - cursor->hot_x;
  525.     y = y - cursor->hot_y;
  526.  
  527.  
  528.     pos = 0;
  529.  
  530.     base = intel_crtc->cursor_addr;
  531.     if (x >= os_display->width)
  532.         base = 0;
  533.  
  534.     if (y >= os_display->height)
  535.         base = 0;
  536.  
  537.     if (x < 0)
  538.     {
  539.         if (x + intel_crtc->cursor_width < 0)
  540.             base = 0;
  541.  
  542.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  543.         x = -x;
  544.     }
  545.     pos |= x << CURSOR_X_SHIFT;
  546.  
  547.     if (y < 0)
  548.     {
  549.         if (y + intel_crtc->cursor_height < 0)
  550.             base = 0;
  551.  
  552.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  553.         y = -y;
  554.     }
  555.     pos |= y << CURSOR_Y_SHIFT;
  556.  
  557.     visible = base != 0;
  558.     if (!visible && !intel_crtc->cursor_visible)
  559.         return;
  560.  
  561.     I915_WRITE(CURPOS(pipe), pos);
  562. //    if (IS_845G(dev) || IS_I865G(dev))
  563. //        i845_update_cursor(crtc, base);
  564. //    else
  565.         i9xx_update_cursor(os_display->crtc, base);
  566.  
  567. };
  568.  
  569.  
  570. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  571. {
  572.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  573.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  574.     cursor_t *old;
  575.  
  576.     old = os_display->cursor;
  577.     os_display->cursor = cursor;
  578.  
  579.     if (!dev_priv->info->cursor_needs_physical)
  580.        intel_crtc->cursor_addr = cursor->cobj->gtt_offset;
  581.     else
  582.         intel_crtc->cursor_addr = cursor->cobj;
  583.  
  584.     intel_crtc->cursor_width = 32;
  585.     intel_crtc->cursor_height = 32;
  586.  
  587.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  588.     return old;
  589. };
  590.  
  591. extern struct drm_device *main_device;
  592.  
  593. #define XY_SRC_COPY_BLT_CMD     ((2<<29)|(0x53<<22)|6)
  594.  
  595. int video_blit(uint64_t src_offset, int  x, int y,
  596.                     int w, int h, int pitch)
  597. {
  598.  
  599.     drm_i915_private_t *dev_priv = main_device->dev_private;
  600.     struct intel_ring_buffer *ring;
  601.  
  602.     u32_t br13, cmd, *b;
  603.     u32_t offset;
  604.  
  605.     int      n=0;
  606.  
  607. //    if( cmd_buffer & 0xF80 )
  608. //        cmd_buffer&= 0xFFFFF000;
  609.  
  610. //    b = (u32_t*)ALIGN(cmd_buffer,16);
  611.  
  612. //    offset = cmd_offset + ((u32_t)b & 0xFFF);
  613.  
  614.     b = cmd_buffer;
  615.  
  616.     cmd =  XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB;
  617.     br13 = os_display->pitch;
  618.     br13 |= 0xCC << 16;
  619.     br13 |= 3 << 24;
  620.  
  621.     b[n++] = cmd;
  622.     b[n++] = br13;
  623.     b[n++] = (y << 16) | x;
  624.     b[n++] = ( (y+h) << 16) | (x+w); // bottom, right
  625.     b[n++] = 0; // dst_offset
  626.     b[n++] = 0; //src_top|src_left
  627.  
  628.     b[n++] = pitch;
  629.     b[n++] = (u32_t)src_offset;
  630.  
  631.     b[n++] = MI_BATCH_BUFFER_END;
  632.     if( n & 1)
  633.         b[n++] = MI_NOOP;
  634.  
  635. //    i915_gem_object_set_to_gtt_domain(obj, false);
  636.  
  637.     ring = &dev_priv->ring[BCS];
  638.     ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  639.  
  640.     intel_ring_begin(ring, 4);
  641. //    if (ret)
  642. //        return ret;
  643.  
  644. //    cmd = MI_FLUSH_DW;
  645. //    if (invalidate & I915_GEM_GPU_DOMAINS)
  646. //        cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
  647.     intel_ring_emit(ring, MI_FLUSH_DW);
  648.     intel_ring_emit(ring, 0);
  649.     intel_ring_emit(ring, 0);
  650.     intel_ring_emit(ring, MI_NOOP);
  651.     intel_ring_advance(ring);
  652.  
  653.  
  654. fail:
  655.     return -1;
  656. };
  657.  
  658.  
  659. int blit_video(u32 hbitmap, int  dst_x, int dst_y,
  660.                int src_x, int src_y, u32 w, u32 h)
  661. {
  662.     drm_i915_private_t *dev_priv = main_device->dev_private;
  663.     struct intel_ring_buffer *ring;
  664.  
  665.     bitmap_t  *bitmap;
  666.     u32_t br13, cmd, *b;
  667.     u32_t offset;
  668.  
  669.     int      n=0;
  670.  
  671.     if(unlikely(hbitmap==0))
  672.         return -1;
  673.  
  674.     bitmap = hman_get_data(&bm_man, hbitmap);
  675.  
  676.     if(unlikely(bitmap==NULL))
  677.         return -1;
  678.  
  679. //    if( cmd_buffer & 0xF80 )
  680. //        cmd_buffer&= 0xFFFFF000;
  681.  
  682. //    b = (u32_t*)ALIGN(cmd_buffer,16);
  683.  
  684. //    offset = cmd_offset + ((u32_t)b & 0xFFF);
  685.  
  686.     b = cmd_buffer;
  687.  
  688.     cmd =  XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB;
  689.     br13 = os_display->pitch;
  690.     br13 |= 0xCC << 16;
  691.     br13 |= 3 << 24;
  692.  
  693.     b[n++] = cmd;
  694.     b[n++] = br13;
  695.     b[n++] = (dst_y << 16) | dst_x;
  696.     b[n++] = ( (dst_y+h) << 16) | (dst_x+w); // bottom, right
  697.     b[n++] = 0; // dst_offset
  698.     b[n++] = (src_y << 16) | src_x;
  699.  
  700.     b[n++] = bitmap->pitch;
  701.     b[n++] = bitmap->gaddr;
  702.  
  703.     b[n++] = MI_BATCH_BUFFER_END;
  704.     if( n & 1)
  705.         b[n++] = MI_NOOP;
  706.  
  707. //    i915_gem_object_set_to_gtt_domain(obj, false);
  708.  
  709.     ring = &dev_priv->ring[BCS];
  710.     ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  711.  
  712.     intel_ring_begin(ring, 4);
  713. //    if (ret)
  714. //        return ret;
  715.  
  716.     intel_ring_emit(ring, MI_FLUSH_DW);
  717.     intel_ring_emit(ring, 0);
  718.     intel_ring_emit(ring, 0);
  719.     intel_ring_emit(ring, MI_NOOP);
  720.     intel_ring_advance(ring);
  721.  
  722.     return 0;
  723. fail:
  724.     return -1;
  725. };
  726.