/programs/system/drivers/ati2d/accel_2d.h |
---|
64,7 → 64,13 |
void *local; |
}local_pixmap_t; |
#define PX_MEM_SYSTEM 0 |
#define PX_MEM_LOCAL 1 |
#define PX_MEM_GART 2 |
#define PX_MEM_MASK 3 |
#define PX_LOCK 1 |
typedef struct |
/programs/system/drivers/ati2d/accel_2d.inc |
---|
567,7 → 567,96 |
}; |
#define ADDRREG(addr) ((volatile u32_t *)(rhd.MMIOBase + (addr))) |
static int blit_host(u32_t dstpitch, int dstx, int dsty, |
u32_t src, int srcx, int srcy, |
int w, int h, int srcpitch) |
{ |
u32_t ifl; |
color_t *src_addr; |
ifl = safe_cli(); |
#if R300_PIO |
R5xxFIFOWait(5); |
OUTREG(R5XX_DP_GUI_MASTER_CNTL, |
RADEON_GMC_DST_PITCH_OFFSET_CNTL | |
// RADEON_GMC_DST_CLIPPING | |
RADEON_GMC_BRUSH_NONE | |
RADEON_GMC_DST_32BPP | |
RADEON_GMC_SRC_DATATYPE_COLOR | |
RADEON_DP_SRC_SOURCE_HOST_DATA | |
// RADEON_GMC_BYTE_MSB_TO_LSB | |
R5XX_GMC_CLR_CMP_CNTL_DIS | |
R5XX_GMC_WR_MSK_DIS | |
R5XX_ROP3_S |
); |
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | |
R5XX_DST_Y_TOP_TO_BOTTOM); |
OUTREG(R5XX_DST_PITCH_OFFSET, dstpitch); |
// OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) & 0xffff)); |
// OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); |
OUTREG(RADEON_DST_Y_X, (dsty << 16) | (dstx & 0xffff)); |
OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); |
src_addr = &((color_t*)src)[srcpitch*srcy/4+srcx]; |
while ( h-- ) |
{ |
color_t *tmp_src = src_addr; |
src_addr += srcpitch/4; |
int left = w; |
while( left ) |
{ |
volatile u32_t *d; |
if( left > 8 ) |
{ |
int i; |
R5xxFIFOWait(8); |
d = ADDRREG(RADEON_HOST_DATA0); |
/* Unrolling doesn't improve performance */ |
for ( i = 0; i < 8; i++) |
*d++ = *tmp_src++; |
left -= 8; |
} |
else |
{ |
R5xxFIFOWait(left); |
if( h ) |
d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); |
else |
d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); |
for ( ; left; --left) |
*d++ = *tmp_src++; |
left = 0; |
}; |
}; |
}; |
#endif |
safe_sti(ifl); |
return ERR_OK; |
} |
int Blit(io_blit_t *blit) |
{ |
clip_t src_clip, dst_clip; |
604,6 → 693,14 |
u32_t *ring, write; |
u32_t ifl; |
if( (srcpixmap->flags & PX_MEM_MASK)==PX_MEM_SYSTEM) |
return blit_host(dstpixmap->pitch_offset, |
blit->dst_x, blit->dst_y, |
srcpixmap->mapped, |
blit->src_x, blit->src_y, |
blit->w, blit->h, |
srcpixmap->pitch); |
ifl = safe_cli(); |
#if R300_PIO |
/programs/system/drivers/ati2d/ati2d.c |
---|
1,8 → 1,13 |
#define R300_PIO 0 /* now we have cp */ |
#define R300_PIO 1 |
#define API_VERSION 0x01000100 |
#define SRV_GETVERSION 0 |
#include "types.h" |
#include <stdio.h> |
72,8 → 77,11 |
R5xx2DInit(); |
#if !R300_PIO |
Init3DEngine(&rhd); |
#endif |
retval = RegService("HDRAW", srv_2d); |
dbgprintf("reg service %s as: %x\n", "HDRAW", retval); |
82,11 → 90,6 |
}; |
#define API_VERSION 0x01000100 |
#define SRV_GETVERSION 0 |
int __stdcall srv_2d(ioctl_t *io) |
{ |
u32_t *inp; |
/programs/system/drivers/ati2d/ati_mem.c |
---|
39,7 → 39,8 |
* already mapped into each client's address space. |
*/ |
struct mem_block { |
struct mem_block |
{ |
struct mem_block *next; |
struct mem_block *prev; |
u32_t start; |
114,7 → 115,6 |
list_for_each(p, heap) |
{ |
if ( !(p->start & USED_BLOCK) && size <= p->size) |
return split_block(p, size); |
} |
/programs/system/drivers/ati2d/init.c |
---|
448,7 → 448,6 |
#endif |
static void RADEONInitMemoryMap(RHDPtr info) |
{ |
u32_t mem_size; |
484,7 → 483,8 |
if ( (info->ChipFamily != CHIP_FAMILY_RS600) && |
(info->ChipFamily != CHIP_FAMILY_RS690) && |
(info->ChipFamily != CHIP_FAMILY_RS740)) { |
(info->ChipFamily != CHIP_FAMILY_RS740)) |
{ |
if (info->IsIGP) |
info->mc_fb_location = INREG(RADEON_NB_TOM); |
else |
995,12 → 995,124 |
info = &rhd; |
return TRUE; |
error1: |
return FALSE; |
}; |
static void RADEONPllErrataAfterIndex() |
{ |
if (!(rhd.ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS)) |
return; |
/* This workaround is necessary on rv200 and RS200 or PLL |
* reads may return garbage (among others...) |
*/ |
(void)INREG(RADEON_CLOCK_CNTL_DATA); |
(void)INREG(RADEON_CRTC_GEN_CNTL); |
} |
static void RADEONPllErrataAfterData() |
{ |
/* This function is required to workaround a hardware bug in some (all?) |
* revisions of the R300. This workaround should be called after every |
* CLOCK_CNTL_INDEX register access. If not, register reads afterward |
* may not be correct. |
*/ |
if (rhd.ChipFamily <= CHIP_FAMILY_RV380) |
{ |
u32_t save, tmp; |
save = INREG(RADEON_CLOCK_CNTL_INDEX); |
tmp = save & ~(0x3f | RADEON_PLL_WR_EN); |
OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp); |
tmp = INREG(RADEON_CLOCK_CNTL_DATA); |
OUTREG(RADEON_CLOCK_CNTL_INDEX, save); |
} |
} |
/* Read PLL register */ |
static u32_t RADEONINPLL(int addr) |
{ |
u32_t data; |
OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); |
RADEONPllErrataAfterIndex(); |
data = INREG(RADEON_CLOCK_CNTL_DATA); |
RADEONPllErrataAfterData(); |
return data; |
}; |
/* Write PLL information */ |
static void RADEONOUTPLL(int addr, u32_t data) |
{ |
OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | |
RADEON_PLL_WR_EN)); |
RADEONPllErrataAfterIndex(); |
OUTREG(RADEON_CLOCK_CNTL_DATA, data); |
RADEONPllErrataAfterData(); |
} |
static void init_pipes(RHDPtr info) |
{ |
u32_t gb_tile_config = 0; |
if ( (info->ChipFamily == CHIP_FAMILY_RV410) || |
(info->ChipFamily == CHIP_FAMILY_R420) || |
(info->ChipFamily == CHIP_FAMILY_RS600) || |
(info->ChipFamily == CHIP_FAMILY_RS690) || |
(info->ChipFamily == CHIP_FAMILY_RS740) || |
(info->ChipFamily == CHIP_FAMILY_RS400) || |
(info->ChipFamily == CHIP_FAMILY_RS480) || IS_R500_3D) |
{ |
u32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); |
info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; |
if (IS_R500_3D) |
OUTPLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); |
} |
else |
{ |
if ((info->ChipFamily == CHIP_FAMILY_R300) || |
(info->ChipFamily == CHIP_FAMILY_R350)) |
{ |
/* R3xx chips */ |
info->num_gb_pipes = 2; |
} |
else { |
/* RV3xx chips */ |
info->num_gb_pipes = 1; |
} |
} |
if (IS_R300_3D || IS_R500_3D) |
{ |
dbgprintf("num quad-pipes is %d\n", info->num_gb_pipes); |
switch(info->num_gb_pipes) { |
case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; |
case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; |
case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; |
default: |
case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; |
} |
OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); |
OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); |
OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); |
OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | |
R300_DC_AUTOFLUSH_ENABLE | |
R300_DC_DC_DISABLE_IGNORE_PE)); |
} |
else |
OUTREG(RADEON_RB3D_CNTL, 0); |
}; |
/programs/system/drivers/ati2d/init_3d.inc |
---|
635,7 → 635,6 |
FINISH_ACCEL(); |
} |
safe_sti(ifl); |
} |
/programs/system/drivers/ati2d/init_cp.c |
---|
20,66 → 20,10 |
#define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */ |
#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ |
#define RADEON_TIMEOUT 4000000 /* Fall out of wait loops after this count */ |
void RADEONPllErrataAfterIndex() |
{ |
if (!(rhd.ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS)) |
return; |
/* This workaround is necessary on rv200 and RS200 or PLL |
* reads may return garbage (among others...) |
*/ |
(void)INREG(RADEON_CLOCK_CNTL_DATA); |
(void)INREG(RADEON_CRTC_GEN_CNTL); |
} |
void RADEONPllErrataAfterData() |
{ |
/* This function is required to workaround a hardware bug in some (all?) |
* revisions of the R300. This workaround should be called after every |
* CLOCK_CNTL_INDEX register access. If not, register reads afterward |
* may not be correct. |
*/ |
if (rhd.ChipFamily <= CHIP_FAMILY_RV380) |
{ |
u32_t save, tmp; |
save = INREG(RADEON_CLOCK_CNTL_INDEX); |
tmp = save & ~(0x3f | RADEON_PLL_WR_EN); |
OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp); |
tmp = INREG(RADEON_CLOCK_CNTL_DATA); |
OUTREG(RADEON_CLOCK_CNTL_INDEX, save); |
} |
} |
/* Read PLL register */ |
u32_t RADEONINPLL(int addr) |
{ |
u32_t data; |
OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); |
RADEONPllErrataAfterIndex(); |
data = INREG(RADEON_CLOCK_CNTL_DATA); |
RADEONPllErrataAfterData(); |
return data; |
}; |
/* Write PLL information */ |
void RADEONOUTPLL(int addr, u32_t data) |
{ |
OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | |
RADEON_PLL_WR_EN)); |
RADEONPllErrataAfterIndex(); |
OUTREG(RADEON_CLOCK_CNTL_DATA, data); |
RADEONPllErrataAfterData(); |
} |
void RADEONEngineFlush(RHDPtr info) |
{ |
int i; |
148,62 → 92,7 |
} |
static void init_pipes(RHDPtr info) |
{ |
u32_t gb_tile_config = 0; |
if ( (info->ChipFamily == CHIP_FAMILY_RV410) || |
(info->ChipFamily == CHIP_FAMILY_R420) || |
(info->ChipFamily == CHIP_FAMILY_RS600) || |
(info->ChipFamily == CHIP_FAMILY_RS690) || |
(info->ChipFamily == CHIP_FAMILY_RS740) || |
(info->ChipFamily == CHIP_FAMILY_RS400) || |
(info->ChipFamily == CHIP_FAMILY_RS480) || IS_R500_3D) |
{ |
u32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); |
info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; |
if (IS_R500_3D) |
OUTPLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); |
} |
else |
{ |
if ((info->ChipFamily == CHIP_FAMILY_R300) || |
(info->ChipFamily == CHIP_FAMILY_R350)) |
{ |
/* R3xx chips */ |
info->num_gb_pipes = 2; |
} |
else { |
/* RV3xx chips */ |
info->num_gb_pipes = 1; |
} |
} |
if (IS_R300_3D || IS_R500_3D) |
{ |
dbgprintf("num quad-pipes is %d\n", info->num_gb_pipes); |
switch(info->num_gb_pipes) { |
case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; |
case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; |
case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; |
default: |
case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; |
} |
OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); |
OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); |
OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); |
OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | |
R300_DC_AUTOFLUSH_ENABLE | |
R300_DC_DC_DISABLE_IGNORE_PE)); |
} |
else |
OUTREG(RADEON_RB3D_CNTL, 0); |
}; |
/* ================================================================ |
* CP control, initialization |
*/ |
501,6 → 390,7 |
radeon_cp_start(&rhd); |
return TRUE; |
}; |
/programs/system/drivers/ati2d/makefile |
---|
22,8 → 22,7 |
blend.inc \ |
r500.inc \ |
pixmap.inc \ |
accel_2d.inc \ |
accel_3d.inc |
accel_2d.inc |
ATI_SRC:= ati2d.c |
/programs/system/drivers/ati2d/pci.c |
---|
60,12 → 60,12 |
int i; |
rhd.chipset = (char*)xf86TokenToString(RADEONChipsets, rhd.PciDeviceID); |
if (!rhd.chipset) |
{ |
if (!rhd.chipset){ |
dbgprintf("ChipID 0x%04x is not recognized\n", rhd.PciDeviceID); |
return FALSE; |
} |
dbgprintf("Chipset: \"%s\" (ChipID = 0x%04x)\n",rhd.chipset,rhd.PciDeviceID); |
dbgprintf("Chipset: \"%s\" (ChipID = 0x%04x)\n", |
rhd.chipset,rhd.PciDeviceID); |
rhd.bus = bus; |
rhd.devfn = devfn; |
93,13 → 93,11 |
base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2)); |
if(base) |
{ |
if (base & PCI_MAP_IO) |
{ |
if (base & PCI_MAP_IO){ |
rhd.ioBase[i] = (u32_t)PCIGETIO(base); |
rhd.memtype[i] = base & PCI_MAP_IO_ATTR_MASK; |
} |
else |
{ |
else{ |
rhd.memBase[i] = (u32_t)PCIGETMEMORY(base); |
rhd.memtype[i] = base & PCI_MAP_MEMORY_ATTR_MASK; |
} |
108,8 → 106,8 |
} |
return &rhd; |
} |
} |
}; |
}; |
return NULL; |
} |
/programs/system/drivers/ati2d/pixmap.inc |
---|
50,7 → 50,7 |
pixmap->width = io->width; |
pixmap->height = io->height; |
pixmap->format = PICT_a8r8g8b8; |
pixmap->flags = io->flags; |
pixmap->flags = PX_MEM_LOCAL; //io->flags; |
pixmap->pitch = pitch; |
pixmap->mapped = mapped; |
pixmap->pitch_offset = ((pitch/64)<<22)| (((u32_t)local+rhd.fbLocation)>>10); |
/programs/system/drivers/ati2d/r500.inc |
---|
71,7 → 71,6 |
} |
dbgprintf("%s: Idle Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS)); |
return FALSE; |
} |
174,6 → 173,7 |
scr_pixmap.width = rhd.displayWidth; |
scr_pixmap.height = rhd.displayHeight; |
scr_pixmap.format = PICT_a8r8g8b8; |
scr_pixmap.flags = PX_MEM_LOCAL; |
scr_pixmap.pitch = rhd.displayWidth * 4 ;//screenpitch; |
scr_pixmap.local = (void*)rhd.fbLocation; |
scr_pixmap.pitch_offset = rhd.dst_pitch_offset; |
188,9 → 188,10 |
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl); |
#if R300_PIO |
#else |
#if !R300_PIO |
init_cp(&rhd); |
#endif |
R5xx2DSetup(); |