Subversion Repositories Kolibri OS

Rev

Rev 3037 | Rev 3051 | 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/i915_drm.h>
  4. #include "i915_drv.h"
  5. #include "intel_drv.h"
  6. #include "hmm.h"
  7. #include "bitmap.h"
  8.  
  9. #define DRIVER_CAPS_0   HW_BIT_BLIT;
  10. #define DRIVER_CAPS_1   0
  11.  
  12. struct context *context_map[256];
  13.  
  14. struct hmm bm_mm;
  15.  
  16. extern struct drm_device *main_device;
  17.  
  18.  
  19. void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
  20. {
  21.     dma_addr_t *pages = bitmap->obj->allocated_pages;
  22.     int i;
  23.  
  24.     free_handle(&bm_mm, bitmap->handle);
  25.     bitmap->handle = 0;
  26.     bitmap->obj->base.read_domains = I915_GEM_DOMAIN_GTT;
  27.     bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  28.  
  29.     mutex_lock(&main_device->struct_mutex);
  30.  
  31.     drm_gem_object_unreference(&bitmap->obj->base);
  32.     mutex_unlock(&main_device->struct_mutex);
  33.  
  34.     if(pages != NULL)
  35.     {
  36.         for (i = 0; i < bitmap->page_count; i++)
  37.             FreePage(pages[i]);
  38.  
  39.         DRM_DEBUG("%s release %d pages\n", __FUNCTION__, bitmap->page_count);
  40.  
  41.         free(pages);
  42.     };
  43.     UserFree(bitmap->uaddr);
  44.     __DestroyObject(bitmap);
  45. };
  46.  
  47.  
  48. static int bitmap_get_pages_gtt(struct drm_i915_gem_object *obj)
  49. {
  50.     int page_count;
  51.  
  52.     /* Get the list of pages out of our struct file.  They'll be pinned
  53.      * at this point until we release them.
  54.      */
  55.  
  56.     page_count = obj->base.size / PAGE_SIZE;
  57.     BUG_ON(obj->allocated_pages == NULL);
  58.     BUG_ON(obj->pages.page != NULL);
  59.  
  60.     obj->pages.page = obj->allocated_pages;
  61.     obj->pages.nents = page_count;
  62.  
  63.  
  64. //   if (obj->tiling_mode != I915_TILING_NONE)
  65. //       i915_gem_object_do_bit_17_swizzle(obj);
  66.  
  67.     return 0;
  68. }
  69.  
  70. static void bitmap_put_pages_gtt(struct drm_i915_gem_object *obj)
  71. {
  72.     int ret, i;
  73.  
  74.     BUG_ON(obj->madv == __I915_MADV_PURGED);
  75.  
  76.     ret = i915_gem_object_set_to_cpu_domain(obj, true);
  77.     if (ret) {
  78.         /* In the event of a disaster, abandon all caches and
  79.          * hope for the best.
  80.          */
  81.         WARN_ON(ret != -EIO);
  82.         i915_gem_clflush_object(obj);
  83.         obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  84.     }
  85.  
  86.     if (obj->madv == I915_MADV_DONTNEED)
  87.         obj->dirty = 0;
  88.  
  89.     obj->dirty = 0;
  90. }
  91.  
  92. static const struct drm_i915_gem_object_ops bitmap_object_ops = {
  93.     .get_pages = bitmap_get_pages_gtt,
  94.     .put_pages = bitmap_put_pages_gtt,
  95. };
  96.  
  97.  
  98.  
  99. #if 0
  100. struct  io_call_10         /*     SRV_CREATE_SURFACE    */
  101. {
  102.     u32     handle;       // ignored
  103.     void   *data;         // ignored
  104.  
  105.     u32     width;
  106.     u32     height;
  107.     u32     pitch;        // ignored
  108.  
  109.     u32     max_width;
  110.     u32     max_height;
  111.     u32     format;       // reserved mbz
  112. };
  113.  
  114. #endif
  115.  
  116. int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
  117. {
  118.     struct drm_i915_gem_object *obj;
  119.  
  120.     bitmap_t   *bitmap;
  121.     u32         handle;
  122.     u32         width, max_width;
  123.     u32         height, max_height;
  124.     u32         size,  max_size;
  125.     u32         pitch, max_pitch;
  126.     void       *uaddr;
  127.     dma_addr_t *pages;
  128.     u32         page_count;
  129.  
  130.     int         i;
  131.  
  132.     int   ret;
  133.  
  134.     pbitmap->handle = 0;
  135.     pbitmap->data   = (void*)-1;
  136.  
  137.     width  = pbitmap->width;
  138.     height = pbitmap->height;
  139.  
  140.     if((width == 0)||(height == 0)||(width > 4096)||(height > 4096))
  141.         goto err1;
  142.  
  143. /*
  144.     if( ((pbitmap->max_width !=0 ) &&
  145.          (pbitmap->max_width < width)) ||
  146.          (pbitmap->max_width > 4096) )
  147.         goto err1;
  148.  
  149.     if( ((pbitmap->max_height !=0 ) &&
  150.          (pbitmap->max_height < width)) ||
  151.          (pbitmap->max_height > 4096) )
  152.         goto err1;
  153.  
  154.     if( pbitmap->format != 0)
  155.         goto err1;
  156. */
  157.  
  158.     max_width  = (pbitmap->max_width ==0) ? width  : pbitmap->max_width;
  159.     max_height = (pbitmap->max_height==0) ? height : pbitmap->max_height;
  160.  
  161.     handle = alloc_handle(&bm_mm);
  162. //    printf("%s %d\n",__FUNCTION__, handle);
  163.  
  164.     if(handle == 0)
  165.         goto err1;
  166.  
  167.     bitmap = CreateObject(GetPid(), sizeof(*bitmap));
  168. //    printf("bitmap %x\n", bitmap);
  169.     if( bitmap == NULL)
  170.         goto err2;
  171.  
  172.     bitmap->handle = handle;
  173.     bitmap->header.destroy = destroy_bitmap;
  174.     bitmap->obj    = NULL;
  175.  
  176.     hmm_set_data(&bm_mm, handle, bitmap);
  177.  
  178.     pitch = ALIGN(width*4,64);
  179.     size =  roundup(pitch*height, PAGE_SIZE);
  180.  
  181. //    printf("pitch %d size %d\n", pitch, size);
  182.  
  183.     max_pitch = ALIGN(max_width*4,64);
  184.     max_size =  roundup(max_pitch*max_height, PAGE_SIZE);
  185.  
  186. //    printf("max_pitch %d max_size %d\n", max_pitch, max_size);
  187.  
  188.     uaddr = UserAlloc(max_size);
  189.     if( uaddr == NULL)
  190.         goto err3;
  191.     else
  192.     {
  193.         u32           max_count;
  194.         dma_addr_t    page;
  195.         char *vaddr = uaddr;
  196.  
  197.         page_count = size/PAGE_SIZE;
  198.         max_count = max_size/PAGE_SIZE;
  199.  
  200.         pages = kzalloc(max_count*sizeof(dma_addr_t), 0);
  201.         if( pages == NULL)
  202.             goto err4;
  203.  
  204.         for(i = 0; i < page_count; i++, vaddr+= PAGE_SIZE)
  205.         {
  206.             page = AllocPage();
  207.             if ( page == 0 )
  208.                 goto err4;
  209.             pages[i] = page;
  210.  
  211.             MapPage(vaddr, page, 0x207);        //map as shared page
  212.         };
  213.         bitmap->page_count = page_count;
  214.         bitmap->max_count  = max_count;
  215.     };
  216.  
  217.     DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__, page_count);
  218.  
  219.     obj = i915_gem_alloc_object(dev, size);
  220.     if (obj == NULL)
  221.         goto err4;
  222.  
  223.     obj->ops = &bitmap_object_ops;
  224.     obj->allocated_pages = pages;
  225.  
  226.     ret = i915_gem_object_pin(obj, PAGE_SIZE, true,true);
  227.     if (ret)
  228.         goto err5;
  229.  
  230.     obj->mapped = uaddr ;
  231.  
  232.     bitmap->handle = handle;
  233.     bitmap->uaddr  = uaddr;
  234.     bitmap->pitch  = pitch;
  235.     bitmap->gaddr  = obj->gtt_offset;
  236.  
  237.     bitmap->width  = width;
  238.     bitmap->height = height;
  239.     bitmap->max_width  = max_width;
  240.     bitmap->max_height = max_height;
  241.  
  242.     bitmap->obj    = obj;
  243.     bitmap->header.destroy = destroy_bitmap;
  244.  
  245.     pbitmap->handle = handle;
  246.     pbitmap->data   = uaddr;
  247.     pbitmap->pitch  = pitch;
  248.  
  249.  
  250.     DRM_DEBUG("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
  251.             __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
  252.  
  253.     return 0;
  254.  
  255. err5:
  256.     mutex_lock(&dev->struct_mutex);
  257.     drm_gem_object_unreference(&obj->base);
  258.     mutex_unlock(&dev->struct_mutex);
  259.  
  260. err4:
  261.     while (i--)
  262.         FreePage(pages[i]);
  263.     free(pages);
  264.     UserFree(uaddr);
  265.  
  266. err3:
  267.     __DestroyObject(bitmap);
  268. err2:
  269.     free_handle(&bm_mm, handle);
  270. err1:
  271.     return -1;
  272. };
  273.  
  274.  
  275. int lock_surface(struct io_call_12 *pbitmap)
  276. {
  277.     int ret;
  278.  
  279.     bitmap_t  *bitmap;
  280.  
  281.     if(unlikely(pbitmap->handle == 0))
  282.         return -1;
  283.  
  284.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle);
  285.  
  286.     if(unlikely(bitmap==NULL))
  287.         return -1;
  288.  
  289.     mutex_lock(&main_device->struct_mutex);
  290.     ret = i915_gem_object_set_to_cpu_domain(bitmap->obj, true);
  291.     mutex_unlock(&main_device->struct_mutex);
  292.  
  293.     if(ret != 0 )
  294.     {
  295.         pbitmap->data  = NULL;
  296.         pbitmap->pitch = 0;
  297.  
  298.         dbgprintf("%s fail\n", __FUNCTION__);
  299.         return ret;
  300.     };
  301.  
  302.     pbitmap->data  = bitmap->uaddr;
  303.     pbitmap->pitch = bitmap->pitch;
  304.  
  305.     return 0;
  306. };
  307.  
  308.  
  309. int resize_surface(struct io_call_14 *pbitmap)
  310. {
  311.     bitmap_t  *bitmap;
  312.     dma_addr_t page, *pages;
  313.     u32        size, page_count;
  314.     u32        width, height;
  315.     u32        pitch;
  316.     int        i;
  317.     int        ret = 0;
  318.  
  319.  
  320.     if(unlikely(pbitmap->handle == 0))
  321.         return -1;
  322.  
  323.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle);
  324.  
  325.     if(unlikely(bitmap==NULL))
  326.         return -1;
  327.  
  328.     if( pbitmap->new_width > bitmap->max_width ||
  329.         pbitmap->new_height > bitmap->max_height)
  330.         return -1;
  331.  
  332.     width  = pbitmap->new_width;
  333.     height = pbitmap->new_height;
  334.  
  335.     pitch = ALIGN(width*4,64);
  336.     size =  roundup(pitch * height, PAGE_SIZE);
  337.     page_count = size/PAGE_SIZE;
  338.  
  339.     DRM_DEBUG("new width %d height %d pitch %d size %d\n",
  340.             width, height, pitch, size);
  341.  
  342.     if( page_count == bitmap->page_count )
  343.     {
  344.         bitmap->width  = width;
  345.         bitmap->height = height;
  346.         bitmap->pitch  = pitch;
  347.     }
  348.     else if(page_count > bitmap->page_count)
  349.     {
  350.         char *vaddr = bitmap->uaddr + PAGE_SIZE * bitmap->page_count;
  351.  
  352.         pages = bitmap->obj->allocated_pages;
  353.  
  354.         DRM_DEBUG("old pages %d new_pages %d vaddr %x\n",
  355.                 bitmap->page_count, page_count, vaddr);
  356.  
  357.         for(i = bitmap->page_count; i < page_count; i++, vaddr+= PAGE_SIZE)
  358.         {
  359.             page = AllocPage();
  360.             if ( page == 0 )
  361.                 goto err4;
  362.             pages[i] = page;
  363.             MapPage(vaddr, page, 0x207);        //map as shared page
  364.         };
  365.  
  366.         DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__,
  367.                   page_count - bitmap->page_count);
  368.  
  369. //        mutex_lock(&main_device->struct_mutex);
  370.  
  371.         i915_gem_object_unpin(bitmap->obj);
  372.         i915_gem_object_unbind(bitmap->obj);
  373.         bitmap->obj->base.size = size;
  374.         bitmap->obj->pages.nents = page_count;
  375.  
  376.         ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true);
  377.         if (ret)
  378.             goto err4;
  379. //        mutex_unlock(&main_device->struct_mutex);
  380.  
  381.         bitmap->page_count = page_count;
  382.         bitmap->width  = width;
  383.         bitmap->height = height;
  384.         bitmap->pitch  = pitch;
  385.         bitmap->gaddr  = bitmap->obj->gtt_offset;
  386.     };
  387.  
  388.     if(ret != 0 )
  389.     {
  390.         pbitmap->data  = NULL;
  391.         pbitmap->pitch = 0;
  392.  
  393.         dbgprintf("%s fail\n", __FUNCTION__);
  394.         return ret;
  395.     };
  396.  
  397.     pbitmap->data  = bitmap->uaddr;
  398.     pbitmap->pitch = bitmap->pitch;
  399.  
  400.     return 0;
  401.  
  402. err4:
  403.     while (i-- > bitmap->page_count)
  404.         FreePage(pages[i]);
  405.  
  406.     return -1;
  407. };
  408.  
  409.  
  410. int init_bitmaps()
  411. {
  412.     int ret;
  413.  
  414.     ret = init_hmm(&bm_mm, 1024);
  415.  
  416.     return ret;
  417. };
  418.  
  419.  
  420.  
  421. int get_driver_caps(hwcaps_t *caps)
  422. {
  423.     int ret = 0;
  424.  
  425.     switch(caps->idx)
  426.     {
  427.         case 0:
  428.             caps->opt[0] = DRIVER_CAPS_0;
  429.             caps->opt[1] = DRIVER_CAPS_1;
  430.             break;
  431.  
  432.         case 1:
  433.             caps->cap1.max_tex_width  = 4096;
  434.             caps->cap1.max_tex_height = 4096;
  435.             break;
  436.         default:
  437.             ret = 1;
  438.     };
  439.     caps->idx = 1;
  440.     return ret;
  441. }
  442.  
  443.  
  444. void __attribute__((regparm(1))) destroy_context(struct context *context)
  445. {
  446.     DRM_DEBUG("destroy context %x\n", context);
  447.  
  448.     context_map[context->slot] = NULL;
  449.  
  450.     mutex_lock(&main_device->struct_mutex);
  451.     drm_gem_object_unreference(&context->obj->base);
  452.     mutex_unlock(&main_device->struct_mutex);
  453.  
  454.     __DestroyObject(context);
  455. };
  456.  
  457.  
  458. #define CURRENT_TASK             (0x80003000)
  459.  
  460. struct context *get_context(struct drm_device *dev)
  461. {
  462.     struct context *context;
  463.     struct io_call_10 io_10;
  464.     int    slot = *((u8*)CURRENT_TASK);
  465.     int    ret;
  466.  
  467.     context = context_map[slot];
  468.  
  469.     if( context != NULL)
  470.         return context;
  471.  
  472.     context = CreateObject(GetPid(), sizeof(*context));
  473.  
  474.     if( context != NULL)
  475.     {
  476.         drm_i915_private_t *dev_priv = dev->dev_private;
  477.         struct drm_i915_gem_object *obj;
  478.  
  479.         obj = i915_gem_alloc_object(dev, 4096);
  480.         i915_gem_object_pin(obj, 4096, true, true);
  481.  
  482.         context->obj = obj;
  483.         context->cmd_buffer = MapIoMem((addr_t)obj->pages.page[0], 4096, PG_SW|PG_NOCACHE);
  484.         context->cmd_offset = obj->gtt_offset;
  485.  
  486.         context->header.destroy = destroy_context;
  487.         context->mask  = NULL;
  488.         context->seqno = 0;
  489.         context->slot  = slot;
  490.  
  491.         context_map[slot] = context;
  492.     };
  493.     return context;
  494. };
  495.  
  496.