=============== HP Visualize FX =============== The Visualize FX is a workstation graphics card manufactured by HP, and commonly found in HP PA-RISC workstations. It comes in PCI variants for PA-RISC, and an AGP variant for use in some x86 HP workstations. Unfortunately, no documentation is available for the card, so we're working more-or-less blind. A GPL driver is available for the x86-AGP variant, unfortunately it simply sets up DRI in order to allow a binary X driver to card initialization, etc. However, the register list it provides has been useful. KyleMcMartin has been working on reverse engineering the card, but there's no working code yet. Physical Characteristics ------------------------ - Visualize FX 2, 4, 6 all have EVC connectors, which require an adapter to go to standard HD-15 VGA monitors. - Visualize FX 2, 4, 6 all have a small white connector for attaching peripherals such as the "Video Out Board" (A4556A). - Visualize FX 4, 6 also have a long thin connector for connecting texture memory. - Visualize FX 6 has a connector on the back to add the geometry accelerator card which is interesting in and of itself as it has RJ45-looking ports labelled "COVE mode" on it's geometry accelerator. - Visualize FX 5, 10 have no connectors onboard, but are still full length cards. - Visualize FXe has neither of these connectors, is much smaller (only one IC) and has HD-15 VGA output. Chipset Info ------------ .. list-table:: :header-rows: 1 - - Card - Family - GAs - TMUs - RASTs - - Visualize FX2 - Summit - TODO - TODO - TODO - - Visualize FX4 - Summit - TODO - TODO - TODO - - Visualize FX6 - Summit - TODO - TODO - TODO - - Visualize FX5 - Lego - TODO - - TODO - - Visualize FX10 - Lego - TODO - - TODO - - Visualize FXe - Pinnacle - TODO - TODO - TODO .. note:: Visualize FX5 and FX10 apparently combined the texture and rasterizer units into one unit. Video Out Board (A4556A) ------------------------ One input port, and three output ports. Input port labelled Genlock for synching to an external clock. Output ports labelled S-Video, CVBS, and Beta SP. Interrupts ---------- Visualize FX {2,4,5,6,10} do not get issued a PCI INT# line. Instead, they interrupt by writing to eim_addr. Visualize FXe does get issued a PCI INT# line. STI Graphics IDs ---------------- :: id 2fc1066b-9a02587, conforms to spec rev. 8.09 <- Visualize FX2 in B180 id 2fc1066b-9a02587, conforms to spec rev. 8.09 <- Visualize FX4 in C3000 id 2fc1066b-9a02587, conforms to spec rev. 8.09 <- Visualize FX6 in C3000 id 35acda30-9a02587, conforms to spec rev. 8.0d <- Visualize FX5 in J6000, A1299 (Fx10pro?) (4 chips), A1262A -> FX5 (3 chips) id 35acda16-9a02587, conforms to spec rev. 8.0c <- Visualize FXe in J6000, A4982B lspci output ------------ - **Visualize FXe in J6000** :: 0000:01:01.0 3D controller: Hewlett-Packard Company Visualize FXe (rev 02) Subsystem: Hewlett-Packard Company: Unknown device 108c Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR- FastB2B- Status: Cap- 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- TAbort- SERR- TAbort- SERR- TAbort- SERR-  concept is that you spew an address, indication of           whether or not to increment as you go, and a number of           data words to write (starting) at that address  followed by the data  the hardware then turns that into the actual writes.  the specific design issue that it is dealing with is:           weakly orderd I/O space writes.  since the CD buffer space is a nice contiguous block of           I/O space, and is written sequentially, you can (1)           have the hardware notice what registers haven't been           written yet, and not process past that, and (2) you can           DMA the CD buffer to the card, rather than using PIO. The following comes from hpgraphics/headers/lego_hw_macros.h:316 from the hpgraphics DRI driver. .. code-block:: cpp /* * First we want a macro that will create a CD packet header. This header has * three fields: * * o bits 27-31 : The number of data words in this packet * o bit 25 : Flag telling us whether to increment the address every time * we write the packet data. 0 means increment. * o bit 24 : Flag telling us to wrap the hardware CD buffer pointer back to * the top of the CD buffer. This needs to be done every time we * wrap the software CD buffer pointer. * o bits 0-23 : The starting address where we will write the packet data * * For more information, refer to section 3.5.1 in the Lego96 ERS */ #define CREATE_CD_PACKET_HEADER(_count, _noCount, _wrap, _addr) \ (((_count) << 27) | ((_noCount) << 25) | ((_wrap) << 24) | (_addr)) So basically we build a packet saying how much data we are going to write, what 24-bit address on the card we want to write to, and whether to increment the address, and write all of it to CD Buffer space on the card. Thanks to LaMontJones for clarifying this. Registers --------- - **TODO**: Check endianness UP_CONTROL (0x0024'9000) ~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: cpp typedef union { struct { unsigned res0 :1; /* <31> reserved */ unsigned him :1; /* <30> ??? */ unsigned hwie :1; /* <29> ? HWC interrupt enable */ unsigned lwie :1; /* <28> ? LWC interrupt enable */ unsigned tmie :1; /* <27> ? TMU interrupt enable */ unsigned vbie :1; /* <26> ? VIDBUS interrupt enable */ unsigned udce :1; /* <25> ??? */ unsigned bdce :1; /* <24> ??? */ unsigned res1 :1; /* <23> reserved */ unsigned hic :1; /* <22> ??? */ unsigned hwic :1; /* <21> ??? */ unsigned lwic :1; /* <20> ??? */ unsigned tmic :1; /* <19> ??? */ unsigned vbic :1; /* <18> ??? */ unsigned udcc :1; /* <17> ??? */ unsigned bdcc :1; /* <16> ??? */ unsigned udpc :1; /* <15> ??? */ unsigned bdpc :1; /* <14> ??? */ unsigned to :1; /* <13> Time Out prevented, must RST */ unsigned tce :1; /* <12> Timeout Circuit Enable */ unsigned udpe :1; /* <11> ??? */ unsigned bdpe :1; /* <10> ??? */ unsigned wfc :1; /* <9> Write Fifo Control */ unsigned rst :1; /* <8> Soft RST */ unsigned scratch:8; /* <7:0> scratch */ } bits; unsigned all; } control_t; UP_INT_ADDR (0x0024'9200) ~~~~~~~~~~~~~~~~~~~~~~~~~ CPU Address interrupts will be targeted at. Use txn_alloc_irq(5) to generate a suitable address. The register is 32-bits wide, so clearly some piece hardware will F-extend before driving the address onto the system bus. UP_INT_DATA (0x0024'9240) ~~~~~~~~~~~~~~~~~~~~~~~~~ Payload of write to CPU Interrupt space @ address INT_ADDR. UP_PSTI_SCRATCH1 (0x0024'9180) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UP_PSTI_SCRATCH2 (0x0024'91a0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UP_PSTI_SCRATCH3 (0x0024'91c0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UP_PSTI_SCRATCH4 (0x0024'91e0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_PSTI_SCRATCH1 (0x0064'1180) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_PSTI_SCRATCH2 (0x0064'11a0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_PSTI_SCRATCH3 (0x0064'11c0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_PSTI_SCRATCH4 (0x0064'11e0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_STI_SCRATCH1 (0x0064'1580) also UB_CLIP_PLANE_STAMP (Lego only?) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_STI_SCRATCH2 (0x0064'15a0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_STI_SCRATCH3 (0x0064'15c0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UB_STI_SCRATCH4 (0x0064'15e0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These appear to be temporary registers used to set flags that can be passed between routines. UB_STATUS (0x0064'1400) ~~~~~~~~~~~~~~~~~~~~~~~ from hpgraphics/headers/lego_hw.h:87: .. code-block:: cpp typedef union { struct { BITFIELD_18( Uint32 UBDRdy : 2, /* <31:30> UnBuffered Data Ready */ Uint32 BDRdy : 2, /* <29:28> Buffered Data Ready */ Uint32 Fault : 1, /* <27> Fault Detected */ Uint32 Ubuff : 1, /* <26> Unbuffered Pipe Busy */ Uint32 IMODE : 1, /* <25> Input Model (1=>CD Buffer) */ Uint32 WPNE : 1, /* <24> Write Pipe Not Empty */ Uint32 HIS : 1, /* <23> Host Interrupt Sent */ Uint32 res22 : 1, /* <22> reserved (was FIR) */ Uint32 HWIR : 1, /* <21> High Water Interrupt Req. */ Uint32 LWIR : 1, /* <20> Low Water Interrupt Req. */ Uint32 TMIR : 1, /* <19> Texture Map Interrupt Req. */ Uint32 VBIR : 1, /* <18> Vertical Blank Interrupt Req. */ Uint32 UDCR : 1, /* <17> Unbuffered DMA Complete Req. */ Uint32 BDCR : 1, /* <16> Buffered DMA Complete Req. */ Uint32 UDPR : 1, /* <15> Unbuff Priv DMA Complete Req.*/ Uint32 BDPR : 1, /* <14> Buff Priv DMA Complete Req. */ Uint32 res12 : 2, /* <13:12> reserved */ Uint32 ffc12 : 12 /* <11:0> FIFO Free Count (LSBs) */ ) } fields; Uint32 bits; } STATUS_Type; Valid bits for UBDRdy/BDRdy, this means the READ_DATA registers has either a requested single or double word waiting in it:: #define STATUS_WordRdy      (1) #define STATUS_DoubleRdy    (3) UB_IRC (0x0064'3030) ~~~~~~~~~~~~~~~~~~~~ UB_UIRC (0x0064'3034) ~~~~~~~~~~~~~~~~~~~~~ B2_IRC (0x00A4'3030) ~~~~~~~~~~~~~~~~~~~~ B3_IRC (0x00E4'3030) ~~~~~~~~~~~~~~~~~~~~ Buffered/Unbuffered Indirect Read Control registers. .. code-block:: cpp /* PDU IRC (indirect Read Control) */ typedef union { struct { BITFIELD_3( Uint32 unused1 : 29, Uint32 op : 2, /* opcode for setting WTR function */ Uint32 WTR : 1 /* Write To Read state flag */ ) } fields; Uint32 bits; } IRC_Type; Valid IRC_type.fields.op functions: .. code-block:: cpp #define PDU_IRC_NOOP 0 /* write is ignored */ #define PDU_IRC_IREAD 1 /* indirect read of IRC register */ #define PDU_IRC_CLEAR 2 /* clear WTR function (disable it) */ #define PDU_IRC_SET 3 /* set WTR function (enable it) */ B2_OTR - Overlay Transparency Register (0x0092'1148) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ??? It seems 3 is written to this during initialization in summit_init_graph. - It's also written about the time the texture mapping system is setup with some other value. B2_WORG (0x00a0'0818) ~~~~~~~~~~~~~~~~~~~~~ Zero is always stored to this inside the kernel, apparently. UB_UREAD_DATA (0x0064'14c0) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ B2_READ_DATA (0x00a4'1480) ~~~~~~~~~~~~~~~~~~~~~~~~~~ B3_READ_DATA (0x00e4'1480) ~~~~~~~~~~~~~~~~~~~~~~~~~~ These registers contain the result of the latest indirect (write-to-read) read request. Check for validity with UBDRdy/BDRdy in the STATUS registers. Typically code sequences look like write -1 to a register, call wait_buf_data, check it's return, and then read the appropriate READ_DATA register. Glossary -------- - Antero - Summit texture engine. - B7 - Geometry accelerator on Lego cards. - Blitzen - Geometry accelerator on Summit cards. - CD buffer - Command-Data buffers, can be host side (DMA), or card side (CD Space). - Concorde - Command processor on Summit cards. - Donner - Codename of the Visualize FX6. - Durango - Codename of the Visualize FX5? - Eolus - Rasterizer on Summit cards. - Heathrow - Command processor on Lego cards. - ITE - Internal Terminal Emulator. The thingy that provides console on HP-UX. - Lego - Architecture of later VisFX (e/5/10). - Pinnacle - Codename of the Visualize FXe, comes in two flavours, Pinnacle I, and Pinnacle II. - Rockwood - Codename of Lego? Rockwood/Silverton/Durango are all related to railways in southwest Colorado. - RT - Raster/Texture engine on Lego cards. - Silverton - Codename of the Visualize FX10? - Summit - Architecture of early VisFX (2/4/6). - WarpDrive - Codename of the Visualize FX (WarpDrive24 == FX2/ WarpDrive48 == FX4).