root/headers/private/graphics/radeon/radeon_interface.h
/*
        Copyright (c) 2002, Thomas Kurschel


        Part of Radeon accelerant
                
        Interface between kernel driver and accelerant
*/


#ifndef _RADEON_INTERFACE_H
#define _RADEON_INTERFACE_H

#include <Accelerant.h>
#include <Drivers.h>
#include <PCI.h>
#include <OS.h>
#include "video_overlay.h"
#include "benaphore.h"
#include "ddc.h"

// magic code for ioctls
// changed from TKRA to TKR1 for RADEON_WAITFORFIFO ioctl
// changed from TKRA to TKR2 for VIP FIFO ioctls
#define RADEON_PRIVATE_DATA_MAGIC       'TKR2'

#define MAX_RADEON_DEVICE_NAME_LENGTH MAXPATHLEN

// list ioctls
enum {
        RADEON_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,

        RADEON_DEVICE_NAME,
        RADEON_GET_LOG_SIZE,
        RADEON_GET_LOG_DATA,
        RADEON_ALLOC_MEM,
        RADEON_FREE_MEM,
        
        RADEON_WAITFORIDLE,
        RADEON_WAITFORFIFO,
        RADEON_RESETENGINE,
        RADEON_VIPREAD,
        RADEON_VIPWRITE,
        RADEON_VIPFIFOREAD,
        RADEON_VIPFIFOWRITE,
        RADEON_FINDVIPDEVICE,
        RADEON_VIPRESET,

        RADEON_WAIT_FOR_CAP_IRQ,        
        RADEON_DMACOPY,
};


// number of indirect buffers
// see CP.c for this magic number
#define NUM_INDIRECT_BUFFERS 253
// size of an indirect buffer in dwords; 
// as hardware wants buffers to be 4k aligned and as we store all
// buffers in one chunk, the size per buffer in bytes must be a multiple of 4k
#define INDIRECT_BUFFER_SIZE (4096/4)

typedef struct {
        uint32  loginfo;
        uint32  logflow;
        uint32  logerror;
        bool    switchhead;
        bool    force_lcd;
        bool    dynamic_clocks; // power saving / management for mobility chips
        bool    force_pci;
        bool    unhide_fastwrites;
        bool    force_acc_dma;  // one or the other
        bool    force_acc_mmio; // one or the other
        bool    acc_writeback;
} radeon_settings;

// type of memory
typedef enum {
        mt_local,               // local graphics memory
        mt_PCI,                 // PCI memory (read: fully cachable)
        mt_AGP,                 // AGP memory (read: not cachable; currently not supported)
        mt_nonlocal,    // non-local graphics memory (alias to one of the 
                                        // previously defined types, see si->nonlocal_type)
        
        mt_last = mt_nonlocal
} memory_type_e;

// list of multi-monitor modes
typedef enum {
        mm_none,        // use one display only
        mm_combine,     // combine displays to larger workspace
        mm_clone,       // clone workspace, all displays show the 
                                // same but have independant timing
        mm_mirror       // mirror heads (as used by Laptop) - not implemented yet
} multi_mode_e;


// displays devices;
// this must be a bit field as multiple devices may be connected to one CRTC
typedef enum {
        dd_none = 0,
        dd_tv_crt = 1,  // CRT on TV-DAC, i.e. on DVI port
        dd_crt = 2,             // CRT on CRT-DAC, i.e. VGA port
        dd_lvds = 4,    // laptop flap panel
        dd_dvi = 8,             // DVI on primary port (i.e. standard DVI connector)
        dd_ctv = 16,    // composite TV on TV-DAC
        dd_stv = 32,    // S-Video out on TV-DAC
        
        // the following connectors/devices are not supported
        dd_dvi_ext = 64 // external DVI (only provided by few models)
} display_device_e;

typedef enum
{
    ddc_none_detected,
    ddc_monid,
    ddc_dvi,
    ddc_vga,
    ddc_crt2
} radeon_ddc_type;

