Get to know a radeon part 1

ATOMBIOS

You’ve probably heard about it if you’ve been following xorg development over the last few months, however there is some confusion as it what it is and how it can be used. ATOMBIOS is a collection of card specific data tables and scripts stored in the rom on recent radeon cards (r4xx cards had the initial version of it). The data tables store card specific information such as connector information and memory timings. The scripts allow you to program specific functionality on a particular card using a common API. Some of the functionality includes: setting crtc timing, setting up DACs, TMDS, and TV encoders, DPMS, crtc routing, and card initialization. The x86 real mode video bios, the windows driver, and fglrx all use ATOMBIOS to initialize and program the card.

In order to use ATOMBIOS, the driver provides a wrapper for the parser and some hooks for touching the hw (read/write memory mapped register, read/write PCI register, allocate/free memory, sleep, etc.). To run one of the scripts you point the parser at the script and it parses it, calling the driver supplied hw hooks to actually program the hw. Each script takes a struct that specifies what parameters you want to use for that script as an input.

For example, if you execute a script to program the pixel clock, you would supply the parameters you want to program (pll1/2, dot clock, M, N, P values, etc.) and execute the script. The parser would then run through the script calling the hw access hooks and programming the card. It might read in one of the PLL regs, then adjust some values and write it out, then wait for a few microseconds for the clock to lock, then read back the value, then write some other register value, etc.

The scripts do basically the same thing you would do if you were programming the registers directly, but since they can be tailored to specific hw, so there is less need for card specific workarounds in the driver code and hw differences are hidden behind a common API.

