Radeon 200M (RS480)
PCI Express card, using 128M of sideport memory. (No)
I've gotten the IGPGART programmed and working using the info from the mmio-traces I took, code in my drm tree. However the 3D driver causes that card to lockup on initial access which isn't too good, but we can get CP acceleration now at least.. - airlied
The card appears to have a PCI GART but attempts to use this have failed on my system - airlied. I've attempted to move the CP into the last 8MBs of the pre-allocated framebuffer and move all the buffer mappings in there as well. This seemed to work for getting CP acceleration for the 2D driver. However attempts to make the 3D driver run failed miserably, it may be a simple problem with the buffer mappings for the r300 memory manager code, but I think it is probably a bit deeper, accessing the framebuffer while the CP is running has sometimes been known to be flaky on other radeons. I'm trying to access it via main RAM so it should work, but doesn't... - airlied
I've ran mmio-trace on the fglrx kernel module and gotten a bunch of indirect register access at 0x168, 0x16c, the 0x2c write looked like an address, and there looks to be a GART table at that address, so perhaps with AGP_BASE + MC_AGP_LOCATION programmed, it will use this GART table. It writes some other registers in this indirect area as well... so that needs some work... I've annotated some of the cpu parsed log at http://www.skynet.ie/~airlied/radeon/r200m/cpu-parsed - airlied 19/02/07
In the current git tree, if DRM is enabled, the X server will hang upon startup. This is because it is waiting for the CP to initialize. The driver submits some commands, and the X server loops infinitely waiting for the CP to become idle. This is probably a bug.. the Xserver should probably wait some reasonable amount of time and then exit (rather than infinitely consuming a whole bunch of CPU.)
In my local tree, if I set MC_AGP_LOCATION to match that of fglrx driver & force PCIE express mode, the X server at least comes up. There is no stipple and the xserver hangs after moving the cursor around.
The memory map is different between the 8.23.5 fglrx driver and the Xorg driver.
I don't know if this is a problem.
 0 0 0xc01203b0 - 0xc01203bb (0xc) IS[B]  0 0 0xc01203c0 - 0xc01203df (0x20) IS[B]
 0 0 0x000003b0 - 0x000003bb (0xc) IS[B]  0 0 0x000003c0 - 0x000003df (0x20) IS[B]