typedef enum
{
    mt_unknown = -1,
    mt_none    = 0,
    mt_crt     = 1,
    mt_lcd     = 2,
    mt_dfp     = 3,
    mt_ctv     = 4,
    mt_stv     = 5
} radeon_monitor_type;

typedef enum
{
        connector_none,
        connector_proprietary,
        connector_crt,
        connector_dvi_i,
        connector_dvi_d,
        connector_ctv,
        connector_stv,
        connector_unsupported,

        connector_none_atom = 0,
        connector_vga_atom,
        connector_dvi_i_atom,
        connector_dvi_d_atom,
        connector_dvi_a_atom,
        connector_stv_atom,
        connector_ctv_atom,
        connector_lvds_atom,
        connector_digital_atom,
        connector_unsupported_atom
} radeon_connector_type;

typedef enum
{
    dac_unknown = -1,
    dac_primary = 0,
    dac_tvdac   = 1
} radeon_dac_type;

typedef enum
{
    tmds_unknown = -1,
    tmds_int     = 0,
    tmds_ext     = 1
} radeon_tmds_type;

typedef struct
{
    radeon_ddc_type ddc_type;
    radeon_dac_type dac_type;
    radeon_tmds_type tmds_type;
    radeon_connector_type connector_type;
    radeon_monitor_type mon_type;
    edid1_info edid;
    bool edid_valid;
} radeon_connector;

typedef struct
{
    bool has_secondary;

    /*
     * The next two are used to make sure CRTC2 is restored before CRTC_EXT,
     * otherwise it could lead to blank screens.
     */
    bool is_secondary_restored;
    bool restore_primary;

    int mon_type1;
    int mon_type2;
        
    bool reversed_DAC;  /* TVDAC used as primary dac */
    bool reversed_TMDS; /* DDC_DVI is used for external TMDS */
    
    radeon_connector port_info[2];
} disp_entity, *ptr_disp_entity;


// type of ASIC
typedef enum {
        rt_r100,                // original Radeon
        rt_rv100,               // original VE version
        rt_rs100,               // IGP 320M
        rt_rv200,               // Radeon 7500
        rt_rs200,               // IGP 330M/340M/350M
        rt_r200,                // Radeon 8500/9100
        rt_rv250,               // Radeon 9000
        rt_rs300,               // IGP rs300
        rt_rv280,               // Radeon 9200  
        // from here on, r300 and up must be located as ATI modified the 
        // PLL design and the PLL code only tests for >= rt_r300
        rt_r300,                // Radeon 9700
        rt_r350,                // Radeon 9800
        rt_rv350,               // Radeon 9600
        rt_rv380,               // X600
        rt_r420                 // X800
} radeon_type;

#define IS_RV100_VARIANT ( \
                (ai->si->asic == rt_rv100)  ||  \
        (ai->si->asic == rt_rv200)  ||  \
        (ai->si->asic == rt_rs100)  ||  \
        (ai->si->asic == rt_rs200)  ||  \
        (ai->si->asic == rt_rv250)  ||  \
        (ai->si->asic == rt_rv280)  ||  \
        (ai->si->asic == rt_rs300))

#define IS_DI_R300_VARIANT ( \
                (di->asic == rt_r300)  ||  \
        (di->asic == rt_r350)  || \
        (di->asic == rt_rv350) || \
        (di->asic == rt_rv380) || \
        (di->asic == rt_r420))
        
#define IS_R300_VARIANT ( \
                (ai->si->asic == rt_r300)  ||  \
        (ai->si->asic == rt_r350)  || \
        (ai->si->asic == rt_rv350) || \
        (ai->si->asic == rt_rv380) || \
        (ai->si->asic == rt_r420))
        
// TV standard
typedef enum {
        ts_off,
        ts_ntsc,
        ts_pal_bdghi,
        ts_pal_m,
        ts_pal_nc,
        ts_scart_pal,
        ts_pal_60,
        ts_max = ts_pal_60
} tv_standard_e;


