Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1028 → Rev 1029

/drivers/video/ati2d/pixmap.inc
0,0 → 1,258
 
int CreatePixmap(pixmap_t *io)
{
local_pixmap_t *pixmap;
 
unsigned pitch;
size_t size;
 
addr_t mem_local = 0;
addr_t mem_dma = 0;
void *mapped;
 
if( (io->width == 0) || (io->width > 2048)||
(io->height == 0)|| (io->height > 2048))
{
dbgprintf("Invalid pixmap size w:%d h:%d\n", io->width,io->height);
return ERR_PARAM;
};
 
pixmap = malloc(sizeof(local_pixmap_t));
 
if(!pixmap)
return ERR_PARAM;
 
pitch = ((io->width+15)&~15)*4;
size = pitch*io->height;
 
dbgprintf("pitch = %d\n", pitch);
 
if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL ) {
mem_local = rhd_mem_alloc(&rhd,RHD_MEM_FB,size);
mem_dma = mem_local + rhd.fbLocation;
}
else
mem_local = mem_dma = AllocPages( size >> 12 );
 
if ( !mem_local) {
dbgprintf("Not enough memory for pixmap\n");
free(pixmap);
return ERR_PARAM;
};
 
pixmap->pitch_offset = ((pitch/64)<<22)| (mem_dma>>10);
pixmap->local = mem_dma;
 
size = (size+4095) & ~ 4095;
 
if (mapped = UserAlloc(size))
{
CommitPages(mapped, mem_dma|7|(1<<9), size);
 
io->mapped = mapped;
io->pitch = pitch;
io->handle = (u32_t)pixmap;
 
pixmap->width = io->width;
pixmap->height = io->height;
pixmap->format = PICT_a8r8g8b8;
pixmap->flags = io->flags;
pixmap->pitch = pitch;
pixmap->mapped = mapped;
 
dbgprintf("pixmap.pitch_offset: %x\n", pixmap->pitch_offset);
dbgprintf("width: %d height: %d\n",pixmap->width,pixmap->height );
dbgprintf("map at %x\n", pixmap->mapped);
 
return ERR_OK;
};
rhd_mem_free(&rhd, RHD_MEM_FB, mem_local);
free(pixmap);
 
return ERR_PARAM;
};
 
 
int DestroyPixmap( pixmap_t *io )
{
local_pixmap_t *pixmap;
size_t size;
 
dbgprintf("Destroy pixmap %x\n", io->handle);
 
if(io->handle == -1)
return ERR_PARAM;
else
pixmap = (local_pixmap_t*)io->handle;
 
size = (pixmap->pitch*pixmap->height+4095) & ~ 4095;
 
UnmapPages(pixmap->mapped, size);
UserFree(pixmap->mapped);
 
if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL )
{
rhd_mem_free(&rhd,RHD_MEM_FB,pixmap->local-rhd.fbLocation);
}
else
{
count_t pages = size >> 12;
addr_t base = pixmap->local;
 
while( pages--)
{
addr_t tmp;
// __asm__ __volatile__(
// "call *__imp__PageFree"
// :"=eax" (tmp):"a" (base) );
// base+= 4096;
};
}
 
free(pixmap);
 
io->format = 0;
io->pitch = 0;
io->mapped = NULL;
io->handle = 0;
 
return ERR_OK;
};
 
 
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
 
#define ATI_PCIE_WRITE 0x4
#define ATI_PCIE_READ 0x8
 
#define upper_32_bits(n) ((u32_t)(((n) >> 16) >> 16))
 
 
static void bind_pcie(u32_t *gart, addr_t base, count_t pages)
{
addr_t page_base;
 
while(pages--)
{
page_base = base & ATI_PCIGART_PAGE_MASK;
 
page_base >>= 8;
page_base |= (upper_32_bits(base) & 0xff) << 24;
page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
 
*gart = page_base;
base+= 4096;
gart++;
}
__asm__ __volatile("sfence":::"memory");
 
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
RADEON_PCIE_TX_GART_EN
| RADEON_PCIE_TX_GART_INVALIDATE_TLB);
}
 
static void bind_pci(u32_t *gart, addr_t base, count_t pages)
{
u32_t tmp;
 
tmp = INREG(RADEON_AIC_CNTL);
OUTREG(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN);
 
while(pages--)
{
*gart = base & ATI_PCIGART_PAGE_MASK;
base+= 4096;
gart++;
}
__asm__ __volatile("sfence":::"memory");
 
OUTREG(RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN);
OUTREG(RADEON_AIC_PT_BASE, rhd.gart_table_dma);
}
 
static addr_t bind_pixmap(local_pixmap_t *pixmap)
{
u32_t *gart = rhd.gart_table;
count_t pages = ((pixmap->height * pixmap->pitch+4095)&~4095)>>12;
addr_t base = pixmap->local;
 
if( rhd.gart_type == RADEON_IS_PCIE)
bind_pcie(gart, base, pages);
else
bind_pci(gart, base, pages);
 
return ((pixmap->pitch / 64) << 22) | (rhd.gart_vm_start >> 10);
}
 
#if 0
 
int LockPixmap(userpixmap_t *io)
{
pixmap_t *pixmap;
size_t size;
void *usermap;
 
dbgprintf("Lock pixmap %x\n", io->pixmap);
 
if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM;
else
pixmap = io->pixmap;
 
if( (pixmap->flags & 1) == PX_LOCK )
return ERR_PARAM;
 
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
if (usermap = UserAlloc(size))
{
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
pixmap->flags |= PX_LOCK;
pixmap->usermap = usermap;
io->usermap = usermap;
io->pitch = pixmap->pitch;
dbgprintf("map at %x\n", io->usermap);
 
return ERR_OK;
}
else
return ERR_PARAM;
};
 
int UnlockPixmap(userpixmap_t *io)
{
pixmap_t *pixmap;
size_t size;
 
dbgprintf("Unlock pixmap %x\n", io->pixmap);
 
if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM;
else
pixmap = io->pixmap;
 
if( (pixmap->flags & 1) != PX_LOCK )
return ERR_PARAM;
 
/* Sanity checks */
 
if( (pixmap->usermap == 0)||
((u32_t)pixmap->usermap >= 0x80000000) ||
((u32_t)pixmap->usermap & 4095)
)
return ERR_PARAM;
 
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
 
UnmapPages(pixmap->usermap, size);
UserFree(pixmap->usermap);
pixmap->usermap = NULL;
pixmap->flags &= ~PX_LOCK;
io->usermap = NULL;
io->pitch = 0;
 
return ERR_OK;
};
 
#endif