forked from KolibriOS/kolibrios
command processor
git-svn-id: svn://kolibrios.org@883 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
673a89c327
commit
ebd406a2e7
@ -3,7 +3,7 @@
|
||||
int ClearPixmap(io_clear_t *io)
|
||||
{
|
||||
u32_t ifl;
|
||||
u32_t *ring, write;
|
||||
u32_t *ring;
|
||||
|
||||
local_pixmap_t *dstpixmap;
|
||||
|
||||
@ -32,7 +32,8 @@ int ClearPixmap(io_clear_t *io)
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(dstpixmap->width<<16)|dstpixmap->height);
|
||||
|
||||
#else
|
||||
BEGIN_RING();
|
||||
BEGIN_RING(6);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
@ -79,10 +80,10 @@ int Line(io_draw_t *draw)
|
||||
|
||||
if ( !LineClip(&clip, &x0, &y0, &x1, &y1 ))
|
||||
{
|
||||
u32_t efl;
|
||||
u32_t ifl;
|
||||
u32_t *ring, write;
|
||||
|
||||
efl = safe_cli();
|
||||
ifl = safe_cli();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
@ -106,7 +107,8 @@ int Line(io_draw_t *draw)
|
||||
OUTREG(R5XX_DST_LINE_START,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_LINE_END,(y1<<16)|x1);
|
||||
#else
|
||||
BEGIN_RING();
|
||||
BEGIN_RING(6);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_POLYLINE, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
@ -121,9 +123,8 @@ int Line(io_draw_t *draw)
|
||||
OUT_RING((y0<<16)|x0);
|
||||
OUT_RING((y1<<16)|x1);
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
safe_sti(efl);
|
||||
safe_sti(ifl);
|
||||
};
|
||||
return ERR_OK;
|
||||
}
|
||||
@ -154,7 +155,7 @@ int DrawRect(io_draw_t* draw)
|
||||
|
||||
if( ! BlockClip( &dst_clip, &x0, &y0, &x1, &y1))
|
||||
{
|
||||
u32_t *ring, write;
|
||||
u32_t *ring;
|
||||
u32_t ifl;
|
||||
int w, h;
|
||||
|
||||
@ -220,7 +221,9 @@ int DrawRect(io_draw_t* draw)
|
||||
}
|
||||
};
|
||||
#else
|
||||
BEGIN_RING();
|
||||
|
||||
BEGIN_RING(64);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
@ -234,8 +237,150 @@ int DrawRect(io_draw_t* draw)
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->color);
|
||||
OUT_RING((draw->x0<<16)|y0);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((w<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
if( draw->color != draw->border)
|
||||
{
|
||||
if( y0 == draw->y0) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((w<<16)|1);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
// y0++;
|
||||
// h--;
|
||||
}
|
||||
if( y1 == yend ) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y1);
|
||||
OUT_RING((w<<16)|1);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
// h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == draw->x0)) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((1<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
}
|
||||
if( (h > 0) && (x1 == xend)) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x1<<16)|y0);
|
||||
OUT_RING((1<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, draw->color);
|
||||
CP_REG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
CP_REG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|h);
|
||||
if( draw->color != draw->border)
|
||||
{
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, draw->border);
|
||||
CP_REG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
CP_REG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
|
||||
|
||||
if( y0 == draw->y0) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend ) {
|
||||
CP_REG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == draw->x0)) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend)) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
COMMIT_RING();
|
||||
#endif
|
||||
safe_sti(ifl);
|
||||
@ -268,13 +413,15 @@ int FillRect(io_fill_t *fill)
|
||||
if( ! BlockClip(&dst_clip, &x0, &y0, &x1, &y1))
|
||||
{
|
||||
u32_t *ring, write;
|
||||
u32_t ifl = safe_cli();
|
||||
|
||||
#if R300_PIO
|
||||
u32_t ifl;
|
||||
|
||||
int w = x1 - x0 + 1;
|
||||
int h = y1 - y0 + 1;
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
R5xxFIFOWait(9);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
@ -350,7 +497,8 @@ int FillRect(io_fill_t *fill)
|
||||
|
||||
|
||||
#else
|
||||
BEGIN_RING();
|
||||
BEGIN_RING(9+10*2);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT, 7));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R5XX_GMC_BRUSH_8X8_MONO_FG_BG |
|
||||
@ -370,6 +518,46 @@ int FillRect(io_fill_t *fill)
|
||||
|
||||
OUT_RING((y0<<16)|x0);
|
||||
OUT_RING((y1<<16)|x1);
|
||||
|
||||
if( (fill->border & 0xFF000000) != 0)
|
||||
{
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, fill->border);
|
||||
|
||||
if( y0 == fill->y)
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend )
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == fill->x))
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend))
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
@ -414,8 +602,9 @@ int Blit(io_blit_t *blit)
|
||||
&blit->w, &blit->h) )
|
||||
{
|
||||
u32_t *ring, write;
|
||||
u32_t ifl;
|
||||
|
||||
u32_t ifl = safe_cli();
|
||||
ifl = safe_cli();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
@ -443,8 +632,8 @@ int Blit(io_blit_t *blit)
|
||||
OUTREG(R5XX_DST_HEIGHT_WIDTH,(blit->h<<16)|blit->w);
|
||||
|
||||
#else
|
||||
BEGIN_RING(7);
|
||||
|
||||
BEGIN_RING();
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT, 5));
|
||||
|
||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
@ -507,7 +696,9 @@ int BlitTransparent(io_blit_t *blit)
|
||||
{
|
||||
u32_t *ring, write;
|
||||
|
||||
u32_t ifl = safe_cli();
|
||||
u32_t ifl;
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
@ -526,7 +717,7 @@ int BlitTransparent(io_blit_t *blit)
|
||||
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
OUTREG(R5XX_CLR_CMP_CLR_SRC, 0xFF000000);
|
||||
OUTREG(R5XX_CLR_CMP_CLR_SRC, blit->key);
|
||||
OUTREG(R5XX_CLR_CMP_MASK, R5XX_CLR_CMP_MSK);
|
||||
OUTREG(R5XX_CLR_CMP_CNTL, R5XX_SRC_CMP_EQ_COLOR | R5XX_CLR_CMP_SRC_SOURCE);
|
||||
|
||||
@ -539,7 +730,8 @@ int BlitTransparent(io_blit_t *blit)
|
||||
|
||||
#else
|
||||
|
||||
BEGIN_RING();
|
||||
BEGIN_RING(10);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8));
|
||||
|
||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
@ -556,8 +748,8 @@ int BlitTransparent(io_blit_t *blit)
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
|
||||
OUT_RING(R5XX_CLR_CMP_SRC_SOURCE | R5XX_SRC_CMP_EQ_COLOR);
|
||||
OUT_RING(0xFF000000);
|
||||
OUT_RING(0xFF000000);
|
||||
OUT_RING(blit->key);
|
||||
OUT_RING(0xFFFFFFFF);
|
||||
|
||||
OUT_RING((blit->src_x<<16)|blit->src_y);
|
||||
OUT_RING((blit->dst_x<<16)|blit->dst_y);
|
||||
|
@ -1,4 +1,8 @@
|
||||
|
||||
|
||||
#define R300_PIO 0 /* now we have cp */
|
||||
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -14,7 +18,7 @@
|
||||
#include "ati2d.h"
|
||||
#include "accel_2d.h"
|
||||
|
||||
RHD_t rhd;
|
||||
RHD_t rhd __attribute__ ((aligned (128))); /* reduce cache lock */
|
||||
|
||||
static clip_t clip;
|
||||
|
||||
@ -163,6 +167,7 @@ int __stdcall srv_2d(ioctl_t *io)
|
||||
#include "pci.c"
|
||||
#include "ati_mem.c"
|
||||
|
||||
#include "init_cp.c"
|
||||
#include "r500.inc"
|
||||
|
||||
#include "clip.inc"
|
||||
|
@ -7,7 +7,6 @@ typedef unsigned int memType;
|
||||
typedef struct { float hi, lo; } range;
|
||||
|
||||
|
||||
#define R300_PIO 1
|
||||
|
||||
#define PCI_CMD_STAT_REG 0x04
|
||||
|
||||
@ -123,13 +122,23 @@ typedef struct
|
||||
} RADEONCardInfo;
|
||||
|
||||
|
||||
|
||||
#define RHD_FB_BAR 0
|
||||
#define RHD_MMIO_BAR 2
|
||||
|
||||
#define RHD_MEM_GART 1
|
||||
#define RHD_MEM_FB 2
|
||||
|
||||
#define RADEON_DEFAULT_GART_SIZE 8 /* MB (must be 2^n and > 4MB) */
|
||||
#define R300_DEFAULT_GART_SIZE 32 /* MB (for R300 and above) */
|
||||
#define RADEON_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */
|
||||
#define RADEON_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */
|
||||
#define RADEON_DEFAULT_GART_TEX_SIZE 1 /* MB (must be page aligned) */
|
||||
|
||||
#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */
|
||||
|
||||
#define RADEON_DEFAULT_PCI_APER_SIZE 32 /* in MB */
|
||||
|
||||
|
||||
typedef struct RHDRec
|
||||
{
|
||||
u32_t MMIOBase;
|
||||
@ -168,8 +177,9 @@ typedef struct RHDRec
|
||||
|
||||
char *chipset;
|
||||
|
||||
int IsIGP;
|
||||
int IsMobility;
|
||||
Bool IsIGP;
|
||||
Bool IsMobility;
|
||||
Bool HasCRTC2;
|
||||
|
||||
u32_t bus;
|
||||
u32_t devfn;
|
||||
@ -193,6 +203,19 @@ typedef struct RHDRec
|
||||
u32_t displayWidth;
|
||||
u32_t displayHeight;
|
||||
|
||||
u32_t gartSize;
|
||||
|
||||
u32_t* ringBase;
|
||||
u32_t ring_rp;
|
||||
u32_t ring_wp;
|
||||
u32_t ringSize;
|
||||
u32_t ring_avail;
|
||||
|
||||
u32_t bufSize;
|
||||
u32_t gartTexSize;
|
||||
u32_t pciAperSize;
|
||||
u32_t CPusecTimeout;
|
||||
|
||||
int __xmin;
|
||||
int __ymin;
|
||||
int __xmax;
|
||||
@ -202,15 +225,24 @@ typedef struct RHDRec
|
||||
u32_t dst_pitch_offset;
|
||||
u32_t surface_cntl;
|
||||
|
||||
u32_t *ring_base;
|
||||
u32_t ring_rp;
|
||||
u32_t ring_wp;
|
||||
|
||||
int RamWidth;
|
||||
volatile u32_t host_rp __attribute__ ((aligned (128)));
|
||||
|
||||
volatile u32_t scratch0 __attribute__ ((aligned (128)));
|
||||
volatile u32_t scratch1;
|
||||
volatile u32_t scratch2;
|
||||
volatile u32_t scratch3;
|
||||
volatile u32_t scratch4;
|
||||
volatile u32_t scratch5;
|
||||
volatile u32_t scratch6;
|
||||
volatile u32_t scratch7;
|
||||
|
||||
int RamWidth __attribute__ ((aligned (128)));
|
||||
Bool IsDDR;
|
||||
|
||||
int num_gb_pipes;
|
||||
int has_tcl;
|
||||
|
||||
}RHD_t, *RHDPtr;
|
||||
|
||||
extern RHD_t rhd;
|
||||
@ -251,44 +283,55 @@ extern RHD_t rhd;
|
||||
# define RADEON_CNTL_PAINT_MULTI 0x00009A00
|
||||
|
||||
#define CP_PACKET0(reg, n) \
|
||||
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
|
||||
(RADEON_CP_PACKET0 | ((n - 1 ) << 16) | ((reg) >> 2))
|
||||
|
||||
#define CP_PACKET1(reg0, reg1) \
|
||||
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
|
||||
|
||||
#define CP_PACKET2() \
|
||||
#define CP_PACKET2() \
|
||||
(RADEON_CP_PACKET2)
|
||||
|
||||
#define CP_PACKET3( pkt, n ) \
|
||||
#define CP_PACKET3( pkt, n ) \
|
||||
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
|
||||
|
||||
#define BEGIN_RING( n ) do { \
|
||||
ring = rhd.ring_base; \
|
||||
write = rhd.ring_wp; \
|
||||
} while (0)
|
||||
|
||||
#define BEGIN_RING( req ) do { \
|
||||
int avail = rhd.ring_rp-rhd.ring_wp; \
|
||||
if (avail <=0 ) avail+= 0x4000; \
|
||||
if( (req)+128 > avail) \
|
||||
{ \
|
||||
rhd.ring_rp = INREG(RADEON_CP_RB_RPTR); \
|
||||
avail = rhd.ring_rp-rhd.ring_wp; \
|
||||
if (avail <= 0) avail+= 0x4000; \
|
||||
if( (req)+128 > avail){ \
|
||||
safe_sti(ifl); \
|
||||
return 0; \
|
||||
}; \
|
||||
} \
|
||||
ring = &rhd.ringBase[rhd.ring_wp]; \
|
||||
}while(0);
|
||||
|
||||
#define ADVANCE_RING()
|
||||
|
||||
#define OUT_RING( x ) do { \
|
||||
ring[write++] = (x); \
|
||||
} while (0)
|
||||
#define OUT_RING( x ) *ring++ = (x)
|
||||
|
||||
#define OUT_RING_REG(reg, val) \
|
||||
do { \
|
||||
OUT_RING(CP_PACKET0(reg, 0)); \
|
||||
OUT_RING(val); \
|
||||
#define CP_REG(reg, val) \
|
||||
do { \
|
||||
ring[0] = CP_PACKET0((reg), 1); \
|
||||
ring[1] = (val); \
|
||||
ring+= 2; \
|
||||
} while (0)
|
||||
|
||||
#define DRM_MEMORYBARRIER() __asm volatile("lock; addl $0,0(%%esp)" : : : "memory");
|
||||
|
||||
#define COMMIT_RING() do { \
|
||||
rhd.ring_wp = write & 0x1FFF; \
|
||||
/* Flush writes to ring */ \
|
||||
DRM_MEMORYBARRIER(); \
|
||||
/*GET_RING_HEAD( dev_priv ); */ \
|
||||
OUTREG( RADEON_CP_RB_WPTR, rhd.ring_wp); \
|
||||
/* read from PCI bus to ensure correct posting */ \
|
||||
INREG( RADEON_CP_RB_RPTR ); \
|
||||
#define COMMIT_RING() do { \
|
||||
rhd.ring_wp = (ring - rhd.ringBase) & 0x3FFF; \
|
||||
/* Flush writes to ring */ \
|
||||
DRM_MEMORYBARRIER(); \
|
||||
/*GET_RING_HEAD( dev_priv ); */ \
|
||||
OUTREG( RADEON_CP_RB_WPTR, rhd.ring_wp); \
|
||||
/* read from PCI bus to ensure correct posting */ \
|
||||
/* INREG( RADEON_CP_RB_RPTR ); */ \
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -318,6 +361,9 @@ extern inline void OUTREG(u16_t offset, u32_t value)
|
||||
*(volatile u32_t *)((u8_t *)(rhd.MMIOBase + offset)) = value;
|
||||
}
|
||||
|
||||
//#define OUTREG( offset, value) \
|
||||
// *(volatile u32_t *)((u8_t *)(rhd.MMIOBase + (u32_t)(offset))) = (u32_t)value
|
||||
|
||||
|
||||
extern inline u32_t _RHDRegRead(RHDPtr rhdPtr, u16_t offset)
|
||||
{
|
||||
@ -335,6 +381,12 @@ MASKREG(u16_t offset, u32_t value, u32_t mask)
|
||||
OUTREG(offset, tmp);
|
||||
};
|
||||
|
||||
|
||||
#define INPLL( addr) RADEONINPLL( addr)
|
||||
|
||||
#define OUTPLL( addr, val) RADEONOUTPLL( addr, val)
|
||||
|
||||
|
||||
extern inline void
|
||||
_RHDRegWrite(RHDPtr rhdPtr, u16_t offset, u32_t value)
|
||||
{
|
||||
|
@ -43,6 +43,70 @@ unsigned INMC(RHDPtr info, int addr)
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Write MC information */
|
||||
void OUTMC(RHDPtr info, int addr, u32_t data)
|
||||
{
|
||||
if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740)) {
|
||||
OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) | RS690_MC_INDEX_WR_EN));
|
||||
OUTREG(RS690_MC_DATA, data);
|
||||
OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
|
||||
}
|
||||
else if (info->ChipFamily == CHIP_FAMILY_RS600) {
|
||||
OUTREG(RS600_MC_INDEX, ((addr & RS600_MC_INDEX_MASK) | RS600_MC_INDEX_WR_EN));
|
||||
OUTREG(RS600_MC_DATA, data);
|
||||
OUTREG(RS600_MC_INDEX, RS600_MC_INDEX_WR_ACK);
|
||||
}
|
||||
else if (IS_AVIVO_VARIANT) {
|
||||
OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000);
|
||||
(void)INREG(AVIVO_MC_INDEX);
|
||||
OUTREG(AVIVO_MC_DATA, data);
|
||||
OUTREG(AVIVO_MC_INDEX, 0);
|
||||
(void)INREG(AVIVO_MC_INDEX);
|
||||
}
|
||||
else {
|
||||
OUTREG(R300_MC_IND_INDEX, (((addr) & 0x3f) | R300_MC_IND_WR_EN));
|
||||
(void)INREG(R300_MC_IND_INDEX);
|
||||
OUTREG(R300_MC_IND_DATA, data);
|
||||
OUTREG(R300_MC_IND_INDEX, 0);
|
||||
(void)INREG(R300_MC_IND_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
static Bool avivo_get_mc_idle(RHDPtr info)
|
||||
{
|
||||
|
||||
if (info->ChipFamily >= CHIP_FAMILY_R600) {
|
||||
/* no idea where this is on r600 yet */
|
||||
return TRUE;
|
||||
}
|
||||
else if (info->ChipFamily == CHIP_FAMILY_RV515) {
|
||||
if (INMC(info, RV515_MC_STATUS) & RV515_MC_STATUS_IDLE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else if (info->ChipFamily == CHIP_FAMILY_RS600)
|
||||
{
|
||||
if (INMC(info, RS600_MC_STATUS) & RS600_MC_STATUS_IDLE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740)) {
|
||||
if (INMC(info, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
if (INMC(info, R520_MC_STATUS) & R520_MC_STATUS_IDLE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOC_FB 0x1
|
||||
#define LOC_AGP 0x2
|
||||
@ -102,6 +166,285 @@ static void radeon_read_mc_fb_agp_location(RHDPtr info, int mask,
|
||||
}
|
||||
}
|
||||
|
||||
static void radeon_write_mc_fb_agp_location(RHDPtr info, int mask, u32_t fb_loc,
|
||||
u32_t agp_loc, u32_t agp_loc_hi)
|
||||
{
|
||||
|
||||
if (info->ChipFamily >= CHIP_FAMILY_RV770) {
|
||||
if (mask & LOC_FB)
|
||||
OUTREG(R700_MC_VM_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP) {
|
||||
OUTREG(R600_MC_VM_AGP_BOT, agp_loc);
|
||||
OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi);
|
||||
}
|
||||
}
|
||||
else if (info->ChipFamily >= CHIP_FAMILY_R600)
|
||||
{
|
||||
if (mask & LOC_FB)
|
||||
OUTREG(R600_MC_VM_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP) {
|
||||
OUTREG(R600_MC_VM_AGP_BOT, agp_loc);
|
||||
OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi);
|
||||
}
|
||||
}
|
||||
else if (info->ChipFamily == CHIP_FAMILY_RV515)
|
||||
{
|
||||
if (mask & LOC_FB)
|
||||
OUTMC(info, RV515_MC_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP)
|
||||
OUTMC(info, RV515_MC_AGP_LOCATION, agp_loc);
|
||||
(void)INMC(info, RV515_MC_AGP_LOCATION);
|
||||
}
|
||||
else if (info->ChipFamily == CHIP_FAMILY_RS600)
|
||||
{
|
||||
if (mask & LOC_FB)
|
||||
OUTMC(info, RS600_MC_FB_LOCATION, fb_loc);
|
||||
/* if (mask & LOC_AGP)
|
||||
OUTMC(pScrn, RS600_MC_AGP_LOCATION, agp_loc);*/
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740))
|
||||
{
|
||||
if (mask & LOC_FB)
|
||||
OUTMC(info, RS690_MC_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP)
|
||||
OUTMC(info, RS690_MC_AGP_LOCATION, agp_loc);
|
||||
}
|
||||
else if (info->ChipFamily >= CHIP_FAMILY_R520)
|
||||
{
|
||||
if (mask & LOC_FB)
|
||||
OUTMC(info, R520_MC_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP)
|
||||
OUTMC(info, R520_MC_AGP_LOCATION, agp_loc);
|
||||
(void)INMC(info, R520_MC_FB_LOCATION);
|
||||
}
|
||||
else {
|
||||
if (mask & LOC_FB)
|
||||
OUTREG(RADEON_MC_FB_LOCATION, fb_loc);
|
||||
if (mask & LOC_AGP)
|
||||
OUTREG(RADEON_MC_AGP_LOCATION, agp_loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void RADEONUpdateMemMapRegisters(RHDPtr info)
|
||||
{
|
||||
u32_t timeout;
|
||||
|
||||
u32_t mc_fb_loc, mc_agp_loc, mc_agp_loc_hi;
|
||||
|
||||
radeon_read_mc_fb_agp_location(info, LOC_FB | LOC_AGP, &mc_fb_loc,
|
||||
&mc_agp_loc, &mc_agp_loc_hi);
|
||||
|
||||
if (IS_AVIVO_VARIANT)
|
||||
{
|
||||
|
||||
if (mc_fb_loc != info->mc_fb_location ||
|
||||
mc_agp_loc != info->mc_agp_location)
|
||||
{
|
||||
u32_t d1crtc, d2crtc;
|
||||
u32_t tmp;
|
||||
// RADEONWaitForIdleMMIO(pScrn);
|
||||
|
||||
OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
|
||||
OUTREG(AVIVO_D2VGA_CONTROL, INREG(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
|
||||
|
||||
/* Stop display & memory access */
|
||||
d1crtc = INREG(AVIVO_D1CRTC_CONTROL);
|
||||
OUTREG(AVIVO_D1CRTC_CONTROL, d1crtc & ~AVIVO_CRTC_EN);
|
||||
|
||||
d2crtc = INREG(AVIVO_D2CRTC_CONTROL);
|
||||
OUTREG(AVIVO_D2CRTC_CONTROL, d2crtc & ~AVIVO_CRTC_EN);
|
||||
|
||||
tmp = INREG(AVIVO_D2CRTC_CONTROL);
|
||||
|
||||
usleep(10000);
|
||||
timeout = 0;
|
||||
while (!(avivo_get_mc_idle(info)))
|
||||
{
|
||||
if (++timeout > 1000000)
|
||||
{
|
||||
dbgprintf("Timeout trying to update memory controller settings !\n");
|
||||
dbgprintf("You will probably crash now ... \n");
|
||||
/* Nothing we can do except maybe try to kill the server,
|
||||
* let's wait 2 seconds to leave the above message a chance
|
||||
* to maybe hit the disk and continue trying to setup despite
|
||||
* the MC being non-idle
|
||||
*/
|
||||
usleep(2000000);
|
||||
}
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
radeon_write_mc_fb_agp_location(info, LOC_FB | LOC_AGP,
|
||||
info->mc_fb_location,
|
||||
info->mc_agp_location,
|
||||
info->mc_agp_location_hi);
|
||||
|
||||
if (info->ChipFamily < CHIP_FAMILY_R600) {
|
||||
OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location);
|
||||
}
|
||||
else {
|
||||
OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000);
|
||||
}
|
||||
|
||||
OUTREG(AVIVO_D1CRTC_CONTROL, d1crtc );
|
||||
|
||||
OUTREG(AVIVO_D2CRTC_CONTROL, d2crtc );
|
||||
|
||||
tmp = INREG(AVIVO_D2CRTC_CONTROL);
|
||||
|
||||
/* Reset the engine and HDP */
|
||||
// RADEONEngineReset(pScrn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Write memory mapping registers only if their value change
|
||||
* since we must ensure no access is done while they are
|
||||
* reprogrammed
|
||||
*/
|
||||
if ( mc_fb_loc != info->mc_fb_location ||
|
||||
mc_agp_loc != info->mc_agp_location)
|
||||
{
|
||||
u32_t crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
|
||||
u32_t old_mc_status, status_idle;
|
||||
|
||||
dbgprintf(" Map Changed ! Applying ...\n");
|
||||
|
||||
/* Make sure engine is idle. We assume the CCE is stopped
|
||||
* at this point
|
||||
*/
|
||||
// RADEONWaitForIdleMMIO(info);
|
||||
|
||||
if (info->IsIGP)
|
||||
goto igp_no_mcfb;
|
||||
|
||||
/* Capture MC_STATUS in case things go wrong ... */
|
||||
old_mc_status = INREG(RADEON_MC_STATUS);
|
||||
|
||||
/* Stop display & memory access */
|
||||
ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
|
||||
OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
|
||||
crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
|
||||
OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
|
||||
crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
|
||||
// RADEONWaitForVerticalSync(pScrn);
|
||||
OUTREG(RADEON_CRTC_GEN_CNTL,
|
||||
(crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN))
|
||||
| RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
|
||||
|
||||
if (info->HasCRTC2)
|
||||
{
|
||||
crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
|
||||
// RADEONWaitForVerticalSync2(pScrn);
|
||||
OUTREG(RADEON_CRTC2_GEN_CNTL, (crtc2_gen_cntl
|
||||
& ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN))
|
||||
| RADEON_CRTC2_DISP_REQ_EN_B);
|
||||
}
|
||||
|
||||
/* Make sure the chip settles down (paranoid !) */
|
||||
usleep(1000);
|
||||
|
||||
/* Wait for MC idle */
|
||||
if (IS_R300_VARIANT)
|
||||
status_idle = R300_MC_IDLE;
|
||||
else
|
||||
status_idle = RADEON_MC_IDLE;
|
||||
|
||||
timeout = 0;
|
||||
while (!(INREG(RADEON_MC_STATUS) & status_idle))
|
||||
{
|
||||
if (++timeout > 1000000)
|
||||
{
|
||||
dbgprintf("Timeout trying to update memory controller settings !\n");
|
||||
dbgprintf("MC_STATUS = 0x%08x (on entry = 0x%08x)\n",
|
||||
INREG(RADEON_MC_STATUS), old_mc_status);
|
||||
dbgprintf("You will probably crash now ... \n");
|
||||
/* Nothing we can do except maybe try to kill the server,
|
||||
* let's wait 2 seconds to leave the above message a chance
|
||||
* to maybe hit the disk and continue trying to setup despite
|
||||
* the MC being non-idle
|
||||
*/
|
||||
usleep(20000);
|
||||
}
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
/* Update maps, first clearing out AGP to make sure we don't get
|
||||
* a temporary overlap
|
||||
*/
|
||||
OUTREG(RADEON_MC_AGP_LOCATION, 0xfffffffc);
|
||||
OUTREG(RADEON_MC_FB_LOCATION, info->mc_fb_location);
|
||||
radeon_write_mc_fb_agp_location(info, LOC_FB | LOC_AGP, info->mc_fb_location,
|
||||
0xfffffffc, 0);
|
||||
|
||||
OUTREG(RADEON_CRTC_GEN_CNTL,crtc_gen_cntl );
|
||||
OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
|
||||
OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl );
|
||||
|
||||
|
||||
igp_no_mcfb:
|
||||
radeon_write_mc_fb_agp_location(info, LOC_AGP, 0,
|
||||
info->mc_agp_location, 0);
|
||||
/* Make sure map fully reached the chip */
|
||||
(void)INREG(RADEON_MC_FB_LOCATION);
|
||||
|
||||
dbgprintf(" Map applied, resetting engine ...\n");
|
||||
|
||||
/* Reset the engine and HDP */
|
||||
// RADEONEngineReset(pScrn);
|
||||
|
||||
/* Make sure we have sane offsets before re-enabling the CRTCs, disable
|
||||
* stereo, clear offsets, and wait for offsets to catch up with hw
|
||||
*/
|
||||
|
||||
OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL);
|
||||
OUTREG(RADEON_CRTC_OFFSET, 0);
|
||||
OUTREG(RADEON_CUR_OFFSET, 0);
|
||||
timeout = 0;
|
||||
while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
|
||||
{
|
||||
if (timeout++ > 1000000) {
|
||||
dbgprintf("Timeout waiting for CRTC offset to update !\n");
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
if (info->HasCRTC2)
|
||||
{
|
||||
OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL);
|
||||
OUTREG(RADEON_CRTC2_OFFSET, 0);
|
||||
OUTREG(RADEON_CUR2_OFFSET, 0);
|
||||
timeout = 0;
|
||||
while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET)
|
||||
{
|
||||
if (timeout++ > 1000000) {
|
||||
dbgprintf("Timeout waiting for CRTC2 offset to update !\n");
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgprintf("Updating display base addresses...\n");
|
||||
|
||||
OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation);
|
||||
if (info->HasCRTC2)
|
||||
OUTREG(RADEON_DISPLAY2_BASE_ADDR, info->fbLocation);
|
||||
OUTREG(RADEON_OV0_BASE_ADDR, info->fbLocation);
|
||||
(void)INREG(RADEON_OV0_BASE_ADDR);
|
||||
|
||||
/* More paranoia delays, wait 100ms */
|
||||
usleep(1000);
|
||||
|
||||
dbgprintf("Memory map updated.\n");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
static void RADEONInitMemoryMap(RHDPtr info)
|
||||
{
|
||||
u32_t mem_size;
|
||||
@ -110,6 +453,10 @@ static void RADEONInitMemoryMap(RHDPtr info)
|
||||
radeon_read_mc_fb_agp_location(info, LOC_FB | LOC_AGP, &info->mc_fb_location,
|
||||
&info->mc_agp_location, &info->mc_agp_location_hi);
|
||||
|
||||
dbgprintf(" MC_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location);
|
||||
dbgprintf(" MC_AGP_LOCATION : 0x%08x\n", (unsigned)info->mc_agp_location);
|
||||
|
||||
|
||||
/* We shouldn't use info->videoRam here which might have been clipped
|
||||
* but the real video RAM instead
|
||||
*/
|
||||
@ -146,6 +493,7 @@ static void RADEONInitMemoryMap(RHDPtr info)
|
||||
else {
|
||||
aper0_base = INREG(RADEON_CONFIG_APER_0_BASE);
|
||||
}
|
||||
dbgprintf("aper0 base %x\n", aper0_base );
|
||||
|
||||
/* Recent chips have an "issue" with the memory controller, the
|
||||
* location must be aligned to the size. We just align it down,
|
||||
@ -170,6 +518,7 @@ static void RADEONInitMemoryMap(RHDPtr info)
|
||||
else {
|
||||
info->mc_fb_location = (aper0_base >> 16) |
|
||||
((aper0_base + mem_size - 1) & 0xffff0000U);
|
||||
dbgprintf("mc fb loc is %08x\n", (unsigned int)info->mc_fb_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,22 +532,25 @@ static void RADEONInitMemoryMap(RHDPtr info)
|
||||
* re-enabled later by the DRM
|
||||
*/
|
||||
|
||||
if (IS_AVIVO_VARIANT) {
|
||||
if (info->ChipFamily >= CHIP_FAMILY_R600) {
|
||||
OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000);
|
||||
}
|
||||
else {
|
||||
OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location);
|
||||
}
|
||||
info->mc_agp_location = 0x003f0000;
|
||||
}
|
||||
else
|
||||
info->mc_agp_location = 0xffffffc0;
|
||||
// if (IS_AVIVO_VARIANT) {
|
||||
// if (info->ChipFamily >= CHIP_FAMILY_R600) {
|
||||
// OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000);
|
||||
// }
|
||||
// else {
|
||||
// OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location);
|
||||
// }
|
||||
// info->mc_agp_location = 0x003f0000;
|
||||
// }
|
||||
// else
|
||||
// info->mc_agp_location = 0xffffffc0;
|
||||
|
||||
dbgprintf("RADEONInitMemoryMap() : \n");
|
||||
dbgprintf(" mem_size : 0x%08x\n", (unsigned)mem_size);
|
||||
dbgprintf(" mem_size : 0x%08x\n", (u32_t)mem_size);
|
||||
dbgprintf(" MC_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location);
|
||||
dbgprintf(" MC_AGP_LOCATION : 0x%08x\n", (unsigned)info->mc_agp_location);
|
||||
dbgprintf(" FB_LOCATION : 0x%08x\n", (unsigned)info->fbLocation);
|
||||
|
||||
RADEONUpdateMemMapRegisters(info);
|
||||
}
|
||||
|
||||
static void RADEONGetVRamType(RHDPtr info)
|
||||
@ -281,10 +633,10 @@ static void RADEONGetVRamType(RHDPtr info)
|
||||
else
|
||||
info->RamWidth = 64;
|
||||
|
||||
/// if (!info->HasCRTC2) {
|
||||
/// info->RamWidth /= 4;
|
||||
/// info->IsDDR = TRUE;
|
||||
/// }
|
||||
if (!info->HasCRTC2) {
|
||||
info->RamWidth /= 4;
|
||||
info->IsDDR = TRUE;
|
||||
}
|
||||
}
|
||||
else if (info->ChipFamily <= CHIP_FAMILY_RV280) {
|
||||
tmp = INREG(RADEON_MEM_CNTL);
|
||||
@ -337,24 +689,34 @@ static u32_t RADEONGetAccessibleVRAM(RHDPtr info)
|
||||
* check if it's a multifunction card by reading the PCI config
|
||||
* header type... Limit those to one aperture size
|
||||
*/
|
||||
// PCI_READ_BYTE(info->PciInfo, &byte, 0xe);
|
||||
// if (byte & 0x80) {
|
||||
// xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
// "Generation 1 PCI interface in multifunction mode"
|
||||
// ", accessible memory limited to one aperture\n");
|
||||
// return aper_size;
|
||||
// }
|
||||
byte = pciReadByte(info->PciTag, 0xe);
|
||||
if (byte & 0x80) {
|
||||
dbgprintf("Generation 1 PCI interface in multifunction mode, "
|
||||
"accessible memory limited to one aperture\n");
|
||||
return aper_size;
|
||||
}
|
||||
|
||||
/* Single function older card. We read HDP_APER_CNTL to see how the BIOS
|
||||
* have set it up. We don't write this as it's broken on some ASICs but
|
||||
* we expect the BIOS to have done the right thing (might be too optimistic...)
|
||||
*/
|
||||
// if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
|
||||
// return aper_size * 2;
|
||||
if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
|
||||
return aper_size * 2;
|
||||
|
||||
return aper_size;
|
||||
}
|
||||
|
||||
int RADEONDRIGetPciAperTableSize(RHDPtr info)
|
||||
{
|
||||
int ret_size;
|
||||
int num_pages;
|
||||
|
||||
num_pages = (info->pciAperSize * 1024 * 1024) / 4096;
|
||||
|
||||
ret_size = num_pages * sizeof(unsigned int);
|
||||
|
||||
return ret_size;
|
||||
}
|
||||
|
||||
static Bool RADEONPreInitVRAM(RHDPtr info)
|
||||
{
|
||||
@ -417,91 +779,28 @@ static Bool RADEONPreInitVRAM(RHDPtr info)
|
||||
info->videoRam &= ~1023;
|
||||
info->FbMapSize = info->videoRam * 1024;
|
||||
|
||||
info->gartSize = RADEON_DEFAULT_GART_SIZE;
|
||||
info->ringSize = RADEON_DEFAULT_RING_SIZE;
|
||||
info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
|
||||
|
||||
info->gartTexSize = info->gartSize - (info->ringSize + info->bufSize);
|
||||
|
||||
info->pciAperSize = RADEON_DEFAULT_PCI_APER_SIZE;
|
||||
info->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT;
|
||||
|
||||
|
||||
|
||||
/* if the card is PCI Express reserve the last 32k for the gart table */
|
||||
|
||||
// if (info->cardType == CARD_PCIE )
|
||||
/* work out the size of pcie aperture */
|
||||
// info->FbSecureSize = RADEONDRIGetPciAperTableSize(info);
|
||||
// else
|
||||
// info->FbSecureSize = 0;
|
||||
// if (info->cardType == CARD_PCIE )
|
||||
// /* work out the size of pcie aperture */
|
||||
// info->FbSecureSize = RADEONDRIGetPciAperTableSize(info);
|
||||
// else
|
||||
// info->FbSecureSize = 0;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#define RADEON_NB_TOM 0x15c
|
||||
|
||||
static size_t rhdGetVideoRamSize(RHDPtr rhdPtr)
|
||||
{
|
||||
size_t RamSize, BARSize;
|
||||
|
||||
if (rhdPtr->ChipFamily == CHIP_FAMILY_RS690)
|
||||
RamSize = (_RHDRegRead(rhdPtr, R5XX_CONFIG_MEMSIZE))>>10;
|
||||
else
|
||||
if (rhdPtr->IsIGP)
|
||||
{
|
||||
u32_t tom = _RHDRegRead(rhdPtr, RADEON_NB_TOM);
|
||||
RamSize = (((tom >> 16) - (tom & 0xffff) + 1) << 6);
|
||||
_RHDRegWrite(rhdPtr,R5XX_CONFIG_MEMSIZE, RamSize<<10);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rhdPtr->ChipFamily < CHIP_FAMILY_R600)
|
||||
{
|
||||
RamSize = (_RHDRegRead(rhdPtr, R5XX_CONFIG_MEMSIZE)) >> 10;
|
||||
if(RamSize==0) RamSize=8192;
|
||||
}
|
||||
else
|
||||
RamSize = (_RHDRegRead(rhdPtr, R6XX_CONFIG_MEMSIZE)) >> 10;
|
||||
};
|
||||
|
||||
BARSize = 1 << (rhdPtr->memsize[RHD_FB_BAR] - 10);
|
||||
if(BARSize==0)
|
||||
BARSize = 0x20000;
|
||||
|
||||
if (RamSize > BARSize) {
|
||||
DBG(dbgprintf("The detected amount of videoram"
|
||||
" exceeds the PCI BAR aperture.\n"));
|
||||
DBG(dbgprintf("Using only %dkB of the total "
|
||||
"%dkB.\n", (int) BARSize, (int) RamSize));
|
||||
return BARSize;
|
||||
}
|
||||
else return RamSize;
|
||||
}
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static Bool
|
||||
rhdMapFB(RHDPtr rhdPtr)
|
||||
{
|
||||
rhdPtr->FbMapSize = 1 << rhdPtr->memsize[RHD_FB_BAR];
|
||||
rhdPtr->PhisBase = rhdPtr->memBase[RHD_FB_BAR];
|
||||
|
||||
// rhdPtr->FbBase = MapIoMem(rhdPtr->PhisBase, rhdPtr->FbMapSize,PG_SW+PG_NOCACHE);
|
||||
|
||||
// if (!rhdPtr->FbBase)
|
||||
// return FALSE;
|
||||
|
||||
/* These devices have an internal address reference, which some other
|
||||
* address registers in there also use. This can be different from the
|
||||
* address in the BAR */
|
||||
if (rhdPtr->ChipFamily < CHIP_FAMILY_R600)
|
||||
rhdPtr->FbIntAddress = _RHDRegRead(rhdPtr, HDP_FB_LOCATION)<< 16;
|
||||
else
|
||||
rhdPtr->FbIntAddress = _RHDRegRead(rhdPtr, R6XX_CONFIG_FB_BASE);
|
||||
|
||||
// rhdPtr->FbIntAddress = _RHDRegRead(rhdPtr, 0x6110);
|
||||
// dbgprintf("rhdPtr->FbIntAddress %x\n",rhdPtr->FbIntAddress);
|
||||
|
||||
if (rhdPtr->FbIntAddress != rhdPtr->PhisBase)
|
||||
dbgprintf("PCI FB Address (BAR) is at "
|
||||
"0x%08X while card Internal Address is 0x%08X\n",
|
||||
(unsigned int) rhdPtr->PhisBase,rhdPtr->FbIntAddress);
|
||||
// dbgprintf("Mapped FB at %p (size 0x%08X)\n",rhdPtr->FbBase, rhdPtr->FbMapSize);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Bool RADEONPreInitChipType(RHDPtr rhdPtr)
|
||||
{
|
||||
@ -575,8 +874,80 @@ static Bool RADEONPreInitChipType(RHDPtr rhdPtr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
|
||||
{
|
||||
unsigned char *RADEONMMIO = info->MMIO;
|
||||
// unsigned long mode = drmAgpGetMode(info->dri->drmFD); /* Default mode */
|
||||
// unsigned int vendor = drmAgpVendorId(info->dri->drmFD);
|
||||
// unsigned int device = drmAgpDeviceId(info->dri->drmFD);
|
||||
/* ignore agp 3.0 mode bit from the chip as it's buggy on some cards with
|
||||
pcie-agp rialto bridge chip - use the one from bridge which must match */
|
||||
uint32_t agp_status = (INREG(RADEON_AGP_STATUS) ); // & RADEON_AGP_MODE_MASK;
|
||||
Bool is_v3 = (agp_status & RADEON_AGPv3_MODE);
|
||||
unsigned int defaultMode;
|
||||
|
||||
if (is_v3) {
|
||||
defaultMode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4;
|
||||
} else {
|
||||
if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4;
|
||||
else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2;
|
||||
else defaultMode = 1;
|
||||
}
|
||||
|
||||
// agpMode = defaultMode;
|
||||
|
||||
dbgprintf(pScreen->myNum, from, "Using AGP %dx\n", dbgprintf);
|
||||
|
||||
mode &= ~RADEON_AGP_MODE_MASK;
|
||||
if (is_v3) {
|
||||
/* only set one mode bit for AGPv3 */
|
||||
switch (defaultMode) {
|
||||
case 8: mode |= RADEON_AGPv3_8X_MODE; break;
|
||||
case 4: default: mode |= RADEON_AGPv3_4X_MODE;
|
||||
}
|
||||
/*TODO: need to take care of other bits valid for v3 mode
|
||||
* currently these bits are not used in all tested cards.
|
||||
*/
|
||||
} else {
|
||||
switch (defaultMode) {
|
||||
case 4: mode |= RADEON_AGP_4X_MODE;
|
||||
case 2: mode |= RADEON_AGP_2X_MODE;
|
||||
case 1: default: mode |= RADEON_AGP_1X_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
/* AGP Fast Writes.
|
||||
* TODO: take into account that certain agp modes don't support fast
|
||||
* writes at all */
|
||||
mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */
|
||||
|
||||
dbgprintf("AGP Mode 0x%08lx\n", mode);
|
||||
|
||||
if (drmAgpEnable(info->dri->drmFD, mode) < 0) {
|
||||
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");
|
||||
drmAgpRelease(info->dri->drmFD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Workaround for some hardware bugs */
|
||||
if (info->ChipFamily < CHIP_FAMILY_R200)
|
||||
OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
|
||||
|
||||
/* Modify the mode if the default mode
|
||||
* is not appropriate for this
|
||||
* particular combination of graphics
|
||||
* card and AGP chipset.
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
Bool RHDPreInit()
|
||||
{
|
||||
RHDPtr info;
|
||||
|
||||
/* We need access to IO space already */
|
||||
if ( !rhdMapMMIO(&rhd) ) {
|
||||
dbgprintf("Failed to map MMIO.\n");
|
||||
@ -599,7 +970,7 @@ Bool RHDPreInit()
|
||||
}
|
||||
dbgprintf("VideoRAM: %d kByte\n",rhd.videoRam);
|
||||
|
||||
rhd.FbFreeStart = 0;
|
||||
// rhd.FbFreeStart = 0;
|
||||
rhd.FbFreeSize = rhd.videoRam << 10;
|
||||
|
||||
// if( !rhdMapFB(&rhd))
|
||||
@ -609,10 +980,14 @@ Bool RHDPreInit()
|
||||
// rhd.FbScanoutSize = 8*1024*1024;
|
||||
|
||||
rhd.FbFreeStart = 10*1024*1024;
|
||||
rhd.FbFreeSize = rhd.FbMapSize - rhd.FbFreeStart;
|
||||
rhd.FbFreeSize = rhd.FbMapSize - rhd.FbFreeStart - rhd.FbSecureSize;
|
||||
|
||||
rhdInitHeap(&rhd);
|
||||
return TRUE;
|
||||
|
||||
info = &rhd;
|
||||
|
||||
|
||||
return TRUE;
|
||||
|
||||
error1:
|
||||
return FALSE;
|
||||
|
508
programs/system/drivers/ati2d/init_cp.c
Normal file
508
programs/system/drivers/ati2d/init_cp.c
Normal file
@ -0,0 +1,508 @@
|
||||
#define RADEON_SCRATCH_REG0 0x15e0
|
||||
#define RADEON_SCRATCH_REG1 0x15e4
|
||||
#define RADEON_SCRATCH_REG2 0x15e8
|
||||
#define RADEON_SCRATCH_REG3 0x15ec
|
||||
#define RADEON_SCRATCH_REG4 0x15f0
|
||||
#define RADEON_SCRATCH_REG5 0x15f4
|
||||
#define RADEON_SCRATCH_UMSK 0x0770
|
||||
#define RADEON_SCRATCH_ADDR 0x0774
|
||||
|
||||
# define RS400_BUS_MASTER_DIS (1 << 14)
|
||||
//# define RADEON_BUS_MASTER_DIS (1 << 6)
|
||||
|
||||
#define RADEON_ISYNC_CNTL 0x1724
|
||||
# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
|
||||
# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1)
|
||||
# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2)
|
||||
# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3)
|
||||
# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
|
||||
# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (info->ChipFamily <= CHIP_FAMILY_RV280)
|
||||
{
|
||||
MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL,
|
||||
~RADEON_RB3D_DC_FLUSH_ALL);
|
||||
for (i = 0; i < RADEON_TIMEOUT; i++) {
|
||||
if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
|
||||
break;
|
||||
}
|
||||
if (i == RADEON_TIMEOUT) {
|
||||
dbgprintf("DC flush timeout: %x\n",
|
||||
(u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL,
|
||||
// ~R300_RB2D_DC_FLUSH_ALL);
|
||||
// for (i = 0; i < RADEON_TIMEOUT; i++) {
|
||||
// if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
|
||||
// break;
|
||||
// }
|
||||
// if (i == RADEON_TIMEOUT) {
|
||||
// dbgprintf("DC flush timeout: %x\n",
|
||||
// (u32_t)INREG(R300_DSTCACHE_CTLSTAT));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int radeon_do_wait_for_idle()
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
ret = R5xxFIFOWaitLocal(64);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < RADEON_TIMEOUT; i++)
|
||||
{
|
||||
if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
|
||||
RADEONEngineFlush(&rhd);
|
||||
return 0;
|
||||
}
|
||||
usleep(1);
|
||||
}
|
||||
dbgprintf("wait idle failed status : 0x%08X 0x%08X\n",
|
||||
INREG(RADEON_RBBM_STATUS),
|
||||
INREG(R300_VAP_CNTL_STATUS));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/* Load the microcode for the CP */
|
||||
|
||||
#include "radeon_microcode.h"
|
||||
|
||||
static void load_microcode(RHDPtr info)
|
||||
{
|
||||
int i;
|
||||
const u32_t (*microcode)[2];
|
||||
|
||||
OUTREG(RADEON_CP_ME_RAM_ADDR, 0);
|
||||
|
||||
if ( (info->ChipFamily == CHIP_FAMILY_LEGACY ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RADEON ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV100 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV200 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS100 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS200 ))
|
||||
{
|
||||
microcode = R100_cp_microcode;
|
||||
dbgprintf("Loading R100 Microcode\n");
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R200 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV250) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV280) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS300))
|
||||
{
|
||||
microcode = R200_cp_microcode;
|
||||
dbgprintf("Loading R200 Microcode\n");
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R350) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV350) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV380) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS400) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS480))
|
||||
{
|
||||
dbgprintf("Loading R300 Microcode\n");
|
||||
microcode = R300_cp_microcode;
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R420) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV410))
|
||||
{
|
||||
dbgprintf("Loading R400 Microcode\n");
|
||||
microcode = R420_cp_microcode;
|
||||
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740))
|
||||
{
|
||||
dbgprintf("Loading RS690/RS740 Microcode\n");
|
||||
microcode = RS690_cp_microcode;
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RV515) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R520) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV530) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R580) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV560) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV570))
|
||||
{
|
||||
dbgprintf("Loading R500 Microcode\n");
|
||||
microcode = R520_cp_microcode;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]);
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_ring_buffer(RHDPtr info)
|
||||
{
|
||||
u32_t ring_base;
|
||||
u32_t tmp;
|
||||
|
||||
info->ringBase = CreateRingBuffer( 64*1024, PG_SW);
|
||||
|
||||
dbgprintf("create cp ring buffer %x\n", rhd.ringBase);
|
||||
ring_base = GetPgAddr(rhd.ringBase);
|
||||
dbgprintf("ring base %x\n", ring_base);
|
||||
|
||||
OUTREG(RADEON_CP_RB_BASE, ring_base);
|
||||
|
||||
info->ring_avail = 64*1024/4 ;
|
||||
|
||||
/* Set the write pointer delay */
|
||||
OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
|
||||
rhd.host_rp = rhd.ring_rp;
|
||||
|
||||
OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
|
||||
|
||||
tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr(&rhd.host_rp);
|
||||
|
||||
OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer
|
||||
|
||||
/* Set ring buffer size */
|
||||
OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13);
|
||||
|
||||
/* Initialize the scratch register pointer. This will cause
|
||||
* the scratch register values to be written out to memory
|
||||
* whenever they are updated.
|
||||
*
|
||||
* We simply put this behind the ring read pointer, this works
|
||||
* with PCI GART as well as (whatever kind of) AGP GART
|
||||
*/
|
||||
|
||||
tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr(&rhd.scratch0);
|
||||
OUTREG(RADEON_SCRATCH_ADDR, tmp);
|
||||
|
||||
OUTREG(RADEON_SCRATCH_UMSK, 0x0);
|
||||
//OUTREG(0x778, 1);
|
||||
|
||||
/* Turn on bus mastering */
|
||||
if ( (info->ChipFamily == CHIP_FAMILY_RS400) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740) )
|
||||
{
|
||||
/* rs400, rs690/rs740 */
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
}
|
||||
else if (!((info->ChipFamily == CHIP_FAMILY_RV380) ||
|
||||
(info->ChipFamily >= CHIP_FAMILY_R420)))
|
||||
{
|
||||
/* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
} /* PCIE cards appears to not need this */
|
||||
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
|
||||
radeon_do_wait_for_idle();
|
||||
|
||||
/* Sync everything up */
|
||||
OUTREG(RADEON_ISYNC_CNTL,
|
||||
(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
#define RADEON_WAIT_UNTIL_IDLE() do { \
|
||||
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) ); \
|
||||
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
|
||||
RADEON_WAIT_3D_IDLECLEAN | \
|
||||
RADEON_WAIT_HOST_IDLECLEAN) ); \
|
||||
} while (0)
|
||||
|
||||
#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
|
||||
# define RADEON_RB3D_ZC_FLUSH (1 << 0)
|
||||
# define RADEON_RB3D_ZC_FREE (1 << 2)
|
||||
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
|
||||
# define RADEON_RB3D_ZC_BUSY (1 << 31)
|
||||
# define R300_ZC_FLUSH (1 << 0)
|
||||
# define R300_ZC_FREE (1 << 1)
|
||||
# define R300_ZC_BUSY (1 << 31)
|
||||
# define RADEON_RB3D_DC_FLUSH (3 << 0)
|
||||
# define RADEON_RB3D_DC_FREE (3 << 2)
|
||||
# define RADEON_RB3D_DC_FLUSH_ALL 0xf
|
||||
# define RADEON_RB3D_DC_BUSY (1 << 31)
|
||||
# define R300_RB3D_DC_FLUSH (2 << 0)
|
||||
# define R300_RB3D_DC_FREE (2 << 2)
|
||||
#
|
||||
#define RADEON_PURGE_CACHE() do { \
|
||||
if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \
|
||||
} else { \
|
||||
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_FLUSH_ZCACHE() do { \
|
||||
if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \
|
||||
OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
|
||||
} else { \
|
||||
OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) ); \
|
||||
OUT_RING( R300_ZC_FLUSH ); \
|
||||
} \
|
||||
} while (0)
|
||||
#define RADEON_PURGE_ZCACHE() do { \
|
||||
if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \
|
||||
} else { \
|
||||
OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int radeon_cp_start(RHDPtr info)
|
||||
{
|
||||
u32_t *ring, write;
|
||||
u32_t ifl;
|
||||
radeon_do_wait_for_idle(64);
|
||||
|
||||
OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
BEGIN_RING(8);
|
||||
/* isync can only be written through cp on r5xx write it here */
|
||||
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1));
|
||||
OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI);
|
||||
RADEON_PURGE_CACHE();
|
||||
RADEON_PURGE_ZCACHE();
|
||||
RADEON_WAIT_UNTIL_IDLE();
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
safe_sti(ifl);
|
||||
|
||||
radeon_do_wait_for_idle();
|
||||
dbgprintf("run cp RPTR= %d\n", INREG(RADEON_CP_RB_RPTR) );
|
||||
};
|
||||
|
||||
|
||||
Bool init_cp(RHDPtr info)
|
||||
{
|
||||
load_microcode(&rhd);
|
||||
|
||||
init_ring_buffer(&rhd);
|
||||
|
||||
radeon_engine_reset(&rhd);
|
||||
|
||||
/* setup the raster pipes */
|
||||
init_pipes(&rhd);
|
||||
|
||||
rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
|
||||
dbgprintf("ring wp= %x\n",rhd.ring_wp);
|
||||
OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp);
|
||||
|
||||
radeon_cp_start(&rhd);
|
||||
|
||||
};
|
||||
|
||||
|
@ -71,9 +71,10 @@ RHDPtr FindPciDevice()
|
||||
rhd.devfn = devfn;
|
||||
rhd.PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
|
||||
rhd.ChipFamily = dev->chip_family;
|
||||
rhd.ChipFamily = dev->chip_family;
|
||||
rhd.IsMobility = dev->mobility;
|
||||
rhd.IsIGP = dev->igp;
|
||||
rhd.HasCRTC2 = !dev->nocrtc2;
|
||||
|
||||
reg2C = PciRead32(bus,devfn, 0x2C);
|
||||
|
||||
|
@ -52,8 +52,6 @@
|
||||
|
||||
#define R5XX_LOOP_COUNT 2000000
|
||||
|
||||
#include "microcode.h"
|
||||
|
||||
#define RADEON_CLOCK_CNTL_DATA 0x000c
|
||||
|
||||
#define RADEON_CLOCK_CNTL_INDEX 0x0008
|
||||
@ -72,65 +70,7 @@
|
||||
# define R300_DISABLE_MC_MCLKB (1 << 21)
|
||||
|
||||
|
||||
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(info);
|
||||
OUTREG(RADEON_CLOCK_CNTL_DATA, data);
|
||||
RADEONPllErrataAfterData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Bool
|
||||
R5xxFIFOWaitLocal(u32_t required) //R100-R500
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < R5XX_LOOP_COUNT; i++)
|
||||
if (required <= (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
|
||||
return TRUE;
|
||||
|
||||
dbgprintf("%s: Timeout 0x%08X.\n", __func__,
|
||||
(unsigned int) INREG(R5XX_RBBM_STATUS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush all dirty data in the Pixel Cache to memory.
|
||||
@ -180,76 +120,6 @@ R5xx2DIdleLocal() //R100-R500
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
R5xx2DReset()
|
||||
{
|
||||
u32_t save, tmp;
|
||||
u32_t clock_cntl_index;
|
||||
u32_t mclk_cntl;
|
||||
|
||||
/* The following RBBM_SOFT_RESET sequence can help un-wedge
|
||||
* an R300 after the command processor got stuck. */
|
||||
save = INREG(R5XX_RBBM_SOFT_RESET);
|
||||
tmp = save | R5XX_SOFT_RESET_CP |
|
||||
R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_SE |
|
||||
R5XX_SOFT_RESET_RE | R5XX_SOFT_RESET_PP |
|
||||
R5XX_SOFT_RESET_E2 | R5XX_SOFT_RESET_RB;
|
||||
OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
|
||||
|
||||
INREG(R5XX_RBBM_SOFT_RESET);
|
||||
tmp &= ~(R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI |
|
||||
R5XX_SOFT_RESET_SE | R5XX_SOFT_RESET_RE |
|
||||
R5XX_SOFT_RESET_PP | R5XX_SOFT_RESET_E2 |
|
||||
R5XX_SOFT_RESET_RB);
|
||||
OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
|
||||
|
||||
INREG(R5XX_RBBM_SOFT_RESET);
|
||||
OUTREG(R5XX_RBBM_SOFT_RESET, save);
|
||||
INREG(R5XX_RBBM_SOFT_RESET);
|
||||
|
||||
R5xx2DFlush();
|
||||
|
||||
#if 0
|
||||
clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
|
||||
RADEONPllErrataAfterIndex(info);
|
||||
|
||||
mclk_cntl = RADEONINPLL(RADEON_MCLK_CNTL);
|
||||
|
||||
RADEONOUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
|
||||
RADEON_FORCEON_MCLKA |
|
||||
RADEON_FORCEON_MCLKB |
|
||||
RADEON_FORCEON_YCLKA |
|
||||
RADEON_FORCEON_YCLKB |
|
||||
RADEON_FORCEON_MC |
|
||||
RADEON_FORCEON_AIC));
|
||||
#endif
|
||||
|
||||
/* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
|
||||
* unexpected behaviour on some machines. Here we use
|
||||
* R5XX_HOST_PATH_CNTL to reset it. */
|
||||
save = INREG(R5XX_HOST_PATH_CNTL);
|
||||
|
||||
tmp = INREG(R5XX_RBBM_SOFT_RESET);
|
||||
tmp |= R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_E2;
|
||||
OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
|
||||
|
||||
INREG(R5XX_RBBM_SOFT_RESET);
|
||||
OUTREG(R5XX_RBBM_SOFT_RESET, 0);
|
||||
|
||||
MASKREG(R5XX_RB2D_DSTCACHE_MODE,
|
||||
R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
|
||||
R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
|
||||
|
||||
OUTREG(R5XX_HOST_PATH_CNTL, save | R5XX_HDP_SOFT_RESET);
|
||||
INREG(R5XX_HOST_PATH_CNTL);
|
||||
OUTREG(R5XX_HOST_PATH_CNTL, save);
|
||||
|
||||
#if 0
|
||||
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
|
||||
RADEONPllErrataAfterIndex(info);
|
||||
RADEONOUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
R5xx2DSetup()
|
||||
@ -268,12 +138,17 @@ R5xx2DSetup()
|
||||
|
||||
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
|
||||
|
||||
R5xxFIFOWaitLocal(1);
|
||||
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,
|
||||
R5XX_DEFAULT_SC_RIGHT_MAX | R5XX_DEFAULT_SC_BOTTOM_MAX);
|
||||
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_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);
|
||||
@ -288,7 +163,7 @@ R5xx2DSetup()
|
||||
void R5xxFIFOWait(u32_t required)
|
||||
{
|
||||
if (!R5xxFIFOWaitLocal(required)) {
|
||||
R5xx2DReset();
|
||||
// R5xx2DReset();
|
||||
R5xx2DSetup();
|
||||
}
|
||||
}
|
||||
@ -296,55 +171,11 @@ void R5xxFIFOWait(u32_t required)
|
||||
void R5xx2DIdle()
|
||||
{
|
||||
if (!R5xx2DIdleLocal()) {
|
||||
R5xx2DReset();
|
||||
// R5xx2DReset();
|
||||
R5xx2DSetup();
|
||||
}
|
||||
}
|
||||
|
||||
static void load_microcode()
|
||||
{
|
||||
u32_t ifl;
|
||||
int i;
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
OUTREG(RADEON_CP_ME_RAM_ADDR,0);
|
||||
|
||||
R5xx2DIdleLocal();
|
||||
|
||||
switch(rhd.ChipFamily)
|
||||
{
|
||||
case CHIP_FAMILY_R300:
|
||||
case CHIP_FAMILY_R350:
|
||||
case CHIP_FAMILY_RV350:
|
||||
dbgprintf("Loading R300 microcode\n");
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case RHD_RV505:
|
||||
case RHD_RV515:
|
||||
case RHD_RV516:
|
||||
case RHD_R520:
|
||||
case RHD_RV530:
|
||||
case RHD_RV535:
|
||||
case RHD_RV550:
|
||||
case RHD_RV560:
|
||||
case RHD_RV570:
|
||||
case RHD_R580:
|
||||
dbgprintf("Loading R500 microcode\n");
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]);
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
safe_sti(ifl);
|
||||
};
|
||||
|
||||
|
||||
void R5xx2DInit()
|
||||
@ -369,20 +200,24 @@ void R5xx2DInit()
|
||||
clip.xmax = rhd.displayWidth - 1;
|
||||
clip.ymax = rhd.displayHeight - 1;
|
||||
|
||||
dbgprintf("width %d \n", rhd.displayWidth);
|
||||
dbgprintf("height %d \n", rhd.displayHeight);
|
||||
dbgprintf("screen width %d height %d\n",
|
||||
rhd.displayWidth, rhd.displayHeight);
|
||||
|
||||
rhd.gui_control = (R5XX_DATATYPE_ARGB8888 << R5XX_GMC_DST_DATATYPE_SHIFT) |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS | R5XX_GMC_DST_PITCH_OFFSET_CNTL;
|
||||
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 = ((screenpitch / 64) << 22) | (rhd.fbLocation >> 10);
|
||||
// rhd.dst_pitch_offset = ((screenpitch / 64) << 22) | (rhd.fbLocation >> 10);
|
||||
|
||||
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;
|
||||
@ -391,50 +226,22 @@ void R5xx2DInit()
|
||||
scr_pixmap.pitch_offset = rhd.dst_pitch_offset;
|
||||
scr_pixmap.mapped = (void*)0;
|
||||
|
||||
R5xxFIFOWaitLocal(2);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
|
||||
MASKREG(R5XX_GB_TILE_CONFIG, 0, R5XX_ENABLE_TILING);
|
||||
OUTREG (R5XX_WAIT_UNTIL, R5XX_WAIT_2D_IDLECLEAN | R5XX_WAIT_3D_IDLECLEAN);
|
||||
MASKREG(R5XX_DST_PIPE_CONFIG, R5XX_PIPE_AUTO_CONFIG, R5XX_PIPE_AUTO_CONFIG);
|
||||
MASKREG(R5XX_RB2D_DSTCACHE_MODE,
|
||||
R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
|
||||
R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
|
||||
R5xxFIFOWaitLocal(1);
|
||||
MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
|
||||
|
||||
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
|
||||
|
||||
#if R300_PIO
|
||||
#else
|
||||
init_cp(&rhd);
|
||||
#endif
|
||||
|
||||
R5xx2DReset();
|
||||
R5xx2DSetup();
|
||||
|
||||
MASKREG( RADEON_AIC_CNTL,0, RADEON_PCIGART_TRANSLATE_EN);
|
||||
|
||||
// load_microcode();
|
||||
|
||||
// rhd.ring_base = CreateRingBuffer(0x8000, PG_SW | PG_NOCACHE);
|
||||
// dbgprintf("create cp ring buffer %x\n", rhd.ring_base);
|
||||
// base = GetPgAddr(rhd.ring_base);
|
||||
|
||||
// OUTREG(RADEON_CP_RB_BASE, base);
|
||||
// dbgprintf("ring base %x\n", base);
|
||||
|
||||
// OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
|
||||
|
||||
// rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
|
||||
// OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
|
||||
|
||||
// OUTREG(RADEON_CP_RB_RPTR_ADDR, 0); // ring buffer read pointer no update
|
||||
|
||||
// OUTREG(RADEON_CP_RB_CNTL, RADEON_RB_NO_UPDATE | 12);
|
||||
// OUTREG(RADEON_SCRATCH_UMSK, 0); // no scratch update
|
||||
|
||||
// MASKREG(RADEON_BUS_CNTL,0,RADEON_BUS_MASTER_DIS);
|
||||
|
||||
// R5xx2DIdleLocal();
|
||||
|
||||
// OUTREG(RADEON_ISYNC_CNTL, RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
// RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
// RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
// RADEON_ISYNC_CPSCRATCH_IDLEGUI);
|
||||
|
||||
// OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); // run
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
1844
programs/system/drivers/ati2d/radeon_microcode.h
Normal file
1844
programs/system/drivers/ati2d/radeon_microcode.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,14 +11,11 @@ IMP
|
||||
_GetPgAddr core.GetPgAddr,
|
||||
_CreateRingBuffer core.CreateRingBuffer,
|
||||
_PciApi core.PciApi,
|
||||
_PciRead8 core.PciRead8,
|
||||
_PciRead32 core.PciRead32,
|
||||
_PciWrite32 core.PciWrite32,
|
||||
_RegService core.RegService,
|
||||
_SysMsgBoardStr core.SysMsgBoardStr,
|
||||
_SelectHwCursor core.SelectHwCursor,
|
||||
_SetHwCursor core.SetHwCursor,
|
||||
_HwCursorCreate core.HwCursorCreate,
|
||||
_HwCursorRestore core.HwCursorRestore
|
||||
_SysMsgBoardStr core.SysMsgBoardStr
|
||||
|
||||
|
||||
FIL ati2d.obj,
|
||||
|
@ -64,6 +64,8 @@ u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
|
||||
#define pciReadLong(tag, reg) \
|
||||
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadByte(tag, reg) \
|
||||
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8");
|
||||
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");
|
||||
|
Loading…
Reference in New Issue
Block a user