0,0 → 1,273 |
|
#define R300_TEST |
|
#include "r5xx_regs.h" |
|
|
#define R5XX_LOOP_COUNT 2000000 |
|
#define RADEON_CLOCK_CNTL_DATA 0x000c |
|
#define RADEON_CLOCK_CNTL_INDEX 0x0008 |
# define RADEON_PLL_WR_EN (1 << 7) |
# define RADEON_PLL_DIV_SEL (3 << 8) |
# define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8) |
|
#define RADEON_MCLK_CNTL 0x0012 /* PLL */ |
# define RADEON_FORCEON_MCLKA (1 << 16) |
# define RADEON_FORCEON_MCLKB (1 << 17) |
# define RADEON_FORCEON_YCLKA (1 << 18) |
# define RADEON_FORCEON_YCLKB (1 << 19) |
# define RADEON_FORCEON_MC (1 << 20) |
# define RADEON_FORCEON_AIC (1 << 21) |
# define R300_DISABLE_MC_MCLKA (1 << 21) |
# define R300_DISABLE_MC_MCLKB (1 << 21) |
|
void radeon_engine_reset(RHDPtr info) |
{ |
u32_t clock_cntl_index; |
u32_t mclk_cntl; |
u32_t rbbm_soft_reset; |
u32_t host_path_cntl; |
|
if (info->ChipFamily <= CHIP_FAMILY_RV410) |
{ |
/* may need something similar for newer chips */ |
clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); |
mclk_cntl = INPLL( RADEON_MCLK_CNTL); |
|
OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | |
RADEON_FORCEON_MCLKA | |
RADEON_FORCEON_MCLKB | |
RADEON_FORCEON_YCLKA | |
RADEON_FORCEON_YCLKB | |
RADEON_FORCEON_MC | |
RADEON_FORCEON_AIC)); |
} |
|
rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); |
|
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | |
RADEON_SOFT_RESET_CP | |
RADEON_SOFT_RESET_HI | |
RADEON_SOFT_RESET_SE | |
RADEON_SOFT_RESET_RE | |
RADEON_SOFT_RESET_PP | |
RADEON_SOFT_RESET_E2 | |
RADEON_SOFT_RESET_RB)); |
INREG(RADEON_RBBM_SOFT_RESET); |
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & |
~(RADEON_SOFT_RESET_CP | |
RADEON_SOFT_RESET_HI | |
RADEON_SOFT_RESET_SE | |
RADEON_SOFT_RESET_RE | |
RADEON_SOFT_RESET_PP | |
RADEON_SOFT_RESET_E2 | |
RADEON_SOFT_RESET_RB))); |
INREG(RADEON_RBBM_SOFT_RESET); |
|
if (info->ChipFamily <= CHIP_FAMILY_RV410) { |
OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); |
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); |
OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); |
} |
}; |
|
static Bool R5xxFIFOWaitLocal(u32_t required) //R100-R500 |
{ |
int i; |
|
for (i = 0; i < RADEON_TIMEOUT; i++) |
if (required <= (INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK)) |
return TRUE; |
|
dbgprintf("%s: Timeout 0x%08X.\n", __func__, (u32_t) INREG(RADEON_RBBM_STATUS)); |
return FALSE; |
} |
|
void FIFOWait(u32_t required) |
{ |
int i; |
for (i = 0; i < 200; i++) |
{ |
if (required <= (INREG(RADEON_RBBM_STATUS) & |
RADEON_RBBM_FIFOCNT_MASK)) |
return ; |
delay(2); |
}; |
}; |
|
|
/* |
* Flush all dirty data in the Pixel Cache to memory. |
*/ |
|
static Bool |
R5xx2DFlush() |
{ |
int i; |
|
MASKREG(R5XX_DSTCACHE_CTLSTAT, |
R5XX_DSTCACHE_FLUSH_ALL, R5XX_DSTCACHE_FLUSH_ALL); |
|
for (i = 0; i < R5XX_LOOP_COUNT; i++) |
if (!(INREG(R5XX_DSTCACHE_CTLSTAT) & R5XX_DSTCACHE_BUSY)) |
return TRUE; |
|
dbgprintf("%s: Timeout 0x%08x.\n", __func__, |
(unsigned int)INREG(R5XX_DSTCACHE_CTLSTAT)); |
return FALSE; |
} |
|
static Bool |
R5xx2DIdleLocal() //R100-R500 |
{ |
int i; |
|
/* wait for fifo to clear */ |
for (i = 0; i < R5XX_LOOP_COUNT; i++) |
if (64 == (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK)) |
break; |
|
if (i == R5XX_LOOP_COUNT) { |
dbgprintf("%s: FIFO Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS)); |
return FALSE; |
} |
|
/* wait for engine to go idle */ |
for (i = 0; i < R5XX_LOOP_COUNT; i++) { |
if (!(INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_ACTIVE)) { |
R5xx2DFlush(); |
return TRUE; |
} |
} |
dbgprintf("%s: Idle Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS)); |
return FALSE; |
} |
|
|
void |
R5xx2DSetup() |
{ |
|
/* Setup engine location. This shouldn't be necessary since we |
* set them appropriately before any accel ops, but let's avoid |
* random bogus DMA in case we inadvertently trigger the engine |
* in the wrong place (happened). */ |
R5xxFIFOWaitLocal(2); |
OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset); |
OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset); |
|
R5xxFIFOWaitLocal(1); |
MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN); |
|
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl); |
|
R5xxFIFOWaitLocal(3); |
OUTREG(R5XX_SC_TOP_LEFT, 0); |
OUTREG(R5XX_SC_BOTTOM_RIGHT, |
RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); |
OUTREG(R5XX_DEFAULT_SC_BOTTOM_RIGHT, |
RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); |
|
R5xxFIFOWaitLocal(1); |
// OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control | |
// R5XX_GMC_BRUSH_SOLID_COLOR | R5XX_GMC_SRC_DATATYPE_COLOR); |
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM); |
|
R5xxFIFOWaitLocal(5); |
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); |
OUTREG(R5XX_DP_BRUSH_BKGD_CLR, 0x00000000); |
OUTREG(R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF); |
OUTREG(R5XX_DP_SRC_BKGD_CLR, 0x00000000); |
OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF); |
|
R5xx2DIdleLocal(); |
} |
|
void R5xxFIFOWait(u32_t required) |
{ |
if (!R5xxFIFOWaitLocal(required)) { |
radeon_engine_reset(&rhd); |
R5xx2DSetup(); |
} |
} |
|
void R5xx2DIdle() |
{ |
if (!R5xx2DIdleLocal()) { |
// R5xx2DReset(); |
R5xx2DSetup(); |
} |
} |
|
|
void R5xx2DInit() |
{ |
u32_t base; |
int screensize; |
int screenpitch; |
|
screensize = GetScreenSize(); |
screenpitch = GetScreenPitch(); |
|
rhd.displayWidth = screensize >> 16; |
rhd.displayHeight = screensize & 0xFFFF; |
|
rhd.__xmin = 0; |
rhd.__ymin = 0; |
rhd.__xmax = rhd.displayWidth - 1; |
rhd.__ymax = rhd.displayHeight - 1; |
|
clip.xmin = 0; |
clip.ymin = 0; |
clip.xmax = rhd.displayWidth - 1; |
clip.ymax = rhd.displayHeight - 1; |
|
dbgprintf("screen width %d height %d\n", |
rhd.displayWidth, rhd.displayHeight); |
|
rhd.gui_control = ((6 << RADEON_GMC_DST_DATATYPE_SHIFT) |
| RADEON_GMC_CLR_CMP_CNTL_DIS |
| RADEON_GMC_DST_PITCH_OFFSET_CNTL); |
|
dbgprintf("gui_control %x \n", rhd.gui_control); |
|
rhd.surface_cntl = 0; |
|
rhd.dst_pitch_offset = (((rhd.displayWidth * 4 / 64)<< 22) | |
(rhd.fbLocation >> 10)); |
|
|
dbgprintf("dst_pitch_offset %x \n", rhd.dst_pitch_offset); |
|
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 = rhd.fbLocation; |
scr_pixmap.pitch_offset = rhd.dst_pitch_offset; |
scr_pixmap.mapped = 0; |
|
R5xxFIFOWaitLocal(2); |
OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset); |
OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset); |
|
R5xxFIFOWaitLocal(1); |
MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN); |
|
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl); |
|
#if !R300_PIO |
|
init_cp(&rhd); |
|
#endif |
|
R5xx2DSetup(); |
|
} |
|
|
|