Subversion Repositories Kolibri OS

Rev

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