/*++

Copyright (c) 1990-1995  Microsoft Corporation

Module Name:

    s3.h

Abstract:

    This module contains the definitions for the S3 miniport driver.

Environment:

    Kernel mode

Revision History:

--*/

#include "dderror.h"
#include "devioctl.h"
#include "miniport.h"

#include "ntddvdeo.h"
#include "video.h"

//
// We don't use the CRT 'min' function because that would drag in
// unwanted CRT baggage.
//

#define MIN(a, b) ((a) < (b) ? (a) : (b))

//
// Size of the ROM we map in
//

#define MAX_ROM_SCAN    512

//
// Number of access ranges used by an S3.
//

#define NUM_S3_ACCESS_RANGES 36
#define NUM_S3_ACCESS_RANGES_USED 22
#define NUM_S3_PCI_ACCESS_RANGES 2
#define S3_EXTENDED_RANGE_START 4

//
// Index of Frame buffer in access range array
//

#define A000_FRAME_BUF   1
#define LINEAR_FRAME_BUF 36

//
// Constants defining 'New Memory-mapped I/O' window:
//

#define NEW_MMIO_WINDOW_SIZE    0x4000000   // Total window size -- 64 MB
#define NEW_MMIO_IO_OFFSET      0x1000000   // Offset to start of little endian
                                            //   control registers -- 16 MB
#define NEW_MMIO_IO_LENGTH      0x0020000   // Length of control registers
                                            //   -- 128 KB

////////////////////////////////////////////////////////////////////////
// Capabilities flags
//
// These are private flags passed to the S3 display driver.  They're
// put in the high word of the 'AttributeFlags' field of the
// 'VIDEO_MODE_INFORMATION' structure (found in 'ntddvdeo.h') passed
// to the display driver via an 'VIDEO_QUERY_AVAIL_MODES' or
// 'VIDEO_QUERY_CURRENT_MODE' IOCTL.
//
// NOTE: These definitions must match those in the S3 display driver's
//       'driver.h'!

typedef enum {
    CAPS_STREAMS_CAPABLE    = 0x00000040,   // Has overlay streams processor
    CAPS_FORCE_DWORD_REREADS= 0x00000080,   // Dword reads occasionally return
                                            //   an incorrect result, so always
                                            //   retry the reads
    CAPS_NEW_MMIO           = 0x00000100,   // Can use 'new memory-mapped
                                            //   I/O' scheme introduced with
                                            //   868/968
    CAPS_POLYGON            = 0x00000200,   // Can do polygons in hardware
    CAPS_24BPP              = 0x00000400,   // Has 24bpp capability
    CAPS_BAD_24BPP          = 0x00000800,   // Has 868/968 early rev chip bugs
                                            //   when at 24bpp
    CAPS_PACKED_EXPANDS     = 0x00001000,   // Can do 'new 32-bit transfers'
    CAPS_PIXEL_FORMATTER    = 0x00002000,   // Can do colour space conversions,
                                            //   and one-dimensional hardware
                                            //   stretches
    CAPS_BAD_DWORD_READS    = 0x00004000,   // Dword or word reads from the
                                            //   frame buffer will occasionally
                                            //   return an incorrect result,
                                            //   so always do byte reads
    CAPS_NO_DIRECT_ACCESS   = 0x00008000,   // Frame buffer can't be directly
                                            //   accessed by GDI or DCI --
                                            //   because dword or word reads
                                            //   would crash system, or Alpha
                                            //   is running in sparse space

    CAPS_HW_PATTERNS        = 0x00010000,   // 8x8 hardware pattern support
    CAPS_MM_TRANSFER        = 0x00020000,   // Memory-mapped image transfers
    CAPS_MM_IO              = 0x00040000,   // Memory-mapped I/O
    CAPS_MM_32BIT_TRANSFER  = 0x00080000,   // Can do 32bit bus size transfers
    CAPS_16_ENTRY_FIFO      = 0x00100000,   // At least 16 entries in FIFO
    CAPS_SW_POINTER         = 0x00200000,   // No hardware pointer; use software
                                            //   simulation
    CAPS_BT485_POINTER      = 0x00400000,   // Use Brooktree 485 pointer
    CAPS_TI025_POINTER      = 0x00800000,   // Use TI TVP3020/3025 pointer
    CAPS_SCALE_POINTER      = 0x01000000,   // Set if the S3 hardware pointer
                                            //   x position has to be scaled by
                                            //   two
    CAPS_SPARSE_SPACE       = 0x02000000,   // Frame buffer is mapped in sparse
                                            //   space on the Alpha
    CAPS_NEW_BANK_CONTROL   = 0x04000000,   // Set if 801/805/928 style banking
    CAPS_NEWER_BANK_CONTROL = 0x08000000,   // Set if 864/964 style banking
    CAPS_RE_REALIZE_PATTERN = 0x10000000,   // Set if we have to work around the
                                            //   864/964 hardware pattern bug
    CAPS_SLOW_MONO_EXPANDS  = 0x20000000,   // Set if we have to slow down
                                            //   monochrome expansions
    CAPS_MM_GLYPH_EXPAND    = 0x40000000,   // Use memory-mapped I/O glyph-
                                            //   expand method of drawing text
    CAPS_WAIT_ON_PALETTE    = 0x80000000,   // Wait for vertical retrace before
                                            //   setting the palette registers
} CAPS;

