Subversion Repositories Kolibri OS

Rev

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