// type of TV-Chip
typedef enum {
        tc_none,
        tc_external_rt1,        // external Rage Theatre
        tc_internal_rt1,        // internal version 1
        tc_internal_rt2,        // internal version 2
} tv_chip_type;


// info about cursor
typedef struct {
        uint8*  data;           // pointer to framebuffer containing cursor image
        uint16  hot_x;
        uint16  hot_y;
        uint16  x;
        uint16  y;
        uint16  width;
        uint16  height;
        uint32  mem_handle;     // memory handle
        uint32  fb_offset;      // offset in frame buffer
        bool    is_visible;     // official flag whether cursor is visible
} cursor_info;


// info about flat panel connected to LVDS or DVI port
typedef struct {
        uint panel_pwr_delay;
        uint panel_xres, panel_yres;
        
        uint h_blank, h_over_plus, h_sync_width;
        uint v_blank, v_over_plus, v_sync_width;
        uint dot_clock;                         // in kHz (this is BeOS like, ATI uses 10 kHz steps!)

        bool is_fp2;                            // true, if second flat panel
//      display_type_e disp_type;
        uint16 ref_div;
        uint8 post_div;
        uint8 feedback_div;
        bool fixed_dividers;
        
        uint64 h_ratio;                         // current stretch ratio, needed for overlays
        uint64 v_ratio;                         // (mode_res/native_res; 32.32)
} fp_info;


// crtc info
typedef struct {
        //bool          is_crtc2;                       // true, if crtc2
        int8            flatpanel_port;         // linked flat panel port (-1 if none)
        bool            cursor_on_screen;       // cursor is visible on this head
        int                     crtc_idx;                       // index of CRTC
        display_device_e active_displays; // currently driven displays
        display_device_e chosen_displays; // displays to be driven after next mode switch
        sem_id          vblank;                         // vertical blank interrupt semaphore
        uint32          rel_x, rel_y;   // relative position in multi-monitor mode
        display_mode mode;                              // display mode of this head
} crtc_info;


// info about PLLs on graphics card as retrieved from BIOS
// all values are in 10kHz
typedef struct {
        uint32 max_pll_freq;            // maximum PLL output frequency
        uint32 min_pll_freq;            // minimum PLL output frequency
        uint32 xclk;                            // core frequency
        uint32 ref_div;                         // default reference divider
        uint32 ref_freq;                        // PLL reference frequency
} general_pll_info;


// mapping of pll divider code to actual divider value
typedef struct {
        uint8 divider;                          // divider
        uint8 code;                                     // code as used in register
} pll_divider_map;


// info about a PLL
// all values are in 10 kHz
typedef struct {
        pll_divider_map *post_divs;     // list of possible post dividers
        pll_divider_map *extra_post_divs; // list of possible extra post dividers
        uint32 ref_freq;                        // reference frequency
        uint32 vco_min, vco_max;        // VCO frequency range
        uint32 min_ref_div, max_ref_div; // reference divider range
        uint32 pll_in_min, pll_in_max; // PLL input frequency range
        uint32 extra_feedback_div;      // hardwired divider before feedback divider
        uint32 min_feedback_div, max_feedback_div; // feedback divider range
        uint32 best_vco;                        // preferred VCO frequency (0 for don't care)
} pll_info;

// info for ext tmds pll
typedef struct {
        uint32 freq;
        uint32 value;
} tmds_pll_info;

// one overlay buffer
typedef struct overlay_buffer_node {
        struct overlay_buffer_node *next, *prev;
        uint32 mem_handle;
        uint32 mem_offset;
        uint ati_space;                         // colour space according to ATI
        uint test_reg;                          // content of test reg
        overlay_buffer buffer;
} overlay_buffer_node;


// info about active overlay
typedef struct {
        overlay_token   ot;
        overlay_buffer  ob;
        overlay_window  ow;
        overlay_view    ov;
        uint16                  h_display_start;
        uint16                  v_display_start;
        
        overlay_buffer_node *on;        // current buffer
        overlay_buffer_node *prev_on; // previous buffer (for temporal deinterlace, currently unused)
        int                             crtc_idx;       // crtc where the overlay is shown on
        uint32                  rel_offset;     // offset of overlay source due to clipping
} overlay_info;