#define CAPS_DAC_POINTER    (CAPS_BT485_POINTER | CAPS_TI025_POINTER)

//
// Supported board definitions.
//

typedef enum _S3_BOARDS {
    S3_GENERIC = 0,
    S3_ORCHID,
    S3_NUMBER_NINE,
    S3_DELL,
    S3_METHEUS,
    S3_DIAMOND,
    S3_HP,
    S3_IBM_PS2,
    MAX_S3_BOARD
} S3_BOARDS;

//
// Chip type definitions -- for families of chips
//
// if you change this typedef it will change the size of the second element
// (named Fixed) of the union in the typedef for S3_VIDEO_FREQUENCIES and
// PS3_VIDEO_FREQUENCIES, look at that typedef for a caution about the effect
// this will have on autoinitialization
//

typedef enum _S3_CHIPSETS {
    S3_911 = 0,    // 911 and 924 boards
    S3_801,        // 801 and 805 boards
    S3_928,        // 928 boards
    S3_864,        // 864, 964, 732, 764, and 765 boards
    S3_866,        // 866, 868, and 968 boards
    MAX_S3_CHIPSET
} S3_CHIPSETS;

//
// Chip subtypes -- for more differentiation within families
//
// Note that ordering is important.
//

typedef enum _S3_SUBTYPE {
    SUBTYPE_911 = 0,    // 911 and 924
    SUBTYPE_80x,        // 801 and 805
    SUBTYPE_928,        // 928 and 928PCI
    SUBTYPE_805i,       // 805i
    SUBTYPE_864,        // 864
    SUBTYPE_964,        // 964
    SUBTYPE_764,        // Trio64
    SUBTYPE_732,        // Trio32
    SUBTYPE_866,        // 866
    SUBTYPE_868,        // 868
    SUBTYPE_765,        // Trio64 V+
    SUBTYPE_968,        // 968
    MAX_S3_SUBTYPE
} S3_SUBTYPE;

//
// DAC type definitions
//

typedef enum _S3_DACS {
    UNKNOWN_DAC = 0,    // unknown DAC type
    BT_485,             // Brooktree's Bt 485
    TI_3020,            // TI's 3020 or 3025
    S3_SDAC,            // S3's SDAC
    MAX_S3_DACS
} S3_DACS;

//
// Hardware pointer capabilities flags
//

typedef enum _POINTER_CAPABILITY {
    POINTER_BUILT_IN            = 0x01, // A pointer is built in to the hardware
    POINTER_WORKS_ONLY_AT_8BPP  = 0x02, // If set, the hardware pointer works
                                        //   only at 8bpp, and only for modes
                                        //   1024x768 or less
    POINTER_NEEDS_SCALING       = 0x04, // x-coordinate must be scaled by 2 at
                                        //   32bpp
} POINTER_CAPABILITY;

//
// Characteristics of each mode
//

typedef struct _S3_VIDEO_MODES {

    USHORT Int10ModeNumberContiguous;
    USHORT Int10ModeNumberNoncontiguous;
    ULONG ScreenStrideContiguous;

    VIDEO_MODE_INFORMATION ModeInformation;

} S3_VIDEO_MODES, *PS3_VIDEO_MODES;

//
// Mode-set specific information.
//

