command processor

git-svn-id: svn://kolibrios.org@883 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-10-22 19:29:38 +00:00
parent 673a89c327
commit ebd406a2e7
10 changed files with 3174 additions and 391 deletions

View File

@ -3,7 +3,7 @@
int ClearPixmap(io_clear_t *io) int ClearPixmap(io_clear_t *io)
{ {
u32_t ifl; u32_t ifl;
u32_t *ring, write; u32_t *ring;
local_pixmap_t *dstpixmap; local_pixmap_t *dstpixmap;
@ -32,7 +32,8 @@ int ClearPixmap(io_clear_t *io)
OUTREG(R5XX_DST_WIDTH_HEIGHT,(dstpixmap->width<<16)|dstpixmap->height); OUTREG(R5XX_DST_WIDTH_HEIGHT,(dstpixmap->width<<16)|dstpixmap->height);
#else #else
BEGIN_RING(); BEGIN_RING(6);
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4)); OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | 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 )) if ( !LineClip(&clip, &x0, &y0, &x1, &y1 ))
{ {
u32_t efl; u32_t ifl;
u32_t *ring, write; u32_t *ring, write;
efl = safe_cli(); ifl = safe_cli();
#if R300_PIO #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_START,(y0<<16)|x0);
OUTREG(R5XX_DST_LINE_END,(y1<<16)|x1); OUTREG(R5XX_DST_LINE_END,(y1<<16)|x1);
#else #else
BEGIN_RING(); BEGIN_RING(6);
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_POLYLINE, 4)); OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_POLYLINE, 4));
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_BRUSH_SOLID_COLOR |
@ -121,9 +123,8 @@ int Line(io_draw_t *draw)
OUT_RING((y0<<16)|x0); OUT_RING((y0<<16)|x0);
OUT_RING((y1<<16)|x1); OUT_RING((y1<<16)|x1);
COMMIT_RING(); COMMIT_RING();
#endif #endif
safe_sti(efl); safe_sti(ifl);
}; };
return ERR_OK; return ERR_OK;
} }
@ -154,7 +155,7 @@ int DrawRect(io_draw_t* draw)
if( ! BlockClip( &dst_clip, &x0, &y0, &x1, &y1)) if( ! BlockClip( &dst_clip, &x0, &y0, &x1, &y1))
{ {
u32_t *ring, write; u32_t *ring;
u32_t ifl; u32_t ifl;
int w, h; int w, h;
@ -220,7 +221,9 @@ int DrawRect(io_draw_t* draw)
} }
}; };
#else #else
BEGIN_RING();
BEGIN_RING(64);
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4)); OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | 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(dstpixmap->pitch_offset);
OUT_RING(draw->color); OUT_RING(draw->color);
OUT_RING((draw->x0<<16)|y0); OUT_RING((x0<<16)|y0);
OUT_RING((w<<16)|h); 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(); COMMIT_RING();
#endif #endif
safe_sti(ifl); safe_sti(ifl);
@ -268,13 +413,15 @@ int FillRect(io_fill_t *fill)
if( ! BlockClip(&dst_clip, &x0, &y0, &x1, &y1)) if( ! BlockClip(&dst_clip, &x0, &y0, &x1, &y1))
{ {
u32_t *ring, write; u32_t *ring, write;
u32_t ifl = safe_cli(); u32_t ifl;
#if R300_PIO
int w = x1 - x0 + 1; int w = x1 - x0 + 1;
int h = y1 - y0 + 1; int h = y1 - y0 + 1;
ifl = safe_cli();
#if R300_PIO
R5xxFIFOWait(9); R5xxFIFOWait(9);
OUTREG(R5XX_DP_GUI_MASTER_CNTL, OUTREG(R5XX_DP_GUI_MASTER_CNTL,
@ -350,7 +497,8 @@ int FillRect(io_fill_t *fill)
#else #else
BEGIN_RING(); BEGIN_RING(9+10*2);
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT, 7)); OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT, 7));
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
R5XX_GMC_BRUSH_8X8_MONO_FG_BG | R5XX_GMC_BRUSH_8X8_MONO_FG_BG |
@ -370,6 +518,46 @@ int FillRect(io_fill_t *fill)
OUT_RING((y0<<16)|x0); OUT_RING((y0<<16)|x0);
OUT_RING((y1<<16)|x1); 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(); COMMIT_RING();
#endif #endif
@ -414,8 +602,9 @@ int Blit(io_blit_t *blit)
&blit->w, &blit->h) ) &blit->w, &blit->h) )
{ {
u32_t *ring, write; u32_t *ring, write;
u32_t ifl;
u32_t ifl = safe_cli(); ifl = safe_cli();
#if R300_PIO #if R300_PIO
@ -443,8 +632,8 @@ int Blit(io_blit_t *blit)
OUTREG(R5XX_DST_HEIGHT_WIDTH,(blit->h<<16)|blit->w); OUTREG(R5XX_DST_HEIGHT_WIDTH,(blit->h<<16)|blit->w);
#else #else
BEGIN_RING(7);
BEGIN_RING();
OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT, 5)); OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT, 5));
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
@ -507,7 +696,9 @@ int BlitTransparent(io_blit_t *blit)
{ {
u32_t *ring, write; u32_t *ring, write;
u32_t ifl = safe_cli(); u32_t ifl;
ifl = safe_cli();
#if R300_PIO #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_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_MASK, R5XX_CLR_CMP_MSK);
OUTREG(R5XX_CLR_CMP_CNTL, R5XX_SRC_CMP_EQ_COLOR | R5XX_CLR_CMP_SRC_SOURCE); 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 #else
BEGIN_RING(); BEGIN_RING(10);
OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8)); OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8));
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 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(dstpixmap->pitch_offset);
OUT_RING(R5XX_CLR_CMP_SRC_SOURCE | R5XX_SRC_CMP_EQ_COLOR); OUT_RING(R5XX_CLR_CMP_SRC_SOURCE | R5XX_SRC_CMP_EQ_COLOR);
OUT_RING(0xFF000000); OUT_RING(blit->key);
OUT_RING(0xFF000000); OUT_RING(0xFFFFFFFF);
OUT_RING((blit->src_x<<16)|blit->src_y); OUT_RING((blit->src_x<<16)|blit->src_y);
OUT_RING((blit->dst_x<<16)|blit->dst_y); OUT_RING((blit->dst_x<<16)|blit->dst_y);

