Subversion Repositories Kolibri OS

Rev

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