22 Responses to “Get to know a radeon part 1”

  1. Jeff Schroeder Says:

    Paragraphs please, this is very interesting, but difficult to read.

    Thanks for posting this.

  2. osiris Says:

    It would be great if you gave some links to sites (wikis) describing how in general graphic card works and what are these pll1/2, dot clock, M, N, P values, PLL.

    About the post: it needs some formatting, but it describes the ATOMBIOS pretty well. Finally I now what it is for.

    Good job!

  3. agd5f Says:

    http://wiki.x.org/wiki/Development/Documentation/HowVideoCardsWork should give you the basics.

  4. Thales Says:

    Waiting for the next post… Great job!

  5. Matthew W. S. Bell Says:

    Layers of indirection and abstractions are in general a good thing.

    However, this suffers the usual problem of BIOS, ACPI, etc. in that the layer is not fixable (or nearly impossible to fix well), which is, indeed, the point of Free Software.

    Is the code in the ATOM BIOS of a sufficient standard? I assume it is controlled only by ATI/AMD…

  6. luc verhaegen Says:

    The claim is that it is a rather solid standard, but in reality it isn’t. And how can it be… the hardware underneath changes, so the interface has to be adapted to it.

  7. agd5f Says:

    The hardware is already changing, but for the the ATOM API has stayed pretty consistent. At this point all current hardware and the stuff in the pipeline will work with the ATOM parser. The register layout has changed significantly within the last few chip generations resulting in a lot of work to support each new layout via direct register programming as opposed to one ATOM API.

    At some point the HW may get to a point were the current ATOM API is no longer a good fit. Either something new will come along to replace ATOM or there will be a new version, or maybe we’ll go back to direct register programming. We can cross that bridge when the time comes. So what if it changes? Right now the register layout changes more often than the ATOM interface. Why rewrite code 2, 3, 4, or more times to handle basic setup and handle card specific quirks when you can do it once?

    ATOM is not a black box. You can run the command scripts through the parser and see exactly what registers/delays/etc. the script is doing. The script format is not particularly complex and the source to the parser is available. You could write your own scripts or edit existing ones and use them to program the hw if you wanted.

  8. vesa Says:

    Would you mind commenting how to use pixel clock programming script? My goal is frame synchronous video playback, but unfortunately my programming skills are mostly in avr assembly. Some pointers to the subject follow:

    http://www-id.imag.fr/~raffin/papers/ID/softgenlock-ipt03.pdf
    http://www.hlrs.de/organization/vis/people/aumueller/genlock/

    the problem to solve is mostly:
    http://www.linuxtv.org/wiki/index.php/Development:_The_DVB_Decoder_Challenge#Screen.2FDecoder_Sync_Aliasing

    I’d rather not use direct register access if there is cleaner and more general approach available. I did some experiments using a hardware solution (means adding a varicap diode and coil in series with video card master oscillator crystal) and it worked great, but my reference was from bt848 analog video input hsync. For use with software decoder that woud mean more hw and some output port too.

  9. agd5f Says:

    The script is used by the driver to program the clock hw. The driver still generates the clock dividers itself. You don’t really need to mess with the driver. Any video driver that can program an arbitrary modeline should be able to do what you want. Use cvt or something else to generate a modeline with the exact timing you want, then tell the driver to use that mode. If you are writing your own driver, take a look at atombios_crtc_set_pll() in atombios_crtc.c in the radeon driver source:
    http://cgit.freedesktop.org/xorg/driver/xf86-video-ati/

  10. vesa Says:

    Ok. Is it possible to update modeline during runtime, without a reset to hw? See, the adjustment needs to be _dynamic_ and happen only in vertical retrace period so that there are no artifacts in the active picture. Needed adjustment range is of the order of few permille or so. It’s just for tracking clock drifts and keeping the phase. There needs to be a hook for running lower/higher dotclock during some variable part of the vsync and that way tweak the refresh rate. Then it is possible to lock screen refresh to dvb stream pts and get completely jitter-free motion for 50(60)i/p content on 50/60 Hz monitors. Anyone else interested in high quality video on Linux? ;)

  11. agd5f Says:

    heh, patches welcome. You can add modes dynamically with xrandr. see xrandr –help for more info. However, using xrandr will do a full mode set on the head you are adjusting. Unfortunately, there is currently no mechanism to dynamically adjust the pixel clock every frame. you’d probably have to mmap the register BAR and manipulate the clock and crtc timing regs directly.

  12. Brian Says:

    Where would one find a description of the AtomBIOS API ?

  13. agd5f Says:

    The radeon source is your best bet at the moment. atombios.h should give you a pretty good idea. If you have any questions, let me know.

  14. Brian Says:

    Ok … thanks , but it would really be nice to be able to read a document. Basically I just want to init the graphics card at 1920×1200x8.

  15. agd5f Says:

    You can’t use atom directly with vbe. The x86 vbe code in the bios uses atom, but it exposes a different API. You should be able to get 1920×1200 with the radeon driver however.

  16. Brian Says:

    The application does not run under Linux or Windows , and uses VESA VBE only to initialize the graphics card.

    In earlier version of the application , when PC’s were relatively slow and the graphics chips were actually much faster than the PC , the application was specific to the Mach64 cards and wrote directly to the Mach64 registers for all the graphics functions.

    However , once the PC’s passed the 1GHz clock speed and FSB and memory speed increased , for almost all 2D functions it was faster to perform the graphics on the host x86 , so I just used VESA to initialize the cards.

    I thought perhaps ATOM was something like the old Texas Instrument TIGA API … if anyone remembers that! I was intrigued by ATOM because it appeared as though it might be easier to use ATOM to modify the CRTC registers rather than writing directly to the CRTC registers for a specific card.

    Since AMD has opened the register documentation (similar to what was provided for the Mach64) for a number of ATI/AMD chips , I will probably just select an appropriate card for the specific 1920×1200 project.

    Question : If I initialize the card using VESA , can I change the resolution from that set by VESA to 1920×1200 by writing directly ONLY to the CRTC registers ?

    Thanks for the help.

  17. agd5f Says:

    You’ll have to adjust the pll and display surface registers, but it shouldn’t bee too difficult. Other than the pll and crtc regs, the other regs you’ll need to touch are in atombios_crtc_mode_set().

  18. Brian Says:

    OK …. thanks !

  19. Brian Says:

    Sorry about all the questions , but I have a customer who has older PC’s which do not have PCI-e. Does AtomBIOS support any PCI cards ?

  20. agd5f Says:

    Yes. there are r5xx based (x1300 or x1550) PCI cards available from several vendors.

  21. Brian Says:

    Thanks again

  22. ati radeon x1300 Says:

    ati radeon x1300…