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 "bitmap.h"
  9. #include "display.h"
  10.  
  11. #include "r100d.h"
  12.  
  13.  
  14. display_t *os_display;
  15.  
  16. static cursor_t*  __stdcall select_cursor(cursor_t *cursor);
  17. static void       __stdcall move_cursor(cursor_t *cursor, int x, int y);
  18.  
  19. extern void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor);
  20.  
  21. void disable_mouse(void)
  22. {};
  23.  
  24. int init_cursor(cursor_t *cursor)
  25. {
  26.     struct radeon_device *rdev;
  27.  
  28.     uint32_t *bits;
  29.     uint32_t *src;
  30.  
  31.     int       i,j;
  32.     int       r;
  33.  
  34.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  35.  
  36.     r = radeon_bo_create(rdev, CURSOR_WIDTH*CURSOR_HEIGHT*4,
  37.                      PAGE_SIZE, false, RADEON_GEM_DOMAIN_VRAM, 0, NULL, &cursor->robj);
  38.  
  39.     if (unlikely(r != 0))
  40.         return r;
  41.  
  42.     r = radeon_bo_reserve(cursor->robj, false);
  43.     if (unlikely(r != 0))
  44.         return r;
  45.  
  46.     r = radeon_bo_pin(cursor->robj, RADEON_GEM_DOMAIN_VRAM, NULL);
  47.     if (unlikely(r != 0))
  48.         return r;
  49.  
  50.     r = radeon_bo_kmap(cursor->robj, (void**)&bits);
  51.     if (r) {
  52.          DRM_ERROR("radeon: failed to map cursor (%d).\n", r);
  53.          return r;
  54.     };
  55.  
  56.     src = cursor->data;
  57.  
  58.     for(i = 0; i < 32; i++)
  59.     {
  60.         for(j = 0; j < 32; j++)
  61.             *bits++ = *src++;
  62.         for(j = 32; j < CURSOR_WIDTH; j++)
  63.             *bits++ = 0;
  64.     }
  65.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  66.         *bits++ = 0;
  67.  
  68.     radeon_bo_kunmap(cursor->robj);
  69.  
  70.  //   cursor->header.destroy = destroy_cursor;
  71.  
  72.     return 0;
  73. };
  74.  
  75. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  76. {
  77.     list_del(&cursor->list);
  78.     radeon_bo_unpin(cursor->robj);
  79.     KernelFree(cursor->data);
  80.     __DestroyObject(cursor);
  81. };
  82.  
  83. static void radeon_show_cursor()
  84. {
  85.     struct radeon_device *rdev = (struct radeon_device *)os_display->ddev->dev_private;
  86.  
  87.  
  88.     if (ASIC_IS_DCE4(rdev)) {
  89.         WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL);
  90.         WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
  91.                EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
  92.     } else if (ASIC_IS_AVIVO(rdev)) {
  93.         WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL);
  94.         WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
  95.                  (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
  96.     } else {
  97.         WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
  98.         WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
  99.                       (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
  100.              ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
  101.     }
  102. }
  103.  
  104. cursor_t* __stdcall select_cursor(cursor_t *cursor)
  105. {
  106.     struct radeon_device *rdev;
  107.     cursor_t *old;
  108.     uint32_t  gpu_addr;
  109.  
  110.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  111.  
  112.     old = os_display->cursor;
  113.  
  114.     os_display->cursor = cursor;
  115.     gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  116.  
  117.     if (ASIC_IS_DCE4(rdev))
  118.     {
  119.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH, 0);
  120.         WREG32(EVERGREEN_CUR_SURFACE_ADDRESS, gpu_addr);
  121.     }
  122.     else if (ASIC_IS_AVIVO(rdev))
  123.     {
  124.         if (rdev->family >= CHIP_RV770)
  125.             WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
  126.         WREG32(AVIVO_D1CUR_SURFACE_ADDRESS,  gpu_addr);
  127.     }
  128.     else {
  129.         WREG32(RADEON_CUR_OFFSET, gpu_addr - rdev->mc.vram_start);
  130.     }
  131.  
  132.     return old;
  133. };
  134.  
  135. static void radeon_lock_cursor(bool lock)
  136. {
  137.     struct radeon_device *rdev;
  138.  
  139.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  140.  
  141.     uint32_t cur_lock;
  142.  
  143.         if (ASIC_IS_DCE4(rdev)) {
  144.                 cur_lock = RREG32(EVERGREEN_CUR_UPDATE);
  145.                 if (lock)
  146.                         cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
  147.                 else
  148.                         cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
  149.         WREG32(EVERGREEN_CUR_UPDATE, cur_lock);
  150.         } else if (ASIC_IS_AVIVO(rdev)) {
  151.         cur_lock = RREG32(AVIVO_D1CUR_UPDATE);
  152.         if (lock)
  153.             cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
  154.         else
  155.             cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
  156.         WREG32(AVIVO_D1CUR_UPDATE, cur_lock);
  157.     } else {
  158.         cur_lock = RREG32(RADEON_CUR_OFFSET);
  159.         if (lock)
  160.             cur_lock |= RADEON_CUR_LOCK;
  161.         else
  162.             cur_lock &= ~RADEON_CUR_LOCK;
  163.         WREG32(RADEON_CUR_OFFSET, cur_lock);
  164.     }
  165. }
  166.  
  167.  
  168. void __stdcall move_cursor(cursor_t *cursor, int x, int y)
  169. {
  170.     struct radeon_device *rdev;
  171.     rdev = (struct radeon_device *)os_display->ddev->dev_private;
  172.  
  173.     int hot_x = cursor->hot_x;
  174.     int hot_y = cursor->hot_y;
  175.     int w     = 32;
  176.  
  177.     radeon_lock_cursor(true);
  178.  
  179.     if (ASIC_IS_DCE4(rdev)) {
  180.         WREG32(EVERGREEN_CUR_POSITION,(x << 16) | y);
  181.         WREG32(EVERGREEN_CUR_HOT_SPOT, (hot_x << 16) | hot_y);
  182.         WREG32(EVERGREEN_CUR_SIZE, ((w - 1) << 16) | 31);
  183.     } else if (ASIC_IS_AVIVO(rdev)) {
  184.         WREG32(AVIVO_D1CUR_POSITION, (x << 16) | y);
  185.         WREG32(AVIVO_D1CUR_HOT_SPOT, (hot_x << 16) | hot_y);
  186.         WREG32(AVIVO_D1CUR_SIZE, ((w - 1) << 16) | 31);
  187.     } else {
  188.  
  189.         uint32_t  gpu_addr;
  190.         int       xorg =0, yorg=0;
  191.  
  192.         x = x - hot_x;
  193.         y = y - hot_y;
  194.  
  195.         if( x < 0 )
  196.         {
  197.             xorg = -x + 1;
  198.             x = 0;
  199.         }
  200.  
  201.         if( y < 0 )
  202.         {
  203.             yorg = -hot_y + 1;
  204.             y = 0;
  205.         };
  206.  
  207.         WREG32(RADEON_CUR_HORZ_VERT_OFF,
  208.                (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
  209.         WREG32(RADEON_CUR_HORZ_VERT_POSN,
  210.                (RADEON_CUR_LOCK | (x << 16) | y));
  211.  
  212.         gpu_addr = radeon_bo_gpu_offset(cursor->robj);
  213.  
  214.         /* offset is from DISP(2)_BASE_ADDRESS */
  215.         WREG32(RADEON_CUR_OFFSET,
  216.          (gpu_addr - rdev->mc.vram_start + (yorg * 256)));
  217.     }
  218.     radeon_lock_cursor(false);
  219. }
  220.  
  221. void __stdcall restore_cursor(int x, int y)
  222. {
  223. };
  224.  
  225.  
  226. bool init_display(struct radeon_device *rdev, videomode_t *usermode)
  227. {
  228.     struct drm_device   *dev;
  229.  
  230.     cursor_t            *cursor;
  231.     bool                 retval = true;
  232.     u32_t                ifl;
  233.  
  234.     ENTER();
  235.  
  236.     os_display = GetDisplay();
  237.  
  238.     dev = os_display->ddev = rdev->ddev;
  239.  
  240.     ifl = safe_cli();
  241.     {
  242.         list_for_each_entry(cursor, &os_display->cursors, list)
  243.         {
  244.             init_cursor(cursor);
  245.         };
  246.  
  247.         os_display->restore_cursor(0,0);
  248.         os_display->init_cursor    = init_cursor;
  249.         os_display->select_cursor  = select_cursor;
  250.         os_display->show_cursor    = NULL;
  251.         os_display->move_cursor    = move_cursor;
  252.         os_display->restore_cursor = restore_cursor;
  253.         os_display->disable_mouse  = disable_mouse;
  254.  
  255.         select_cursor(os_display->cursor);
  256.         radeon_show_cursor();
  257.     };
  258.     safe_sti(ifl);
  259.  
  260. //    init_bitmaps();
  261.  
  262.     LEAVE();
  263.  
  264.     return retval;
  265. };
  266.  
  267.  
  268. struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
  269. {
  270. #define BYTES_PER_LONG (BITS_PER_LONG/8)
  271. #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
  272.     int fb_info_size = sizeof(struct fb_info);
  273.     struct fb_info *info;
  274.     char *p;
  275.  
  276.     if (size)
  277.         fb_info_size += PADDING;
  278.  
  279.     p = kzalloc(fb_info_size + size, GFP_KERNEL);
  280.  
  281.     if (!p)
  282.         return NULL;
  283.  
  284.     info = (struct fb_info *) p;
  285.  
  286.     if (size)
  287.         info->par = p + fb_info_size;
  288.  
  289.     return info;
  290. #undef PADDING
  291. #undef BYTES_PER_LONG
  292. }
  293.  
  294. void framebuffer_release(struct fb_info *info)
  295. {
  296.     kfree(info);
  297. }
  298.  
  299.  
  300. /* 23 bits of float fractional data */
  301. #define I2F_FRAC_BITS  23
  302. #define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
  303.  
  304. /*
  305.  * Converts unsigned integer into 32-bit IEEE floating point representation.
  306.  * Will be exact from 0 to 2^24.  Above that, we round towards zero
  307.  * as the fractional bits will not fit in a float.  (It would be better to
  308.  * round towards even as the fpu does, but that is slower.)
  309.  */
  310. __pure uint32_t int2float(uint32_t x)
  311. {
  312.     uint32_t msb, exponent, fraction;
  313.  
  314.     /* Zero is special */
  315.     if (!x) return 0;
  316.  
  317.     /* Get location of the most significant bit */
  318.     msb = __fls(x);
  319.  
  320.     /*
  321.      * Use a rotate instead of a shift because that works both leftwards
  322.      * and rightwards due to the mod(32) behaviour.  This means we don't
  323.      * need to check to see if we are above 2^24 or not.
  324.      */
  325.     fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
  326.     exponent = (127 + msb) << I2F_FRAC_BITS;
  327.  
  328.     return fraction + exponent;
  329. }
  330.  
  331.