Subversion Repositories Kolibri OS

Rev

Rev 2004 | Rev 3120 | 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 "display.h"
  9. #include "drm_fb_helper.h"
  10.  
  11. struct radeon_fbdev {
  12.     struct drm_fb_helper        helper;
  13.     struct radeon_framebuffer   rfb;
  14.     struct list_head fbdev_list;
  15.     struct radeon_device        *rdev;
  16. };
  17.  
  18. struct radeon_fbdev *kos_rfbdev;
  19.  
  20.  
  21. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  22. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  23.  
  24. int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
  25.  
  26. void disable_mouse(void);
  27.  
  28. static void radeon_show_cursor_kms(struct drm_crtc *crtc)
  29. {
  30.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  31.     struct radeon_device *rdev = crtc->dev->dev_private;
  32.  
  33.     if (ASIC_IS_DCE4(rdev)) {
  34.         WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
  35.         WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
  36.                EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
  37.     } else if (ASIC_IS_AVIVO(rdev)) {
  38.         WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
  39.         WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
  40.                  (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
  41.     } else {
  42.         switch (radeon_crtc->crtc_id) {
  43.         case 0:
  44.             WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
  45.             break;
  46.         case 1:
  47.             WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
  48.             break;
  49.         default:
  50.             return;
  51.         }
  52.  
  53.         WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
  54.                       (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
  55.              ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
  56.     }
  57. }
  58.  
  59. static void radeon_lock_cursor_kms(struct drm_crtc *crtc, bool lock)
  60. {
  61.     struct radeon_device *rdev = crtc->dev->dev_private;
  62.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  63.     uint32_t cur_lock;
  64.  
  65.     if (ASIC_IS_DCE4(rdev)) {
  66.         cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
  67.         if (lock)
  68.             cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
  69.         else
  70.             cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
  71.         WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
  72.     } else if (ASIC_IS_AVIVO(rdev)) {
  73.         cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
  74.         if (lock)
  75.             cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
  76.         else
  77.             cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
  78.         WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
  79.     } else {
  80.         cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
  81.         if (lock)
  82.             cur_lock |= RADEON_CUR_LOCK;
  83.         else
  84.             cur_lock &= ~RADEON_CUR_LOCK;
  85.         WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
  86.     }
  87. }
  88.  
  89. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  90. {
  91.     struct radeon_device *rdev;
  92.     struct radeon_crtc   *radeon_crtc;
  93.     cursor_t *old;
  94.     uint32_t  gpu_addr;
  95.  
  96.     rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
  97.     radeon_crtc = to_radeon_crtc(rdisplay->crtc);
  98.  
  99.     old = rdisplay->cursor;
  100.  
  101.     rdisplay->cursor = cursor;
  102.     gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  103.  
  104.     if (ASIC_IS_DCE4(rdev)) {
  105.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
  106.                0);
  107.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
  108.                gpu_addr);
  109.     } else if (ASIC_IS_AVIVO(rdev)) {
  110.         if (rdev->family >= CHIP_RV770)
  111.             WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
  112.         WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
  113.     }
  114.     else {
  115.         radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start;
  116.         /* offset is from DISP(2)_BASE_ADDRESS */
  117.         WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
  118.     }
  119.  
  120.     return old;
  121. };
  122.  
  123. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  124. {
  125.     struct radeon_device *rdev;
  126.     rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
  127.     struct drm_crtc *crtc = rdisplay->crtc;
  128.     struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  129.  
  130.     int hot_x = cursor->hot_x;
  131.     int hot_y = cursor->hot_y;
  132.     int w = 32;
  133.  
  134.     radeon_lock_cursor_kms(crtc, true);
  135.  
  136.     if (ASIC_IS_DCE4(rdev)) {
  137.         WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset,
  138.                (x << 16) | y);
  139.         WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset,
  140.                (hot_x << 16) | hot_y);
  141.         WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
  142.                ((w - 1) << 16) | 31);
  143.     } else if (ASIC_IS_AVIVO(rdev)) {
  144.         WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
  145.                (x << 16) | y);
  146.         WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
  147.                (hot_x << 16) | hot_y);
  148.         WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
  149.                ((w - 1) << 16) | 31);
  150.     } else {
  151.         if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
  152.             y *= 2;
  153.  
  154.         uint32_t  gpu_addr;
  155.         int       xorg =0, yorg=0;
  156.  
  157.         x = x - hot_x;
  158.         y = y - hot_y;
  159.  
  160.         if( x < 0 )
  161.         {
  162.             xorg = -x + 1;
  163.             x = 0;
  164.         }
  165.  
  166.         if( y < 0 )
  167.         {
  168.             yorg = -hot_y + 1;
  169.             y = 0;
  170.         };
  171.  
  172.         WREG32(RADEON_CUR_HORZ_VERT_OFF,
  173.                (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
  174.         WREG32(RADEON_CUR_HORZ_VERT_POSN,
  175.                (RADEON_CUR_LOCK | (x << 16) | y));
  176.  
  177.         gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  178.  
  179.         /* offset is from DISP(2)_BASE_ADDRESS */
  180.         WREG32(RADEON_CUR_OFFSET,
  181.          (gpu_addr - rdev->mc.vram_start + (yorg * 256)));
  182.     }
  183.     radeon_lock_cursor_kms(crtc, false);
  184. }
  185.  
  186. static char *manufacturer_name(unsigned char *x)
  187. {
  188.     static char name[4];
  189.  
  190.     name[0] = ((x[0] & 0x7C) >> 2) + '@';
  191.     name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
  192.     name[2] = (x[1] & 0x1F) + '@';
  193.     name[3] = 0;
  194.  
  195.     return name;
  196. }
  197.  
  198. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  199.               videomode_t *reqmode, bool strict)
  200. {
  201.     struct drm_display_mode  *mode = NULL, *tmpmode;
  202.  
  203.     struct drm_fb_helper *fb_helper;
  204.  
  205.     fb_helper = &kos_rfbdev->helper;
  206.  
  207.  
  208.     bool ret = false;
  209.  
  210.     ENTER();
  211.  
  212.     dbgprintf("width %d height %d vrefresh %d\n",
  213.                reqmode->width, reqmode->height, reqmode->freq);
  214.  
  215.     list_for_each_entry(tmpmode, &connector->modes, head)
  216.     {
  217.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  218.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  219.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  220.         {
  221.             mode = tmpmode;
  222.             goto do_set;
  223.         }
  224.     };
  225.  
  226.     if( (mode == NULL) && (strict == false) )
  227.     {
  228.         list_for_each_entry(tmpmode, &connector->modes, head)
  229.         {
  230.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  231.                 (drm_mode_height(tmpmode) == reqmode->height) )
  232.             {
  233.                 mode = tmpmode;
  234.                 goto do_set;
  235.             }
  236.         };
  237.     };
  238.  
  239. do_set:
  240.  
  241.     if( mode != NULL )
  242.     {
  243.         struct drm_framebuffer   *fb;
  244.         struct drm_encoder       *encoder;
  245.         struct drm_crtc          *crtc;
  246.  
  247. //        char  con_edid[128];
  248.         char *con_name;
  249.         char *enc_name;
  250.  
  251.         encoder = connector->encoder;
  252.         crtc = encoder->crtc;
  253.  
  254. //        fb = list_first_entry(&dev->mode_config.fb_kernel_list,
  255. //                              struct drm_framebuffer, filp_head);
  256.  
  257. //        memcpy(con_edid, connector->edid_blob_ptr->data, 128);
  258.  
  259. //        dbgprintf("Manufacturer: %s Model %x Serial Number %u\n",
  260. //        manufacturer_name(con_edid + 0x08),
  261. //        (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
  262. //        (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
  263. //            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
  264.  
  265.         con_name = drm_get_connector_name(connector);
  266.         enc_name = drm_get_encoder_name(encoder);
  267.  
  268.         dbgprintf("set mode %d %d connector %s encoder %s\n",
  269.                    reqmode->width, reqmode->height, con_name, enc_name);
  270.  
  271.         fb = fb_helper->fb;
  272.  
  273.         fb->width  = reqmode->width;
  274.         fb->height = reqmode->height;
  275.  
  276.         fb->pitches[0] = fb->pitches[1] = fb->pitches[2] =
  277.                          fb->pitches[3] = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
  278.         fb->bits_per_pixel = 32;
  279.         fb->depth = 24;
  280.  
  281.         crtc->fb = fb;
  282.         crtc->enabled = true;
  283.         rdisplay->crtc = crtc;
  284.  
  285.         ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
  286.  
  287.         select_cursor_kms(rdisplay->cursor);
  288.         radeon_show_cursor_kms(crtc);
  289.  
  290.         if (ret == true)
  291.         {
  292.             rdisplay->width    = fb->width;
  293.             rdisplay->height   = fb->height;
  294.             rdisplay->pitch    = fb->pitches[0];
  295.             rdisplay->vrefresh = drm_mode_vrefresh(mode);
  296.  
  297.             sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  298.  
  299.             dbgprintf("new mode %d x %d pitch %d\n",
  300.                        fb->width, fb->height, fb->pitches[0]);
  301.         }
  302.         else
  303.             DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  304.                        fb->width, fb->height, crtc);
  305.     }
  306.  
  307.     LEAVE();
  308.     return ret;
  309. };
  310.  
  311. static int count_connector_modes(struct drm_connector* connector)
  312. {
  313.     struct drm_display_mode  *mode;
  314.     int count = 0;
  315.  
  316.     list_for_each_entry(mode, &connector->modes, head)
  317.     {
  318.         count++;
  319.     };
  320.     return count;
  321. };
  322.  
  323. static struct drm_connector* get_def_connector(struct drm_device *dev)
  324. {
  325.     struct drm_connector  *connector;
  326.     struct drm_connector_helper_funcs *connector_funcs;
  327.  
  328.     struct drm_connector  *def_connector = NULL;
  329.  
  330.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  331.     {
  332.         struct drm_encoder  *encoder;
  333.         struct drm_crtc     *crtc;
  334.  
  335.         if( connector->status != connector_status_connected)
  336.             continue;
  337.  
  338.         connector_funcs = connector->helper_private;
  339.         encoder = connector_funcs->best_encoder(connector);
  340.         if( encoder == NULL)
  341.             continue;
  342.  
  343.         connector->encoder = encoder;
  344.  
  345.         crtc = encoder->crtc;
  346.  
  347.         dbgprintf("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x",
  348.                    connector, connector->base.id,
  349.                    connector->status, connector->encoder,
  350.                    crtc);
  351.  
  352. //        if (crtc == NULL)
  353. //            continue;
  354.  
  355.         def_connector = connector;
  356.  
  357.         break;
  358.     };
  359.  
  360.     return def_connector;
  361. };
  362.  
  363.  
  364.  
  365. bool init_display_kms(struct radeon_device *rdev, videomode_t *usermode)
  366. {
  367.     struct drm_device   *dev;
  368.  
  369.     struct drm_connector    *connector;
  370.     struct drm_connector_helper_funcs *connector_funcs;
  371.     struct drm_encoder      *encoder;
  372.     struct drm_crtc         *crtc = NULL;
  373.     struct drm_framebuffer  *fb;
  374.     struct drm_display_mode *native;
  375.  
  376.  
  377.     cursor_t            *cursor;
  378.     bool                 retval = false;
  379.     u32_t                ifl;
  380.  
  381.     struct radeon_fbdev  *rfbdev;
  382.     struct drm_fb_helper *fb_helper;
  383.  
  384.     int i;
  385.  
  386.     ENTER();
  387.  
  388.     dev = rdev->ddev;
  389.  
  390.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  391.     {
  392.         if( connector->status != connector_status_connected)
  393.             continue;
  394.  
  395.         connector_funcs = connector->helper_private;
  396.         encoder = connector_funcs->best_encoder(connector);
  397.         if( encoder == NULL)
  398.         {
  399.             dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
  400.                       connector, connector->base.id);
  401.             continue;
  402.         }
  403.         connector->encoder = encoder;
  404.  
  405.         dbgprintf("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x\n",
  406.                connector, connector->base.id,
  407.                connector->status, connector->encoder,
  408.                encoder->crtc);
  409.  
  410.         crtc = encoder->crtc;
  411.         break;
  412.     };
  413.  
  414.     if(connector == NULL)
  415.     {
  416.         dbgprintf("No active connectors!\n");
  417.         return -1;
  418.     };
  419.  
  420.     {
  421.         struct drm_display_mode *tmp;
  422.  
  423.         list_for_each_entry(tmp, &connector->modes, head) {
  424.             if (drm_mode_width(tmp) > 16384 ||
  425.                 drm_mode_height(tmp) > 16384)
  426.                 continue;
  427.             if (tmp->type & DRM_MODE_TYPE_PREFERRED)
  428.             {
  429.                 native = tmp;
  430.                 break;
  431.             };
  432.         }
  433.     }
  434.  
  435.     if( ASIC_IS_AVIVO(rdev) && native )
  436.     {
  437.         dbgprintf("native w %d h %d\n", native->hdisplay, native->vdisplay);
  438.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(connector->encoder);
  439.         radeon_encoder->rmx_type = RMX_FULL;
  440.         radeon_encoder->native_mode = *native;
  441.     };
  442.  
  443.  
  444.     if(crtc == NULL)
  445.     {
  446.         struct drm_crtc *tmp_crtc;
  447.         int crtc_mask = 1;
  448.  
  449.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  450.         {
  451.             if (encoder->possible_crtcs & crtc_mask)
  452.             {
  453.                 crtc = tmp_crtc;
  454.                 encoder->crtc = crtc;
  455.                 break;
  456.             };
  457.             crtc_mask <<= 1;
  458.         };
  459.     };
  460.  
  461.     if(crtc == NULL)
  462.     {
  463.         dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
  464.         return -1;
  465.     };
  466.  
  467.  
  468.     dbgprintf("[Select CRTC:%d]\n", crtc->base.id);
  469.  
  470.  
  471. //    drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
  472.  
  473.     rdisplay = GetDisplay();
  474.     rdisplay->ddev = dev;
  475.     rdisplay->connector = connector;
  476.     rdisplay->crtc = crtc;
  477.  
  478.     rdisplay->supported_modes = count_connector_modes(connector);
  479.  
  480.  
  481.  
  482.     ifl = safe_cli();
  483.     {
  484.         list_for_each_entry(cursor, &rdisplay->cursors, list)
  485.         {
  486.             init_cursor(cursor);
  487.         };
  488.  
  489.     };
  490.     safe_sti(ifl);
  491.  
  492.  
  493.     dbgprintf("current mode %d x %d x %d\n",
  494.               rdisplay->width, rdisplay->height, rdisplay->vrefresh);
  495.     dbgprintf("user mode mode %d x %d x %d\n",
  496.               usermode->width, usermode->height, usermode->freq);
  497.  
  498.  
  499.     if( (usermode->width  != 0) &&
  500.         (usermode->height != 0) &&
  501.         ( (usermode->width  != rdisplay->width)  ||
  502.           (usermode->height != rdisplay->height) ||
  503.           (usermode->freq   != rdisplay->vrefresh) ) )
  504.     {
  505.  
  506.         retval = set_mode(dev, rdisplay->connector, usermode, false);
  507.     }
  508.     else
  509.     {
  510.         usermode->width  = rdisplay->width;
  511.         usermode->height = rdisplay->height;
  512.         usermode->freq   = 60;
  513.         retval = set_mode(dev, rdisplay->connector, usermode, false);
  514.     };
  515.  
  516.     ifl = safe_cli();
  517.     {
  518.         rdisplay->restore_cursor(0,0);
  519.         rdisplay->init_cursor    = init_cursor;
  520.         rdisplay->select_cursor  = select_cursor_kms;
  521.         rdisplay->show_cursor    = NULL;
  522.         rdisplay->move_cursor    = move_cursor_kms;
  523.         rdisplay->restore_cursor = restore_cursor;
  524.         rdisplay->disable_mouse  = disable_mouse;
  525.  
  526.         select_cursor_kms(rdisplay->cursor);
  527.         radeon_show_cursor_kms(rdisplay->crtc);
  528.     };
  529.     safe_sti(ifl);
  530.  
  531.     LEAVE();
  532.  
  533.     return retval;
  534. };
  535.  
  536. int get_modes(videomode_t *mode, int *count)
  537. {
  538.     int err = -1;
  539.  
  540. //    ENTER();
  541.  
  542.     dbgprintf("mode %x count %d\n", mode, *count);
  543.  
  544.     if( *count == 0 )
  545.     {
  546.         *count = rdisplay->supported_modes;
  547.         err = 0;
  548.     }
  549.     else if( mode != NULL )
  550.     {
  551.         struct drm_display_mode  *drmmode;
  552.         int i = 0;
  553.  
  554.         if( *count > rdisplay->supported_modes)
  555.             *count = rdisplay->supported_modes;
  556.  
  557.         list_for_each_entry(drmmode, &rdisplay->connector->modes, head)
  558.         {
  559.             if( i < *count)
  560.             {
  561.                 mode->width  = drm_mode_width(drmmode);
  562.                 mode->height = drm_mode_height(drmmode);
  563.                 mode->bpp    = 32;
  564.                 mode->freq   = drm_mode_vrefresh(drmmode);
  565.                 i++;
  566.                 mode++;
  567.             }
  568.             else break;
  569.         };
  570.         *count = i;
  571.         err = 0;
  572.     };
  573. //    LEAVE();
  574.     return err;
  575. }
  576.  
  577. int set_user_mode(videomode_t *mode)
  578. {
  579.     int err = -1;
  580.  
  581. //    ENTER();
  582.  
  583.     dbgprintf("width %d height %d vrefresh %d\n",
  584.                mode->width, mode->height, mode->freq);
  585.  
  586.     if( (mode->width  != 0)  &&
  587.         (mode->height != 0)  &&
  588.         (mode->freq   != 0 ) &&
  589.         ( (mode->width   != rdisplay->width)  ||
  590.           (mode->height  != rdisplay->height) ||
  591.           (mode->freq    != rdisplay->vrefresh) ) )
  592.     {
  593.         if( set_mode(rdisplay->ddev, rdisplay->connector, mode, true) )
  594.             err = 0;
  595.     };
  596.  
  597. //    LEAVE();
  598.     return err;
  599. };
  600.  
  601.  
  602. int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
  603.                      struct drm_mode_fb_cmd2 *mode_cmd,
  604.                      struct drm_gem_object **gobj_p)
  605. {
  606.     struct radeon_device *rdev = rfbdev->rdev;
  607.     struct drm_gem_object *gobj = NULL;
  608.     struct radeon_bo *rbo = NULL;
  609.     bool fb_tiled = false; /* useful for testing */
  610.     u32 tiling_flags = 0;
  611.     int ret;
  612.     int aligned_size, size;
  613.     int height = mode_cmd->height;
  614.     u32 bpp, depth;
  615.  
  616.     static struct radeon_bo kos_bo;
  617.     static struct drm_mm_node  vm_node;
  618.  
  619.  
  620.     drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
  621.  
  622.     /* need to align pitch with crtc limits */
  623.     mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp,
  624.                           fb_tiled) * ((bpp + 1) / 8);
  625.  
  626.     if (rdev->family >= CHIP_R600)
  627.         height = ALIGN(mode_cmd->height, 8);
  628.     size = mode_cmd->pitches[0] * height;
  629.     aligned_size = ALIGN(size, PAGE_SIZE);
  630.  
  631.  
  632.     ret = drm_gem_object_init(rdev->ddev, &kos_bo.gem_base, aligned_size);
  633.     if (unlikely(ret)) {
  634.         printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
  635.                aligned_size);
  636.         return -ENOMEM;
  637.     }
  638.  
  639.     kos_bo.rdev = rdev;
  640.     kos_bo.gem_base.driver_private = NULL;
  641.     kos_bo.surface_reg = -1;
  642.     kos_bo.domain = RADEON_GEM_DOMAIN_VRAM;
  643.  
  644.     INIT_LIST_HEAD(&kos_bo.list);
  645.  
  646.     gobj = &kos_bo.gem_base;
  647.     rbo = gem_to_radeon_bo(gobj);
  648.  
  649.     if (fb_tiled)
  650.         tiling_flags = RADEON_TILING_MACRO;
  651.  
  652. //    if (tiling_flags) {
  653. //        ret = radeon_bo_set_tiling_flags(rbo,
  654. //                         tiling_flags | RADEON_TILING_SURFACE,
  655. //                         mode_cmd->pitches[0]);
  656. //        if (ret)
  657. //            dev_err(rdev->dev, "FB failed to set tiling flags\n");
  658. //    }
  659.  
  660.     vm_node.size = 0xC00000 >> 12;
  661.     vm_node.start = 0;
  662.     vm_node.mm = NULL;
  663.  
  664.     rbo->tbo.vm_node = &vm_node;
  665.     rbo->tbo.offset  = rbo->tbo.vm_node->start << PAGE_SHIFT;
  666.     rbo->tbo.offset += (u64)rbo->rdev->mc.vram_start;
  667.     rbo->kptr        = (void*)0xFE000000;
  668.     rbo->pin_count   = 1;
  669.  
  670.  
  671.     *gobj_p = gobj;
  672.     return 0;
  673. }
  674.  
  675.  
  676.