summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/radeon_reg.h33
-rw-r--r--src/radeon_video.c3
-rw-r--r--src/radeon_video.h10
-rw-r--r--src/radeon_vip.c200
-rw-r--r--src/theatre_reg.h35
5 files changed, 244 insertions, 37 deletions
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index c53d173f..6e2a4431 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -1277,6 +1277,8 @@
#define RADEON_SW_SEMAPHORE 0x013c
#define RADEON_TEST_DEBUG_CNTL 0x0120
+#define RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN 0x00000001
+
#define RADEON_TEST_DEBUG_MUX 0x0124
#define RADEON_TEST_DEBUG_OUT 0x012c
#define RADEON_TMDS_PLL_CNTL 0x02a8
@@ -1304,7 +1306,36 @@
#define RADEON_VGA_DDA_ON_OFF 0x02ec
#define RADEON_VID_BUFFER_CONTROL 0x0900
#define RADEON_VIDEOMUX_CNTL 0x0190
-#define RADEON_VIPH_CONTROL 0x0c40 /* ? */
+
+ /* VIP bus */
+#define RADEON_VIPH_CH0_DATA 0x0c00
+#define RADEON_VIPH_CH1_DATA 0x0c04
+#define RADEON_VIPH_CH2_DATA 0x0c08
+#define RADEON_VIPH_CH3_DATA 0x0c0c
+#define RADEON_VIPH_CH0_ADDR 0x0c10
+#define RADEON_VIPH_CH1_ADDR 0x0c14
+#define RADEON_VIPH_CH2_ADDR 0x0c18
+#define RADEON_VIPH_CH3_ADDR 0x0c1c
+#define RADEON_VIPH_CH0_SBCNT 0x0c20
+#define RADEON_VIPH_CH1_SBCNT 0x0c24
+#define RADEON_VIPH_CH2_SBCNT 0x0c28
+#define RADEON_VIPH_CH3_SBCNT 0x0c2c
+#define RADEON_VIPH_CH0_ABCNT 0x0c30
+#define RADEON_VIPH_CH1_ABCNT 0x0c34
+#define RADEON_VIPH_CH2_ABCNT 0x0c38
+#define RADEON_VIPH_CH3_ABCNT 0x0c3c
+#define RADEON_VIPH_CONTROL 0x0c40
+#define RADEON_VIPH_DV_LAT 0x0c44
+#define RADEON_VIPH_BM_CHUNK 0x0c48
+#define RADEON_VIPH_DV_INT 0x0c4c
+#define RADEON_VIPH_TIMEOUT_STAT 0x0c50
+#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_STAT 0x00000010
+#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_AK 0x00000010
+#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS 0x01000000
+
+#define RADEON_VIPH_REG_DATA 0x0084
+#define RADEON_VIPH_REG_ADDR 0x0080
+
#define RADEON_WAIT_UNTIL 0x1720
# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
diff --git a/src/radeon_video.c b/src/radeon_video.c
index d079c898..4512e472 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -895,6 +895,9 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
/* Initialize I2C bus */
RADEONInitI2C(pScrn, pPriv);
if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
+
+ /* Initialize VIP bus */
+ RADEONVIP_init(pScrn, pPriv);
#if 0 /* this is just here for easy debugging - normally off */
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n");
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 24016851..781b54c2 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -7,6 +7,8 @@
#include "tda9885.h"
#include "i2c_def.h"
+#include "generic_bus.h"
+
/* Xvideo port struct */
typedef struct {
CARD32 transform_index;
@@ -32,7 +34,10 @@ typedef struct {
CARD8 tuner_type;
MSP3430Ptr msp3430;
TDA9885Ptr tda9885;
-
+
+ /* VIP bus and devices */
+ GENERIC_BUS_Ptr VIP;
+
Bool video_stream_active;
int encoding;
CARD32 frequency;
@@ -73,5 +78,8 @@ typedef struct {
void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
void RADEONResetI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
+void RADEONVIP_init(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
+void RADEONVIP_reset(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
+
#endif
diff --git a/src/radeon_vip.c b/src/radeon_vip.c
new file mode 100644
index 00000000..d1ac15f2
--- /dev/null
+++ b/src/radeon_vip.c
@@ -0,0 +1,200 @@
+#include "radeon.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_reg.h"
+#include "Xv.h"
+#include "radeon_video.h"
+
+#include "xf86.h"
+#include "xf86PciInfo.h"
+
+#include "generic_bus.h"
+
+#define VIP_NAME "RADEON VIP BUS"
+#define VIP_TYPE "ATI VIP BUS"
+
+/* Status defines */
+#define VIP_BUSY 0
+#define VIP_IDLE 1
+#define VIP_RESET 2
+
+static Bool RADEONVIP_ioctl(GENERIC_BUS_Ptr b, long ioctl, long arg1, char *arg2)
+{
+ long count;
+ switch(ioctl){
+ case GB_IOCTL_GET_NAME:
+ count=strlen(VIP_NAME)+1;
+ if(count>arg1)return FALSE;
+ memcpy(arg2,VIP_NAME,count);
+ return TRUE;
+
+ case GB_IOCTL_GET_TYPE:
+ count=strlen(VIP_TYPE)+1;
+ if(count>arg1)return FALSE;
+ memcpy(arg2,VIP_TYPE,count);
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+static CARD32 RADEONVIP_idle(GENERIC_BUS_Ptr b)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ CARD32 timeout;
+
+ RADEONWaitForIdleMMIO(pScrn);
+ timeout = INREG(RADEON_VIPH_TIMEOUT_STAT);
+ if(timeout & RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_STAT) /* lockup ?? */
+ {
+ RADEONWaitForFifo(pScrn, 2);
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (timeout & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_AK);
+ RADEONWaitForIdleMMIO(pScrn);
+ return (INREG(RADEON_VIPH_CONTROL) & 0x2000) ? VIP_BUSY : VIP_RESET;
+ }
+ RADEONWaitForIdleMMIO(pScrn);
+ return (INREG(RADEON_VIPH_CONTROL) & 0x2000) ? VIP_BUSY : VIP_IDLE ;
+}
+
+/* address format:
+ ((device & 0x3)<<14) | (fifo << 12) | (addr)
+*/
+
+static Bool RADEONVIP_read(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD8 *buffer)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 status,tmp;
+
+ if((count!=1) && (count!=2) && (count!=4))
+ {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Attempt to access VIP bus with non-stadard transaction length\n");
+ return FALSE;
+ }
+
+ RADEONWaitForFifo(pScrn, 2);
+ OUTREG(RADEON_VIPH_REG_ADDR, address | 0x2000);
+ write_mem_barrier();
+ while(VIP_BUSY == (status = RADEONVIP_idle(b)));
+ if(VIP_IDLE != status) return FALSE;
+
+/*
+ disable RADEON_VIPH_REGR_DIS to enable VIP cycle.
+ The LSB of RADEON_VIPH_TIMEOUT_STAT are set to 0
+ because 1 would have acknowledged various VIP
+ interrupts unexpectedly
+*/
+ RADEONWaitForIdleMMIO(pScrn);
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, INREG(RADEON_VIPH_TIMEOUT_STAT) & (0xffffff00 & ~RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS) );
+ write_mem_barrier();
+/*
+ the value returned here is garbage. The read merely initiates
+ a register cycle
+*/
+ RADEONWaitForIdleMMIO(pScrn);
+ INREG(RADEON_VIPH_REG_DATA);
+
+ while(VIP_BUSY == (status = RADEONVIP_idle(b)));
+ if(VIP_IDLE != status) return FALSE;
+/*
+ set RADEON_VIPH_REGR_DIS so that the read won't take too long.
+*/
+ RADEONWaitForIdleMMIO(pScrn);
+ tmp=INREG(RADEON_VIPH_TIMEOUT_STAT);
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (tmp & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS);
+ write_mem_barrier();
+ RADEONWaitForIdleMMIO(pScrn);
+ switch(count){
+ case 1:
+ *buffer=(CARD8)(INREG(RADEON_VIPH_REG_DATA) & 0xff);
+ break;
+ case 2:
+ *(CARD16 *)buffer=(CARD16) (INREG(RADEON_VIPH_REG_DATA) & 0xffff);
+ break;
+ case 4:
+ *(CARD32 *)buffer=(CARD32) ( INREG(RADEON_VIPH_REG_DATA) & 0xffffffff);
+ break;
+ }
+ while(VIP_BUSY == (status = RADEONVIP_idle(b)));
+ if(VIP_IDLE != status) return FALSE;
+ /*
+ so that reading RADEON_VIPH_REG_DATA would not trigger unnecessary vip cycles.
+*/
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (INREG(RADEON_VIPH_TIMEOUT_STAT) & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS);
+ write_mem_barrier();
+ return TRUE;
+}
+
+static Bool RADEONVIP_write(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD8 *buffer)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ CARD32 status;
+
+
+ if((count!=4))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to access VIP bus with non-stadard transaction length\n");
+ return FALSE;
+ }
+
+ RADEONWaitForFifo(pScrn, 2);
+ OUTREG(RADEON_VIPH_REG_ADDR, address & (~0x2000));
+ while(VIP_BUSY == (status = RADEONVIP_idle(b)));
+
+ if(VIP_IDLE != status) return FALSE;
+
+ RADEONWaitForFifo(pScrn, 2);
+ switch(count){
+ case 4:
+ OUTREG(RADEON_VIPH_REG_DATA, *(CARD32 *)buffer);
+ break;
+ }
+ write_mem_barrier();
+ while(VIP_BUSY == (status = RADEONVIP_idle(b)));
+ if(VIP_IDLE != status) return FALSE;
+ return TRUE;
+}
+
+void RADEONVIP_reset(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+
+ RADEONWaitForIdleMMIO(pScrn);
+ switch(info->ChipFamily){
+ case CHIP_FAMILY_RV250:
+ OUTREG(RADEON_VIPH_CONTROL, 0x003F0009); /* slowest, timeout in 16 phases */
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (INREG(RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS);
+ OUTREG(RADEON_VIPH_DV_LAT, 0x444400FF); /* set timeslice */
+ OUTREG(RADEON_VIPH_BM_CHUNK, 0x0);
+ OUTREG(RADEON_TEST_DEBUG_CNTL, INREG(RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN));
+ break;
+ default:
+ OUTREG(RADEON_VIPH_CONTROL, 0x003F0004); /* slowest, timeout in 16 phases */
+ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (INREG(RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS);
+ OUTREG(RADEON_VIPH_DV_LAT, 0x444400FF); /* set timeslice */
+ OUTREG(RADEON_VIPH_BM_CHUNK, 0x151);
+ OUTREG(RADEON_TEST_DEBUG_CNTL, INREG(RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN));
+ }
+}
+
+void RADEONVIP_init(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
+{
+ pPriv->VIP=xcalloc(1,sizeof(GENERIC_BUS_Rec));
+ pPriv->VIP->scrnIndex=pScrn->scrnIndex;
+ pPriv->VIP->DriverPrivate.ptr=pPriv;
+ pPriv->VIP->ioctl=RADEONVIP_ioctl;
+ pPriv->VIP->read=RADEONVIP_read;
+ pPriv->VIP->write=RADEONVIP_write;
+
+ RADEONVIP_reset(pScrn, pPriv);
+}
diff --git a/src/theatre_reg.h b/src/theatre_reg.h
index cb1f92bd..8a8a1624 100644
--- a/src/theatre_reg.h
+++ b/src/theatre_reg.h
@@ -2,31 +2,6 @@
#define __THEATRE_REGS_H__
-#define VIPH_CH0_DATA 0x0c00
-#define VIPH_CH1_DATA 0x0c04
-#define VIPH_CH2_DATA 0x0c08
-#define VIPH_CH3_DATA 0x0c0c
-#define VIPH_CH0_ADDR 0x0c10
-#define VIPH_CH1_ADDR 0x0c14
-#define VIPH_CH2_ADDR 0x0c18
-#define VIPH_CH3_ADDR 0x0c1c
-#define VIPH_CH0_SBCNT 0x0c20
-#define VIPH_CH1_SBCNT 0x0c24
-#define VIPH_CH2_SBCNT 0x0c28
-#define VIPH_CH3_SBCNT 0x0c2c
-#define VIPH_CH0_ABCNT 0x0c30
-#define VIPH_CH1_ABCNT 0x0c34
-#define VIPH_CH2_ABCNT 0x0c38
-#define VIPH_CH3_ABCNT 0x0c3c
-#define VIPH_CONTROL 0x0c40
-#define VIPH_DV_LAT 0x0c44
-#define VIPH_BM_CHUNK 0x0c48
-#define VIPH_DV_INT 0x0c4c
-#define VIPH_TIMEOUT_STAT 0x0c50
-
-#define VIPH_REG_DATA 0x0084
-#define VIPH_REG_ADDR 0x0080
-
/* Address Space Rage Theatre Registers (VIP Access) */
#define VIP_VIP_VENDOR_DEVICE_ID 0x0000
#define VIP_VIP_SUB_VENDOR_DEVICE_ID 0x0004
@@ -219,16 +194,6 @@
#define VIP_SPDIF_TX_CNT_REG 0x0820
#define VIP_IIS_TX_CNT_REG 0x0824
-/* Status defines */
-#define VIP_BUSY 0
-#define VIP_IDLE 1
-#define VIP_RESET 2
-
-#define VIPH_TIMEOUT_STAT__VIPH_REG_STAT 0x00000010
-#define VIPH_TIMEOUT_STAT__VIPH_REG_AK 0x00000010
-#define VIPH_TIMEOUT_STAT__VIPH_REGR_DIS 0x01000000
-#define TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN 0x00000001
-
#define RT100_ATI_ID 0x4D541002
#define RT200_ATI_ID 0x4f4a1002