// each accelerant gets one "virtual card", i.e. you
// can have independant accelerants for each head
// (this is an ongoing project ;)
typedef struct {
        uint32          id;                             // identifier used to know which card the 2D accelerator
                                                                // is prepared for (we use area_id of this structure)
        bool            assigned_crtc[2];       // mask of heads assigned to virtual card
        bool            used_crtc[2];   // mask of heads assigned to virtual card
        
        display_device_e controlled_displays; // displays devices controlled byvc
        display_device_e connected_displays; // bit-field of connected displays
        
        int8            independant_heads;      // number of heads to be programmed independantly
        int8            different_heads;        // number of heads showing different parts of framebuffer
        bool            scroll;                 // scrolling in virtual area enabled

        uint32          datatype;               // Radeon code for pixel format
        uint            bpp;                    // bytes per pixel
        uint32          pitch;                  // byte offset between two lines

        uint32          eff_width, eff_height;  // size of visible area (including both monitors)
        uint32          fb_mem_handle;  // memory handle
        uint32          fb_offset;              // offset of frame buffer in graphics mem

        cursor_info     cursor;

        bool            swap_displays;  // true to swap monitors
        bool            use_laptop_panel; // true to always use laptop panel
        tv_standard_e tv_standard;      // standard to use for TV Out
        bool            enforce_mode_change; // set to make sure next display mode change 
                                                                // is executed even if display mode seems to be
                                                                // still the same

        frame_buffer_config fbc;        // data for direct frame buffer access

        display_mode mode;                      // offical mode with multi-monitor bits set     
        overlay_buffer_node     *overlay_buffers;       // list of allocated overlay buffers
        
        //int8          whished_overlay_head;   // head where users whishes the overlay to be
        bool            uses_overlay;   // true if this virtual card owns overlay
        
        int                     state_buffer_idx;
        int                     state_buffer_size;
} virtual_card;


// status of overlay
typedef struct {
        int32   inuse;                          // one, if someone allocated overlay head
                                                                // (this doesn't necessarily mean that an overlay is shown)
        uintptr_t       token;                  // arbitrarily chosen token to identify overlay owner
                                                                // (increased by 1 whenever there is a new owner)
        uint32  auto_flip_reg;          // content of auto_flip_reg
} overlay_mgr_info;


// info about indirect CP buffer
typedef struct {
        int             next;                           // next used/free buffer (-1 for EOL)
        int32   send_tag;                       // tag assigned when buffer was submitted
} indirect_buffer;


// info about command processor (CP) state
typedef struct {
        benaphore       lock;                   // lock to be acquired when talking to CP or
                                                                // when accesing this structure

        // ring buffer (in non-local memory)
        struct {
                uint32  mem_offset;                     // offset in non-local memory
                uint32  vm_base;                        // base of ring buffer as seen by graphics card
                uint32  tail, tail_mask;        // next write position in dwords; mask for wrap-arounds
                uint32  size;                           // size in dwords
                //uint32        head_offset;    // offset for automatically updates head in DMA buffer

                //uint32                        start_offset;
                memory_type_e   mem_type;
                //uint32        *start;                 // pointer to ring buffer
                //vuint32       *head;                  // pointer to automatically updated read position
                
                uint32  space;                  // known space in ring buffer
                uint32  mem_handle;             // handle of memory of indirect buffers
        } ring;
        
        // feedback registers (in PCI memory)
        struct {
                //vuint32 *ptr;                 // pointer to scratch registers
                uint32                  scratch_mem_offset;     // offset of scratch registers in feedback memory
                uint32                  head_mem_offset;        // offset of head register in feedback memory
                uint32                  scratch_vm_start;       // virtual address of scratch as seen by GC
                uint32                  head_vm_address;        // virtual address of head as seen by GC
                memory_type_e   mem_type;               // memory type of feedback memory
                uint32                  mem_handle;             // handle of feedback memory
        } feedback;
        

        // indirect buffers (in non-local memory)
        // for indeces: -1 means "none"
        struct {
                int                     free_list;              // index of first empty buffer
                int                     oldest,                 // oldest submitted buffer
                                        newest;                 // newest submitted buffer
                int                     active_state;   // index of active state buffer
                uint64          cur_tag;                // tag of last submitted indirect buffer

                memory_type_e mem_type;         
                uint32          mem_offset;             // offset of indirect buffers in non-local memory               
                uint32          vm_start;               // start of indirect buffers as seen by graphics card
                
                indirect_buffer buffers[NUM_INDIRECT_BUFFERS];  // info about buffers
                uint32          mem_handle;             // handle of memory of indirect buffers
        } buffers;
} CP_info;