typedef struct _S3_VIDEO_FREQUENCIES {

    ULONG BitsPerPel;
    ULONG ScreenWidth;
    ULONG ScreenFrequency;
    union {

        //
        // The compiler uses the first element of a union to determine where
        // it places the values given when the union is autoinitialized.
        //
        // If size of the Fixed element of this union is changed by adding
        // chips to the enum typedef for S3_CHIPSET then the Int10 element
        // needs to be padded with dummy fields to make autoinitialization
        // of the Fixed element work correctly.
        //
        // If values are removed from the S3_CHIPSET typedef then either the
        // Int10 element should shrunk by removing pads or the Fixed element
        // should be padded.
        //

        struct {

            ULONG_PTR FrequencyPrimarySet;
            ULONG_PTR FrequencyPrimaryMask;
            ULONG_PTR FrequencySecondarySet;
            ULONG_PTR FrequencySecondaryMask;
            ULONG_PTR SizePad0;             // make struct sizes match

        } Int10;

        struct {

            union {

                //
                // This is done so that Clock overlays FrequencyPrimarySet
                // and CRTCTable[1] overlays FrequencyPrimaryMask, whether
                // we are compiling for 32 or 64 bits.
                //

                ULONG Clock;
                ULONG_PTR Pad;
            };
            PUSHORT CRTCTable[MAX_S3_CHIPSET];

        } Fixed;
    };

    PS3_VIDEO_MODES ModeEntry;
    ULONG ModeIndex;
    UCHAR ModeValid;

} S3_VIDEO_FREQUENCIES, *PS3_VIDEO_FREQUENCIES;

//
// Streams parameter information.
//

typedef struct _K2TABLE {
    USHORT  ScreenWidth;
    UCHAR   BitsPerPel;
    UCHAR   RefreshRate;
    UCHAR   MemoryFlags;
    UCHAR   MemorySpeed;
    ULONG   Value;
} K2TABLE;

#define MEM_1EDO 0x0
#define MEM_2EDO 0x2
#define MEM_FAST 0x3
#define MEM_TYPE_MASK 0x3

#define MEM_1MB 0x0
#define MEM_2MB 0x10
#define MEM_SIZE_MASK 0x10

//
// Private IOCTL for communicating S3 streams parameters.  These definitions
// must match those in the display driver!
//