Look how the addresses are different.
This should provide me more info about what these mean: http://www.xfree86.org/current/DESIGN9.html
The stipple pattern never appears on the screen.
When DRI is enabled, the CP does not appear to be working. The indirect buffer is never executed.. Infact, I don't even think that the ring buffer is working properly. (Because the CP_IB_BASE is set to 0x00000000)
The CP configuration for the fglrx 8.32.5 driver is as follows:
memory_aperture=0xc8000000 register_aperture=0xc0100000 MEM_BASE=0xc8000008 MC_FB_LOCATION=0x57ff5000 MC_AGP_LOCATION=0x5fff5800 DISPLAY_BASE_ADDR=0x50000000 OVERLAY_BASE_ADDR=0x50000000 AGP_BASE=0x58000000 ----------------- CP registers ------------------ RADEON_CP_RB_BASE=0x58000000 RADEON_CP_RB_CNTL=0x08040f11 RADEON_CP_RB_RPTR_ADDR=0x00000000 RADEON_CP_RB_RPTR=0x0001b150 RADEON_CP_RB_WPTR=0x0001b150 RADEON_CP_RB_WPTR_DELAY=0x00000000 RADEON_CP_IB_BASE=0x58710000 RADEON_CP_CSQ_CNTL=0x80000000
and the values for my current hacked radeon drivers are:
memory_aperture=0xc8000000 register_aperture=0xc0100000 MEM_BASE=0xc8000008 MC_FB_LOCATION=0x57ff5000 MC_AGP_LOCATION=0x5fff5800 DISPLAY_BASE_ADDR=0x50000000 OVERLAY_BASE_ADDR=0x50000000 AGP_BASE=0x00000000 ----------------- CP registers ------------------ RADEON_CP_RB_BASE=0x58000000 RADEON_CP_RB_CNTL=0x00000011 RADEON_CP_RB_RPTR_ADDR=0x3471e000 RADEON_CP_RB_RPTR=0x0000001e RADEON_CP_RB_WPTR=0x0000001e RADEON_CP_RB_WPTR_DELAY=0x00000000 RADEON_CP_IB_BASE=0x00000000 RADEON_CP_CSQ_CNTL=0x40000000
Here are some interesting differences:
- The AGP_BASE for the fglrx is set to 0x58000000 (same as the CP_RB_BASE). For the radeon driver, the AGP_BASE is set to 0x00000000.
- The CP_RB_RPTR_ADDR is set to 0x00000000 for fglrx, and to 0x3471e000 for the radeon driver. Maybe the 0x00000 indicates some magic offset where the ring buffer should be stored.
- The CP read and write pointers have advanced for the fglrx, so the CP is working for the fglrx.
- For the radeon driver, look at how the RADEON_CP_IB_BASE is 0, so the CP (I think) never received the command to execute an indirect buffer.
After a few second of mouse movement, the box hangs.
- I suspect that this is related to the improper command processor setup.
I don't know how the GART is setup for this card. None of the RADEON_PCIE registers are called in the trace of 8.32.5.
All attemps to dump this areas when fglrx is running return 0.
Something funny is going on..
UPDATE: I looks like Dave got a step further in understanding this. Using kmmio to trap the different accesses going on in kernel space, it appears that the 0x168 and 0x16C registers are indirect registers for configuring the memory controller.
Also, the accesses to 0x168/0x16C seem to have the following pattern:
- Write to 0x168 (setup the index) (Where 0x100 indicates a write..)
- Read/Write to/from 0x16C
- Write 7f to 0x168 (Maybe a commit or something?)
I turned on PC recording in kmmio. It reveals some interesting things about what those indirect memory accesses are doing. First, all of the calls to the 168/16C registers are in: MCIL_ModifyRegister (So it looks like this is the Memory Controller that it is accessing.)
Next, I recorded the address of the function which called MCIL_ModifyRegister:
read -> 0x00001000 _ZN9GartRS48023InitializeGartRegistersEv write <- 0x00001000 _ZN9GartRS48023InitializeGartRegistersEv write <- 0x00000005 _ZN9GartRS48023InitializeGartRegistersEv read[2b] -> 0x00000000 _ZN9GartRS48023InitializeGartRegistersEv write[12b] <- 0x42040800 _ZN9GartRS48023InitializeGartRegistersEv write[12c] <- 0x33b00000 _ZN9GartRS48023InitializeGartRegistersEv read -> 0x01400000 _ZN9GartRS48023InitializeGartRegistersEv write <- 0x01400000 _ZN9GartRS48023InitializeGartRegistersEv read -> 0x00000005 _ZN9GartRS48010EnableGartEv write <- 0x00000005 _ZN9GartRS48010EnableGartEv read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv write[12e] <- 0x00000001 _ZN9GartRS48012flushGartTLBEv read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv write[12e] <- 0x00000000 _ZN9GartRS48012flushGartTLBEv read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv write[12e] <- 0x00000001 _ZN9GartRS48012flushGartTLBEv read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv write[12e] <- 0x00000000 _ZN9GartRS48012flushGartTLBEv
So, some interesting things come out of this: I think that:
- 38/138 turns on the GART. (Write 0x5)
- 2e/12e flushs the Gart TLB (Write 0x1 and then 0x0)
- 2c/12c The address of the GART table (Write the physical address of the GART table)
- 2b/12b (?) (Write 0x42040800)
- 18/118 (?) (Read and then write 0x00001000)
- 39/139 (?) (Read and then write 0x01400000) Comment by Slice: "Chips R200-RV280 use reg 1d8 for address of PCI Gart table Chips R300-RV420 use res ab0 - Lo 32 bits, ab4 - Hi 32 bits of Gart table address reg 1d0 has bit 0 for PCI_GART_ENABLE in both cases"
Radeon 200M (RS480) PCI Express 128 M sideport memory (UMA/system memory usage disabled.)
01:05.0 VGA compatible controller: ATI Technologies Inc ATI Radeon XPRESS 200M 5955 (PCIE) (prog-if 00 [VGA]) Subsystem: Hewlett-Packard Company Unknown device 30a4 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- Latency: 66 (2000ns min), Cache Line Size 08 Interrupt: pin A routed to IRQ 7 Region 0: Memory at c0000000 (32-bit, prefetchable) [size=256M] Region 1: I/O ports at 9000 [size=256] Region 2: Memory at b0100000 (32-bit, non-prefetchable) [size=64K] [virtual] Expansion ROM at b0120000 [disabled] [size=128K] Capabilities:  Power Management version 2 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME-
NOTE: The firegl 8.32.5 driver works with this card ONLY if I use 128M of sideport. (No UMA) NOTE2: The 8.24.5 fglrx driver works if I have 128M UMA + 128M of sideport.
Some of these are of the Radeon200, but they basically apply:
http://www.techreport.com/reviews/2004q4/radeon-xpress200/index.x?pg=1 http://3dgpu.com/archives/2004/11/08/ati-radeon-xpress-200g-review/ http://www.driverheaven.net/reviews/RadeonXpress/ http://www.hothardware.com/viewarticle.cfm?articleid=597&cid=3 http://www.pcper.com/article.php?aid=88 http://techreport.com/reviews/2004q4/radeon-xpress200/index.x?pg=1
ATI's 200M page: http://ati.amd.com/products/Radeonxpress200m/index.html
White paper about hypermemory: http://www.ati.com/technology/HyperMemory_Whitepaper.pdf
Another man's OpenGL problems with the 200M under windows: http://fixthe200m.wordpress.com/
Handy Facts for Radeon Reverse engineers
- It seems that the commands issued to the CP are just register,value pairs... You could issue these directly using MMIOs, but when you hand it to the CP, it will do the work for you. (If someone know better, please tell me..)
- The Radeon Xserver uses DRI to draw the stipple pattern, so if you see it on the screen, the CP is at least partially working..
- Here's a pretty good explanation about how the radeon deals with memory (bus view vs. card view):
One way to figure out how the driver interacts with the card is either to:
Dump the registers
Trace the register accesses
Trace userspace MMIOs: http://people.freedesktop.org/~glisse/libsegfault.tar.bz2
Trace kernelspace MMIOs: git://people.freedesktop.org/~jrmuizel/mmio-trace
Here's some code to convert register names/values to human readable text: http://ozlabs.org/~jk/code/bitfield/
I'm currently working on a config file for the radeon_RS480, but I imagine much of the R300 family is similar.
NOTE: It is unclear what all of the registers do, so there seems to be a smattering of different places which define this.
Radeon Xorg Driver: (FIXME)
http://svn.mplayerhq.hu/mplayer/trunk/drivers/radeon.h?view=markup The Kernel's list:
http://www.gelato.unsw.edu.au/lxr/source/include/video/radeon.h Possibly related: