Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #include <linux/list.h>
  3. #include <drm/drmP.h>
  4. #include "radeon_drm.h"
  5. #include "radeon.h"
  6.  
  7.  
  8. static struct drm_mm   mm_gtt;
  9. static struct drm_mm   mm_vram;
  10.  
  11.  
  12. /**
  13.  * Initialize an already allocate GEM object of the specified size with
  14.  * shmfs backing store.
  15.  */
  16. int drm_gem_object_init(struct drm_device *dev,
  17.             struct drm_gem_object *obj, size_t size)
  18. {
  19.     BUG_ON((size & (PAGE_SIZE - 1)) != 0);
  20.  
  21.     obj->dev = dev;
  22.     obj->filp = NULL;
  23.  
  24.     atomic_set(&obj->handle_count, 0);
  25.     obj->size = size;
  26.  
  27.     return 0;
  28. }
  29.  
  30.  
  31. int drm_mm_alloc(struct drm_mm *mm, size_t num_pages,
  32.                  struct drm_mm_node **node)
  33. {
  34.     struct drm_mm_node *vm_node;
  35.     int    r;
  36.  
  37. retry_pre_get:
  38.  
  39.     r = drm_mm_pre_get(mm);
  40.  
  41.     if (unlikely(r != 0))
  42.        return r;
  43.  
  44.     vm_node = drm_mm_search_free(mm, num_pages, 0, 0);
  45.  
  46.     if (unlikely(vm_node == NULL)) {
  47.         r = -ENOMEM;
  48.         return r;
  49.     }
  50.  
  51.     *node =  drm_mm_get_block_atomic(vm_node, num_pages, 0);
  52.  
  53.     if (unlikely(*node == NULL)) {
  54.             goto retry_pre_get;
  55.     }
  56.  
  57.     return 0;
  58. };
  59.  
  60.  
  61.  
  62. void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
  63. {
  64.     u32 c = 0;
  65.  
  66.     rbo->placement.fpfn = 0;
  67.     rbo->placement.lpfn = 0;
  68.     rbo->placement.placement = rbo->placements;
  69.     rbo->placement.busy_placement = rbo->placements;
  70.     if (domain & RADEON_GEM_DOMAIN_VRAM)
  71.         rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
  72.                     TTM_PL_FLAG_VRAM;
  73.     if (domain & RADEON_GEM_DOMAIN_GTT)
  74.         rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
  75.     if (domain & RADEON_GEM_DOMAIN_CPU)
  76.         rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
  77.     if (!c)
  78.         rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
  79.     rbo->placement.num_placement = c;
  80.     rbo->placement.num_busy_placement = c;
  81. }
  82.  
  83.  
  84. int radeon_bo_init(struct radeon_device *rdev)
  85. {
  86.     int r;
  87.  
  88.     DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
  89.         rdev->mc.mc_vram_size >> 20,
  90.         (unsigned long long)rdev->mc.aper_size >> 20);
  91.     DRM_INFO("RAM width %dbits %cDR\n",
  92.             rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
  93.  
  94.     r = drm_mm_init(&mm_vram, 0xC00000 >> PAGE_SHIFT,
  95.                ((rdev->mc.real_vram_size - 0xC00000) >> PAGE_SHIFT));
  96.     if (r) {
  97.         DRM_ERROR("Failed initializing VRAM heap.\n");
  98.         return r;
  99.     };
  100.  
  101.     r = drm_mm_init(&mm_gtt, 0, rdev->mc.gtt_size >> PAGE_SHIFT);
  102.     if (r) {
  103.         DRM_ERROR("Failed initializing GTT heap.\n");
  104.         return r;
  105.     }
  106.  
  107.     return 0;
  108. }
  109.  
  110.  
  111. int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
  112. {
  113.     int r;
  114.  
  115.     bo->tbo.reserved.counter = 1;
  116.  
  117.     return 0;
  118. }
  119.  
  120. void ttm_bo_unreserve(struct ttm_buffer_object *bo)
  121. {
  122.     bo->reserved.counter = 1;
  123. }
  124.  
  125. struct sg_table;
  126.  
  127. int radeon_bo_create(struct radeon_device *rdev,
  128.                 unsigned long size, int byte_align, bool kernel, u32 domain,
  129.                 struct sg_table *sg, struct radeon_bo **bo_ptr)
  130. {
  131.         struct radeon_bo *bo;
  132.     enum ttm_bo_type type;
  133.  
  134.     size_t num_pages;
  135.     struct drm_mm      *mman;
  136.     u32                 bo_domain;
  137.     int r;
  138.  
  139.     num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  140.  
  141.     size = num_pages << PAGE_SHIFT;
  142.  
  143.     if (num_pages == 0) {
  144.         dbgprintf("Illegal buffer object size.\n");
  145.         return -EINVAL;
  146.     }
  147.  
  148.     if(domain & RADEON_GEM_DOMAIN_VRAM)
  149.     {
  150.         mman = &mm_vram;
  151.         bo_domain = RADEON_GEM_DOMAIN_VRAM;
  152.     }
  153.     else if(domain & RADEON_GEM_DOMAIN_GTT)
  154.     {
  155.         mman = &mm_gtt;
  156.         bo_domain = RADEON_GEM_DOMAIN_GTT;
  157.     }
  158.     else return -EINVAL;
  159.  
  160.     if (kernel) {
  161.         type = ttm_bo_type_kernel;
  162.     } else {
  163.         type = ttm_bo_type_device;
  164.     }
  165.     *bo_ptr = NULL;
  166.     bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
  167.     if (bo == NULL)
  168.         return -ENOMEM;
  169.  
  170.         r = drm_gem_object_init(rdev->ddev, &bo->gem_base, size);
  171.     if (unlikely(r)) {
  172.                 kfree(bo);
  173.                 return r;
  174.         }
  175.     bo->rdev = rdev;
  176.         bo->gem_base.driver_private = NULL;
  177.     bo->surface_reg = -1;
  178.     bo->tbo.num_pages = num_pages;
  179.     bo->domain = domain;
  180.  
  181.     INIT_LIST_HEAD(&bo->list);
  182.  
  183. //    radeon_ttm_placement_from_domain(bo, domain);
  184.     /* Kernel allocation are uninterruptible */
  185.  
  186.     r = drm_mm_alloc(mman, num_pages, &bo->tbo.vm_node);
  187.     if (unlikely(r != 0))
  188.         return r;
  189.  
  190.     *bo_ptr = bo;
  191.  
  192.     return 0;
  193. }
  194.  
  195. #define page_tabs  0xFDC00000      /* just another hack */
  196.  
  197. int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
  198. {
  199.     int r=0, i;
  200.  
  201.     if (bo->pin_count) {
  202.         bo->pin_count++;
  203.         if (gpu_addr)
  204.             *gpu_addr = radeon_bo_gpu_offset(bo);
  205.         return 0;
  206.     }
  207.  
  208.     bo->tbo.offset = bo->tbo.vm_node->start << PAGE_SHIFT;
  209.  
  210.     if(bo->domain & RADEON_GEM_DOMAIN_VRAM)
  211.     {
  212.         bo->tbo.offset += (u64)bo->rdev->mc.vram_start;
  213.     }
  214.     else if (bo->domain & RADEON_GEM_DOMAIN_GTT)
  215.     {
  216.         u32_t *pagelist;
  217.         bo->kptr  = KernelAlloc( bo->tbo.num_pages << PAGE_SHIFT );
  218.         dbgprintf("kernel alloc %x\n", bo->kptr );
  219.  
  220.         pagelist =  &((u32_t*)page_tabs)[(u32_t)bo->kptr >> 12];
  221.         dbgprintf("pagelist %x\n", pagelist);
  222.         radeon_gart_bind(bo->rdev, bo->tbo.offset,
  223.                          bo->tbo.vm_node->size,  pagelist, NULL);
  224.         bo->tbo.offset += (u64)bo->rdev->mc.gtt_start;
  225.     }
  226.     else
  227.     {
  228.         DRM_ERROR("Unknown placement %x\n", bo->domain);
  229.         bo->tbo.offset = -1;
  230.         r = -1;
  231.     };
  232.  
  233.     if (unlikely(r != 0)) {
  234.         DRM_ERROR("radeon: failed to pin object.\n");
  235.     }
  236.  
  237.     if (likely(r == 0)) {
  238.         bo->pin_count = 1;
  239.         if (gpu_addr != NULL)
  240.             *gpu_addr = radeon_bo_gpu_offset(bo);
  241.     }
  242.  
  243.     if (unlikely(r != 0))
  244.         dev_err(bo->rdev->dev, "%p pin failed\n", bo);
  245.     return r;
  246. };
  247.  
  248. int radeon_bo_unpin(struct radeon_bo *bo)
  249. {
  250.     int r = 0;
  251.  
  252.     if (!bo->pin_count) {
  253.         dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo);
  254.         return 0;
  255.     }
  256.     bo->pin_count--;
  257.     if (bo->pin_count)
  258.         return 0;
  259.  
  260.     if( bo->tbo.vm_node )
  261.     {
  262.         drm_mm_put_block(bo->tbo.vm_node);
  263.         bo->tbo.vm_node = NULL;
  264.     };
  265.  
  266.     return r;
  267. }
  268.  
  269. int radeon_bo_kmap(struct radeon_bo *bo, void **ptr)
  270. {
  271.     bool is_iomem;
  272.  
  273.     if (bo->kptr) {
  274.         if (ptr) {
  275.             *ptr = bo->kptr;
  276.         }
  277.         return 0;
  278.     }
  279.  
  280.     if(bo->domain & RADEON_GEM_DOMAIN_VRAM)
  281.     {
  282.         bo->cpu_addr = bo->rdev->mc.aper_base +
  283.                        (bo->tbo.vm_node->start << PAGE_SHIFT);
  284.         bo->kptr = (void*)MapIoMem(bo->cpu_addr,
  285.                         bo->tbo.vm_node->size << 12, PG_SW);
  286.     }
  287.     else
  288.     {
  289.         return -1;
  290.     }
  291.  
  292.     if (ptr) {
  293.         *ptr = bo->kptr;
  294.     }
  295.  
  296.     return 0;
  297. }
  298.  
  299. int radeon_bo_user_map(struct radeon_bo *bo, void **ptr)
  300. {
  301.     bool is_iomem;
  302.  
  303.     if (bo->uptr) {
  304.         if (ptr) {
  305.             *ptr = bo->uptr;
  306.         }
  307.         return 0;
  308.     }
  309.  
  310.     if(bo->domain & RADEON_GEM_DOMAIN_VRAM)
  311.     {
  312.         return -1;
  313.     }
  314.     else
  315.     {
  316.         bo->uptr = UserAlloc(bo->tbo.num_pages << PAGE_SHIFT);
  317.         if(bo->uptr)
  318.         {
  319.             u32_t *src, *dst;
  320.             int count;
  321.             src =  &((u32_t*)page_tabs)[(u32_t)bo->kptr >> 12];
  322.             dst =  &((u32_t*)page_tabs)[(u32_t)bo->uptr >> 12];
  323.             count = bo->tbo.num_pages;
  324.  
  325.             while(count--)
  326.             {
  327.               *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
  328.             };
  329.         }
  330.         else
  331.             return -1;
  332.     }
  333.  
  334.     if (ptr) {
  335.         *ptr = bo->uptr;
  336.     }
  337.  
  338.     return 0;
  339. }
  340.  
  341. void radeon_bo_kunmap(struct radeon_bo *bo)
  342. {
  343.     if (bo->kptr == NULL)
  344.         return;
  345.  
  346.     if (bo->domain & RADEON_GEM_DOMAIN_VRAM)
  347.     {
  348.         FreeKernelSpace(bo->kptr);
  349.     }
  350.  
  351.     bo->kptr = NULL;
  352.  
  353. }
  354.  
  355. void radeon_bo_unref(struct radeon_bo **bo)
  356. {
  357.     struct ttm_buffer_object *tbo;
  358.  
  359.     if ((*bo) == NULL)
  360.         return;
  361.  
  362.     *bo = NULL;
  363. }
  364.  
  365.  
  366. void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
  367.                 uint32_t *tiling_flags,
  368.                 uint32_t *pitch)
  369. {
  370. //    BUG_ON(!atomic_read(&bo->tbo.reserved));
  371.     if (tiling_flags)
  372.         *tiling_flags = bo->tiling_flags;
  373.     if (pitch)
  374.         *pitch = bo->pitch;
  375. }
  376.  
  377.  
  378. /**
  379.  * Allocate a GEM object of the specified size with shmfs backing store
  380.  */
  381. struct drm_gem_object *
  382. drm_gem_object_alloc(struct drm_device *dev, size_t size)
  383. {
  384.     struct drm_gem_object *obj;
  385.  
  386.     BUG_ON((size & (PAGE_SIZE - 1)) != 0);
  387.  
  388.     obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  389.  
  390.     obj->dev = dev;
  391.     obj->size = size;
  392.     return obj;
  393. }
  394.  
  395.  
  396. int radeon_fb_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
  397.             unsigned long size, bool kernel, u32 domain,
  398.             struct radeon_bo **bo_ptr)
  399. {
  400.     enum ttm_bo_type    type;
  401.  
  402.     struct radeon_bo    *bo;
  403.     struct drm_mm       *mman;
  404.     struct drm_mm_node  *vm_node;
  405.  
  406.     size_t  num_pages;
  407.     u32     bo_domain;
  408.     int     r;
  409.  
  410.     num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  411.  
  412.     if (num_pages == 0) {
  413.         dbgprintf("Illegal buffer object size.\n");
  414.         return -EINVAL;
  415.     }
  416.  
  417.     if( (domain & RADEON_GEM_DOMAIN_VRAM) !=
  418.         RADEON_GEM_DOMAIN_VRAM )
  419.     {
  420.         return -EINVAL;
  421.     };
  422.  
  423.     if (kernel) {
  424.         type = ttm_bo_type_kernel;
  425.     } else {
  426.         type = ttm_bo_type_device;
  427.     }
  428.     *bo_ptr = NULL;
  429.     bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
  430.     if (bo == NULL)
  431.         return -ENOMEM;
  432.  
  433.     bo->rdev = rdev;
  434. //    bo->gobj = gobj;
  435.     bo->surface_reg = -1;
  436.     bo->tbo.num_pages = num_pages;
  437.     bo->domain = domain;
  438.  
  439.     INIT_LIST_HEAD(&bo->list);
  440.  
  441. //    radeon_ttm_placement_from_domain(bo, domain);
  442.     /* Kernel allocation are uninterruptible */
  443.  
  444.     vm_node = kzalloc(sizeof(*vm_node),0);
  445.  
  446.     vm_node->size = 0xC00000 >> 12;
  447.     vm_node->start = 0;
  448.     vm_node->mm = NULL;
  449.  
  450.     bo->tbo.vm_node = vm_node;
  451.     bo->tbo.offset  = bo->tbo.vm_node->start << PAGE_SHIFT;
  452.     bo->tbo.offset += (u64)bo->rdev->mc.vram_start;
  453.     bo->kptr        = (void*)0xFE000000;
  454.     bo->pin_count   = 1;
  455.  
  456.     *bo_ptr = bo;
  457.  
  458.     return 0;
  459. }
  460.