// info about different graphics-related memory
// (see memory_type_e)
typedef struct {
        area_id         area;                           // area to memory
        uint32          size;                           // usable size in bytes
        uint32          virtual_addr_start;     // virtual address (for graphics card!)
        uint32          virtual_size;           // reserved virtual address space in bytes
} memory_type_info;


// data published by kernel and shared by all accelerant/virtual cards
typedef struct {
        // filled out by kernel
        CP_info cp;                             // info concerning command processor
        bool    acc_dma;                        // prevent use of dma engine
        
        // set by accelerant
        struct {
                uint64          count;          // count of submitted CP commands
                uint64          last_idle;      // count when engine was idle last time
                uint64          written;        // last count passed to CP
                benaphore       lock;           // engine lock
        } engine;       

        uint16          vendor_id;              // PCI vendor id
        uint16          device_id;              // PCI device id
        uint8           revision;               // PCI device revision
        
        radeon_type     asic;                   // ASIC version
        bool            is_mobility;            // mobility version
        bool            is_igp;                 // might need to know if it's an integrated chip
        bool            is_atombios;

        tv_chip_type    tv_chip;                // type of TV-Out encoder
        bool            new_pll;                // r300 style PLL
        bool            has_no_i2c;             // I2C is broken
        uint16          panel_pwr_delay;        // delay for LCD backlight to stabilise
        uint8           theatre_channel;        // VIP channel of Rage Theatre (if applicable)
                
        general_pll_info        pll;
        tmds_pll_info           tmds_pll[4];

        area_id         regs_area;              // area of memory mapped registers
        area_id         ROM_area;               // area of ROM
        phys_addr_t     framebuffer_pci;        // physical address of frame buffer (aka local memory)
                                                        // this is a hack needed by BeOS

        crtc_info       crtc[2];                // info about each crtc
        uint8           num_crtc;               // number of physical heads
        
        fp_info         flatpanels[2];  // info about connected flat panels (if any)
        disp_entity     routing;                // info if display connector routings eg DVI-I <- EXT TMDS <- DAC2 <- CRTC2

        memory_type_info        memory[mt_last];        // info about memory types
        memory_type_e   nonlocal_type;  // default type of non-local memory

        uint8   *local_mem;                     // address of local memory; 
                                                                // this is a hack requested by BeOS
                                                                                                
        area_id mode_list_area;         // area containing display mode list
        uint    mode_count;
        
        uint32  active_vc;                      // currently selected virtual card in terms of 2D acceleration
                
        uint32  dac_cntl2;                      // content of dac_cntl2 register
        uint32  tmds_pll_cntl;                  // undocumented here be dragons
        uint32  tmds_transmitter_cntl;          // undocumented here be dragons

        overlay_info    pending_overlay;        // overlay to be shown
        overlay_info    active_overlay;         // overlay shown
        overlay_mgr_info overlay_mgr;           // status of overlay
        
        // data needed for VBI emulation 
        // (currently not fully implemented - if the user disabled graphics card
        //  IRQ in the BIOS, it's his fault)
        int             refresh_period;         // duration of one frame in ms
        int             blank_period;           // vertical blank period of a frame in ms
        int             enable_virtual_irq;     // true, to enable virtual interrupts
        
        radeon_settings settings;       // settings from radeon.settings file
        
        struct log_info_t *log;         // fast logger data
} shared_info;