View File

@ -1,4 +1,8 @@
#define R300_PIO 0 /* now we have cp */
#include "types.h" #include "types.h"
#include <stdio.h> #include <stdio.h>
@ -14,7 +18,7 @@
#include "ati2d.h" #include "ati2d.h"
#include "accel_2d.h" #include "accel_2d.h"
RHD_t rhd; RHD_t rhd __attribute__ ((aligned (128))); /* reduce cache lock */
static clip_t clip; static clip_t clip;
@ -163,6 +167,7 @@ int __stdcall srv_2d(ioctl_t *io)
#include "pci.c" #include "pci.c"
#include "ati_mem.c" #include "ati_mem.c"
#include "init_cp.c"
#include "r500.inc" #include "r500.inc"
#include "clip.inc" #include "clip.inc"

View File

@ -7,7 +7,6 @@ typedef unsigned int memType;
typedef struct { float hi, lo; } range; typedef struct { float hi, lo; } range;
#define R300_PIO 1
#define PCI_CMD_STAT_REG 0x04 #define PCI_CMD_STAT_REG 0x04
@ -123,13 +122,23 @@ typedef struct
} RADEONCardInfo; } RADEONCardInfo;
#define RHD_FB_BAR 0 #define RHD_FB_BAR 0
#define RHD_MMIO_BAR 2 #define RHD_MMIO_BAR 2
#define RHD_MEM_GART 1 #define RHD_MEM_GART 1
#define RHD_MEM_FB 2 #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 typedef struct RHDRec
{ {
u32_t MMIOBase; u32_t MMIOBase;
@ -168,8 +177,9 @@ typedef struct RHDRec
char *chipset; char *chipset;
int IsIGP; Bool IsIGP;
int IsMobility; Bool IsMobility;
Bool HasCRTC2;
u32_t bus; u32_t bus;
u32_t devfn; u32_t devfn;
@ -193,6 +203,19 @@ typedef struct RHDRec
u32_t displayWidth; u32_t displayWidth;
u32_t displayHeight; 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 __xmin;
int __ymin; int __ymin;
int __xmax; int __xmax;
@ -202,15 +225,24 @@ typedef struct RHDRec
u32_t dst_pitch_offset; u32_t dst_pitch_offset;
u32_t surface_cntl; 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; Bool IsDDR;
int num_gb_pipes; int num_gb_pipes;
int has_tcl; int has_tcl;
}RHD_t, *RHDPtr; }RHD_t, *RHDPtr;
extern RHD_t rhd; extern RHD_t rhd;
@ -251,7 +283,7 @@ extern RHD_t rhd;
# define RADEON_CNTL_PAINT_MULTI 0x00009A00 # define RADEON_CNTL_PAINT_MULTI 0x00009A00
#define CP_PACKET0(reg, n) \ #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) \ #define CP_PACKET1(reg0, reg1) \
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) (RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
@ -262,33 +294,44 @@ extern RHD_t rhd;
#define CP_PACKET3( pkt, n ) \ #define CP_PACKET3( pkt, n ) \
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) (RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
#define BEGIN_RING( n ) do { \
ring = rhd.ring_base; \ #define BEGIN_RING( req ) do { \
write = rhd.ring_wp; \ int avail = rhd.ring_rp-rhd.ring_wp; \
} while (0) 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 ADVANCE_RING()
#define OUT_RING( x ) do { \ #define OUT_RING( x ) *ring++ = (x)
ring[write++] = (x); \
} while (0)
#define OUT_RING_REG(reg, val) \ #define CP_REG(reg, val) \
do { \ do { \
OUT_RING(CP_PACKET0(reg, 0)); \ ring[0] = CP_PACKET0((reg), 1); \
OUT_RING(val); \ ring[1] = (val); \
ring+= 2; \
} while (0) } while (0)
#define DRM_MEMORYBARRIER() __asm volatile("lock; addl $0,0(%%esp)" : : : "memory"); #define DRM_MEMORYBARRIER() __asm volatile("lock; addl $0,0(%%esp)" : : : "memory");
#define COMMIT_RING() do { \ #define COMMIT_RING() do { \
rhd.ring_wp = write & 0x1FFF; \ rhd.ring_wp = (ring - rhd.ringBase) & 0x3FFF; \
/* Flush writes to ring */ \ /* Flush writes to ring */ \
DRM_MEMORYBARRIER(); \ DRM_MEMORYBARRIER(); \
/*GET_RING_HEAD( dev_priv ); */ \ /*GET_RING_HEAD( dev_priv ); */ \
OUTREG( RADEON_CP_RB_WPTR, rhd.ring_wp); \ OUTREG( RADEON_CP_RB_WPTR, rhd.ring_wp); \
/* read from PCI bus to ensure correct posting */ \ /* read from PCI bus to ensure correct posting */ \
INREG( RADEON_CP_RB_RPTR ); \ /* INREG( RADEON_CP_RB_RPTR ); */ \
} while (0) } 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; *(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) 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); OUTREG(offset, tmp);
}; };
#define INPLL( addr) RADEONINPLL( addr)
#define OUTPLL( addr, val) RADEONOUTPLL( addr, val)
extern inline void extern inline void
_RHDRegWrite(RHDPtr rhdPtr, u16_t offset, u32_t value) _RHDRegWrite(RHDPtr rhdPtr, u16_t offset, u32_t value)
{ {

View File

@ -43,6 +43,70 @@ unsigned INMC(RHDPtr info, int addr)
return data; 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_FB 0x1
#define LOC_AGP 0x2 #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) static void RADEONInitMemoryMap(RHDPtr info)
{ {
u32_t mem_size; 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, radeon_read_mc_fb_agp_location(info, LOC_FB | LOC_AGP, &info->mc_fb_location,
&info->mc_agp_location, &info->mc_agp_location_hi); &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 /* We shouldn't use info->videoRam here which might have been clipped
* but the real video RAM instead * but the real video RAM instead
*/ */
@ -146,6 +493,7 @@ static void RADEONInitMemoryMap(RHDPtr info)
else { else {
aper0_base = INREG(RADEON_CONFIG_APER_0_BASE); 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 /* Recent chips have an "issue" with the memory controller, the
* location must be aligned to the size. We just align it down, * location must be aligned to the size. We just align it down,
@ -170,6 +518,7 @@ static void RADEONInitMemoryMap(RHDPtr info)
else { else {
info->mc_fb_location = (aper0_base >> 16) | info->mc_fb_location = (aper0_base >> 16) |
((aper0_base + mem_size - 1) & 0xffff0000U); ((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 * re-enabled later by the DRM
*/ */
if (IS_AVIVO_VARIANT) { // if (IS_AVIVO_VARIANT) {
if (info->ChipFamily >= CHIP_FAMILY_R600) { // if (info->ChipFamily >= CHIP_FAMILY_R600) {
OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000); // OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000);
} // }
else { // else {
OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location); // OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location);
} // }
info->mc_agp_location = 0x003f0000; // info->mc_agp_location = 0x003f0000;
} // }
else // else
info->mc_agp_location = 0xffffffc0; // info->mc_agp_location = 0xffffffc0;
dbgprintf("RADEONInitMemoryMap() : \n"); 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_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location);
dbgprintf(" MC_AGP_LOCATION : 0x%08x\n", (unsigned)info->mc_agp_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) static void RADEONGetVRamType(RHDPtr info)
@ -281,10 +633,10 @@ static void RADEONGetVRamType(RHDPtr info)
else else
info->RamWidth = 64; info->RamWidth = 64;
/// if (!info->HasCRTC2) { if (!info->HasCRTC2) {
/// info->RamWidth /= 4; info->RamWidth /= 4;
/// info->IsDDR = TRUE; info->IsDDR = TRUE;
/// } }
} }
else if (info->ChipFamily <= CHIP_FAMILY_RV280) { else if (info->ChipFamily <= CHIP_FAMILY_RV280) {
tmp = INREG(RADEON_MEM_CNTL); 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 * check if it's a multifunction card by reading the PCI config
* header type... Limit those to one aperture size * header type... Limit those to one aperture size
*/ */
// PCI_READ_BYTE(info->PciInfo, &byte, 0xe); byte = pciReadByte(info->PciTag, 0xe);
// if (byte & 0x80) { if (byte & 0x80) {
// xf86DrvMsg(pScrn->scrnIndex, X_INFO, dbgprintf("Generation 1 PCI interface in multifunction mode, "
// "Generation 1 PCI interface in multifunction mode" "accessible memory limited to one aperture\n");
// ", accessible memory limited to one aperture\n"); return aper_size;
// return aper_size; }
// }
/* Single function older card. We read HDP_APER_CNTL to see how the BIOS /* 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 * 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...) * we expect the BIOS to have done the right thing (might be too optimistic...)
*/ */
// if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
// return aper_size * 2; return aper_size * 2;
return aper_size; 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) static Bool RADEONPreInitVRAM(RHDPtr info)
{ {
@ -417,91 +779,28 @@ static Bool RADEONPreInitVRAM(RHDPtr info)
info->videoRam &= ~1023; info->videoRam &= ~1023;
info->FbMapSize = info->videoRam * 1024; 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 the card is PCI Express reserve the last 32k for the gart table */
// if (info->cardType == CARD_PCIE ) // if (info->cardType == CARD_PCIE )
/* work out the size of pcie aperture */ // /* work out the size of pcie aperture */
// info->FbSecureSize = RADEONDRIGetPciAperTableSize(info); // info->FbSecureSize = RADEONDRIGetPciAperTableSize(info);
// else // else
// info->FbSecureSize = 0; // 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) static Bool RADEONPreInitChipType(RHDPtr rhdPtr)
{ {
@ -575,8 +874,80 @@ static Bool RADEONPreInitChipType(RHDPtr rhdPtr)
return TRUE; 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() Bool RHDPreInit()
{ {
RHDPtr info;
/* We need access to IO space already */ /* We need access to IO space already */
if ( !rhdMapMMIO(&rhd) ) { if ( !rhdMapMMIO(&rhd) ) {
dbgprintf("Failed to map MMIO.\n"); dbgprintf("Failed to map MMIO.\n");
@ -599,7 +970,7 @@ Bool RHDPreInit()
} }
dbgprintf("VideoRAM: %d kByte\n",rhd.videoRam); dbgprintf("VideoRAM: %d kByte\n",rhd.videoRam);
rhd.FbFreeStart = 0; // rhd.FbFreeStart = 0;
rhd.FbFreeSize = rhd.videoRam << 10; rhd.FbFreeSize = rhd.videoRam << 10;
// if( !rhdMapFB(&rhd)) // if( !rhdMapFB(&rhd))
@ -609,9 +980,13 @@ Bool RHDPreInit()
// rhd.FbScanoutSize = 8*1024*1024; // rhd.FbScanoutSize = 8*1024*1024;
rhd.FbFreeStart = 10*1024*1024; rhd.FbFreeStart = 10*1024*1024;
rhd.FbFreeSize = rhd.FbMapSize - rhd.FbFreeStart; rhd.FbFreeSize = rhd.FbMapSize - rhd.FbFreeStart - rhd.FbSecureSize;
rhdInitHeap(&rhd); rhdInitHeap(&rhd);
info = &rhd;
return TRUE; return TRUE;
error1: error1:

View 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);
};

View File

@ -74,6 +74,7 @@ RHDPtr FindPciDevice()
rhd.ChipFamily = dev->chip_family; rhd.ChipFamily = dev->chip_family;
rhd.IsMobility = dev->mobility; rhd.IsMobility = dev->mobility;
rhd.IsIGP = dev->igp; rhd.IsIGP = dev->igp;
rhd.HasCRTC2 = !dev->nocrtc2;
reg2C = PciRead32(bus,devfn, 0x2C); reg2C = PciRead32(bus,devfn, 0x2C);

View File

@ -52,8 +52,6 @@
#define R5XX_LOOP_COUNT 2000000 #define R5XX_LOOP_COUNT 2000000
#include "microcode.h"
#define RADEON_CLOCK_CNTL_DATA 0x000c #define RADEON_CLOCK_CNTL_DATA 0x000c
#define RADEON_CLOCK_CNTL_INDEX 0x0008 #define RADEON_CLOCK_CNTL_INDEX 0x0008
@ -72,65 +70,7 @@
# define R300_DISABLE_MC_MCLKB (1 << 21) # 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. * 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 void
R5xx2DSetup() R5xx2DSetup()
@ -268,12 +138,17 @@ R5xx2DSetup()
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl); 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, 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); R5xxFIFOWaitLocal(1);
OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control | // OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control |
R5XX_GMC_BRUSH_SOLID_COLOR | R5XX_GMC_SRC_DATATYPE_COLOR); // 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); R5xxFIFOWaitLocal(5);
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF);
@ -288,7 +163,7 @@ R5xx2DSetup()
void R5xxFIFOWait(u32_t required) void R5xxFIFOWait(u32_t required)
{ {
if (!R5xxFIFOWaitLocal(required)) { if (!R5xxFIFOWaitLocal(required)) {
R5xx2DReset(); // R5xx2DReset();
R5xx2DSetup(); R5xx2DSetup();
} }
} }
@ -296,55 +171,11 @@ void R5xxFIFOWait(u32_t required)
void R5xx2DIdle() void R5xx2DIdle()
{ {
if (!R5xx2DIdleLocal()) { if (!R5xx2DIdleLocal()) {
R5xx2DReset(); // R5xx2DReset();
R5xx2DSetup(); 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() void R5xx2DInit()
@ -369,20 +200,24 @@ void R5xx2DInit()
clip.xmax = rhd.displayWidth - 1; clip.xmax = rhd.displayWidth - 1;
clip.ymax = rhd.displayHeight - 1; clip.ymax = rhd.displayHeight - 1;
dbgprintf("width %d \n", rhd.displayWidth); dbgprintf("screen width %d height %d\n",
dbgprintf("height %d \n", rhd.displayHeight); rhd.displayWidth, rhd.displayHeight);
rhd.gui_control = (R5XX_DATATYPE_ARGB8888 << R5XX_GMC_DST_DATATYPE_SHIFT) | rhd.gui_control = ((6 << RADEON_GMC_DST_DATATYPE_SHIFT)
R5XX_GMC_CLR_CMP_CNTL_DIS | R5XX_GMC_DST_PITCH_OFFSET_CNTL; | RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_DST_PITCH_OFFSET_CNTL);
dbgprintf("gui_control %x \n", rhd.gui_control); dbgprintf("gui_control %x \n", rhd.gui_control);
rhd.surface_cntl = 0; 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); dbgprintf("dst_pitch_offset %x \n", rhd.dst_pitch_offset);
scr_pixmap.width = rhd.displayWidth; scr_pixmap.width = rhd.displayWidth;
scr_pixmap.height = rhd.displayHeight; scr_pixmap.height = rhd.displayHeight;
scr_pixmap.format = PICT_a8r8g8b8; scr_pixmap.format = PICT_a8r8g8b8;
@ -391,50 +226,22 @@ void R5xx2DInit()
scr_pixmap.pitch_offset = rhd.dst_pitch_offset; scr_pixmap.pitch_offset = rhd.dst_pitch_offset;
scr_pixmap.mapped = (void*)0; 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); R5xxFIFOWaitLocal(1);
OUTREG (R5XX_WAIT_UNTIL, R5XX_WAIT_2D_IDLECLEAN | R5XX_WAIT_3D_IDLECLEAN); MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
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);
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
#if R300_PIO
#else
init_cp(&rhd);
#endif
R5xx2DReset();
R5xx2DSetup(); 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
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,14 +11,11 @@ IMP
_GetPgAddr core.GetPgAddr, _GetPgAddr core.GetPgAddr,
_CreateRingBuffer core.CreateRingBuffer, _CreateRingBuffer core.CreateRingBuffer,
_PciApi core.PciApi, _PciApi core.PciApi,
_PciRead8 core.PciRead8,
_PciRead32 core.PciRead32, _PciRead32 core.PciRead32,
_PciWrite32 core.PciWrite32, _PciWrite32 core.PciWrite32,
_RegService core.RegService, _RegService core.RegService,
_SysMsgBoardStr core.SysMsgBoardStr, _SysMsgBoardStr core.SysMsgBoardStr
_SelectHwCursor core.SelectHwCursor,
_SetHwCursor core.SetHwCursor,
_HwCursorCreate core.HwCursorCreate,
_HwCursorRestore core.HwCursorRestore
FIL ati2d.obj, FIL ati2d.obj,

View File

@ -64,6 +64,8 @@ u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
#define pciReadLong(tag, reg) \ #define pciReadLong(tag, reg) \
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(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 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"); u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");