Subversion Repositories Kolibri OS

Rev

Rev 3764 | Rev 5271 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <drm/drmP.h>
  3. #include <drm/radeon_drm.h>
  4. #include <drm.h>
  5. #include <drm_mm.h>
  6. #include "radeon.h"
  7. #include "radeon_object.h"
  8. #include "drm_fb_helper.h"
  9. #include "hmm.h"
  10. #include "bitmap.h"
  11. #include "display.h"
  12.  
  13. extern struct drm_framebuffer *main_fb;
  14. extern struct drm_gem_object  *main_fb_obj;
  15.  
  16. display_t *os_display;
  17.  
  18. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  19. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  20.  
  21. int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
  22.  
  23. void disable_mouse(void);
  24.  
  25. static void radeon_show_cursor_kms(struct drm_crtc *crtc)
  26. {
  27.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  28.     struct radeon_device *rdev = crtc->dev->dev_private;
  29.  
  30.     if (ASIC_IS_DCE4(rdev)) {
  31.         WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
  32.         WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
  33.                EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
  34.     } else if (ASIC_IS_AVIVO(rdev)) {
  35.         WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
  36.         WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
  37.                  (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
  38.     } else {
  39.         switch (radeon_crtc->crtc_id) {
  40.         case 0:
  41.             WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
  42.             break;
  43.         case 1:
  44.             WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
  45.             break;
  46.         default:
  47.             return;
  48.         }
  49.  
  50.         WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
  51.                       (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
  52.              ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
  53.     }
  54. }
  55.  
  56. static void radeon_lock_cursor_kms(struct drm_crtc *crtc, bool lock)
  57. {
  58.     struct radeon_device *rdev = crtc->dev->dev_private;
  59.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  60.     uint32_t cur_lock;
  61.  
  62.     if (ASIC_IS_DCE4(rdev)) {
  63.         cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
  64.         if (lock)
  65.             cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
  66.         else
  67.             cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
  68.         WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
  69.     } else if (ASIC_IS_AVIVO(rdev)) {
  70.         cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
  71.         if (lock)
  72.             cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
  73.         else
  74.             cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
  75.         WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
  76.     } else {
  77.         cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
  78.         if (lock)
  79.             cur_lock |= RADEON_CUR_LOCK;
  80.         else
  81.             cur_lock &= ~RADEON_CUR_LOCK;
  82.         WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
  83.     }
  84. }
  85.  
  86. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  87. {
  88.     struct radeon_device *rdev;
  89.     struct radeon_crtc   *radeon_crtc;
  90.     cursor_t *old;
  91.     uint32_t  gpu_addr;
  92.  
  93.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  94.     radeon_crtc = to_radeon_crtc(os_display->crtc);
  95.  
  96.     old = os_display->cursor;
  97.  
  98.     os_display->cursor = cursor;
  99.     gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  100.  
  101.     if (ASIC_IS_DCE4(rdev)) {
  102.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
  103.                0);
  104.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
  105.                gpu_addr);
  106.     } else if (ASIC_IS_AVIVO(rdev)) {
  107.         if (rdev->family >= CHIP_RV770)
  108.             WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
  109.         WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
  110.     }
  111.     else {
  112.         radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start;
  113.         /* offset is from DISP(2)_BASE_ADDRESS */
  114.         WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
  115.     }
  116.  
  117.     return old;
  118. };
  119.  
  120. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  121. {
  122.     struct radeon_device *rdev;
  123.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  124.     struct drm_crtc *crtc = os_display->crtc;
  125.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  126.  
  127.     int hot_x = cursor->hot_x;
  128.     int hot_y = cursor->hot_y;
  129.     int w = 32;
  130.  
  131.     radeon_lock_cursor_kms(crtc, true);
  132.  
  133.     if (ASIC_IS_DCE4(rdev)) {
  134.         WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset,
  135.                (x << 16) | y);
  136.         WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset,
  137.                (hot_x << 16) | hot_y);
  138.         WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
  139.                ((w - 1) << 16) | 31);
  140.     } else if (ASIC_IS_AVIVO(rdev)) {
  141.         WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
  142.                (x << 16) | y);
  143.         WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
  144.                (hot_x << 16) | hot_y);
  145.         WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
  146.                ((w - 1) << 16) | 31);
  147.     } else {
  148.         if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
  149.             y *= 2;
  150.  
  151.         uint32_t  gpu_addr;
  152.         int       xorg =0, yorg=0;
  153.  
  154.         x = x - hot_x;
  155.         y = y - hot_y;
  156.  
  157.         if( x < 0 )
  158.         {
  159.             xorg = -x + 1;
  160.             x = 0;
  161.         }
  162.  
  163.         if( y < 0 )
  164.         {
  165.             yorg = -hot_y + 1;
  166.             y = 0;
  167.         };
  168.  
  169.         WREG32(RADEON_CUR_HORZ_VERT_OFF,
  170.                (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
  171.         WREG32(RADEON_CUR_HORZ_VERT_POSN,
  172.                (RADEON_CUR_LOCK | (x << 16) | y));
  173.  
  174.         gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  175.  
  176.         /* offset is from DISP(2)_BASE_ADDRESS */
  177.         WREG32(RADEON_CUR_OFFSET,
  178.          (gpu_addr - rdev->mc.vram_start + (yorg * 256)));
  179.     }
  180.     radeon_lock_cursor_kms(crtc, false);
  181. }
  182.  
  183. static char *manufacturer_name(unsigned char *x)
  184. {
  185.     static char name[4];
  186.  
  187.     name[0] = ((x[0] & 0x7C) >> 2) + '@';
  188.     name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
  189.     name[2] = (x[1] & 0x1F) + '@';
  190.     name[3] = 0;
  191.  
  192.     return name;
  193. }
  194.  
  195. static int set_mode(struct drm_device *dev, struct drm_connector *connector,
  196.                     struct drm_crtc *crtc, videomode_t *reqmode, bool strict)
  197. {
  198.     struct drm_display_mode  *mode = NULL, *tmpmode;
  199.     struct drm_framebuffer  *fb         = NULL;
  200.     struct drm_mode_set     set;
  201.     const char *con_name;
  202.     unsigned hdisplay, vdisplay;
  203.     int ret;
  204.  
  205.     drm_modeset_lock_all(dev);
  206.  
  207.     list_for_each_entry(tmpmode, &connector->modes, head)
  208.     {
  209.         if( (tmpmode->hdisplay == reqmode->width)  &&
  210.             (tmpmode->vdisplay == reqmode->height) &&
  211.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  212.         {
  213.             mode = tmpmode;
  214.             goto do_set;
  215.         }
  216.         };
  217.  
  218.     if( (mode == NULL) && (strict == false) )
  219.     {
  220.         list_for_each_entry(tmpmode, &connector->modes, head)
  221.         {
  222.             if( (tmpmode->hdisplay == reqmode->width)  &&
  223.                 (tmpmode->vdisplay == reqmode->height) )
  224.             {
  225.                 mode = tmpmode;
  226.                 goto do_set;
  227.             }
  228.        };
  229.     };
  230.  
  231.     DRM_ERROR("%s failed\n", __FUNCTION__);
  232.  
  233.     return -1;
  234.  
  235. do_set:
  236.  
  237.     con_name = connector->name;
  238.  
  239.     DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s\n",
  240.               reqmode->width, reqmode->height, crtc->base.id,
  241.               con_name);
  242.  
  243.     drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  244.  
  245.     hdisplay = mode->hdisplay;
  246.     vdisplay = mode->vdisplay;
  247.  
  248.     if (crtc->invert_dimensions)
  249.         swap(hdisplay, vdisplay);
  250.  
  251.     fb = main_fb;
  252.  
  253.     fb->width  = reqmode->width;
  254.     fb->height = reqmode->height;
  255.  
  256.     fb->pitches[0] =
  257.     fb->pitches[1] =
  258.     fb->pitches[2] =
  259.     fb->pitches[3] = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
  260.     fb->bits_per_pixel = 32;
  261.     fb->depth = 24;
  262.  
  263.     crtc->enabled = true;
  264.     os_display->crtc = crtc;
  265.  
  266.     set.crtc = crtc;
  267.     set.x = 0;
  268.     set.y = 0;
  269.     set.mode = mode;
  270.     set.connectors = &connector;
  271.     set.num_connectors = 1;
  272.     set.fb = fb;
  273.  
  274.     ret = drm_mode_set_config_internal(&set);
  275.  
  276.     drm_modeset_unlock_all(dev);
  277.  
  278.     select_cursor_kms(os_display->cursor);
  279.     radeon_show_cursor_kms(crtc);
  280.  
  281.     if ( !ret )
  282.     {
  283.         os_display->width    = fb->width;
  284.         os_display->height   = fb->height;
  285.         os_display->vrefresh = drm_mode_vrefresh(mode);
  286.  
  287.         sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  288.  
  289.         DRM_DEBUG_KMS("new mode %d x %d pitch %d\n",
  290.                        fb->width, fb->height, fb->pitches[0]);
  291.     }
  292.     else
  293.         DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  294.                    fb->width, fb->height, crtc);
  295.  
  296.     return ret;
  297. }
  298.  
  299. static int count_connector_modes(struct drm_connector* connector)
  300. {
  301.     struct drm_display_mode  *mode;
  302.     int count = 0;
  303.  
  304.     list_for_each_entry(mode, &connector->modes, head)
  305.     {
  306.         count++;
  307.     };
  308.     return count;
  309. };
  310.  
  311. static struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder)
  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.             encoder->crtc = tmp_crtc;
  321.             DRM_DEBUG_KMS("use CRTC %p ID %d\n", tmp_crtc, tmp_crtc->base.id);
  322.             return tmp_crtc;
  323.         };
  324.         crtc_mask <<= 1;
  325.     };
  326.     return NULL;
  327. };
  328.  
  329. static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector,
  330.                   struct drm_crtc **boot_crtc)
  331. {
  332.     struct drm_connector_helper_funcs *connector_funcs;
  333.     struct drm_connector *connector;
  334.     struct drm_encoder   *encoder;
  335.     struct drm_crtc      *crtc;
  336.  
  337.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  338.     {
  339.         if( connector->status != connector_status_connected)
  340.             continue;
  341.  
  342.         encoder = connector->encoder;
  343.  
  344.         if(encoder == NULL)
  345.         {
  346.             connector_funcs = connector->helper_private;
  347.             encoder = connector_funcs->best_encoder(connector);
  348.  
  349.             if( encoder == NULL)
  350.             {
  351.                 DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
  352.                         connector, connector->base.id);
  353.                 continue;
  354.             };
  355.         }
  356.  
  357.         crtc = encoder->crtc;
  358.         if(crtc == NULL)
  359.             crtc = get_possible_crtc(dev, encoder);
  360.  
  361.         if(crtc != NULL)
  362.         {
  363.             *boot_connector = connector;
  364.             *boot_crtc = crtc;
  365.             connector->encoder = encoder;
  366.             DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %p ID: %d CRTC %p ID:%d\n",
  367.                            connector, connector->base.id, connector->status,
  368.                            encoder, encoder->base.id, crtc, crtc->base.id );
  369.             return 0;
  370.         }
  371.         else
  372.             DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
  373.  
  374.     };
  375.  
  376.     return -ENOENT;
  377. };
  378.  
  379. static int get_boot_mode(struct drm_connector *connector, videomode_t *usermode)
  380. {
  381.     struct drm_display_mode *mode;
  382.  
  383.     list_for_each_entry(mode, &connector->modes, head)
  384.     {
  385.         DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n",
  386.                 mode->hdisplay, mode->vdisplay,
  387.                 drm_mode_vrefresh(mode));
  388.  
  389.         if( os_display->width  == mode->hdisplay &&
  390.             os_display->height == mode->vdisplay &&
  391.             drm_mode_vrefresh(mode) == 60)
  392.         {
  393.             usermode->width  = os_display->width;
  394.             usermode->height = os_display->height;
  395.             usermode->freq   = 60;
  396.             return 1;
  397.         }
  398.     }
  399.     return 0;
  400. }
  401.  
  402. int init_display_kms(struct drm_device *dev, videomode_t *usermode)
  403. {
  404.     struct drm_connector_helper_funcs *connector_funcs;
  405.     struct drm_connector    *connector = NULL;
  406.     struct drm_crtc         *crtc = NULL;
  407.     struct drm_framebuffer  *fb;
  408.  
  409.     cursor_t            *cursor;
  410.     u32_t                ifl;
  411.     int        ret;
  412.  
  413.     mutex_lock(&dev->mode_config.mutex);
  414.  
  415.     ret = choose_config(dev, &connector, &crtc);
  416.     if(ret)
  417.     {
  418.         DRM_DEBUG_KMS("No active connectors!\n");
  419.         mutex_unlock(&dev->mode_config.mutex);
  420.         return -1;
  421.     };
  422.  
  423.     {
  424.         struct drm_display_mode *tmp, *native = NULL;
  425.         struct radeon_device *rdev = dev->dev_private;
  426.  
  427.         list_for_each_entry(tmp, &connector->modes, head) {
  428.             if (tmp->hdisplay > 16384 ||
  429.                 tmp->vdisplay > 16384)
  430.                 continue;
  431.             if (tmp->type & DRM_MODE_TYPE_PREFERRED)
  432.             {
  433.                 native = tmp;
  434.                 break;
  435.             };
  436.         }
  437.  
  438.         if( ASIC_IS_AVIVO(rdev) && native )
  439.         {
  440.             struct radeon_encoder *radeon_encoder = to_radeon_encoder(connector->encoder);
  441.             radeon_encoder->rmx_type = RMX_FULL;
  442.             radeon_encoder->native_mode = *native;
  443.         };
  444.     }
  445.  
  446. #if 0
  447.     mutex_lock(&dev->object_name_lock);
  448.     idr_preload(GFP_KERNEL);
  449.  
  450.     if (!main_fb_obj->name) {
  451.         ret = idr_alloc(&dev->object_name_idr, &main_fb_obj, 1, 0, GFP_NOWAIT);
  452.  
  453.         main_fb_obj->name = ret;
  454.  
  455.         /* Allocate a reference for the name table.  */
  456.         drm_gem_object_reference(main_fb_obj);
  457.  
  458.         DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->name );
  459.     }
  460.  
  461.     idr_preload_end();
  462.     mutex_unlock(&dev->object_name_lock);
  463.     drm_gem_object_unreference(main_fb_obj);
  464. #endif
  465.  
  466.     os_display = GetDisplay();
  467.     os_display->ddev = dev;
  468.     os_display->connector = connector;
  469.     os_display->crtc = crtc;
  470.  
  471.     os_display->supported_modes = count_connector_modes(connector);
  472.  
  473.     ifl = safe_cli();
  474.     {
  475.         list_for_each_entry(cursor, &os_display->cursors, list)
  476.         {
  477.             init_cursor(cursor);
  478.         };
  479.  
  480.         os_display->restore_cursor(0,0);
  481.         os_display->init_cursor    = init_cursor;
  482.         os_display->select_cursor  = select_cursor_kms;
  483.         os_display->show_cursor    = NULL;
  484.         os_display->move_cursor    = move_cursor_kms;
  485.         os_display->restore_cursor = restore_cursor;
  486.         os_display->disable_mouse  = disable_mouse;
  487.         select_cursor_kms(os_display->cursor);
  488.     };
  489.     safe_sti(ifl);
  490.  
  491.  
  492. //    dbgprintf("current mode %d x %d x %d\n",
  493. //              os_display->width, os_display->height, os_display->vrefresh);
  494. //    dbgprintf("user mode mode %d x %d x %d\n",
  495. //              usermode->width, usermode->height, usermode->freq);
  496.  
  497.     if( (usermode->width == 0) ||
  498.         (usermode->height == 0))
  499.     {
  500.         if( !get_boot_mode(connector, usermode))
  501.         {
  502.             struct drm_display_mode *mode;
  503.  
  504.             mode = list_entry(connector->modes.next, typeof(*mode), head);
  505.             usermode->width  = mode->hdisplay;
  506.             usermode->height = mode->vdisplay;
  507.             usermode->freq   = drm_mode_vrefresh(mode);
  508.         };
  509.     };
  510.  
  511.     mutex_unlock(&dev->mode_config.mutex);
  512.  
  513.     set_mode(dev, os_display->connector, os_display->crtc, usermode, false);
  514.  
  515.     radeon_show_cursor_kms(os_display->crtc);
  516.  
  517.     return 0;
  518. };
  519.  
  520.  
  521. int get_videomodes(videomode_t *mode, int *count)
  522. {
  523.     int err = -1;
  524.  
  525.     if( *count == 0 )
  526.     {
  527.         *count = os_display->supported_modes;
  528.         err = 0;
  529.     }
  530.     else if( mode != NULL )
  531.     {
  532.         struct drm_display_mode  *drmmode;
  533.         int i = 0;
  534.  
  535.         if( *count > os_display->supported_modes)
  536.             *count = os_display->supported_modes;
  537.  
  538.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  539.         {
  540.             if( i < *count)
  541.             {
  542.                 mode->width  = drmmode->hdisplay;
  543.                 mode->height = drmmode->vdisplay;
  544.                 mode->bpp    = 32;
  545.                 mode->freq   = drm_mode_vrefresh(drmmode);
  546.                 i++;
  547.                 mode++;
  548.             }
  549.             else break;
  550.         };
  551.         *count = i;
  552.         err = 0;
  553.     };
  554.     return err;
  555. };
  556.  
  557. int set_user_mode(videomode_t *mode)
  558. {
  559.     int err = -1;
  560.  
  561.     if( (mode->width  != 0)  &&
  562.         (mode->height != 0)  &&
  563.         (mode->freq   != 0 ) &&
  564.         ( (mode->width   != os_display->width)  ||
  565.           (mode->height  != os_display->height) ||
  566.           (mode->freq    != os_display->vrefresh) ) )
  567.     {
  568.         return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true);
  569.     };
  570.  
  571.     return -1;
  572. };
  573.  
  574.  
  575.  
  576.  
  577.  
  578. #if 0
  579. typedef struct
  580. {
  581.     int left;
  582.     int top;
  583.     int right;
  584.     int bottom;
  585. }rect_t;
  586.  
  587. extern struct hmm bm_mm;
  588. struct drm_device *main_device;
  589.  
  590. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  591.  
  592. #define CURRENT_TASK             (0x80003000)
  593.  
  594. static u32_t get_display_map()
  595. {
  596.     u32_t   addr;
  597.  
  598.     addr = (u32_t)os_display;
  599.     addr+= sizeof(display_t);            /*  shoot me  */
  600.     return *(u32_t*)addr;
  601. }
  602.  
  603. #include "clip.inc"
  604. #include "r100d.h"
  605.  
  606. # define PACKET3_BITBLT                 0x92
  607. # define PACKET3_TRANS_BITBLT           0x9C
  608. # define R5XX_SRC_CMP_EQ_COLOR      (4 <<  0)
  609. # define R5XX_SRC_CMP_NEQ_COLOR     (5 <<  0)
  610. # define R5XX_CLR_CMP_SRC_SOURCE    (1 << 24)
  611.  
  612. int srv_blit_bitmap(u32 hbitmap, int  dst_x, int dst_y,
  613.                int src_x, int src_y, u32 w, u32 h)
  614. {
  615.     struct context *context;
  616.  
  617.     bitmap_t  *bitmap;
  618.     rect_t     winrc;
  619.     clip_t     dst_clip;
  620.     clip_t     src_clip;
  621.     u32_t      width;
  622.     u32_t      height;
  623.  
  624.     u32_t      br13, cmd, slot_mask, *b;
  625.     u32_t      offset;
  626.     u8         slot;
  627.     int        n=0;
  628.     int        ret;
  629.  
  630.     if(unlikely(hbitmap==0))
  631.         return -1;
  632.  
  633.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, hbitmap);
  634.  
  635.     if(unlikely(bitmap==NULL))
  636.         return -1;
  637.  
  638.     context = get_context(main_drm_device);
  639.     if(unlikely(context == NULL))
  640.         return -1;
  641.  
  642.     GetWindowRect(&winrc);
  643.     {
  644.         static warn_count;
  645.  
  646.         if(warn_count < 1)
  647.         {
  648.             printf("left %d top %d right %d bottom %d\n",
  649.                     winrc.left, winrc.top, winrc.right, winrc.bottom);
  650.             printf("bitmap width %d height %d\n", w, h);
  651.             warn_count++;
  652.         };
  653.     };
  654.  
  655.  
  656.     dst_clip.xmin   = 0;
  657.     dst_clip.ymin   = 0;
  658.     dst_clip.xmax   = winrc.right-winrc.left;
  659.     dst_clip.ymax   = winrc.bottom -winrc.top;
  660.  
  661.     src_clip.xmin   = 0;
  662.     src_clip.ymin   = 0;
  663.     src_clip.xmax   = bitmap->width  - 1;
  664.     src_clip.ymax   = bitmap->height - 1;
  665.  
  666.     width  = w;
  667.     height = h;
  668.  
  669.     if( blit_clip(&dst_clip, &dst_x, &dst_y,
  670.                   &src_clip, &src_x, &src_y,
  671.                   &width, &height) )
  672.         return 0;
  673.  
  674.     dst_x+= winrc.left;
  675.     dst_y+= winrc.top;
  676.  
  677.     slot = *((u8*)CURRENT_TASK);
  678.  
  679.     slot_mask = (u32_t)slot<<24;
  680.  
  681.     {
  682. #if 0
  683. #else
  684.         u8* src_offset;
  685.         u8* dst_offset;
  686.         u32 color;
  687.  
  688.         u32 ifl;
  689.  
  690.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  691.         src_offset += (u32)bitmap->uaddr;
  692.  
  693.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  694.         dst_offset+= get_display_map();
  695.  
  696.         u32_t tmp_h = height;
  697.  
  698.       ifl = safe_cli();
  699.         while( tmp_h--)
  700.         {
  701.             u32 tmp_w = width;
  702.  
  703.             u32* tmp_src = src_offset;
  704.             u8*  tmp_dst = dst_offset;
  705.  
  706.             src_offset+= bitmap->pitch;
  707.             dst_offset+= os_display->width;
  708.  
  709.             while( tmp_w--)
  710.             {
  711.                 color = *tmp_src;
  712.  
  713.                 if(*tmp_dst == slot)
  714.                     color |= 0xFF000000;
  715.                 else
  716.                     color = 0x00;
  717.  
  718.                 *tmp_src = color;
  719.                 tmp_src++;
  720.                 tmp_dst++;
  721.             };
  722.         };
  723.       safe_sti(ifl);
  724. #endif
  725.     }
  726.  
  727.     {
  728.         static warn_count;
  729.  
  730.         if(warn_count < 1)
  731.         {
  732.             printf("blit width %d height %d\n",
  733.                     width, height);
  734.             warn_count++;
  735.         };
  736.     };
  737.  
  738.  
  739. //    if((context->cmd_buffer & 0xFC0)==0xFC0)
  740. //        context->cmd_buffer&= 0xFFFFF000;
  741.  
  742. //    b = (u32_t*)ALIGN(context->cmd_buffer,64);
  743.  
  744. //    offset = context->cmd_offset + ((u32_t)b & 0xFFF);
  745.  
  746.  
  747. //    context->cmd_buffer+= n*4;
  748.  
  749.     struct radeon_device *rdev = main_drm_device->dev_private;
  750.     struct radeon_ib *ib = &context->ib;
  751.  
  752.     ib->ptr[0] = PACKET0(0x15cc, 0);
  753.     ib->ptr[1] = 0xFFFFFFFF;
  754.     ib->ptr[2] = PACKET3(PACKET3_TRANS_BITBLT, 11);
  755.     ib->ptr[3] =  RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
  756.                   RADEON_GMC_DST_PITCH_OFFSET_CNTL |
  757.                   RADEON_GMC_SRC_CLIPPING |
  758.                   RADEON_GMC_DST_CLIPPING |
  759.                   RADEON_GMC_BRUSH_NONE |
  760.                   (RADEON_COLOR_FORMAT_ARGB8888 << 8) |
  761.                   RADEON_GMC_SRC_DATATYPE_COLOR |
  762.                   RADEON_ROP3_S |
  763.                   RADEON_DP_SRC_SOURCE_MEMORY |
  764.                   RADEON_GMC_WR_MSK_DIS;
  765.  
  766.     ib->ptr[4] = ((bitmap->pitch/64) << 22) | (bitmap->gaddr >> 10);
  767.     ib->ptr[5] = ((os_display->pitch/64) << 22) | (rdev->mc.vram_start >> 10);
  768.     ib->ptr[6] = (0x1fff) | (0x1fff << 16);
  769.     ib->ptr[7] = 0;
  770.     ib->ptr[8] = (0x1fff) | (0x1fff << 16);
  771.  
  772.     ib->ptr[9] = R5XX_CLR_CMP_SRC_SOURCE | R5XX_SRC_CMP_EQ_COLOR;
  773.     ib->ptr[10] = 0x00000000;
  774.     ib->ptr[11] = 0xFFFFFFFF;
  775.  
  776.     ib->ptr[12] = (src_x << 16) | src_y;
  777.     ib->ptr[13] = (dst_x << 16) | dst_y;
  778.     ib->ptr[14] = (width << 16) | height;
  779.  
  780.     ib->ptr[15] = PACKET2(0);
  781.  
  782.     ib->length_dw = 16;
  783.  
  784.     ret = radeon_ib_schedule(rdev, ib, NULL);
  785.     if (ret) {
  786.         DRM_ERROR("radeon: failed to schedule ib (%d).\n", ret);
  787.         goto fail;
  788.     }
  789.  
  790.     ret = radeon_fence_wait(ib->fence, false);
  791.     if (ret) {
  792.         DRM_ERROR("radeon: fence wait failed (%d).\n", ret);
  793.         goto fail;
  794.     }
  795.  
  796.     radeon_fence_unref(&ib->fence);
  797.  
  798. fail:
  799.     return ret;
  800. };
  801.  
  802. #endif
  803.