#define IOCTL_VIDEO_S3_QUERY_STREAMS_PARAMETERS                        \
    CTL_CODE(FILE_DEVICE_VIDEO, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _VIDEO_QUERY_STREAMS_MODE {
    ULONG ScreenWidth;
    ULONG BitsPerPel;
    ULONG RefreshRate;
} VIDEO_QUERY_STREAMS_MODE;

typedef struct _VIDEO_QUERY_STREAMS_PARAMETERS {
    ULONG MinOverlayStretch;
    ULONG FifoValue;
} VIDEO_QUERY_STREAMS_PARAMETERS;


//
// Register definitions used with VideoPortRead/Write functions
//
// It's a good idea to write your miniport to allow for easy register
// re-mapping, but I wouldn't recommend that anyone use this particular
// implementation because it's pretty dumb.
//

#define DAC_PIXEL_MASK_REG     (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[2] + (0x03C6 - 0x03C0))
#define BT485_ADDR_CMD_REG0    (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[2] + (0x03C6 - 0x03C0))
#define TI025_INDEX_REG        (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[2] + (0x03C6 - 0x03C0))
#define TI025_DATA_REG         (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[2] + (0x03C7 - 0x03C0))
#define CRT_DATA_REG           (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[3] + (0x03D5 - 0x03D4))
#define SYSTEM_CONTROL_REG     (PVOID)((PUCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[3] + (0x03DA - 0x03D4))

#define CRT_ADDRESS_REG        ((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[3]
#define GP_STAT                ((PHW_DEVICE_EXTENSION)HwDeviceExtension)->MappedAddress[12]        // 0x9AE8

#define DAC_ADDRESS_WRITE_PORT (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03C8 - 0x03C0))
#define DAC_DATA_REG_PORT      (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03C9 - 0x03C0))
#define MISC_OUTPUT_REG_WRITE  (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03C2 - 0x03C0))
#define MISC_OUTPUT_REG_READ   (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03CC - 0x03C0))
#define SEQ_ADDRESS_REG        (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03C4 - 0x03C0))
#define SEQ_DATA_REG           (PVOID)((PUCHAR)HwDeviceExtension->MappedAddress[2] + (0x03C5 - 0x03C0))




#define IOCTL_PRIVATE_GET_FUNCTIONAL_UNIT \
    CTL_CODE(FILE_DEVICE_VIDEO, 0x180, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _FUNCTIONAL_UNIT_INFO {
    ULONG FunctionalUnitID;
    ULONG Reserved;
} FUNCTIONAL_UNIT_INFO, *PFUNCTIONAL_UNIT_INFO;

//
// Define device extension structure. This is device dependent/private
// information.
//

typedef struct _HW_DEVICE_EXTENSION {
    PHYSICAL_ADDRESS PhysicalFrameAddress;
    ULONG PhysicalFrameIoSpace;
    ULONG FrameLength;
    PHYSICAL_ADDRESS PhysicalRegisterAddress;
    ULONG RegisterLength;
    UCHAR RegisterSpace;
    PHYSICAL_ADDRESS PhysicalMmIoAddress;
    ULONG MmIoLength;
    ULONG ChildCount;
    UCHAR MmIoSpace;
    UCHAR FrequencySecondaryIndex;
    UCHAR BiosPresent;
    UCHAR CR5C;
    BOOLEAN bNeedReset;
    PUCHAR MmIoBase;
    PS3_VIDEO_MODES ActiveModeEntry;
    PS3_VIDEO_FREQUENCIES ActiveFrequencyEntry;
    PS3_VIDEO_FREQUENCIES Int10FrequencyTable;
    PS3_VIDEO_FREQUENCIES FixedFrequencyTable;
    USHORT PCIDeviceID;
    ULONG FunctionalUnitID;
    ULONG BoardID;
    S3_CHIPSETS ChipID;
    S3_SUBTYPE  SubTypeID;
    ULONG DacID;
    ULONG Capabilities;
    ULONG NumAvailableModes;
    ULONG NumTotalModes;
    ULONG AdapterMemorySize;
    PVOID MappedAddress[NUM_S3_ACCESS_RANGES];
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;


//
// SDAC M and N paramaters
//

typedef struct {
    UCHAR   m;
    UCHAR   n;
} SDAC_PLL_PARMS;

#define SDAC_TABLE_SIZE         16


//
// Highest valid DAC color register index.
//

#define VIDEO_MAX_COLOR_REGISTER  0xFF

//
// Data
//

//
// Global Physical Access Ranges.
// Logical access ranges must be stored in the HwDeviceExtension so different
// addresses can be used for different boards.
//

extern VIDEO_ACCESS_RANGE S3AccessRanges[];

//
// Memory Size array
//

extern ULONG gacjMemorySize[];

//
// nnlck.c clock generator table
//

extern long vclk_range[];

//
// Hard-coded modeset tables
//

extern USHORT  s3_set_vga_mode[];
extern USHORT  s3_set_vga_mode_no_bios[];

extern USHORT  S3_911_Enhanced_Mode[];
extern USHORT  S3_801_Enhanced_Mode[];
extern USHORT  S3_928_Enhanced_Mode[];
extern USHORT  S3_928_1280_Enhanced_Mode[];

//
//  Externs for 864 PPC board
//

extern USHORT  S3_864_Enhanced_Mode[];
extern USHORT  S3_864_1280_Enhanced_Mode[];
extern SDAC_PLL_PARMS SdacTable[];
extern UCHAR MParameterTable[];

//
// Hard-coded modeset frequency tables
//

extern S3_VIDEO_FREQUENCIES GenericFixedFrequencyTable[];
extern S3_VIDEO_FREQUENCIES OrchidFixedFrequencyTable[];
extern S3_VIDEO_FREQUENCIES NumberNine928NewFixedFrequencyTable[];

//
// Int 10 frequency tables
//

extern S3_VIDEO_FREQUENCIES GenericFrequencyTable[];
extern S3_VIDEO_FREQUENCIES Dell805FrequencyTable[];
extern S3_VIDEO_FREQUENCIES NumberNine928NewFrequencyTable[];
extern S3_VIDEO_FREQUENCIES NumberNine928OldFrequencyTable[];
extern S3_VIDEO_FREQUENCIES Metheus928FrequencyTable[];
extern S3_VIDEO_FREQUENCIES Generic64NewFrequencyTable[];
extern S3_VIDEO_FREQUENCIES Generic64OldFrequencyTable[];
extern S3_VIDEO_FREQUENCIES NumberNine64FrequencyTable[];
extern S3_VIDEO_FREQUENCIES Diamond64FrequencyTable[];
extern S3_VIDEO_FREQUENCIES HerculesFrequencyTable[];
extern S3_VIDEO_FREQUENCIES Hercules64FrequencyTable[];
extern S3_VIDEO_FREQUENCIES Hercules68FrequencyTable[];
//
// Mode Tables
//

extern S3_VIDEO_MODES S3Modes[];
extern ULONG NumS3VideoModes;

//
// Streams Tables
//

extern K2TABLE K2WidthRatio[];
extern K2TABLE K2FifoValue[];

//
// Function prototypes
//

//
// sdac.c
//

BOOLEAN
InitializeSDAC(
    PHW_DEVICE_EXTENSION
    );

BOOLEAN
FindSDAC(
    PHW_DEVICE_EXTENSION
    );

//
// nnclk.c
//

long calc_clock(long, int);
long gcd(long, long);
VOID set_clock(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    LONG clock_value);

//
// S3.c
//

ULONG
S3GetChildDescriptor(
    PVOID HwDeviceExtension,
    PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
    PVIDEO_CHILD_TYPE pChildType,
    PVOID pvChildDescriptor,
    PULONG pHwId,
    PULONG pUnused
    );

VP_STATUS
GetDeviceDataCallback(
    PVOID HwDeviceExtension,
    PVOID Context,
    VIDEO_DEVICE_DATA_TYPE DeviceDataType,
    PVOID Identifier,
    ULONG IdentifierLength,
    PVOID ConfigurationData,
    ULONG ConfigurationDataLength,
    PVOID ComponentInformation,
    ULONG ComponentInformationLength
    );

VP_STATUS
S3FindAdapter(
    PVOID HwDeviceExtension,
    PVOID HwContext,
    PWSTR ArgumentString,
    PVIDEO_PORT_CONFIG_INFO ConfigInfo,
    PUCHAR Again
    );

BOOLEAN
S3Initialize(
    PVOID HwDeviceExtension
    );

BOOLEAN
S3ResetHw(
    PVOID HwDeviceExtension,
    ULONG Columns,
    ULONG Rows
    );

BOOLEAN
S3StartIO(
    PVOID HwDeviceExtension,
    PVIDEO_REQUEST_PACKET RequestPacket
    );

VP_STATUS
S3SetColorLookup(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PVIDEO_CLUT ClutBuffer,
    ULONG ClutBufferSize
    );

VOID
SetHWMode(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PUSHORT pusCmdStream
    );

VP_STATUS
S3RegistryCallback(
    PVOID HwDeviceExtension,
    PVOID Context,
    PWSTR ValueName,
    PVOID ValueData,
    ULONG ValueLength
    );

LONG
CompareRom(
    PUCHAR Rom,
    PUCHAR String
    );

VOID
MapLinearControlSpace(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

BOOLEAN
S3IsaDetection(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PULONG key
    );

VOID
S3GetInfo(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    POINTER_CAPABILITY *PointerCapability,
    VIDEO_ACCESS_RANGE accessRange[]
    );

VOID
S3DetermineFrequencyTable(
    PVOID HwDeviceExtension,
    VIDEO_ACCESS_RANGE accessRange[],
    INTERFACE_TYPE AdapterInterfaceType
    );

VOID
S3DetermineDACType(
    PVOID HwDeviceExtension,
    POINTER_CAPABILITY *PointerCapability
    );

VOID
S3ValidateModes(
    PVOID HwDeviceExtension,
    POINTER_CAPABILITY *PointerCapability
    );

VOID
S3DetermineMemorySize(
    PVOID HwDeviceExtension
    );

VOID
S3RecordChipType(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PULONG key
    );

VOID
AlphaDetermineMemoryUsage(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    VIDEO_ACCESS_RANGE accessRange[]
    );


ULONG
UnlockExtendedRegs(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

VOID
LockExtendedRegs(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    ULONG key
    );

//
// Non-int 10 platform support
//

VOID
ZeroMemAndDac(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

VP_STATUS
Set_Oem_Clock(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

VP_STATUS
Wait_VSync(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

BOOLEAN
Bus_Test(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );

BOOLEAN
Set864MemoryTiming(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );



BOOLEAN
S3ConfigurePCI(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PULONG NumPCIAccessRanges,
    PVIDEO_ACCESS_RANGE PCIAccessRanges
    );

VP_STATUS
QueryStreamsParameters(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    VIDEO_QUERY_STREAMS_MODE *pStreamsMode,
    VIDEO_QUERY_STREAMS_PARAMETERS *pStreamsParameters
    );

VOID
WorkAroundForMach(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    );


//
// ddc.c
//

BOOLEAN
GetDdcInformation (
    PHW_DEVICE_EXTENSION phwDeviceExtension,
    PUCHAR QueryBuffer,
    ULONG BufferSize
    );

//
// power management
//

VP_STATUS
S3GetPowerState(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    ULONG HwDeviceId,
    PVIDEO_POWER_MANAGEMENT VideoPowerManagement
    );

VP_STATUS
S3SetPowerState(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    ULONG HwDeviceId,
    PVIDEO_POWER_MANAGEMENT VideoPowerManagement
    );

#define VESA_POWER_FUNCTION 0x4f10
#define VESA_POWER_ON       0x0000
#define VESA_POWER_STANDBY  0x0100
#define VESA_POWER_SUSPEND  0x0200
#define VESA_POWER_OFF      0x0400
#define VESA_GET_POWER_FUNC 0x0000
#define VESA_SET_POWER_FUNC 0x0001
#define VESA_STATUS_SUCCESS 0x004f