Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. int CreatePixmap(pixmap_t *io)
  3. {
  4.     local_pixmap_t *pixmap;
  5.  
  6.     unsigned pitch;
  7.     size_t size;
  8.  
  9.     addr_t  mem_local = 0;
  10.     addr_t  mem_dma   = 0;
  11.     void   *mapped;
  12.  
  13.     if( (io->width == 0) || (io->width > 2048)||
  14.         (io->height == 0)|| (io->height > 2048))
  15.     {
  16.         dbgprintf("Invalid pixmap size w:%d h:%d\n", io->width,io->height);
  17.         return ERR_PARAM;
  18.     };
  19.  
  20.     pixmap = malloc(sizeof(local_pixmap_t));
  21.  
  22.     if(!pixmap)
  23.         return ERR_PARAM;
  24.  
  25.     pitch = ((io->width+15)&~15)*4;
  26.     size = pitch*io->height;
  27.  
  28.     dbgprintf("pitch = %d\n", pitch);
  29.  
  30.     if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL ) {
  31.         mem_local = rhd_mem_alloc(&rhd,RHD_MEM_FB,size);
  32.         mem_dma = mem_local + rhd.fbLocation;
  33.     }
  34.     else
  35.         mem_local = mem_dma = AllocPages( size >> 12 );
  36.  
  37.     if ( !mem_local) {
  38.         dbgprintf("Not enough memory for pixmap\n");
  39.         free(pixmap);
  40.         return ERR_PARAM;
  41.     };
  42.  
  43.     pixmap->pitch_offset = ((pitch/64)<<22)| (mem_dma>>10);
  44.     pixmap->local   = mem_dma;
  45.  
  46.     size = (size+4095) & ~ 4095;
  47.  
  48.     if (mapped = UserAlloc(size))
  49.     {
  50.         CommitPages(mapped, mem_dma|7|(1<<9), size);
  51.  
  52.         io->mapped = mapped;
  53.         io->pitch   = pitch;
  54.         io->handle  = (u32_t)pixmap;
  55.  
  56.         pixmap->width   = io->width;
  57.         pixmap->height  = io->height;
  58.         pixmap->format  = PICT_a8r8g8b8;
  59.         pixmap->flags   = io->flags;
  60.         pixmap->pitch   = pitch;
  61.         pixmap->mapped  = mapped;
  62.  
  63.         dbgprintf("pixmap.pitch_offset: %x\n", pixmap->pitch_offset);
  64.         dbgprintf("width: %d height: %d\n",pixmap->width,pixmap->height );
  65.         dbgprintf("map at %x\n", pixmap->mapped);
  66.  
  67.         return ERR_OK;
  68.     };
  69.     rhd_mem_free(&rhd, RHD_MEM_FB, mem_local);
  70.     free(pixmap);
  71.  
  72.     return ERR_PARAM;
  73. };
  74.  
  75.  
  76. int DestroyPixmap( pixmap_t *io )
  77. {
  78.     local_pixmap_t *pixmap;
  79.     size_t size;
  80.  
  81.     dbgprintf("Destroy pixmap %x\n", io->handle);
  82.  
  83.     if(io->handle == -1)
  84.         return ERR_PARAM;
  85.     else
  86.         pixmap = (local_pixmap_t*)io->handle;
  87.  
  88.     size = (pixmap->pitch*pixmap->height+4095) & ~ 4095;
  89.  
  90.     UnmapPages(pixmap->mapped, size);
  91.     UserFree(pixmap->mapped);
  92.  
  93.     if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL )
  94.     {
  95.         rhd_mem_free(&rhd,RHD_MEM_FB,pixmap->local-rhd.fbLocation);
  96.     }
  97.     else
  98.     {
  99.         count_t pages = size >> 12;
  100.         addr_t  base  = pixmap->local;
  101.  
  102.         while( pages--)
  103.         {
  104.             addr_t tmp;
  105.  //           __asm__ __volatile__(
  106. //            "call *__imp__PageFree"
  107. //            :"=eax" (tmp):"a" (base) );
  108. //            base+= 4096;
  109.         };
  110.     }
  111.  
  112.     free(pixmap);
  113.  
  114.     io->format  = 0;
  115.     io->pitch   = 0;
  116.     io->mapped  = NULL;
  117.     io->handle  = 0;
  118.  
  119.     return ERR_OK;
  120. };
  121.  
  122.  
  123. # define ATI_PCIGART_PAGE_SIZE      4096    /**< PCI GART page size */
  124. # define ATI_PCIGART_PAGE_MASK          (~(ATI_PCIGART_PAGE_SIZE-1))
  125.  
  126. #define ATI_PCIE_WRITE  0x4
  127. #define ATI_PCIE_READ   0x8
  128.  
  129. #define upper_32_bits(n) ((u32_t)(((n) >> 16) >> 16))
  130.  
  131.  
  132. static void bind_pcie(u32_t *gart, addr_t base, count_t pages)
  133. {
  134.     addr_t page_base;
  135.  
  136.     while(pages--)
  137.     {
  138.         page_base = base & ATI_PCIGART_PAGE_MASK;
  139.  
  140.         page_base >>= 8;
  141.         page_base |= (upper_32_bits(base) & 0xff) << 24;
  142.         page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
  143.  
  144.         *gart = page_base;
  145.         base+= 4096;
  146.         gart++;
  147.     }
  148.     __asm__ __volatile("sfence":::"memory");
  149.  
  150.     RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
  151.                       RADEON_PCIE_TX_GART_EN
  152.                      | RADEON_PCIE_TX_GART_INVALIDATE_TLB);
  153. }
  154.  
  155. static void bind_pci(u32_t *gart, addr_t base, count_t pages)
  156. {
  157.     u32_t tmp;
  158.  
  159.     tmp = INREG(RADEON_AIC_CNTL);
  160.     OUTREG(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN);
  161.  
  162.     while(pages--)
  163.     {
  164.         *gart = base & ATI_PCIGART_PAGE_MASK;
  165.          base+= 4096;
  166.          gart++;
  167.     }
  168.     __asm__ __volatile("sfence":::"memory");
  169.  
  170.     OUTREG(RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN);
  171.     OUTREG(RADEON_AIC_PT_BASE, rhd.gart_table_dma);
  172. }
  173.  
  174. static addr_t bind_pixmap(local_pixmap_t *pixmap)
  175. {
  176.     u32_t   *gart = rhd.gart_table;
  177.     count_t  pages = ((pixmap->height * pixmap->pitch+4095)&~4095)>>12;
  178.     addr_t   base = pixmap->local;
  179.  
  180.     if( rhd.gart_type == RADEON_IS_PCIE)
  181.         bind_pcie(gart, base, pages);
  182.     else
  183.         bind_pci(gart, base, pages);
  184.  
  185.     return ((pixmap->pitch / 64) << 22) | (rhd.gart_vm_start >> 10);
  186. }
  187.  
  188. #if 0
  189.  
  190. int LockPixmap(userpixmap_t *io)
  191. {
  192.    pixmap_t *pixmap;
  193.    size_t    size;
  194.    void     *usermap;
  195.  
  196.    dbgprintf("Lock pixmap %x\n", io->pixmap);
  197.  
  198.    if(io->pixmap == (pixmap_t*)-1)
  199.      return ERR_PARAM;
  200.    else
  201.      pixmap = io->pixmap;
  202.  
  203.    if( (pixmap->flags & 1) == PX_LOCK )
  204.      return ERR_PARAM;
  205.  
  206.    size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
  207.    if (usermap = UserAlloc(size))
  208.    {
  209.      CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
  210.      pixmap->flags |= PX_LOCK;
  211.      pixmap->usermap = usermap;
  212.      io->usermap = usermap;
  213.      io->pitch   = pixmap->pitch;
  214.      dbgprintf("map at %x\n", io->usermap);
  215.  
  216.      return ERR_OK;
  217.    }
  218.    else
  219.      return ERR_PARAM;
  220. };
  221.  
  222. int UnlockPixmap(userpixmap_t *io)
  223. {
  224.   pixmap_t *pixmap;
  225.   size_t    size;
  226.  
  227.   dbgprintf("Unlock pixmap %x\n", io->pixmap);
  228.  
  229.   if(io->pixmap == (pixmap_t*)-1)
  230.     return ERR_PARAM;
  231.   else
  232.     pixmap = io->pixmap;
  233.  
  234.   if( (pixmap->flags & 1) != PX_LOCK )
  235.     return ERR_PARAM;
  236.  
  237. /*   Sanity checks  */
  238.  
  239.   if( (pixmap->usermap == 0)||
  240.       ((u32_t)pixmap->usermap >= 0x80000000) ||
  241.       ((u32_t)pixmap->usermap & 4095)
  242.     )
  243.     return ERR_PARAM;
  244.  
  245.   size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
  246.  
  247.   UnmapPages(pixmap->usermap, size);
  248.   UserFree(pixmap->usermap);
  249.   pixmap->usermap =  NULL;
  250.   pixmap->flags  &= ~PX_LOCK;
  251.   io->usermap     =  NULL;
  252.   io->pitch       =  0;
  253.  
  254.   return ERR_OK;
  255. };
  256.  
  257. #endif
  258.  
  259.