// retrieve the area_id of the kernel/accelerant shared info
typedef struct {
        uint32  magic;                          // magic number
        area_id shared_info_area;
        area_id virtual_card_area;
} radeon_get_private_data;

// get devie name (used to clone accelerant)
typedef struct {
        uint32  magic;                          // magic number
        char    *name;                          // pointer to buffer containing name (in)
} radeon_device_name;

// alloc (non-)local memory
typedef struct {
        uint32                  magic;
        memory_type_e   memory_type;// type of memory
        uint32                  size;           // size in bytes
        uint32                  offset;         // offset in memory
        uint32                  handle;         // handle (needed to free memory)
        bool                    global;         // set this to true if memory should persist even
                                                                // if client gets terminated
} radeon_alloc_mem;

// free (non-)local memory
typedef struct {
        uint32                  magic;
        memory_type_e   memory_type;// type of memory
        uint32                  handle;         // memory handle 
        bool                    global;         // must be same as on alloc_local_mem
} radeon_free_mem;

// wait for idle
typedef struct {
        uint32                  magic;
        bool                    keep_lock;      // keep lock after engine is idle
} radeon_wait_for_idle;

// wait for idle
typedef struct {
        uint32                  magic;
        int                             entries;        // keep lock after engine is idle
} radeon_wait_for_fifo;

// read VIP register
typedef struct {
        uint32                  magic;
        uint                    channel;        // channel, i.e. device
        uint                    address;        // address
        uint32                  data;           // read data
        bool                    lock;           // true, if CP lock must be acquired
} radeon_vip_read;

// write VIP register
typedef struct {
        uint32                  magic;
        uint                    channel;        // channel, i.e. device
        uint                    address;        // address
        uint32                  data;           // data to write
        bool                    lock;           // true, if CP lock must be acquired
} radeon_vip_write;

// read VIP fifo
typedef struct {
        uint32                  magic;
        uint                    channel;        // channel, i.e. device
        uint                    address;        // address
        uint32                  count;          // size of buffer
        uint8                   *data;          // read data
        bool                    lock;           // true, if CP lock must be acquired
} radeon_vip_fifo_read;

// write VIP fifo
typedef struct {
        uint32                  magic;
        uint                    channel;        // channel, i.e. device
        uint                    address;        // address
        uint32                  count;          // size of buffer
        uint8                   *data;          // data to write
        bool                    lock;           // true, if CP lock must be acquired
} radeon_vip_fifo_write;

// find channel of device with given ID
typedef struct {
        uint32                  magic;
        uint32                  device_id;      // id of device
        uint                    channel;        // channel of device (-1 if not found)
} radeon_find_vip_device;

// reset / init VIP
typedef struct {
        uint32                  magic;
        bool                    lock;
} radeon_vip_reset;


// wait for capture interrupt and get status about
typedef struct {
        uint32                  magic;
        bigtime_t               timeout;        // timeout to wait for irq
        bigtime_t               timestamp;      // timestamp when last capturing was finished
        uint32                  int_status;     // content of RADEON_CAP_INT_STATUS
        uint32                  counter;        // number of capture interrupts so far
} radeon_wait_for_cap_irq;

// copy data from frame buffer to some memory location
typedef struct {
        uint32                  magic;
        uint32                  src;            // offset of source data in frame buffer
        void                    *target;        // target buffer
        size_t                  size;           // number of bytes to copy
        bool                    lock_mem;       // true, if target needs to be locked
        bool                    contiguous;     // true, if target is physically contiguous
} radeon_dma_copy;

// parameter for ioctl without further arguments
typedef struct {
        uint32                  magic;
} radeon_no_arg;

#endif