Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2007, 2008  Egbert Eich   <eich@novell.com>
  3.  * Copyright 2007, 2008  Luc Verhaegen <lverhaegen@novell.com>
  4.  * Copyright 2007, 2008  Matthias Hopf <mhopf@novell.com>
  5.  * Copyright 2007, 2008  Advanced Micro Devices, Inc.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included in
  15.  * all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23.  * OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25. /* #define RHD_DEBUG */
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include "xf86.h"
  31.  
  32.  
  33. /* only for testing now */
  34.  
  35. #include "rhd.h"
  36. #include "edid.h"
  37. #include "rhd_atombios.h"
  38. #include "rhd_connector.h"
  39. #include "rhd_output.h"
  40. #include "rhd_biosscratch.h"
  41. #include "rhd_monitor.h"
  42. #include "rhd_card.h"
  43. #include "rhd_regs.h"
  44.  
  45. #ifdef ATOM_BIOS
  46. # include "rhd_atomwrapper.h"
  47. //# include "xf86int10.h"
  48. # ifdef ATOM_BIOS_PARSER
  49. #  define INT8 INT8
  50. #  define INT16 INT16
  51. #  define INT32 INT32
  52. #  include "AtomBios/includes/CD_Common_Types.h"
  53. # else
  54. #  ifndef ULONG
  55. typedef unsigned int ULONG;
  56. #   define ULONG ULONG
  57. #  endif
  58. #  ifndef UCHAR
  59. typedef unsigned char UCHAR;
  60. #   define UCHAR UCHAR
  61. #  endif
  62. #  ifndef USHORT
  63. typedef unsigned short USHORT;
  64. #   define USHORT USHORT
  65. #  endif
  66. # endif
  67.  
  68. # include "atomBios/includes/atombios.h"
  69. # include "atomBios/includes/ObjectID.h"
  70.  
  71. typedef AtomBiosResult (*AtomBiosRequestFunc)(atomBiosHandlePtr handle,
  72.                                           AtomBiosRequestID unused, AtomBiosArgPtr data);
  73. typedef struct rhdConnectorInfo *rhdConnectorInfoPtr;
  74.  
  75. static AtomBiosResult rhdAtomInit(atomBiosHandlePtr unused1,
  76.                                       AtomBiosRequestID unused2, AtomBiosArgPtr data);
  77. static AtomBiosResult rhdAtomTearDown(atomBiosHandlePtr handle,
  78.                                           AtomBiosRequestID unused1, AtomBiosArgPtr unused2);
  79. static AtomBiosResult rhdAtomGetDataInCodeTable(atomBiosHandlePtr handle,
  80.                                                 AtomBiosRequestID unused, AtomBiosArgPtr data);
  81. static AtomBiosResult rhdAtomVramInfoQuery(atomBiosHandlePtr handle,
  82.                                                AtomBiosRequestID func, AtomBiosArgPtr data);
  83. static AtomBiosResult rhdAtomTmdsInfoQuery(atomBiosHandlePtr handle,
  84.                                                AtomBiosRequestID func, AtomBiosArgPtr data);
  85. static AtomBiosResult rhdAtomAllocateFbScratch(atomBiosHandlePtr handle,
  86.                                                    AtomBiosRequestID func, AtomBiosArgPtr data);
  87. static AtomBiosResult rhdAtomLvdsGetTimings(atomBiosHandlePtr handle,
  88.                                         AtomBiosRequestID unused, AtomBiosArgPtr data);
  89. static AtomBiosResult rhdAtomLvdsInfoQuery(atomBiosHandlePtr handle,
  90.                                                AtomBiosRequestID func,  AtomBiosArgPtr data);
  91. static AtomBiosResult rhdAtomGPIOI2CInfoQuery(atomBiosHandlePtr handle,
  92.                                                   AtomBiosRequestID func, AtomBiosArgPtr data);
  93. static AtomBiosResult rhdAtomFirmwareInfoQuery(atomBiosHandlePtr handle,
  94.                                                    AtomBiosRequestID func, AtomBiosArgPtr data);
  95. static AtomBiosResult rhdAtomConnectorInfo(atomBiosHandlePtr handle,
  96.              AtomBiosRequestID unused, AtomBiosArgPtr data);
  97. static AtomBiosResult rhdAtomOutputDeviceList(atomBiosHandlePtr handle,
  98.                                            AtomBiosRequestID unused, AtomBiosArgPtr data);
  99. static AtomBiosResult
  100. rhdAtomAnalogTVInfoQuery(atomBiosHandlePtr handle,
  101.                          AtomBiosRequestID func, AtomBiosArgPtr data);
  102. static AtomBiosResult
  103. rhdAtomGetConditionalGoldenSetting(atomBiosHandlePtr handle,
  104.                                    AtomBiosRequestID func, AtomBiosArgPtr data);
  105.  
  106. # ifdef ATOM_BIOS_PARSER
  107. static AtomBiosResult rhdAtomExec(atomBiosHandlePtr handle,
  108.                                    AtomBiosRequestID unused, AtomBiosArgPtr data);
  109. # endif
  110. static AtomBiosResult
  111. rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle,
  112.                               AtomBiosRequestID func, AtomBiosArgPtr data);
  113. static AtomBiosResult
  114. rhdAtomIntegratedSystemInfoQuery(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data);
  115. static AtomBiosResult
  116. atomSetRegisterListLocation(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data);
  117. static AtomBiosResult
  118. atomRestoreRegisters(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data);
  119.  
  120.  
  121. enum msgDataFormat {
  122.     MSG_FORMAT_NONE,
  123.     MSG_FORMAT_HEX,
  124.     MSG_FORMAT_DEC
  125. };
  126.  
  127. enum atomRegisterType {
  128.     atomRegisterMMIO,
  129.     atomRegisterMC,
  130.     atomRegisterPLL,
  131.     atomRegisterPCICFG
  132. };
  133.  
  134. struct atomBIOSRequests {
  135.     AtomBiosRequestID id;
  136.     AtomBiosRequestFunc request;
  137.     char *message;
  138.     enum msgDataFormat message_format;
  139. } AtomBiosRequestList [] = {
  140.     {ATOMBIOS_INIT,                     rhdAtomInit,
  141.      "AtomBIOS Init",                           MSG_FORMAT_NONE},
  142.     {ATOMBIOS_TEARDOWN,                 rhdAtomTearDown,
  143.      "AtomBIOS Teardown",                       MSG_FORMAT_NONE},
  144. # ifdef ATOM_BIOS_PARSER
  145.     {ATOMBIOS_EXEC,                     rhdAtomExec,
  146.      "AtomBIOS Exec",                           MSG_FORMAT_NONE},
  147. #endif
  148.     {ATOMBIOS_ALLOCATE_FB_SCRATCH,      rhdAtomAllocateFbScratch,
  149.      "AtomBIOS Set FB Space",                   MSG_FORMAT_NONE},
  150.     {ATOMBIOS_GET_CONNECTORS,           rhdAtomConnectorInfo,
  151.      "AtomBIOS Get Connectors",                 MSG_FORMAT_NONE},
  152.     {ATOMBIOS_GET_OUTPUT_DEVICE_LIST,   rhdAtomOutputDeviceList,
  153.      "AtomBIOS Get Output Info",                MSG_FORMAT_NONE},
  154.     {ATOMBIOS_GET_PANEL_MODE,           rhdAtomLvdsGetTimings,
  155.      "AtomBIOS Get Panel Mode",                 MSG_FORMAT_NONE},
  156.     {ATOMBIOS_GET_PANEL_EDID,           rhdAtomLvdsGetTimings,
  157.      "AtomBIOS Get Panel EDID",                 MSG_FORMAT_NONE},
  158.     {ATOMBIOS_GET_CODE_DATA_TABLE,      rhdAtomGetDataInCodeTable,
  159.      "AtomBIOS Get Datatable from Codetable",   MSG_FORMAT_NONE},
  160.     {GET_DEFAULT_ENGINE_CLOCK,          rhdAtomFirmwareInfoQuery,
  161.      "Default Engine Clock",                    MSG_FORMAT_DEC},
  162.     {GET_DEFAULT_MEMORY_CLOCK,          rhdAtomFirmwareInfoQuery,
  163.      "Default Memory Clock",                    MSG_FORMAT_DEC},
  164.     {GET_MAX_PIXEL_CLOCK_PLL_OUTPUT,    rhdAtomFirmwareInfoQuery,
  165.      "Maximum Pixel ClockPLL Frequency Output", MSG_FORMAT_DEC},
  166.     {GET_MIN_PIXEL_CLOCK_PLL_OUTPUT,    rhdAtomFirmwareInfoQuery,
  167.      "Minimum Pixel ClockPLL Frequency Output", MSG_FORMAT_DEC},
  168.     {GET_MAX_PIXEL_CLOCK_PLL_INPUT,     rhdAtomFirmwareInfoQuery,
  169.      "Maximum Pixel ClockPLL Frequency Input", MSG_FORMAT_DEC},
  170.     {GET_MIN_PIXEL_CLOCK_PLL_INPUT,     rhdAtomFirmwareInfoQuery,
  171.      "Minimum Pixel ClockPLL Frequency Input", MSG_FORMAT_DEC},
  172.     {GET_MAX_PIXEL_CLK,                 rhdAtomFirmwareInfoQuery,
  173.      "Maximum Pixel Clock",                     MSG_FORMAT_DEC},
  174.     {GET_REF_CLOCK,                     rhdAtomFirmwareInfoQuery,
  175.      "Reference Clock",                         MSG_FORMAT_DEC},
  176.     {GET_FW_FB_START,                   rhdAtomVramInfoQuery,
  177.       "Start of VRAM area used by Firmware",    MSG_FORMAT_HEX},
  178.     {GET_FW_FB_SIZE,                    rhdAtomVramInfoQuery,
  179.       "Framebuffer space used by Firmware (kb)", MSG_FORMAT_DEC},
  180.     {ATOM_TMDS_MAX_FREQUENCY,           rhdAtomTmdsInfoQuery,
  181.      "TMDS Max Frequency",                      MSG_FORMAT_DEC},
  182.     {ATOM_TMDS_PLL_CHARGE_PUMP,         rhdAtomTmdsInfoQuery,
  183.      "TMDS PLL ChargePump",                     MSG_FORMAT_DEC},
  184.     {ATOM_TMDS_PLL_DUTY_CYCLE,          rhdAtomTmdsInfoQuery,
  185.      "TMDS PLL DutyCycle",                      MSG_FORMAT_DEC},
  186.     {ATOM_TMDS_PLL_VCO_GAIN,            rhdAtomTmdsInfoQuery,
  187.      "TMDS PLL VCO Gain",                       MSG_FORMAT_DEC},
  188.     {ATOM_TMDS_PLL_VOLTAGE_SWING,       rhdAtomTmdsInfoQuery,
  189.      "TMDS PLL VoltageSwing",                   MSG_FORMAT_DEC},
  190.     {ATOM_LVDS_SUPPORTED_REFRESH_RATE,  rhdAtomLvdsInfoQuery,
  191.      "LVDS Supported Refresh Rate",             MSG_FORMAT_DEC},
  192.     {ATOM_LVDS_OFF_DELAY,               rhdAtomLvdsInfoQuery,
  193.      "LVDS Off Delay",                          MSG_FORMAT_DEC},
  194.     {ATOM_LVDS_SEQ_DIG_ONTO_DE,         rhdAtomLvdsInfoQuery,
  195.      "LVDS SEQ Dig onto DE",                    MSG_FORMAT_DEC},
  196.     {ATOM_LVDS_SEQ_DE_TO_BL,            rhdAtomLvdsInfoQuery,
  197.      "LVDS SEQ DE to BL",                       MSG_FORMAT_DEC},
  198.     {ATOM_LVDS_TEMPORAL_DITHER,         rhdAtomLvdsInfoQuery,
  199.      "LVDS Temporal Dither ",                   MSG_FORMAT_HEX},
  200.     {ATOM_LVDS_SPATIAL_DITHER,          rhdAtomLvdsInfoQuery,
  201.      "LVDS Spatial Dither ",                    MSG_FORMAT_HEX},
  202.     {ATOM_LVDS_DUALLINK,                rhdAtomLvdsInfoQuery,
  203.      "LVDS Duallink",                           MSG_FORMAT_HEX},
  204.     {ATOM_LVDS_GREYLVL,                 rhdAtomLvdsInfoQuery,
  205.      "LVDS Grey Level",                         MSG_FORMAT_HEX},
  206.     {ATOM_LVDS_FPDI,                    rhdAtomLvdsInfoQuery,
  207.      "LVDS FPDI",                               MSG_FORMAT_HEX},
  208.     {ATOM_LVDS_24BIT,                   rhdAtomLvdsInfoQuery,
  209.      "LVDS 24Bit",                              MSG_FORMAT_HEX},
  210.     {ATOM_GPIO_I2C_CLK_MASK,            rhdAtomGPIOI2CInfoQuery,
  211.      "GPIO_I2C_Clk_Mask",                       MSG_FORMAT_HEX},
  212.     {ATOM_GPIO_I2C_CLK_MASK_SHIFT,      rhdAtomGPIOI2CInfoQuery,
  213.      "GPIO_I2C_Clk_Mask_Shift",                 MSG_FORMAT_HEX},
  214.     {ATOM_GPIO_I2C_DATA_MASK,           rhdAtomGPIOI2CInfoQuery,
  215.      "GPIO_I2C_Data_Mask",                      MSG_FORMAT_HEX},
  216.     {ATOM_GPIO_I2C_DATA_MASK_SHIFT,     rhdAtomGPIOI2CInfoQuery,
  217.      "GPIO_I2C_Data_Mask_Shift",                MSG_FORMAT_HEX},
  218.     {ATOM_DAC1_BG_ADJ,          rhdAtomCompassionateDataQuery,
  219.      "DAC1 BG Adjustment",                      MSG_FORMAT_HEX},
  220.     {ATOM_DAC1_DAC_ADJ,         rhdAtomCompassionateDataQuery,
  221.      "DAC1 DAC Adjustment",                     MSG_FORMAT_HEX},
  222.     {ATOM_DAC1_FORCE,           rhdAtomCompassionateDataQuery,
  223.      "DAC1 Force Data",                         MSG_FORMAT_HEX},
  224.     {ATOM_DAC2_CRTC2_BG_ADJ,    rhdAtomCompassionateDataQuery,
  225.      "DAC2_CRTC2 BG Adjustment",                MSG_FORMAT_HEX},
  226.     {ATOM_DAC2_NTSC_BG_ADJ,     rhdAtomCompassionateDataQuery,
  227.      "DAC2_NTSC BG Adjustment",                 MSG_FORMAT_HEX},
  228.     {ATOM_DAC2_PAL_BG_ADJ,      rhdAtomCompassionateDataQuery,
  229.      "DAC2_PAL BG Adjustment",                  MSG_FORMAT_HEX},
  230.     {ATOM_DAC2_CV_BG_ADJ,       rhdAtomCompassionateDataQuery,
  231.      "DAC2_CV BG Adjustment",                   MSG_FORMAT_HEX},
  232.     {ATOM_DAC2_CRTC2_DAC_ADJ,   rhdAtomCompassionateDataQuery,
  233.      "DAC2_CRTC2 DAC Adjustment",               MSG_FORMAT_HEX},
  234.     {ATOM_DAC2_NTSC_DAC_ADJ,    rhdAtomCompassionateDataQuery,
  235.      "DAC2_NTSC DAC Adjustment",                MSG_FORMAT_HEX},
  236.     {ATOM_DAC2_PAL_DAC_ADJ,     rhdAtomCompassionateDataQuery,
  237.      "DAC2_PAL DAC Adjustment",                 MSG_FORMAT_HEX},
  238.     {ATOM_DAC2_CV_DAC_ADJ,      rhdAtomCompassionateDataQuery,
  239.      "DAC2_CV DAC Adjustment",                  MSG_FORMAT_HEX},
  240.     {ATOM_DAC2_CRTC2_FORCE,     rhdAtomCompassionateDataQuery,
  241.      "DAC2_CRTC2 Force",                        MSG_FORMAT_HEX},
  242.     {ATOM_DAC2_CRTC2_MUX_REG_IND,rhdAtomCompassionateDataQuery,
  243.      "DAC2_CRTC2 Mux Register Index",           MSG_FORMAT_HEX},
  244.     {ATOM_DAC2_CRTC2_MUX_REG_INFO,rhdAtomCompassionateDataQuery,
  245.      "DAC2_CRTC2 Mux Register Info",            MSG_FORMAT_HEX},
  246.     {ATOM_ANALOG_TV_MODE, rhdAtomAnalogTVInfoQuery,
  247.      "Analog TV Mode",                          MSG_FORMAT_NONE},
  248.     {ATOM_ANALOG_TV_DEFAULT_MODE, rhdAtomAnalogTVInfoQuery,
  249.      "Analog TV Default Mode",                  MSG_FORMAT_DEC},
  250.     {ATOM_ANALOG_TV_SUPPORTED_MODES, rhdAtomAnalogTVInfoQuery,
  251.      "Analog TV Supported Modes",               MSG_FORMAT_HEX},
  252.     {ATOM_GET_CONDITIONAL_GOLDEN_SETTINGS, rhdAtomGetConditionalGoldenSetting,
  253.      "Conditional Golden Setting",              MSG_FORMAT_NONE},
  254.     {ATOM_GET_PCIENB_CFG_REG7, rhdAtomIntegratedSystemInfoQuery,
  255.      "PCIE NB Cfg7Reg",                         MSG_FORMAT_HEX},
  256.     {ATOM_GET_CAPABILITY_FLAG, rhdAtomIntegratedSystemInfoQuery,
  257.      "CapabilityFlag",                          MSG_FORMAT_HEX},
  258.     {ATOM_GET_PCIE_LANES, rhdAtomIntegratedSystemInfoQuery,
  259.      "PCI Lanes",                               MSG_FORMAT_NONE},
  260.     {ATOM_SET_REGISTER_LIST_LOCATION, atomSetRegisterListLocation,
  261.      "Register List Location",                  MSG_FORMAT_NONE},
  262.     {ATOM_RESTORE_REGISTERS, atomRestoreRegisters,
  263.      "Restore Registers",                       MSG_FORMAT_NONE},
  264.     {FUNC_END,                                  NULL,
  265.      NULL,                                      MSG_FORMAT_NONE}
  266. };
  267.  
  268. /*
  269.  * This works around a bug in atombios.h where
  270.  * ATOM_MAX_SUPPORTED_DEVICE_INFO is specified incorrectly.
  271.  */
  272.  
  273. #define ATOM_MAX_SUPPORTED_DEVICE_INFO_HD (ATOM_DEVICE_RESERVEDF_INDEX+1)
  274. typedef struct _ATOM_SUPPORTED_DEVICES_INFO_HD
  275. {
  276.     ATOM_COMMON_TABLE_HEADER      sHeader;
  277.     USHORT                        usDeviceSupport;
  278.     ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_HD];
  279.     ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_HD];
  280. } ATOM_SUPPORTED_DEVICES_INFO_HD;
  281.  
  282. typedef struct _atomDataTables
  283. {
  284.     unsigned char                       *UtilityPipeLine;
  285.     ATOM_MULTIMEDIA_CAPABILITY_INFO     *MultimediaCapabilityInfo;
  286.     ATOM_MULTIMEDIA_CONFIG_INFO         *MultimediaConfigInfo;
  287.     ATOM_STANDARD_VESA_TIMING           *StandardVESA_Timing;
  288.     union {
  289.         void                            *base;
  290.         ATOM_FIRMWARE_INFO              *FirmwareInfo;
  291.         ATOM_FIRMWARE_INFO_V1_2         *FirmwareInfo_V_1_2;
  292.         ATOM_FIRMWARE_INFO_V1_3         *FirmwareInfo_V_1_3;
  293.         ATOM_FIRMWARE_INFO_V1_4         *FirmwareInfo_V_1_4;
  294.     } FirmwareInfo;
  295.     ATOM_DAC_INFO                       *DAC_Info;
  296.     union {
  297.         void                            *base;
  298.         ATOM_LVDS_INFO                  *LVDS_Info;
  299.         ATOM_LVDS_INFO_V12              *LVDS_Info_v12;
  300.     } LVDS_Info;
  301.     ATOM_TMDS_INFO                      *TMDS_Info;
  302.     ATOM_ANALOG_TV_INFO                 *AnalogTV_Info;
  303.     union {
  304.         void                            *base;
  305.         ATOM_SUPPORTED_DEVICES_INFO     *SupportedDevicesInfo;
  306.         ATOM_SUPPORTED_DEVICES_INFO_2   *SupportedDevicesInfo_2;
  307.         ATOM_SUPPORTED_DEVICES_INFO_2d1 *SupportedDevicesInfo_2d1;
  308.         ATOM_SUPPORTED_DEVICES_INFO_HD  *SupportedDevicesInfo_HD;
  309.     } SupportedDevicesInfo;
  310.     ATOM_GPIO_I2C_INFO                  *GPIO_I2C_Info;
  311.     ATOM_VRAM_USAGE_BY_FIRMWARE         *VRAM_UsageByFirmware;
  312.     ATOM_GPIO_PIN_LUT                   *GPIO_Pin_LUT;
  313.     ATOM_VESA_TO_INTENAL_MODE_LUT       *VESA_ToInternalModeLUT;
  314.     union {
  315.         void                            *base;
  316.         ATOM_COMPONENT_VIDEO_INFO       *ComponentVideoInfo;
  317.         ATOM_COMPONENT_VIDEO_INFO_V21   *ComponentVideoInfo_v21;
  318.     } ComponentVideoInfo;
  319. /**/unsigned char                       *PowerPlayInfo;
  320.     COMPASSIONATE_DATA                  *CompassionateData;
  321.     ATOM_DISPLAY_DEVICE_PRIORITY_INFO   *SaveRestoreInfo;
  322. /**/unsigned char                       *PPLL_SS_Info;
  323.     ATOM_OEM_INFO                       *OemInfo;
  324.     ATOM_XTMDS_INFO                     *XTMDS_Info;
  325.     ATOM_ASIC_MVDD_INFO                 *MclkSS_Info;
  326.     ATOM_OBJECT_HEADER                  *Object_Header;
  327.     INDIRECT_IO_ACCESS                  *IndirectIOAccess;
  328.     ATOM_MC_INIT_PARAM_TABLE            *MC_InitParameter;
  329. /**/unsigned char                       *ASIC_VDDC_Info;
  330.     ATOM_ASIC_INTERNAL_SS_INFO          *ASIC_InternalSS_Info;
  331. /**/unsigned char                       *TV_VideoMode;
  332.     union {
  333.         void                            *base;
  334.         ATOM_VRAM_INFO_V2               *VRAM_Info_v2;
  335.         ATOM_VRAM_INFO_V3               *VRAM_Info_v3;
  336.     } VRAM_Info;
  337.     ATOM_MEMORY_TRAINING_INFO           *MemoryTrainingInfo;
  338.     union {
  339.         void                            *base;
  340.         ATOM_INTEGRATED_SYSTEM_INFO     *IntegratedSystemInfo;
  341.         ATOM_INTEGRATED_SYSTEM_INFO_V2  *IntegratedSystemInfo_v2;
  342.     } IntegratedSystemInfo;
  343.     ATOM_ASIC_PROFILING_INFO            *ASIC_ProfilingInfo;
  344.     ATOM_VOLTAGE_OBJECT_INFO            *VoltageObjectInfo;
  345.     ATOM_POWER_SOURCE_INFO              *PowerSourceInfo;
  346. } atomDataTables, *atomDataTablesPtr;
  347.  
  348. struct atomSaveListRecord
  349. {
  350.     /* header */
  351.     int Length;
  352.     int Last;
  353.     struct atomRegisterList{
  354.         enum atomRegisterType Type;
  355.         CARD32 Address;
  356.         CARD32 Value;
  357.     } RegisterList[1];
  358. };
  359.  
  360. struct atomSaveListObject
  361. {
  362.     struct atomSaveListObject *next;
  363.     struct atomSaveListRecord **SaveList;
  364. };
  365.  
  366. typedef struct _atomBiosHandle {
  367.     int scrnIndex;
  368.     RHDPtr rhdPtr;
  369.     unsigned char *BIOSBase;
  370.     atomDataTablesPtr atomDataPtr;
  371.     pointer *scratchBase;
  372.     CARD32 fbBase;
  373.     PCITAG PciTag;
  374.     unsigned int BIOSImageSize;
  375.     unsigned char *codeTable;
  376.     struct atomSaveListRecord **SaveList;
  377.     struct atomSaveListObject *SaveListObjects;
  378. } atomBiosHandleRec;
  379.  
  380. enum {
  381.     legacyBIOSLocation = 0xC0000,
  382.     legacyBIOSMax = 0x10000
  383. };
  384.  
  385. struct atomConnectorInfoPrivate {
  386.     enum atomDevice *Devices;
  387. };
  388.  
  389. #  ifdef ATOM_BIOS_PARSER
  390.  
  391. #   define LOG_CAIL LOG_DEBUG + 1
  392.  
  393. static void
  394. atomDebugPrintPspace(atomBiosHandlePtr handle, AtomBiosArgPtr data, int size)
  395. {
  396.     CARD32 *pspace = (CARD32 *)data->exec.pspace;
  397.     int i = 0;
  398.  
  399.     size >>= 2;
  400.  
  401.     while (i++,size--)
  402.         RHDDebug(handle->scrnIndex, " Pspace[%2.2i]: 0x%8.8x\n", i, *(pspace++));
  403. }
  404.  
  405. /*
  406. #define va_start(v,l) __builtin_va_start(v,l)
  407. #define va_end(v)       __builtin_va_end(v)
  408. #define va_arg(v,l)     __builtin_va_arg(v,l)
  409. #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
  410. #define va_copy(d,s)    __builtin_va_copy(d,s)
  411. #endif
  412. #define __va_copy(d,s)  __builtin_va_copy(d,s)
  413.  
  414. typedef __builtin_va_list __gnuc_va_list;
  415. typedef __gnuc_va_list va_list;
  416.  
  417. #define arg(x) va_arg (ap, u32_t)
  418.  
  419. static void
  420. CailDebug(int scrnIndex, const char *format, ...)
  421. {
  422.     va_list ap;
  423.  
  424.     va_start(ap, format);
  425.     xf86VDrvMsgVerb(scrnIndex, X_INFO, LOG_CAIL, format, ap);
  426.     va_end(ap);
  427. }
  428. #   define CAILFUNC(ptr) \
  429.   CailDebug(((atomBiosHandlePtr)(ptr))->scrnIndex, "CAIL: %s\n", __func__)
  430. */
  431.  
  432. #  endif
  433.  
  434. #  define DEBUG_VERSION(index, handle, version) \
  435.     xf86DrvMsgVerb(handle->scrnIndex, X_INFO, 3, "%s returned version %i for index 0x%x\n" ,__func__,version.cref,index)
  436. #  define DEBUG_VERSION_NAME(index, handle, name, version)              \
  437.     xf86DrvMsgVerb(handle->scrnIndex, X_INFO, 3, "%s(%s) returned version %i for index 0x%x\n",\
  438.                    __func__,name,version.cref,index)
  439.  
  440. static int
  441. rhdAtomAnalyzeCommonHdr(ATOM_COMMON_TABLE_HEADER *hdr)
  442. {
  443.   if (hdr->usStructureSize == 0xaa55)
  444.     return FALSE;
  445.  
  446.   return TRUE;
  447. }
  448.  
  449. static int
  450. rhdAtomAnalyzeRomHdr(unsigned char *rombase,
  451.               ATOM_ROM_HEADER *hdr,
  452.                      unsigned int *data_offset, unsigned int *code_table)
  453. {
  454.     if (!rhdAtomAnalyzeCommonHdr(&hdr->sHeader)) {
  455.      return FALSE;
  456.   }
  457.     xf86DrvMsg(-1,X_NONE,"\tSubsystemVendorID: 0x%4.4x SubsystemID: 0x%4.4x\n",
  458.                hdr->usSubsystemVendorID,hdr->usSubsystemID);
  459.     xf86DrvMsg(-1,X_NONE,"\tIOBaseAddress: 0x%4.4x\n",hdr->usIoBaseAddress);
  460.     xf86DrvMsgVerb(-1,X_NONE,3,"\tFilename: %s\n",rombase + hdr->usConfigFilenameOffset);
  461.     xf86DrvMsgVerb(-1,X_NONE,3,"\tBIOS Bootup Message: %s\n",
  462.                    rombase + hdr->usBIOS_BootupMessageOffset);
  463.  
  464.   *data_offset = hdr->usMasterDataTableOffset;
  465.     *code_table = hdr->usMasterCommandTableOffset;
  466.  
  467.   return TRUE;
  468. }
  469.  
  470. static int
  471. rhdAtomAnalyzeRomDataTable(unsigned char *base, int offset,
  472.                     void *ptr,unsigned short *size)
  473. {
  474.     ATOM_COMMON_TABLE_HEADER *table = (ATOM_COMMON_TABLE_HEADER *)
  475.         (base + offset);
  476.  
  477.    if (!*size || !rhdAtomAnalyzeCommonHdr(table)) {
  478.     if (*size) *size -= 2;
  479.     *(void **)ptr = NULL;
  480.     return FALSE;
  481.   }
  482.   *size -= 2;
  483.   *(void **)ptr = (void *)(table);
  484.   return TRUE;
  485. }
  486.  
  487. static Bool
  488. rhdAtomGetTableRevisionAndSize(ATOM_COMMON_TABLE_HEADER *hdr,
  489.                                CARD8 *contentRev,
  490.                                CARD8 *formatRev,
  491.                                unsigned short *size)
  492. {
  493.     if (!hdr)
  494.         return FALSE;
  495.  
  496.     if (contentRev) *contentRev = hdr->ucTableContentRevision;
  497.     if (formatRev) *formatRev = hdr->ucTableFormatRevision;
  498.     if (size) *size = (short)hdr->usStructureSize
  499.                    - sizeof(ATOM_COMMON_TABLE_HEADER);
  500.  
  501.     return TRUE;
  502. }
  503.  
  504. static Bool
  505. rhdAtomGetCommandTableRevisionSize(atomBiosHandlePtr handle, int index,
  506.                                    CARD8 *contentRev, CARD8 *formatRev, unsigned short *size)
  507. {
  508.     unsigned short offset = ((USHORT *)&(((ATOM_MASTER_COMMAND_TABLE *)handle->codeTable)
  509.                                          ->ListOfCommandTables))[index];
  510.     ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *hdr = (ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *)(handle->BIOSBase + offset);
  511.     ATOM_COMMON_TABLE_HEADER hdr1 = hdr->CommonHeader;
  512.  
  513.     if (!offset) {
  514.         *contentRev = *formatRev = 0;
  515.         return FALSE;
  516.     }
  517.     return rhdAtomGetTableRevisionAndSize(&hdr1, contentRev, formatRev, size);
  518. }
  519.  
  520. static Bool
  521. rhdAtomAnalyzeMasterDataTable(unsigned char *base,
  522.                               ATOM_MASTER_DATA_TABLE *table,
  523.                               atomDataTablesPtr data)
  524. {
  525.     ATOM_MASTER_LIST_OF_DATA_TABLES *data_table =
  526.         &table->ListOfDataTables;
  527.     unsigned short size;
  528.  
  529.     if (!rhdAtomAnalyzeCommonHdr(&table->sHeader))
  530.         return FALSE;
  531.     if (!rhdAtomGetTableRevisionAndSize(&table->sHeader,NULL,NULL,
  532.                                         &size))
  533.         return FALSE;
  534. # define SET_DATA_TABLE(x) {\
  535.    rhdAtomAnalyzeRomDataTable(base,data_table->x,(void *)(&(data->x)),&size); \
  536.     }
  537.  
  538. # define SET_DATA_TABLE_VERS(x) {\
  539.    rhdAtomAnalyzeRomDataTable(base,data_table->x,&(data->x.base),&size); \
  540.     }
  541.  
  542.     SET_DATA_TABLE(UtilityPipeLine);
  543.     SET_DATA_TABLE(MultimediaCapabilityInfo);
  544.     SET_DATA_TABLE(MultimediaConfigInfo);
  545.     SET_DATA_TABLE(StandardVESA_Timing);
  546.     SET_DATA_TABLE_VERS(FirmwareInfo);
  547.     SET_DATA_TABLE(DAC_Info);
  548.     SET_DATA_TABLE_VERS(LVDS_Info);
  549.     SET_DATA_TABLE(TMDS_Info);
  550.     SET_DATA_TABLE(AnalogTV_Info);
  551.     SET_DATA_TABLE_VERS(SupportedDevicesInfo);
  552.     SET_DATA_TABLE(GPIO_I2C_Info);
  553.     SET_DATA_TABLE(VRAM_UsageByFirmware);
  554.     SET_DATA_TABLE(GPIO_Pin_LUT);
  555.     SET_DATA_TABLE(VESA_ToInternalModeLUT);
  556.     SET_DATA_TABLE_VERS(ComponentVideoInfo);
  557.     SET_DATA_TABLE(PowerPlayInfo);
  558.     SET_DATA_TABLE(CompassionateData);
  559.     SET_DATA_TABLE(SaveRestoreInfo);
  560.     SET_DATA_TABLE(PPLL_SS_Info);
  561.     SET_DATA_TABLE(OemInfo);
  562.     SET_DATA_TABLE(XTMDS_Info);
  563.     SET_DATA_TABLE(MclkSS_Info);
  564.     SET_DATA_TABLE(Object_Header);
  565.     SET_DATA_TABLE(IndirectIOAccess);
  566.     SET_DATA_TABLE(MC_InitParameter);
  567.     SET_DATA_TABLE(ASIC_VDDC_Info);
  568.     SET_DATA_TABLE(ASIC_InternalSS_Info);
  569.     SET_DATA_TABLE(TV_VideoMode);
  570.     SET_DATA_TABLE_VERS(VRAM_Info);
  571.     SET_DATA_TABLE(MemoryTrainingInfo);
  572.     SET_DATA_TABLE_VERS(IntegratedSystemInfo);
  573.     SET_DATA_TABLE(ASIC_ProfilingInfo);
  574.     SET_DATA_TABLE(VoltageObjectInfo);
  575.     SET_DATA_TABLE(PowerSourceInfo);
  576. # undef SET_DATA_TABLE
  577.  
  578.     return TRUE;
  579. }
  580.  
  581. static Bool
  582. rhdAtomGetTables(RHDPtr rhdPtr, unsigned char *base,
  583.                  atomDataTables *atomDataPtr, unsigned char **codeTablePtr,
  584.                  unsigned int BIOSImageSize)
  585. {
  586.   unsigned int  data_offset;
  587.     unsigned int  code_offset;
  588.     int scrnIndex=0;
  589.  
  590.   unsigned int atom_romhdr_off =  *(unsigned short*)
  591.         (base + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER);
  592.   ATOM_ROM_HEADER *atom_rom_hdr =
  593.         (ATOM_ROM_HEADER *)(base + atom_romhdr_off);
  594.  
  595.     RHDFUNCI(scrnIndex);
  596.  
  597.     if (atom_romhdr_off + sizeof(ATOM_ROM_HEADER) > BIOSImageSize) {
  598.         xf86DrvMsg(scrnIndex,X_ERROR,
  599.                    "%s: AtomROM header extends beyond BIOS image\n",__func__);
  600.     return FALSE;
  601.   }
  602.  
  603.     if (memcmp("ATOM",&atom_rom_hdr->uaFirmWareSignature,4)) {
  604.         xf86DrvMsg(scrnIndex,X_ERROR,"%s: No AtomBios signature found\n",
  605.                    __func__);
  606.     return FALSE;
  607.   }
  608.     xf86DrvMsg(scrnIndex, X_INFO, "ATOM BIOS Rom: \n");
  609.     if (!rhdAtomAnalyzeRomHdr(base, atom_rom_hdr, &data_offset, &code_offset)) {
  610.         xf86DrvMsg(scrnIndex, X_ERROR, "RomHeader invalid\n");
  611.      return FALSE;
  612.   }
  613.  
  614.     if (data_offset + sizeof (ATOM_MASTER_DATA_TABLE) > BIOSImageSize) {
  615.         xf86DrvMsg(scrnIndex,X_ERROR,"%s: Atom data table outside of BIOS\n",
  616.                    __func__);
  617.         return FALSE;
  618.   }
  619.  
  620.     if (code_offset + sizeof (ATOM_MASTER_COMMAND_TABLE) > BIOSImageSize) {
  621.         xf86DrvMsg(scrnIndex, X_ERROR, "%s: Atom command table outside of BIOS\n",
  622.                    __func__);
  623.         (*codeTablePtr) = NULL;
  624.     } else
  625.         (*codeTablePtr) = base + code_offset;
  626.  
  627.   if (!rhdAtomAnalyzeMasterDataTable(base, (ATOM_MASTER_DATA_TABLE *)
  628.                                        (base + data_offset),
  629.                                        atomDataPtr)) {
  630.         xf86DrvMsg(scrnIndex, X_ERROR, "%s: ROM Master Table invalid\n",
  631.                    __func__);
  632.     return FALSE;
  633.   }
  634.  
  635.   return TRUE;
  636. }
  637.  
  638. static Bool
  639. rhdAtomGetFbBaseAndSize(atomBiosHandlePtr handle, unsigned int *base,
  640.                         unsigned int *size)
  641. {
  642.   AtomBiosArgRec data;
  643.   if (RHDAtomBiosFunc(handle->rhdPtr, handle, GET_FW_FB_SIZE, &data)
  644.         == ATOM_SUCCESS) {
  645.         if (data.val == 0) {
  646.             xf86DrvMsg(handle->scrnIndex, X_WARNING, "%s: AtomBIOS specified VRAM "
  647.                        "scratch space size invalid\n", __func__);
  648.             return FALSE;
  649.         }
  650.         if (size)
  651.             *size = (int)data.val;
  652.     } else
  653.     return FALSE;
  654.     if (RHDAtomBiosFunc(handle->rhdPtr, handle, GET_FW_FB_START, &data)
  655.         == ATOM_SUCCESS) {
  656.     if (data.val == 0)
  657.             return FALSE;
  658.     if (base)
  659.             *base = (int)data.val;
  660.   }
  661.   return TRUE;
  662. }
  663.  
  664. /*
  665.  * Uses videoRam form ScrnInfoRec.
  666.  */
  667. static AtomBiosResult
  668. rhdAtomAllocateFbScratch(atomBiosHandlePtr handle,
  669.                          AtomBiosRequestID func, AtomBiosArgPtr data)
  670. {
  671.   unsigned int fb_base = 0;
  672.   unsigned int fb_size = 0;
  673.   unsigned int start = data->fb.start;
  674.   unsigned int size = data->fb.size;
  675.   handle->scratchBase = NULL;
  676.   handle->fbBase = 0;
  677.  
  678.     if (rhdAtomGetFbBaseAndSize(handle, &fb_base, &fb_size)) {
  679.         xf86DrvMsg(handle->scrnIndex, X_INFO, "AtomBIOS requests %ikB"
  680.                    " of VRAM scratch space\n",fb_size);
  681.     fb_size *= 1024; /* convert to bytes */
  682.         xf86DrvMsg(handle->scrnIndex, X_INFO, "AtomBIOS VRAM scratch base: 0x%x\n",
  683.                    fb_base);
  684.     } else {
  685.     fb_size = 20 * 1024;
  686.             xf86DrvMsg(handle->scrnIndex, X_INFO, " default to: %i\n",fb_size);
  687.   }
  688.     if (fb_base && fb_size && size) {
  689.         /* 4k align */
  690.     fb_size = (fb_size & ~(CARD32)0xfff) + ((fb_size & 0xfff) ? 1 : 0);
  691.         if ((fb_base + fb_size) > (start + size)) {
  692.             xf86DrvMsg(handle->scrnIndex, X_WARNING,
  693.                        "%s: FW FB scratch area %i (size: %i)"
  694.                        " extends beyond available framebuffer size %i\n",
  695.                        __func__, fb_base, fb_size, size);
  696.         } else if ((fb_base + fb_size) < (start + size)) {
  697.             xf86DrvMsg(handle->scrnIndex, X_WARNING,
  698.                        "%s: FW FB scratch area not located "
  699.                   "at the end of VRAM. Scratch End: "
  700.                   "0x%x VRAM End: 0x%x\n", __func__,
  701.                        (unsigned int)(fb_base + fb_size),
  702.                        size);
  703.         } else if (fb_base < start) {
  704.             xf86DrvMsg(handle->scrnIndex, X_WARNING,
  705.                        "%s: FW FB scratch area extends below "
  706.                     "the base of the free VRAM: 0x%x Base: 0x%x\n",
  707.                        __func__, (unsigned int)(fb_base), start);
  708.         } else {
  709.           size -= fb_size;
  710.           handle->fbBase = fb_base;
  711.             return ATOM_SUCCESS;
  712.         }
  713.     }
  714.  
  715.     if (!handle->fbBase) {
  716.         xf86DrvMsg(handle->scrnIndex, X_INFO,
  717.                    "Cannot get VRAM scratch space. "
  718.                    "Allocating in main memory instead\n");
  719.         handle->scratchBase = xcalloc(fb_size,1);
  720.         return ATOM_SUCCESS;
  721.     }
  722.     return ATOM_FAILED;
  723. }
  724.  
  725. # ifdef ATOM_BIOS_PARSER
  726. static Bool
  727. rhdAtomASICInit(atomBiosHandlePtr handle)
  728. {
  729.     ASIC_INIT_PS_ALLOCATION asicInit;
  730.     AtomBiosArgRec data;
  731.  
  732.     RHDFUNC(handle);
  733.  
  734.     RHDAtomBiosFunc(handle->rhdPtr, handle,
  735.                     GET_DEFAULT_ENGINE_CLOCK,
  736.                     &data);
  737.     asicInit.sASICInitClocks.ulDefaultEngineClock = data.val / 10;/*in 10 Khz*/
  738.     RHDAtomBiosFunc(handle->rhdPtr, handle,
  739.                     GET_DEFAULT_MEMORY_CLOCK,
  740.                     &data);
  741.     asicInit.sASICInitClocks.ulDefaultMemoryClock = data.val / 10;/*in 10 Khz*/
  742.     data.exec.dataSpace = NULL;
  743.     data.exec.index = GetIndexIntoMasterTable(COMMAND, ASIC_Init);
  744.     data.exec.pspace = &asicInit;
  745.  
  746.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling ASIC Init\n");
  747.     atomDebugPrintPspace(handle, &data, sizeof(asicInit));
  748.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  749.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  750.         xf86DrvMsg(handle->scrnIndex, X_INFO, "ASIC_INIT Successful\n");
  751.         return TRUE;
  752.     }
  753.     xf86DrvMsg(handle->scrnIndex, X_INFO, "ASIC_INIT Failed\n");
  754.     return FALSE;
  755. }
  756.  
  757. /*
  758.  *
  759.  */
  760. struct atomCodeTableVersion
  761. rhdAtomASICInitVersion(atomBiosHandlePtr handle)
  762. {
  763.     struct atomCodeTableVersion version;
  764.     int index = GetIndexIntoMasterTable(COMMAND, ASIC_Init);
  765.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  766.     return version;
  767. }
  768.  
  769. /*
  770.  *
  771.  */
  772. Bool
  773. rhdAtomSetScaler(atomBiosHandlePtr handle, enum atomScaler scalerID, enum atomScaleMode mode)
  774. {
  775.     ENABLE_SCALER_PARAMETERS scaler;
  776.     AtomBiosArgRec data;
  777.  
  778.     RHDFUNC(handle);
  779.  
  780.     switch (scalerID) {
  781.         case atomScaler1:
  782.             scaler.ucScaler = ATOM_SCALER1;
  783.             break;
  784.         case atomScaler2:
  785.             scaler.ucScaler = ATOM_SCALER2;
  786.             break;
  787.     }
  788.  
  789.     switch (mode) {
  790.         case atomScaleDisable:
  791.             scaler.ucEnable = ATOM_SCALER_DISABLE;
  792.             break;
  793.         case atomScaleCenter:
  794.             scaler.ucEnable = ATOM_SCALER_CENTER;
  795.             break;
  796.         case atomScaleExpand:
  797.             scaler.ucEnable = ATOM_SCALER_EXPANSION;
  798.             break;
  799.         case atomScaleMulttabExpand:
  800.             scaler.ucEnable = ATOM_SCALER_MULTI_EX;
  801.             break;
  802.     }
  803.  
  804.     data.exec.dataSpace = NULL;
  805.     data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
  806.     data.exec.pspace = &scaler;
  807.     atomDebugPrintPspace(handle, &data, sizeof(scaler));
  808.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling EnableScaler\n");
  809.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  810.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  811.         xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableScaler Successful\n");
  812.         return TRUE;
  813.     }
  814.     xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableScaler Failed\n");
  815.     return FALSE;
  816. }
  817.  
  818. /*
  819.  *
  820.  */
  821. struct atomCodeTableVersion
  822. rhdAtomSetScalerVersion(atomBiosHandlePtr handle)
  823. {
  824.     struct atomCodeTableVersion version;
  825.     int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
  826.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  827.     return version;
  828. }
  829.  
  830. /*
  831.  *
  832.  */
  833. Bool
  834. rhdAtomSetTVEncoder(atomBiosHandlePtr handle, Bool enable, int mode)
  835. {
  836.     TV_ENCODER_CONTROL_PS_ALLOCATION tvEncoder;
  837.     AtomBiosArgRec data;
  838.  
  839.     RHDFUNC(handle);
  840.  
  841.     tvEncoder.sTVEncoder.ucTvStandard = mode;
  842.     tvEncoder.sTVEncoder.ucAction = enable ? 1 :0;
  843.  
  844.     data.exec.dataSpace = NULL;
  845.     data.exec.pspace = &tvEncoder;
  846.     data.exec.index =  GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
  847.  
  848.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling SetTVEncoder\n");
  849.     atomDebugPrintPspace(handle, &data, sizeof(tvEncoder));
  850.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  851.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  852.         xf86DrvMsg(handle->scrnIndex, X_INFO, "SetTVEncoder Successful\n");
  853.         return TRUE;
  854.     }
  855.     xf86DrvMsg(handle->scrnIndex, X_INFO, "SetTVEncoder Failed\n");
  856.     return FALSE;
  857. }
  858.  
  859. /*
  860.  *
  861.  */
  862. #if (ATOM_TRANSMITTER_CONFIG_COHERENT != ATOM_TRANSMITTER_CONFIG_V2_COHERENT)
  863. # error
  864. #endif
  865.  
  866. Bool
  867. rhdAtomDigTransmitterControl(atomBiosHandlePtr handle, enum atomTransmitter id,
  868.                              enum atomTransmitterAction action, struct atomTransmitterConfig *config)
  869. {
  870.     DIG_TRANSMITTER_CONTROL_PARAMETERS Transmitter;
  871.     AtomBiosArgRec data;
  872.     char *name = NULL;
  873.     struct atomCodeTableVersion version;
  874.  
  875.     RHDFUNC(handle);
  876.  
  877.     switch (action) {
  878.         case atomTransDisable:
  879.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_DISABLE;
  880.             break;
  881.         case atomTransEnable:
  882.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
  883.             break;
  884.         case atomTransEnableOutput:
  885.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT;
  886.             break;
  887.         case atomTransDisableOutput:
  888.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT;
  889.             break;
  890.         case atomTransLcdBlOff:
  891.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_LCD_BLOFF;
  892.             break;
  893.         case atomTransLcdBlOn:
  894.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_LCD_BLON;
  895.             break;
  896.         case atomTransLcdBlBrightness:
  897.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL;
  898.             break;
  899.         case atomTransSetup:
  900.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_SETUP;
  901.             break;
  902.         case atomTransInit:
  903.             Transmitter.ucAction = ATOM_TRANSMITTER_ACTION_INIT;
  904.             break;
  905.     }
  906.  
  907.     Transmitter.ucConfig = 0;
  908.  
  909.     /* INIT is only called by ASIC_Init, for our actions this is always the PXLCLK */
  910.     switch (config->LinkCnt) {
  911.         case atomSingleLink:
  912.             Transmitter.usPixelClock = config->PixelClock * 4 / 10;
  913.             break;
  914.  
  915.         case atomDualLink:
  916.             Transmitter.usPixelClock = config->PixelClock * 2/ 10;
  917.             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
  918.             break;
  919.     }
  920.  
  921.     if (config->Coherent)
  922.         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
  923.  
  924.     switch (id) {
  925.         case atomTransmitterDIG1:
  926.         case atomTransmitterUNIPHY:
  927.         case atomTransmitterUNIPHY1:
  928.         case atomTransmitterUNIPHY2:
  929.         case atomTransmitterPCIEPHY:
  930.             data.exec.index =  GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
  931.             name = "UNIPHYTransmitterControl";
  932.  
  933.             rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version.cref, &version.fref, NULL);
  934.  
  935.             if (version.fref > 1 || version.cref > 2)
  936.                 return FALSE;
  937.  
  938.             switch (version.cref) {
  939.                 case 1:
  940.  
  941.             switch (config->Link) {
  942.                 case atomTransLinkA:
  943.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
  944.                     break;
  945.                 case atomTransLinkAB:
  946.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA_B;
  947.                     break;
  948.                 case atomTransLinkB:
  949.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
  950.                     break;
  951.                 case atomTransLinkBA:
  952.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB_A;
  953.                     break;
  954.             }
  955.             switch (config->Encoder) {
  956.                 case atomEncoderDIG1:
  957.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
  958.                     break;
  959.  
  960.                 case atomEncoderDIG2:
  961.                     Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
  962.                     break;
  963.                 default:
  964.                     xf86DrvMsg(handle->scrnIndex, X_ERROR,
  965.                                "%s called with invalid encoder %x for DIG transmitter\n",
  966.                                __func__, config->Encoder);
  967.                     return FALSE;
  968.             }
  969.             if (id == atomTransmitterPCIEPHY) {
  970.                 switch (config->Lanes) {
  971.                     case atomPCIELaneNONE:
  972.                         Transmitter.ucConfig |= 0;
  973.                         break;
  974.                     case atomPCIELane0_3:
  975.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
  976.                         break;
  977.                     case atomPCIELane0_7:
  978.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
  979.                         break;
  980.                     case atomPCIELane4_7:
  981.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
  982.                         break;
  983.                     case atomPCIELane8_11:
  984.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
  985.                         break;
  986.                     case atomPCIELane8_15:
  987.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
  988.                         break;
  989.                     case atomPCIELane12_15:
  990.                         Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
  991.                         break;
  992.                 }
  993.                 /* According to ATI this is the only one used so far */
  994.                 Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
  995.             }
  996.                     break;
  997.                 case 2:
  998.                     if (id == atomTransmitterPCIEPHY) {
  999.                         xf86DrvMsg(handle->scrnIndex, X_ERROR,
  1000.                                    "%s PCIPHY not valid for DCE 3.2\n",
  1001.                                    __func__);
  1002.                         return FALSE;
  1003.                     }
  1004.                     switch (config->Link) {
  1005.                         case atomTransLinkA:
  1006.                         case atomTransLinkAB:
  1007.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_LINKA;
  1008.                             break;
  1009.                         case atomTransLinkB:
  1010.                         case atomTransLinkBA:
  1011.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_LINKB;
  1012.                             break;
  1013.                         default:
  1014.                             xf86DrvMsg(handle->scrnIndex, X_ERROR,
  1015.                                        "%s called with invalid transmitter link selection %x for DIG transmitter\n",
  1016.                                        __func__, config->Link);
  1017.                             return FALSE;
  1018.                     }
  1019.                     switch (config->Encoder) {
  1020.                         case atomEncoderDIG1:
  1021.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER;
  1022.                             break;
  1023.                         case atomEncoderDIG2:
  1024.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER;
  1025.                             break;
  1026.                         default:
  1027.                             xf86DrvMsg(handle->scrnIndex, X_ERROR,
  1028.                                        "%s called with invalid encoder %x for DIG transmitter\n",
  1029.                                        __func__, config->Encoder);
  1030.                             return FALSE;
  1031.                     }
  1032.                     switch (id) {
  1033.                         case atomTransmitterUNIPHY:
  1034.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1;
  1035.                             break;
  1036.                         case atomTransmitterUNIPHY1:
  1037.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2;
  1038.                             break;
  1039.                         case atomTransmitterUNIPHY2:
  1040.                             Transmitter.ucConfig |= ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3;
  1041.                             break;
  1042.                         default:
  1043.                             break;
  1044.                     }
  1045.  
  1046.                     if (config->Mode == atomDP)
  1047.                         Transmitter.ucConfig |= ATOM_TRASMITTER_CONFIG_V2_DP_CONNECTOR;
  1048.                     break;
  1049.             }
  1050.  
  1051.             break;
  1052.  
  1053.         case atomTransmitterLVTMA:
  1054.         case atomTransmitterDIG2:
  1055.             data.exec.index =  GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
  1056.             name = "DIG2TransmitterControl";
  1057.             break;
  1058.     }
  1059.  
  1060.     data.exec.dataSpace = NULL;
  1061.     data.exec.pspace = &Transmitter;
  1062.  
  1063.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling %s\n",name);
  1064.     atomDebugPrintPspace(handle, &data, sizeof(Transmitter));
  1065.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  1066.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  1067.         xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Successful\n",name);
  1068.         return TRUE;
  1069.     }
  1070.     xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Failed\n",name);
  1071.     return FALSE;
  1072. }
  1073.  
  1074. /*
  1075.  *
  1076.  */
  1077. struct atomCodeTableVersion
  1078. rhdAtomDigTransmitterControlVersion(atomBiosHandlePtr handle)
  1079. {
  1080.     struct atomCodeTableVersion version;
  1081.     int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
  1082.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  1083.     DEBUG_VERSION(index, handle, version);
  1084.     return version;
  1085. }
  1086.  
  1087. /*
  1088.  *
  1089.  */
  1090. Bool
  1091. rhdAtomOutputControl(atomBiosHandlePtr handle, enum atomOutput OutputId, enum atomOutputAction Action)
  1092. {
  1093.     AtomBiosArgRec data;
  1094.     CARD8 version;
  1095.     char *name;
  1096.  
  1097.     union
  1098.     {
  1099.         DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS op;
  1100.         DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION opa;
  1101.     } ps;
  1102.  
  1103.     RHDFUNC(handle);
  1104.  
  1105.     switch (Action) {
  1106.         case atomOutputEnable:
  1107.             ps.op.ucAction = ATOM_ENABLE;
  1108.             break;
  1109.         case atomOutputDisable:
  1110.             ps.op.ucAction = ATOM_DISABLE;
  1111.             break;
  1112.         default: /* handle below */
  1113.             if (OutputId != atomLCDOutput)
  1114.                 return FALSE;
  1115.     }
  1116.  
  1117.     switch (OutputId) {
  1118.         case atomDVOOutput:
  1119.             data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
  1120.             name = "DVOOutputControl";
  1121.             if (!rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version, NULL, NULL))
  1122.                 return FALSE;
  1123.             switch  (version) {
  1124.                 case 1:
  1125.                 case 2:
  1126.                     break;
  1127.                 case 3:      /* For now. This needs to be treated like DIGTransmitterControl. @@@ */
  1128.                     return FALSE;
  1129.             }
  1130.             break;
  1131.         case atomLCDOutput:
  1132.             data.exec.index = GetIndexIntoMasterTable(COMMAND,  LCD1OutputControl);
  1133.             name = "LCD1OutputControl";
  1134.             switch (Action) {
  1135.                 case atomOutputEnable:
  1136.                 case atomOutputDisable:
  1137.                     break;
  1138.                 case atomOutputLcdOn:
  1139.                     ps.op.ucAction = ATOM_LCD_BLON;
  1140.                     break;
  1141.                 case atomOutputLcdOff:
  1142.                     ps.op.ucAction = ATOM_LCD_BLOFF;
  1143.                     break;
  1144.                 case atomOutputLcdBrightnessControl:
  1145.                     ps.op.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL;
  1146.                     break;
  1147.                 case atomOutputLcdSelftestStart:
  1148.                     ps.op.ucAction = ATOM_LCD_SELFTEST_START;
  1149.                     break;
  1150.                 case atomOutputLcdSelftestStop:
  1151.                     ps.op.ucAction = ATOM_LCD_SELFTEST_STOP;
  1152.                     break;
  1153.                 case atomOutputEncoderInit:
  1154.                     ps.op.ucAction = ATOM_ENCODER_INIT;
  1155.                     break;
  1156.                 default:
  1157.                     return FALSE;
  1158.             }
  1159.             break;
  1160.         case atomCVOutput:
  1161.             data.exec.index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
  1162.             name = "CV1OutputControl";
  1163.             break;
  1164.         case atomTVOutput:
  1165.             name = "TV1OutputControl";
  1166.             data.exec.index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
  1167.             break;
  1168.         case atomLVTMAOutput:
  1169.             name = "LVTMAOutputControl";
  1170.             data.exec.index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
  1171.             switch (Action) {
  1172.                 case atomOutputEnable:
  1173.                 case atomOutputDisable:
  1174.                     break;
  1175.                 case atomOutputLcdOn:
  1176.                     ps.op.ucAction = ATOM_LCD_BLON;
  1177.                     break;
  1178.                 case atomOutputLcdOff:
  1179.                     ps.op.ucAction = ATOM_LCD_BLOFF;
  1180.                     break;
  1181.                 case atomOutputLcdBrightnessControl:
  1182.                     ps.op.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL;
  1183.                     break;
  1184.                 case atomOutputLcdSelftestStart:
  1185.                     ps.op.ucAction = ATOM_LCD_SELFTEST_START;
  1186.                     break;
  1187.                 case atomOutputLcdSelftestStop:
  1188.                     ps.op.ucAction = ATOM_LCD_SELFTEST_STOP;
  1189.                     break;
  1190.                 case atomOutputEncoderInit:
  1191.                     ps.op.ucAction = ATOM_ENCODER_INIT;
  1192.                     break;
  1193.                 default:
  1194.                     return FALSE;
  1195.             }
  1196.             break;
  1197.         case atomTMDSAOutput:
  1198.             name = "TMDSAOutputControl";
  1199.             data.exec.index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
  1200.             break;
  1201.         case atomDAC1Output:
  1202.             name = "DAC1OutputControl";
  1203.             data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
  1204.             break;
  1205.         case atomDAC2Output:
  1206.             name = "DAC2OutputControl";
  1207.             data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
  1208.             break;
  1209.         default:
  1210.             return FALSE;
  1211.     }
  1212.  
  1213.     data.exec.dataSpace = NULL;
  1214.     data.exec.pspace = &ps;
  1215.  
  1216.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling %s\n",name);
  1217.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  1218.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  1219.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  1220.         xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Successful\n",name);
  1221.         return TRUE;
  1222.     }
  1223.     xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Failed\n",name);
  1224.  
  1225.     return FALSE;
  1226. }
  1227.  
  1228. /*
  1229.  *
  1230.  */
  1231. struct atomCodeTableVersion
  1232. rhdAtomOutputControlVersion(atomBiosHandlePtr handle, enum atomOutput OutputId)
  1233. {
  1234.     struct atomCodeTableVersion version = {0 , 0};
  1235.     int index;
  1236.     char *name;
  1237.  
  1238.     switch (OutputId) {
  1239.         case atomDVOOutput:
  1240.             index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
  1241.             name = "DVOOutputControl";
  1242.             break;
  1243.         case atomLCDOutput:
  1244.             index = GetIndexIntoMasterTable(COMMAND,  LCD1OutputControl);
  1245.             name = "LCD1OutputControl";
  1246.             break;
  1247.         case atomCVOutput:
  1248.             index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
  1249.             name = "CV1OutputControl";
  1250.             break;
  1251.         case atomTVOutput:
  1252.             index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
  1253.             name = "TV1OutputControl";
  1254.             break;
  1255.         case atomLVTMAOutput:
  1256.             index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
  1257.             name = "LVTMAOutputControl";
  1258.             break;
  1259.         case atomTMDSAOutput:
  1260.             index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
  1261.             name = "TMDSAOutputControl";
  1262.             break;
  1263.         case atomDAC1Output:
  1264.             index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
  1265.             name = "DAC1OutputControl";
  1266.             break;
  1267.         case atomDAC2Output:
  1268.             index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
  1269.             name = "DAC2OutputContro";
  1270.             break;
  1271.         default:
  1272.             return version;
  1273.     }
  1274.  
  1275.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  1276.     DEBUG_VERSION_NAME(index, handle, name, version);
  1277.     return version;
  1278. }
  1279.  
  1280. /*
  1281.  *
  1282.  */
  1283. Bool
  1284. AtomDACLoadDetection(atomBiosHandlePtr handle, enum atomDevice Device, enum atomDAC dac)
  1285. {
  1286.     AtomBiosArgRec data;
  1287.     union
  1288.     {
  1289.         DAC_LOAD_DETECTION_PARAMETERS ld;
  1290.         DAC_LOAD_DETECTION_PS_ALLOCATION lda;
  1291.     } ps;
  1292.  
  1293.     RHDFUNC(handle);
  1294.  
  1295.     data.exec.dataSpace = NULL;
  1296.     data.exec.pspace = &ps;
  1297.     data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
  1298.     ps.ld.ucMisc = 0;
  1299.  
  1300.     switch (Device) {
  1301.         case atomCRT1:
  1302.             ps.ld.usDeviceID = ATOM_DEVICE_CRT1_SUPPORT;
  1303.             break;
  1304.         case atomCRT2:
  1305.             ps.ld.usDeviceID = ATOM_DEVICE_CRT2_SUPPORT;
  1306.             break;
  1307.         case atomTV1:
  1308.             ps.ld.usDeviceID = ATOM_DEVICE_TV1_SUPPORT;
  1309.             ps.ld.ucMisc = DAC_LOAD_MISC_YPrPb;
  1310.             break;
  1311.         case atomTV2:
  1312.             ps.ld.usDeviceID = ATOM_DEVICE_TV2_SUPPORT;
  1313.             ps.ld.ucMisc = DAC_LOAD_MISC_YPrPb;
  1314.             break;
  1315.         case atomCV:
  1316.             ps.ld.usDeviceID = ATOM_DEVICE_CV_SUPPORT;
  1317.             break;
  1318.         case atomLCD1:
  1319.         case atomDFP1:
  1320.         case atomLCD2:
  1321.         case atomDFP2:
  1322.         case atomDFP3:
  1323.         case atomDFP4:
  1324.         case atomDFP5:
  1325.         case atomNone:
  1326.             xf86DrvMsg(handle->scrnIndex, X_ERROR, "Unsupported device for load detection.\n");
  1327.             return FALSE;
  1328.     }
  1329.     switch (dac) {
  1330.         case atomDACA:
  1331.             ps.ld.ucDacType = ATOM_DAC_A;
  1332.             break;
  1333.         case atomDACB:
  1334.             ps.ld.ucDacType = ATOM_DAC_B;
  1335.             break;
  1336.         case atomDACExt:
  1337.             ps.ld.ucDacType = ATOM_EXT_DAC;
  1338.             break;
  1339.     }
  1340.  
  1341.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling DAC_LoadDetection\n");
  1342.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  1343.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  1344.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  1345.         xf86DrvMsg(handle->scrnIndex, X_INFO, "DAC_LoadDetection Successful\n");
  1346.         return TRUE;
  1347.     }
  1348.     xf86DrvMsg(handle->scrnIndex, X_INFO, "DAC_LoadDetection Failed\n");
  1349.  
  1350.     return FALSE;
  1351. }
  1352.  
  1353. /*
  1354.  *
  1355.  */
  1356. struct atomCodeTableVersion
  1357. AtomDACLoadDetectionVersion(atomBiosHandlePtr handle, enum atomDevice id)
  1358. {
  1359.     struct atomCodeTableVersion version;
  1360.     int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
  1361.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  1362.  
  1363.     DEBUG_VERSION(index, handle, version);
  1364.  
  1365.     return version;
  1366. }
  1367.  
  1368. /*
  1369.  *
  1370.  */
  1371. Bool
  1372. rhdAtomEncoderControl(atomBiosHandlePtr handle, enum atomEncoder EncoderId,
  1373.                              enum atomEncoderAction Action, struct atomEncoderConfig *Config)
  1374. {
  1375.     AtomBiosArgRec data;
  1376.     char *name = NULL;
  1377.     CARD8 version;
  1378.  
  1379.     union
  1380.     {
  1381.         DAC_ENCODER_CONTROL_PARAMETERS dac;
  1382.         DAC_ENCODER_CONTROL_PS_ALLOCATION dac_a;
  1383.         TV_ENCODER_CONTROL_PARAMETERS tv;
  1384.         TV_ENCODER_CONTROL_PS_ALLOCATION tv_a;
  1385.         LVDS_ENCODER_CONTROL_PARAMETERS lvds;
  1386.         LVDS_ENCODER_CONTROL_PS_ALLOCATION lvds_a;
  1387.         DIG_ENCODER_CONTROL_PARAMETERS dig;
  1388.         DIG_ENCODER_CONTROL_PS_ALLOCATION dig_a;
  1389.         EXTERNAL_ENCODER_CONTROL_PARAMETER ext;
  1390.         EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION ext_a;
  1391.         DVO_ENCODER_CONTROL_PARAMETERS dvo;
  1392.         DVO_ENCODER_CONTROL_PS_ALLOCATION dvo_a;
  1393.         DVO_ENCODER_CONTROL_PARAMETERS_V3 dvo_v3;
  1394.         DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3_a;
  1395.         LVDS_ENCODER_CONTROL_PARAMETERS_V2 lvdsv2;
  1396.         LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 lvds2_a;
  1397.         USHORT usPixelClock;
  1398.     } ps;
  1399.  
  1400.     RHDFUNC(handle);
  1401.  
  1402.     ps.usPixelClock = Config->PixelClock / 10;
  1403.  
  1404.     switch (EncoderId) {
  1405.         case atomEncoderDACA:
  1406.         case atomEncoderDACB:
  1407.             if (EncoderId == atomEncoderDACA) {
  1408.                 name = "DACAEncoderControl";
  1409.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
  1410.             } else {
  1411.                 name = "DACBEncoderControl";
  1412.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
  1413.             }
  1414.             {
  1415.                 DAC_ENCODER_CONTROL_PARAMETERS *dac = &ps.dac;
  1416.                 switch (Config->u.dac.DacStandard) {
  1417.                     case atomDAC_VGA:
  1418.                         dac->ucDacStandard = ATOM_DAC1_PS2;
  1419.                         break;
  1420.                     case atomDAC_CV:
  1421.                         dac->ucDacStandard = ATOM_DAC1_CV;
  1422.                         break;
  1423.                     case atomDAC_NTSC:
  1424.                         dac->ucDacStandard = ATOM_DAC1_NTSC;
  1425.                         break;
  1426.                     case atomDAC_PAL:
  1427.                         dac->ucDacStandard = ATOM_DAC1_PAL;
  1428.                         break;
  1429.                 }
  1430.                 switch (Action) {
  1431.                     case atomEncoderOn:
  1432.                         dac->ucAction = ATOM_ENABLE;
  1433.                         break;
  1434.                     case atomEncoderOff:
  1435.                         dac->ucAction = ATOM_DISABLE;
  1436.                         break;
  1437.                     default:
  1438.                         xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: DAC unknown action\n",__func__);
  1439.                         return FALSE;
  1440.                 }
  1441.             }
  1442.             break;
  1443.         case atomEncoderTV:
  1444.             data.exec.index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
  1445.             name = "TVAEncoderControl";
  1446.             {
  1447.                 TV_ENCODER_CONTROL_PARAMETERS *tv = &ps.tv;
  1448.                 switch (Config->u.tv.TvStandard) {
  1449.                     case RHD_TV_NTSC:
  1450.                         tv->ucTvStandard = ATOM_TV_NTSC;
  1451.                         break;
  1452.                     case RHD_TV_NTSCJ:
  1453.                         tv->ucTvStandard = ATOM_TV_NTSCJ;
  1454.                         break;
  1455.                     case RHD_TV_PAL:
  1456.                         tv->ucTvStandard = ATOM_TV_PAL;
  1457.                         break;
  1458.                     case RHD_TV_PALM:
  1459.                         tv->ucTvStandard = ATOM_TV_PALM;
  1460.                         break;
  1461.                     case RHD_TV_PALCN:
  1462.                         tv->ucTvStandard = ATOM_TV_PALCN;
  1463.                         break;
  1464.                     case RHD_TV_PALN:
  1465.                         tv->ucTvStandard = ATOM_TV_PALN;
  1466.                         break;
  1467.                     case RHD_TV_PAL60:
  1468.                         tv->ucTvStandard = ATOM_TV_PAL60;
  1469.                         break;
  1470.                     case RHD_TV_SECAM:
  1471.                         tv->ucTvStandard = ATOM_TV_SECAM;
  1472.                         break;
  1473.                     case RHD_TV_CV:
  1474.                         tv->ucTvStandard = ATOM_TV_CV;
  1475.                         break;
  1476.                     case RHD_TV_NONE:
  1477.                         return FALSE;
  1478.                 }
  1479.                 switch (Action) {
  1480.                     case atomEncoderOn:
  1481.                         tv->ucAction = ATOM_ENABLE;
  1482.                         break;
  1483.                     case atomEncoderOff:
  1484.                         tv->ucAction = ATOM_DISABLE;
  1485.                         break;
  1486.                     default:
  1487.                         xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: TV unknown action\n",__func__);
  1488.                         return FALSE;
  1489.                 }
  1490.             }
  1491.             break;
  1492.         case atomEncoderTMDS1:
  1493.         case atomEncoderTMDS2:
  1494.         case atomEncoderLVDS:
  1495.             if (EncoderId == atomEncoderLVDS) {
  1496.                 name = "LVDSEncoderControl";
  1497.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
  1498.             } else if (EncoderId == atomEncoderTMDS1) {
  1499.                 name = "TMDSAEncoderControl";
  1500.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, TMDSAEncoderControl);
  1501.             } else {
  1502.                 name = "LVTMAEncoderControl";
  1503.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, LVTMAEncoderControl);
  1504.             }
  1505.             if (!rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version, NULL, NULL))
  1506.                 return FALSE;
  1507.             switch  (version) {
  1508.                 case 1:
  1509.                 {
  1510.                     LVDS_ENCODER_CONTROL_PARAMETERS *lvds = &ps.lvds;
  1511.                     lvds->ucMisc = 0;
  1512.                     if (Config->u.lvds.LinkCnt == atomDualLink)
  1513.                         lvds->ucMisc |= 0x1;
  1514.                     if (Config->u.lvds.Is24bit)
  1515.                         lvds->ucMisc |= 0x1 << 1;
  1516.  
  1517.                     switch (Action) {
  1518.                         case atomEncoderOn:
  1519.                             lvds->ucAction = ATOM_ENABLE;
  1520.                             break;
  1521.                         case atomEncoderOff:
  1522.                             lvds->ucAction = ATOM_DISABLE;
  1523.                             break;
  1524.                         default:
  1525.                             xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: LVDS unknown action\n",__func__);
  1526.                             return FALSE;
  1527.                     }
  1528.                     break;
  1529.                 }
  1530.                 case 2:
  1531.                 case 3:
  1532.                 {
  1533.                     LVDS_ENCODER_CONTROL_PARAMETERS_V2 *lvds = &ps.lvdsv2;
  1534.  
  1535.                     lvds->ucMisc = 0;
  1536.                     if (Config->u.lvds2.LinkCnt == atomDualLink)
  1537.                         lvds->ucMisc |= PANEL_ENCODER_MISC_DUAL;
  1538.                     if (Config->u.lvds2.Coherent)
  1539.                         lvds->ucMisc |= PANEL_ENCODER_MISC_COHERENT;
  1540.                     if (Config->u.lvds2.LinkB)
  1541.                         lvds->ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
  1542.                     if (Config->u.lvds2.Hdmi)
  1543.                         lvds->ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
  1544.                     lvds->ucTruncate = 0;
  1545.                     lvds->ucSpatial = 0;
  1546.                     lvds->ucTemporal = 0;
  1547.                     lvds->ucFRC = 0;
  1548.  
  1549.                     if (EncoderId == atomEncoderLVDS) {
  1550.                         if (Config->u.lvds2.Is24bit) {
  1551.                             lvds->ucTruncate |= PANEL_ENCODER_TRUNCATE_DEPTH;
  1552.                             lvds->ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
  1553.                             lvds->ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
  1554.                         }
  1555.                         switch (Config->u.lvds2.TemporalGrey) {
  1556.                             case atomTemporalDither0:
  1557.                                 break;
  1558.                             case atomTemporalDither4:
  1559.                                 lvds->ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
  1560.                             case atomTemporalDither2:
  1561.                                 lvds->ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_EN;
  1562.                                 break;
  1563.                         }
  1564.                         switch (Config->u.lvds2.SpatialDither)
  1565.                             lvds->ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_EN;
  1566.                     }
  1567.  
  1568.                     switch (Action) {
  1569.                         case atomEncoderOn:
  1570.                             lvds->ucAction = ATOM_ENABLE;
  1571.                             break;
  1572.                         case atomEncoderOff:
  1573.                             lvds->ucAction = ATOM_DISABLE;
  1574.                             break;
  1575.                         default:
  1576.                             xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: LVDS2 unknown action\n",__func__);
  1577.                             return FALSE;
  1578.                     }
  1579.                     break;
  1580.                 }
  1581.                 default:
  1582.                     xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: LVDS unknown version\n",__func__);
  1583.                     return FALSE;
  1584.             }
  1585.             break;
  1586.         case atomEncoderDIG1:
  1587.         case atomEncoderDIG2:
  1588.         case atomEncoderExternal:
  1589.         {
  1590.             DIG_ENCODER_CONTROL_PARAMETERS *dig = &ps.dig;
  1591.             struct atomCodeTableVersion version;
  1592.  
  1593.             if (EncoderId == atomEncoderDIG1) {
  1594.                 name = "DIG1EncoderControl";
  1595.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
  1596.             } else if (EncoderId == atomEncoderDIG2) {
  1597.                 name = "DIG2EncoderControl";
  1598.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
  1599.             } else {
  1600.                 name = "ExternalEncoderControl";
  1601.                 data.exec.index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
  1602.             }
  1603.             rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version.cref, &version.fref, NULL);
  1604.             if (version.fref > 1 || version.cref > 2)
  1605.                 return FALSE;
  1606.  
  1607.             dig->ucConfig = 0;
  1608.             switch (version.cref) {
  1609.                 case 1:
  1610.             switch (Config->u.dig.Link) {
  1611.                 case atomTransLinkA:
  1612.                     dig->ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
  1613.                     break;
  1614.                 case atomTransLinkAB:
  1615.                     dig->ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
  1616.                     break;
  1617.                 case atomTransLinkB:
  1618.                     dig->ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
  1619.                     break;
  1620.                 case atomTransLinkBA:
  1621.                     dig->ucConfig |= ATOM_ENCODER_CONFIG_LINKB_A;
  1622.                     break;
  1623.             }
  1624.  
  1625.             if (EncoderId != atomEncoderExternal) {
  1626.                 switch (Config->u.dig.Transmitter) {
  1627.                     case atomTransmitterUNIPHY:
  1628.                     case atomTransmitterPCIEPHY:
  1629.                     case atomTransmitterDIG1:
  1630.                         dig->ucConfig |= ATOM_ENCODER_CONFIG_UNIPHY;
  1631.                         break;
  1632.                     case atomTransmitterLVTMA:
  1633.                     case atomTransmitterDIG2:
  1634.                         dig->ucConfig |= ATOM_ENCODER_CONFIG_LVTMA;
  1635.                         break;
  1636.                         /*
  1637.                          * these are not DCE3.0 but we need them here as DIGxEncoderControl tables for
  1638.                          * DCE3.2 still report cref 1.
  1639.                          */
  1640.                             case atomTransmitterUNIPHY1:
  1641.                                 dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
  1642.                                 break;
  1643.                             case atomTransmitterUNIPHY2:
  1644.                                 dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
  1645.                                 break;
  1646.                             default:
  1647.                                 xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: Invalid Transmitter for DCE3.0: %x\n",
  1648.                                            __func__, Config->u.dig.Transmitter);
  1649.                                 return FALSE;
  1650.                         }
  1651.                     }
  1652.                     break;
  1653.  
  1654.                 case 2:
  1655.                     switch (Config->u.dig.Link) {
  1656.                         case atomTransLinkA:
  1657.                         case atomTransLinkAB:
  1658.                             dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_LINKA;
  1659.                             break;
  1660.                         case atomTransLinkB:
  1661.                         case atomTransLinkBA:
  1662.                             dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_LINKB;
  1663.                             break;
  1664.                     }
  1665.                     switch (Config->u.dig.Transmitter) {
  1666.                         case atomTransmitterUNIPHY:
  1667.                             dig->ucConfig |= ATOM_ENCODER_CONFIG_UNIPHY;
  1668.                             break;
  1669.                         case atomTransmitterUNIPHY1:
  1670.                             dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
  1671.                             break;
  1672.                         case atomTransmitterUNIPHY2:
  1673.                             dig->ucConfig |= ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
  1674.                             break;
  1675.                         default:
  1676.                             xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: Invalid Encoder for DCE3.2: %x\n",
  1677.                                        __func__, Config->u.dig.Transmitter);
  1678.                             return FALSE;
  1679.                 }
  1680.                     break;
  1681.  
  1682.                 default:
  1683.                     return FALSE;
  1684.             }
  1685.  
  1686.             switch (Config->u.dig.EncoderMode) {
  1687.                 case atomDVI:
  1688.                     dig->ucEncoderMode = ATOM_ENCODER_MODE_DVI;
  1689.                     break;
  1690.                 case atomDP:
  1691.                     dig->ucEncoderMode = ATOM_ENCODER_MODE_DP;
  1692.                     break;
  1693.                 case atomLVDS:
  1694.                     dig->ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
  1695.                     break;
  1696.                 case atomHDMI:
  1697.                     dig->ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
  1698.                     break;
  1699.                 case atomSDVO:
  1700.                     dig->ucEncoderMode = ATOM_ENCODER_MODE_SDVO;
  1701.                     break;
  1702.                 case atomNoEncoder:
  1703.                 case atomTVComposite:
  1704.                 case atomTVSVideo:
  1705.                 case atomTVComponent:
  1706.                 case atomCRT:
  1707.                     xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s called with invalid DIG encoder mode %i\n",
  1708.                                __func__,Config->u.dig.EncoderMode);
  1709.                     return FALSE;
  1710.                     break;
  1711.             }
  1712.  
  1713.             switch (Action) {
  1714.                 case atomEncoderOn:
  1715.                     dig->ucAction = ATOM_ENABLE;
  1716.                     break;
  1717.                 case atomEncoderOff:
  1718.                     dig->ucAction = ATOM_DISABLE;
  1719.                     break;
  1720.                 default:
  1721.                     xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: DIG unknown action\n",__func__);
  1722.                     return FALSE;
  1723.             }
  1724.  
  1725.             switch (Config->u.dig.LinkCnt) {
  1726.                 case atomSingleLink:
  1727.                     dig->ucLaneNum = 4;
  1728.                     break;
  1729.                 case atomDualLink:
  1730.                     dig->ucLaneNum = 8;
  1731.                     break;
  1732.             }
  1733.             break;
  1734.         case atomEncoderDVO:
  1735.             name = "DVOEncoderControl";
  1736.             data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
  1737.             if (!rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version.cref, NULL, NULL))
  1738.                 return FALSE;
  1739.             switch  (version.cref) {
  1740.                 case 1:
  1741.                 case 2:
  1742.                 {
  1743.                     DVO_ENCODER_CONTROL_PARAMETERS *dvo = &ps.dvo;
  1744.                     dvo->usEncoderID = Config->u.dvo.EncoderID;
  1745.                     switch (Config->u.dvo.DvoDeviceType) {
  1746.                         case atomLCD1:
  1747.                         case atomLCD2:
  1748.                             dvo->ucDeviceType = ATOM_DEVICE_LCD1_INDEX;
  1749.                             break;
  1750.                         case atomCRT1:
  1751.                         case atomCRT2:
  1752.                             dvo->ucDeviceType = ATOM_DEVICE_CRT1_INDEX;
  1753.                             break;
  1754.                         case atomDFP1:
  1755.                         case atomDFP2:
  1756.                         case atomDFP3:
  1757.                         case atomDFP4:
  1758.                         case atomDFP5:
  1759.                             dvo->ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
  1760.                             break;
  1761.                         case atomTV1:
  1762.                         case atomTV2:
  1763.                             dvo->ucDeviceType = ATOM_DEVICE_TV1_INDEX;
  1764.                             break;
  1765.                         case atomCV:
  1766.                             dvo->ucDeviceType = ATOM_DEVICE_CV_INDEX;
  1767.                             break;
  1768.                         case atomNone:
  1769.                             return FALSE;
  1770.                     }
  1771.                     if (Config->u.dvo.digital) {
  1772.                         dvo->usDevAttr.sDigAttrib.ucAttribute = 0; /* @@@ What do these attributes mean? */
  1773.                     } else {
  1774.                         switch (Config->u.dvo.u.TVMode) {
  1775.                             case RHD_TV_NTSC:
  1776.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_NTSC;
  1777.                                 break;
  1778.                             case RHD_TV_NTSCJ:
  1779.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_NTSCJ;
  1780.                                 break;
  1781.                             case RHD_TV_PAL:
  1782.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_PAL;
  1783.                                 break;
  1784.                             case RHD_TV_PALM:
  1785.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_PALM;
  1786.                                 break;
  1787.                             case RHD_TV_PALCN:
  1788.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_PALCN;
  1789.                                 break;
  1790.                             case RHD_TV_PALN:
  1791.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_PALN;
  1792.                                 break;
  1793.                             case RHD_TV_PAL60:
  1794.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_PAL60;
  1795.                                 break;
  1796.                             case RHD_TV_SECAM:
  1797.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_SECAM;
  1798.                                 break;
  1799.                             case RHD_TV_CV:
  1800.                                 dvo->usDevAttr.sAlgAttrib.ucTVStandard = ATOM_TV_CV;
  1801.                                 break;
  1802.                             case RHD_TV_NONE:
  1803.                                 return FALSE;
  1804.                         }
  1805.                     }
  1806.                     switch (Action) {
  1807.                         case atomEncoderOn:
  1808.                             dvo->ucAction = ATOM_ENABLE;
  1809.                             break;
  1810.                         case atomEncoderOff:
  1811.                             dvo->ucAction = ATOM_DISABLE;
  1812.                             break;
  1813.                         default:
  1814.                             xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: DVO unknown action\n",__func__);
  1815.                             return FALSE;
  1816.                     }
  1817.                 break;
  1818.                 }
  1819.                 case 3:
  1820.                 {
  1821.                     DVO_ENCODER_CONTROL_PARAMETERS_V3 *dvo = &ps.dvo_v3;
  1822.                     dvo->ucDVOConfig = 0;
  1823.                     if (Config->u.dvo3.Rate == atomDVO_RateSDR)
  1824.                         dvo->ucDVOConfig |= DVO_ENCODER_CONFIG_SDR_SPEED;
  1825.                     else
  1826.                         dvo->ucDVOConfig |= DVO_ENCODER_CONFIG_DDR_SPEED;
  1827.                     switch (Config->u.dvo3.DvoOutput) {
  1828.                         case atomDVO_OutputLow12Bit:
  1829.                             dvo->ucDVOConfig = DVO_ENCODER_CONFIG_LOW12BIT;
  1830.                             break;
  1831.                         case atomDVO_OutputHigh12Bit:
  1832.                             dvo->ucDVOConfig = DVO_ENCODER_CONFIG_UPPER12BIT;
  1833.                             break;
  1834.                         case atomDVO_Output24Bit:
  1835.                             dvo->ucDVOConfig = DVO_ENCODER_CONFIG_24BIT;
  1836.                             break;
  1837.                     }
  1838.                     switch (Action) {
  1839.                         case atomEncoderOn:
  1840.                             dvo->ucAction = ATOM_ENABLE;
  1841.                             break;
  1842.                         case atomEncoderOff:
  1843.                             dvo->ucAction = ATOM_DISABLE;
  1844.                             break;
  1845.                         default:
  1846.                             xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: DVO3 unknown action\n",__func__);
  1847.                             return FALSE;
  1848.                     }
  1849.                     break;
  1850.                 }
  1851.             }
  1852.             break;
  1853.         }
  1854.         case atomEncoderNone:
  1855.             return FALSE;
  1856.     }
  1857.  
  1858.     data.exec.dataSpace = NULL;
  1859.     data.exec.pspace = &ps;
  1860.  
  1861.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling %s\n",name);
  1862.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  1863.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  1864.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  1865.         xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Successful\n",name);
  1866.         return TRUE;
  1867.     }
  1868.     xf86DrvMsg(handle->scrnIndex, X_INFO, "%s Failed\n",name);
  1869.     return FALSE;
  1870. }
  1871.  
  1872. /*
  1873.  *
  1874.  */
  1875. struct atomCodeTableVersion
  1876. rhdAtomEncoderControlVersion(atomBiosHandlePtr handle, enum atomEncoder EncoderId)
  1877. {
  1878.     struct atomCodeTableVersion version = { 0, 0 };
  1879.     int index;
  1880.     char *name;
  1881.  
  1882.     switch (EncoderId) {
  1883.         case atomEncoderDACA:
  1884.             index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
  1885.             name = "DAC1EncoderControl";
  1886.             break;
  1887.         case atomEncoderDACB:
  1888.             index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
  1889.             name = "DAC2EncoderControl";
  1890.             break;
  1891.         case atomEncoderTV:
  1892.             index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
  1893.             name = "TVEncoderControl";
  1894.             break;
  1895.         case atomEncoderTMDS1:
  1896.         case atomEncoderTMDS2:
  1897.             index = GetIndexIntoMasterTable(COMMAND, TMDSAEncoderControl);
  1898.             name = "TMDSAEncoderControl";
  1899.             break;
  1900.         case atomEncoderLVDS:
  1901.             index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
  1902.             name = " LVDSEncoderControl";
  1903.             break;
  1904.         case atomEncoderDIG1:
  1905.             index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
  1906.             name = "DIG1EncoderControl";
  1907.             break;
  1908.         case atomEncoderDIG2:
  1909.             index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
  1910.             name = "DIG2EncoderControl";
  1911.             break;
  1912.         case atomEncoderExternal:
  1913.             index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
  1914.             name = "ExternalEncoderControl";
  1915.             break;
  1916.         case atomEncoderDVO:
  1917.             index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
  1918.             name = "DVOEncoderControl";
  1919.             break;
  1920.         default:
  1921.             return version;
  1922.     }
  1923.  
  1924.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  1925.  
  1926.     DEBUG_VERSION_NAME(index, handle, name, version);
  1927.  
  1928.     return version;
  1929. }
  1930.  
  1931. /*
  1932.  *
  1933.  */
  1934. Bool
  1935. rhdAtomUpdateCRTC_DoubleBufferRegisters(atomBiosHandlePtr handle, enum atomCrtc CrtcId,
  1936.                                         enum atomCrtcAction Action)
  1937. {
  1938.     AtomBiosArgRec data;
  1939.     union
  1940.     {
  1941.         ENABLE_CRTC_PARAMETERS crtc;
  1942.         ENABLE_CRTC_PS_ALLOCATION crtc_a;
  1943.     } ps;
  1944.  
  1945.     RHDFUNC(handle);
  1946.  
  1947.     switch (CrtcId) {
  1948.         case atomCrtc1:
  1949.             ps.crtc.ucCRTC = ATOM_CRTC1;
  1950.             break;
  1951.         case atomCrtc2:
  1952.             ps.crtc.ucCRTC = ATOM_CRTC2;
  1953.             break;
  1954.     }
  1955.  
  1956.     switch (Action) {
  1957.         case atomCrtcEnable:
  1958.             ps.crtc.ucEnable = ATOM_ENABLE;
  1959.             break;
  1960.         case atomCrtcDisable:
  1961.             ps.crtc.ucEnable = ATOM_DISABLE;
  1962.             break;
  1963.     }
  1964.  
  1965.     data.exec.index = GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
  1966.  
  1967.     data.exec.dataSpace = NULL;
  1968.     data.exec.pspace = &ps;
  1969.  
  1970.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling UpdateCRTC_DoubleBufferRegisters\n");
  1971.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  1972.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  1973.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  1974.         xf86DrvMsg(handle->scrnIndex, X_INFO, "UpdateCRTC_DoubleBufferRegisters Successful\n");
  1975.         return TRUE;
  1976.     }
  1977.     xf86DrvMsg(handle->scrnIndex, X_INFO, "UpdateCRTC_DoubleBufferRegisters Failed\n");
  1978.     return FALSE;
  1979. }
  1980.  
  1981. /*
  1982.  *
  1983.  */
  1984. struct atomCodeTableVersion
  1985. rhdAtomUpdateCRTC_DoubleBufferRegistersVersion(atomBiosHandlePtr handle)
  1986. {
  1987.     struct atomCodeTableVersion version;
  1988.     int index = GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
  1989.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  1990.  
  1991.     DEBUG_VERSION(index, handle, version);
  1992.  
  1993.     return version;
  1994. }
  1995.  
  1996. /*
  1997.  *
  1998.  */
  1999. Bool
  2000. rhdAtomEnableCrtc(atomBiosHandlePtr handle, enum atomCrtc CrtcId,
  2001.                   enum atomCrtcAction Action)
  2002. {
  2003.     AtomBiosArgRec data;
  2004.     union
  2005.     {
  2006.         ENABLE_CRTC_PARAMETERS crtc;
  2007.         ENABLE_CRTC_PS_ALLOCATION crtc_a;
  2008.     } ps;
  2009.  
  2010.     RHDFUNC(handle);
  2011.  
  2012.     switch (CrtcId) {
  2013.         case atomCrtc1:
  2014.             ps.crtc.ucCRTC = ATOM_CRTC1;
  2015.             break;
  2016.         case atomCrtc2:
  2017.             ps.crtc.ucCRTC = ATOM_CRTC2;
  2018.             break;
  2019.     }
  2020.  
  2021.     switch (Action) {
  2022.         case atomCrtcEnable:
  2023.             ps.crtc.ucEnable = ATOM_ENABLE;
  2024.             break;
  2025.         case atomCrtcDisable:
  2026.             ps.crtc.ucEnable = ATOM_DISABLE;
  2027.             break;
  2028.     }
  2029.  
  2030.     data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
  2031.  
  2032.     data.exec.dataSpace = NULL;
  2033.     data.exec.pspace = &ps;
  2034.  
  2035.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling EnableCRTC\n");
  2036.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2037.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2038.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2039.         xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableCRTC Successful\n");
  2040.         return TRUE;
  2041.     }
  2042.     xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableCRTC Failed\n");
  2043.     return FALSE;
  2044. }
  2045.  
  2046. /*
  2047.  *
  2048.  */
  2049. struct atomCodeTableVersion
  2050. rhdAtomEnableCrtcVersion(atomBiosHandlePtr handle)
  2051. {
  2052.     struct atomCodeTableVersion version;
  2053.     int index = GetIndexIntoMasterTable(COMMAND,  EnableCRTC);
  2054.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2055.  
  2056.     DEBUG_VERSION(index, handle, version);
  2057.  
  2058.     return version;
  2059. }
  2060.  
  2061. /*
  2062.  *
  2063.  */
  2064. Bool
  2065. rhdAtomEnableCrtcMemReq(atomBiosHandlePtr handle, enum atomCrtc CrtcId,
  2066.                   enum atomCrtcAction Action)
  2067. {
  2068.     AtomBiosArgRec data;
  2069.     union
  2070.     {
  2071.         ENABLE_CRTC_PARAMETERS crtc;
  2072.         ENABLE_CRTC_PS_ALLOCATION crtc_a;
  2073.     } ps;
  2074.  
  2075.     RHDFUNC(handle);
  2076.  
  2077.     switch (CrtcId) {
  2078.         case atomCrtc1:
  2079.             ps.crtc.ucCRTC = ATOM_CRTC1;
  2080.             break;
  2081.         case atomCrtc2:
  2082.             ps.crtc.ucCRTC = ATOM_CRTC2;
  2083.             break;
  2084.     }
  2085.  
  2086.     switch (Action) {
  2087.         case atomCrtcEnable:
  2088.             ps.crtc.ucEnable = ATOM_ENABLE;
  2089.             break;
  2090.         case atomCrtcDisable:
  2091.             ps.crtc.ucEnable = ATOM_DISABLE;
  2092.             break;
  2093.     }
  2094.  
  2095.     data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
  2096.  
  2097.     data.exec.dataSpace = NULL;
  2098.     data.exec.pspace = &ps;
  2099.  
  2100.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling EnableCRTCMemReq\n");
  2101.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2102.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2103.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2104.         xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableCRTCMemReq Successful\n");
  2105.         return TRUE;
  2106.     }
  2107.     xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableCRTCMemReq Failed\n");
  2108.     return FALSE;
  2109. }
  2110.  
  2111. /*
  2112.  *
  2113.  */
  2114. struct atomCodeTableVersion
  2115. rhdAtomEnableCrtcMemReqVersion(atomBiosHandlePtr handle)
  2116. {
  2117.     struct atomCodeTableVersion version;
  2118.     int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
  2119.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2120.  
  2121.     DEBUG_VERSION(index, handle, version);
  2122.  
  2123.     return version;
  2124.  
  2125. }
  2126.  
  2127. /*
  2128.  *
  2129.  */
  2130. Bool
  2131. rhdAtomSetCRTCTimings(atomBiosHandlePtr handle, enum atomCrtc id, DisplayModePtr mode, int depth)
  2132. {
  2133.     AtomBiosArgRec data;
  2134.     union
  2135.     {
  2136.         SET_CRTC_TIMING_PARAMETERS  crtc;
  2137. /*      SET_CRTC_TIMING_PS_ALLOCATION crtc_a; */
  2138.     } ps;
  2139.     ATOM_MODE_MISC_INFO_ACCESS* msc = &(ps.crtc.susModeMiscInfo);
  2140.  
  2141.     RHDFUNC(handle);
  2142.  
  2143.     ps.crtc.usH_Total = mode->CrtcHTotal;
  2144.     ps.crtc.usH_Disp = mode->CrtcHDisplay;
  2145.     ps.crtc.usH_SyncStart = mode->CrtcHSyncStart;
  2146.     ps.crtc.usH_SyncWidth = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
  2147.     ps.crtc.usV_Total = mode->CrtcVTotal;
  2148.     ps.crtc.usV_Disp = mode->CrtcVDisplay;
  2149.     ps.crtc.usV_SyncStart = mode->CrtcVSyncStart;
  2150.     ps.crtc.usV_SyncWidth = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
  2151.     ps.crtc.ucOverscanRight = mode->CrtcHBlankStart - mode->CrtcHDisplay;
  2152.     ps.crtc.ucOverscanLeft = mode->CrtcVTotal - mode->CrtcVBlankEnd;
  2153.     ps.crtc.ucOverscanBottom = mode->CrtcVBlankStart - mode->CrtcVDisplay;
  2154.     ps.crtc.ucOverscanTop = mode->CrtcVTotal - mode->CrtcVBlankEnd;
  2155.     switch (id) {
  2156.         case atomCrtc1:
  2157.             ps.crtc.ucCRTC = ATOM_CRTC1;
  2158.             break;
  2159.         case atomCrtc2:
  2160.             ps.crtc.ucCRTC = ATOM_CRTC2;
  2161.             break;
  2162.     }
  2163.  
  2164.     msc->sbfAccess.HorizontalCutOff = 0;
  2165.     msc->sbfAccess.HSyncPolarity = (mode->Flags & V_NHSYNC) ? 1 : 0;
  2166.     msc->sbfAccess.VSyncPolarity = (mode->Flags & V_NVSYNC) ? 1 : 0;
  2167.     msc->sbfAccess.VerticalCutOff = 0;
  2168.     msc->sbfAccess.H_ReplicationBy2 = 0;
  2169.     msc->sbfAccess.V_ReplicationBy2 = (mode->Flags & V_DBLSCAN) ? 1 : 0;
  2170.     msc->sbfAccess.CompositeSync =  (mode->Flags & V_CSYNC);
  2171.     msc->sbfAccess.Interlace = (mode->Flags & V_INTERLACE) ? 1 : 0;
  2172.     msc->sbfAccess.DoubleClock = (mode->Flags & V_DBLCLK) ? 1 : 0;
  2173.     msc->sbfAccess.RGB888 = (depth == 24) ? 1 : 0;
  2174.  
  2175.     data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
  2176.  
  2177.     data.exec.dataSpace = NULL;
  2178.     data.exec.pspace = &ps;
  2179.  
  2180.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling SetCRTC_Timing\n");
  2181.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2182.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2183.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2184.         xf86DrvMsg(handle->scrnIndex, X_INFO, "SetCRTC_Timing Successful\n");
  2185.         return TRUE;
  2186.   }
  2187.     xf86DrvMsg(handle->scrnIndex, X_INFO, "SetCRTC_Timing Failed\n");
  2188.     return FALSE;
  2189. }
  2190.  
  2191. /*
  2192.  *
  2193.  */
  2194. struct atomCodeTableVersion
  2195. rhdAtomSetCRTCTimingsVersion(atomBiosHandlePtr handle)
  2196. {
  2197.     struct atomCodeTableVersion version;
  2198.     int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
  2199.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2200.  
  2201.     DEBUG_VERSION(index, handle, version);
  2202.     return version;
  2203.  
  2204. }
  2205.  
  2206. /*
  2207.  *
  2208.  */
  2209. Bool
  2210. rhdAtomSetCRTCOverscan(atomBiosHandlePtr handle, enum atomCrtc id, struct atomCrtcOverscan *config)
  2211. {
  2212.     AtomBiosArgRec data;
  2213.     union
  2214.     {
  2215.         SET_CRTC_OVERSCAN_PARAMETERS  ovscn;
  2216.         SET_CRTC_OVERSCAN_PS_ALLOCATION ovscn_a;
  2217.     } ps;
  2218.  
  2219.     RHDFUNC(handle);
  2220.  
  2221.     data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
  2222.     data.exec.dataSpace = NULL;
  2223.     data.exec.pspace = &ps;
  2224.  
  2225.     switch(id) {
  2226.         case atomCrtc1:
  2227.             ps.ovscn.ucCRTC = ATOM_CRTC1;
  2228.             break;
  2229.         case atomCrtc2:
  2230.             ps.ovscn.ucCRTC = ATOM_CRTC2;
  2231.             break;
  2232.     }
  2233.     ps.ovscn.usOverscanRight = config->ovscnRight;
  2234.     ps.ovscn.usOverscanLeft = config->ovscnLeft;
  2235.     ps.ovscn.usOverscanBottom = config->ovscnBottom;
  2236.     ps.ovscn.usOverscanTop = config->ovscnTop;
  2237.  
  2238.     xf86DrvMsg(handle->scrnIndex, X_INFO, "CallingSetCRTC_OverScan\n");
  2239.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2240.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2241.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2242.         xf86DrvMsg(handle->scrnIndex, X_INFO, "Set CRTC_OverScan Successful\n");
  2243.         return TRUE;
  2244.     }
  2245.     xf86DrvMsg(handle->scrnIndex, X_INFO, "SetCRTC_OverScan Failed\n");
  2246.     return FALSE;
  2247. }
  2248.  
  2249. /*
  2250.  *
  2251.  */
  2252. struct atomCodeTableVersion
  2253. rhdAtomSetCRTCOverscanVersion(atomBiosHandlePtr handle)
  2254. {
  2255.     struct atomCodeTableVersion version;
  2256.     int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
  2257.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2258.  
  2259.     DEBUG_VERSION(index, handle, version);
  2260.     return version;
  2261. }
  2262.  
  2263. /*
  2264.  *
  2265.  */
  2266. Bool
  2267. rhdAtomBlankCRTC(atomBiosHandlePtr handle, enum atomCrtc id, struct atomCrtcBlank *config)
  2268. {
  2269.   AtomBiosArgRec data;
  2270.     union
  2271.     {
  2272.         BLANK_CRTC_PARAMETERS blank;
  2273.         BLANK_CRTC_PS_ALLOCATION blank_a;
  2274.     } ps;
  2275.  
  2276.     RHDFUNC(handle);
  2277.  
  2278.     data.exec.index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
  2279.     data.exec.pspace = &ps;
  2280.     data.exec.dataSpace = NULL;
  2281.  
  2282.     switch(id) {
  2283.         case atomCrtc1:
  2284.             ps.blank.ucCRTC = ATOM_CRTC1;
  2285.             break;
  2286.         case atomCrtc2:
  2287.             ps.blank.ucCRTC = ATOM_CRTC2;
  2288.             break;
  2289.     }
  2290.  
  2291.     switch (config->Action) {
  2292.         case atomBlankOn:
  2293.             ps.blank.ucBlanking = ATOM_BLANKING;
  2294.             break;
  2295.         case atomBlankOff:
  2296.             ps.blank.ucBlanking = ATOM_BLANKING_OFF;
  2297.             break;
  2298.     }
  2299.     ps.blank.usBlackColorRCr = config->r;
  2300.     ps.blank.usBlackColorGY = config->g;
  2301.     ps.blank.usBlackColorBCb = config->b;
  2302.  
  2303.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling BlankCRTC\n");
  2304.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2305.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2306.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2307.         xf86DrvMsg(handle->scrnIndex, X_INFO, "BlankCRTC Successful\n");
  2308.         return TRUE;
  2309.     }
  2310.     xf86DrvMsg(handle->scrnIndex, X_INFO, "BlankCRTC Failed\n");
  2311.   return FALSE;
  2312. }
  2313.  
  2314. /*
  2315.  *
  2316.  */
  2317. struct atomCodeTableVersion
  2318. rhdAtomBlankCRTCVersion(atomBiosHandlePtr handle)
  2319. {
  2320.     struct atomCodeTableVersion version;
  2321.     int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
  2322.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2323.  
  2324.     DEBUG_VERSION(index, handle, version);
  2325.     return version;
  2326. }
  2327.  
  2328. /*
  2329.  *
  2330.  */
  2331. static int
  2332. atomGetDevice(atomBiosHandlePtr handle, enum atomDevice Device)
  2333. {
  2334.     switch (Device) {
  2335.         case atomCRT1:
  2336.             return ATOM_DEVICE_CRT1_INDEX;
  2337.         case atomLCD1:
  2338.             return ATOM_DEVICE_LCD1_INDEX;
  2339.         case atomTV1:
  2340.             return ATOM_DEVICE_TV1_INDEX;
  2341.         case atomDFP1:
  2342.             return ATOM_DEVICE_DFP1_INDEX;
  2343.         case atomCRT2:
  2344.             return ATOM_DEVICE_CRT2_INDEX;
  2345.         case atomLCD2:
  2346.             return ATOM_DEVICE_LCD2_INDEX;
  2347.         case atomTV2:
  2348.             return ATOM_DEVICE_TV2_INDEX;
  2349.         case atomDFP2:
  2350.             return ATOM_DEVICE_DFP2_INDEX;
  2351.         case atomCV:
  2352.             return ATOM_DEVICE_CV_INDEX;
  2353.         case atomDFP3:
  2354.             return ATOM_DEVICE_DFP3_INDEX;
  2355.         case atomDFP4:
  2356.             return ATOM_DEVICE_DFP4_INDEX;
  2357.         case atomDFP5:
  2358.             return ATOM_DEVICE_DFP5_INDEX;
  2359.         case atomNone:
  2360.             xf86DrvMsg(handle->scrnIndex, X_ERROR, "Invalid Device\n");
  2361.             return ATOM_MAX_SUPPORTED_DEVICE;
  2362.     }
  2363.  
  2364.     return ATOM_MAX_SUPPORTED_DEVICE;
  2365. }
  2366.  
  2367. /*
  2368.  *
  2369.  */
  2370. Bool
  2371. rhdAtomSetPixelClock(atomBiosHandlePtr handle, enum atomPxclk PCLKId, struct atomPixelClockConfig *Config)
  2372. {
  2373.     AtomBiosArgRec data;
  2374.     CARD8 version;
  2375.     Bool NeedMode = FALSE;
  2376.     union {
  2377.         PIXEL_CLOCK_PARAMETERS  pclk;
  2378.         PIXEL_CLOCK_PARAMETERS_V2  pclk_v2;
  2379.         PIXEL_CLOCK_PARAMETERS_V3  pclk_v3;
  2380.         SET_PIXEL_CLOCK_PS_ALLOCATION pclk_a;
  2381.     } ps;
  2382.  
  2383.     data.exec.index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
  2384.  
  2385.     if (!rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version, NULL, NULL))
  2386.         return FALSE;
  2387.     switch  (version) {
  2388.         case 1:
  2389.             if (Config->Enable)
  2390.                 ps.pclk.usPixelClock = Config->PixelClock / 10;
  2391.             else
  2392.                 ps.pclk.usPixelClock = 0;
  2393.             ps.pclk.usRefDiv = Config->RefDiv;
  2394.             ps.pclk.usFbDiv = Config->FbDiv;
  2395.             ps.pclk.ucPostDiv = Config->PostDiv;
  2396.             ps.pclk.ucFracFbDiv = Config->FracFbDiv;
  2397.             ps.pclk.ucRefDivSrc = 0; /* What's this? @@@ */
  2398.             switch (PCLKId) {
  2399.                 case atomPclk1:
  2400.                     ps.pclk.ucPpll = ATOM_PPLL1;
  2401.                     break;
  2402.                 case atomPclk2:
  2403.                     ps.pclk.ucPpll = ATOM_PPLL2;
  2404.                     break;
  2405.             }
  2406.             switch (Config->Crtc) {
  2407.                 case atomCrtc1:
  2408.                     ps.pclk.ucCRTC = ATOM_CRTC1;
  2409.                     break;
  2410.                 case atomCrtc2:
  2411.                     ps.pclk.ucCRTC = ATOM_CRTC2;
  2412.                     break;
  2413.             }
  2414.             break;
  2415.         case 2:
  2416.             if (Config->Enable)
  2417.                 ps.pclk_v2.usPixelClock = Config->PixelClock / 10;
  2418.             else
  2419.                 ps.pclk_v2.usPixelClock = 0;
  2420.             ps.pclk_v2.usRefDiv = Config->RefDiv;
  2421.             ps.pclk_v2.usFbDiv = Config->FbDiv;
  2422.             ps.pclk_v2.ucPostDiv = Config->PostDiv;
  2423.             ps.pclk_v2.ucFracFbDiv = Config->FracFbDiv;
  2424.             switch (PCLKId) {
  2425.                 case atomPclk1:
  2426.                     ps.pclk_v2.ucPpll = ATOM_PPLL1;
  2427.                     break;
  2428.                 case atomPclk2:
  2429.                     ps.pclk_v2.ucPpll = ATOM_PPLL2;
  2430.                     break;
  2431.             }
  2432.             ps.pclk_v2.ucRefDivSrc = 1; /* See above... @@@ */
  2433.             switch (Config->Crtc) {
  2434.                 case atomCrtc1:
  2435.                     ps.pclk_v2.ucCRTC = ATOM_CRTC1;
  2436.                     break;
  2437.                 case atomCrtc2:
  2438.                     ps.pclk_v2.ucCRTC = ATOM_CRTC2;
  2439.                     break;
  2440.             }
  2441.             ASSERTF((!Config->Enable || Config->u.v2.Device != atomNone), "Invalid Device Id\n");
  2442.             ps.pclk_v2.ucMiscInfo = 0;
  2443.             ps.pclk_v2.ucMiscInfo |= (Config->u.v2.Force ? MISC_FORCE_REPROG_PIXEL_CLOCK : 0);
  2444.             if (Config->u.v2.Device != atomNone)
  2445.                 ps.pclk_v2.ucMiscInfo |= (atomGetDevice(handle, Config->u.v2.Device)
  2446.                                           << MISC_DEVICE_INDEX_SHIFT);
  2447.             RHDDebug(handle->scrnIndex,"%s Device: %i PixelClock: %i RefDiv: 0x%x FbDiv: 0x%x PostDiv: 0x%x "
  2448.                      "PLL: %i Crtc: %i MiscInfo: 0x%x\n",
  2449.                    __func__,
  2450.                    Config->u.v2.Device,
  2451.                    ps.pclk_v2.usPixelClock,
  2452.                    ps.pclk_v2.usRefDiv,
  2453.                    ps.pclk_v2.usFbDiv,
  2454.                    ps.pclk_v2.ucPostDiv,
  2455.                    ps.pclk_v2.ucPpll,
  2456.                    ps.pclk_v2.ucCRTC,
  2457.                    ps.pclk_v2.ucMiscInfo
  2458.                 );
  2459.             break;
  2460.         case 3:
  2461.             if (Config->Enable)
  2462.                 ps.pclk_v3.usPixelClock = Config->PixelClock / 10;
  2463.             else
  2464.                 ps.pclk.usPixelClock = 0;
  2465.             ps.pclk_v3.usRefDiv = Config->RefDiv;
  2466.             ps.pclk_v3.usFbDiv = Config->FbDiv;
  2467.             ps.pclk_v3.ucPostDiv = Config->PostDiv;
  2468.             ps.pclk_v3.ucFracFbDiv = Config->FracFbDiv;
  2469.             switch (PCLKId) {
  2470.                 case atomPclk1:
  2471.                     ps.pclk_v3.ucPpll = ATOM_PPLL1;
  2472.                     break;
  2473.                 case atomPclk2:
  2474.                     ps.pclk_v3.ucPpll = ATOM_PPLL2;
  2475.                     break;
  2476.             }
  2477.             switch (Config->u.v3.OutputType) {
  2478.                 case atomOutputKldskpLvtma:
  2479.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
  2480.                     NeedMode = TRUE;
  2481.                     break;
  2482.                 case atomOutputUniphyA:
  2483.                 case atomOutputUniphyB:
  2484.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
  2485.                     NeedMode = TRUE;
  2486.                     break;
  2487.                 case atomOutputUniphyC:
  2488.                 case atomOutputUniphyD:
  2489.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
  2490.                     NeedMode = TRUE;
  2491.                     break;
  2492.                 case atomOutputUniphyE:
  2493.                 case atomOutputUniphyF:
  2494.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
  2495.                     NeedMode = TRUE;
  2496.                     break;
  2497.  
  2498.                 case atomOutputDacA:
  2499.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
  2500.                     break;
  2501.                 case atomOutputDacB:
  2502.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
  2503.                     break;
  2504.                 case atomOutputDvo:
  2505.                     ps.pclk_v3.ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
  2506.                     NeedMode = TRUE;
  2507.                     break;
  2508.                 case atomOutputTmdsa:
  2509.                 case atomOutputLvtma:
  2510.                 case atomOutputNone:
  2511.                     return FALSE;
  2512.             }
  2513.             if (NeedMode) {
  2514.                 switch (Config->u.v3.EncoderMode) {
  2515.                     case atomNoEncoder:
  2516.                         ps.pclk_v3.ucEncoderMode = 0;
  2517.                     case atomDVI:
  2518.                         ps.pclk_v3.ucEncoderMode = ATOM_ENCODER_MODE_DVI;
  2519.                         break;
  2520.                     case atomDP:
  2521.                         ps.pclk_v3.ucEncoderMode = ATOM_ENCODER_MODE_DP;
  2522.                         break;
  2523.                     case atomLVDS:
  2524.                         ps.pclk_v3.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
  2525.                         break;
  2526.                     case atomHDMI:
  2527.                         ps.pclk_v3.ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
  2528.                         break;
  2529.                     case atomSDVO:
  2530.                         ps.pclk_v3.ucEncoderMode = ATOM_ENCODER_MODE_SDVO;
  2531.                         break;
  2532.                     default:
  2533.                         xf86DrvMsg(handle->scrnIndex, X_ERROR,"%s: invalid encoder type.\n",__func__);
  2534.                         return FALSE;
  2535.                 }
  2536.             }
  2537.             ps.pclk_v3.ucMiscInfo = (Config->u.v3.Force ? PIXEL_CLOCK_MISC_FORCE_PROG_PPLL : 0x0)
  2538.                 | (Config->u.v3.UsePpll ?  PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK : 0x0)
  2539.                 | ((Config->Crtc == atomCrtc2) ? PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2 : PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1);
  2540.  
  2541.             RHDDebug(handle->scrnIndex,"%s PixelClock: %i RefDiv: 0x%x FbDiv: 0x%x PostDiv: 0x%x PLL: %i OutputType: %x "
  2542.                    "EncoderMode: %x MiscInfo: 0x%x\n",
  2543.                    __func__,
  2544.                    ps.pclk_v3.usPixelClock,
  2545.                    ps.pclk_v3.usRefDiv,
  2546.                    ps.pclk_v3.usFbDiv,
  2547.                    ps.pclk_v3.ucPostDiv,
  2548.                    ps.pclk_v3.ucPpll,
  2549.                    ps.pclk_v3.ucTransmitterId,
  2550.                    ps.pclk_v3.ucEncoderMode,
  2551.                    ps.pclk_v3.ucMiscInfo
  2552.                 );
  2553.             break;
  2554.         default:
  2555.             return FALSE;
  2556.     }
  2557.  
  2558.     data.exec.dataSpace = NULL;
  2559.     data.exec.pspace = &ps;
  2560.  
  2561.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling SetPixelClock\n");
  2562.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2563.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2564.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2565.         xf86DrvMsg(handle->scrnIndex, X_INFO, "SetPixelClock Successful\n");
  2566.         return TRUE;
  2567.     }
  2568.     xf86DrvMsg(handle->scrnIndex, X_INFO, "SetPixelClock Failed\n");
  2569.     return FALSE;
  2570. }
  2571.  
  2572. /*
  2573.  *
  2574.  */
  2575. struct atomCodeTableVersion
  2576. rhdAtomSetPixelClockVersion(atomBiosHandlePtr handle)
  2577. {
  2578.     struct atomCodeTableVersion version;
  2579.     int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
  2580.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2581.  
  2582.     DEBUG_VERSION(index, handle, version);
  2583.  
  2584.     return version;
  2585.  
  2586. }
  2587.  
  2588. /*
  2589.  *
  2590.  */
  2591. Bool
  2592. rhdAtomSelectCrtcSource(atomBiosHandlePtr handle, enum atomCrtc CrtcId,
  2593.                         struct atomCrtcSourceConfig *config)
  2594. {
  2595.     AtomBiosArgRec data;
  2596.     CARD8 version;
  2597.     Bool NeedMode = FALSE;
  2598.  
  2599.     union
  2600.     {
  2601.         SELECT_CRTC_SOURCE_PARAMETERS crtc;
  2602.         SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_a;
  2603.         SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc2;
  2604. /*      SELECT_CRTC_SOURCE_PS_ALLOCATION_V2 crtc2_a; */
  2605.     } ps;
  2606.  
  2607.     RHDFUNC(handle);
  2608.  
  2609.     data.exec.index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
  2610.  
  2611.     if (!rhdAtomGetCommandTableRevisionSize(handle, data.exec.index, &version, NULL, NULL))
  2612.         return FALSE;
  2613.  
  2614.     switch  (version) {
  2615.         case 1:
  2616.             switch (CrtcId) {
  2617.                 case atomCrtc1:
  2618.                     ps.crtc.ucCRTC = ATOM_CRTC1;
  2619.                     break;
  2620.                 case atomCrtc2:
  2621.                     ps.crtc.ucCRTC = ATOM_CRTC2;
  2622.                     break;
  2623.             }
  2624.             switch (config->u.Device) {
  2625.                 case atomCRT1:
  2626.                     ps.crtc.ucDevice = ATOM_DEVICE_CRT1_INDEX;
  2627.                     break;
  2628.                 case atomLCD1:
  2629.                     ps.crtc.ucDevice = ATOM_DEVICE_LCD1_INDEX;
  2630.             break;
  2631.                 case atomTV1:
  2632.                     ps.crtc.ucDevice = ATOM_DEVICE_TV1_INDEX;
  2633.             break;
  2634.                 case atomDFP1:
  2635.                     ps.crtc.ucDevice = ATOM_DEVICE_DFP1_INDEX;
  2636.             break;
  2637.                 case atomCRT2:
  2638.                     ps.crtc.ucDevice = ATOM_DEVICE_CRT2_INDEX;
  2639.             break;
  2640.                 case atomLCD2:
  2641.                     ps.crtc.ucDevice = ATOM_DEVICE_LCD2_INDEX;
  2642.             break;
  2643.                 case atomTV2:
  2644.                     ps.crtc.ucDevice = ATOM_DEVICE_TV2_INDEX;
  2645.             break;
  2646.                 case atomDFP2:
  2647.                     ps.crtc.ucDevice = ATOM_DEVICE_DFP2_INDEX;
  2648.             break;
  2649.                 case atomCV:
  2650.                     ps.crtc.ucDevice = ATOM_DEVICE_CV_INDEX;
  2651.             break;
  2652.                 case atomDFP3:
  2653.                     ps.crtc.ucDevice = ATOM_DEVICE_DFP3_INDEX;
  2654.             break;
  2655.                 case atomDFP4:
  2656.                     ps.crtc.ucDevice = ATOM_DEVICE_DFP4_INDEX;
  2657.                     break;
  2658.                 case atomDFP5:
  2659.                     ps.crtc.ucDevice = ATOM_DEVICE_DFP5_INDEX;
  2660.                     break;
  2661.                 case atomNone:
  2662.                     return FALSE;
  2663.     }
  2664.             break;
  2665.         case 2:
  2666.             switch (CrtcId) {
  2667.                 case atomCrtc1:
  2668.                     ps.crtc2.ucCRTC = ATOM_CRTC1;
  2669.                     break;
  2670.                 case atomCrtc2:
  2671.                     ps.crtc2.ucCRTC = ATOM_CRTC2;
  2672.             break;
  2673.     }
  2674.             switch (config->u.crtc2.Encoder) {
  2675.                 case atomEncoderDACA:
  2676.                     ps.crtc2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
  2677.                     break;
  2678.                 case atomEncoderDACB:
  2679.                     ps.crtc2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
  2680.                     break;
  2681.                 case atomEncoderTV:
  2682.                     ps.crtc2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
  2683.                     break;
  2684.                 case atomEncoderDVO:
  2685.                     ps.crtc2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
  2686.                     NeedMode = TRUE;
  2687.                     break;
  2688.                 case atomEncoderDIG1:
  2689.                     ps.crtc2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
  2690.                     NeedMode = TRUE;
  2691.                     break;
  2692.  
  2693.                 case atomEncoderDIG2:
  2694.                     ps.crtc2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
  2695.                     break;
  2696.                 case atomEncoderExternal:
  2697.                     ps.crtc2.ucEncoderID = ASIC_EXT_DIG_ENCODER_ID;
  2698.                     break;
  2699.                 case atomEncoderTMDS1:
  2700.                 case atomEncoderTMDS2:
  2701.                 case atomEncoderLVDS:
  2702.                 case atomEncoderNone:
  2703.                     return FALSE;
  2704.             }
  2705.             if (NeedMode) {
  2706.                 switch (config->u.crtc2.Mode) {
  2707.                     case atomDVI:
  2708.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
  2709.                         break;
  2710.                     case atomDP:
  2711.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
  2712.                         break;
  2713.                     case atomLVDS:
  2714.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
  2715.                         break;
  2716.                     case atomHDMI:
  2717.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_HDMI;
  2718.                         break;
  2719.                     case atomSDVO:
  2720.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_SDVO;
  2721.                         break;
  2722.                     case atomTVComposite:
  2723.                     case atomTVSVideo:
  2724.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
  2725.                         break;
  2726.                     case atomTVComponent:
  2727.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
  2728.                         break;
  2729.                     case atomCRT:
  2730.                         ps.crtc2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
  2731.                         break;
  2732.                     case atomNoEncoder:
  2733.                         xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: invalid encoder type.\n",__func__);
  2734.                         return FALSE;
  2735.                 }
  2736.             }
  2737.             break;
  2738.     }
  2739.  
  2740.     data.exec.dataSpace = NULL;
  2741.     data.exec.pspace = &ps;
  2742.  
  2743.     xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling SelectCRTCSource\n");
  2744.     atomDebugPrintPspace(handle, &data, sizeof(ps));
  2745.     if (RHDAtomBiosFunc(handle->rhdPtr, handle,
  2746.                         ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
  2747.         xf86DrvMsg(handle->scrnIndex, X_INFO, "SelectCRTCSource Successful\n");
  2748.         return TRUE;
  2749.     }
  2750.     xf86DrvMsg(handle->scrnIndex, X_INFO, "SelectCRTCSource Failed\n");
  2751.     return FALSE;
  2752. }
  2753.  
  2754. /*
  2755.  *
  2756.  */
  2757. struct atomCodeTableVersion
  2758. rhdAtomSelectCrtcSourceVersion(atomBiosHandlePtr handle)
  2759. {
  2760.     struct atomCodeTableVersion version;
  2761.     int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
  2762.     rhdAtomGetCommandTableRevisionSize(handle, index, &version.cref, &version.fref, NULL);
  2763.     DEBUG_VERSION(index, handle, version);
  2764.     return version;
  2765. }
  2766.  
  2767.  
  2768. # endif  /* ATOM_BIOS_PARSER */
  2769.  
  2770.  
  2771. static AtomBiosResult
  2772. rhdAtomInit(atomBiosHandlePtr unused1, AtomBiosRequestID unused2,
  2773.                     AtomBiosArgPtr data)
  2774. {
  2775.     int scrnIndex = data->val;
  2776.     RHDPtr rhdPtr = data->val;
  2777.   unsigned char *ptr;
  2778.   atomDataTablesPtr atomDataPtr;
  2779.   atomBiosHandlePtr handle = NULL;
  2780.   unsigned int BIOSImageSize = 0;
  2781.   Bool unposted = FALSE;
  2782.     unsigned char* codeTable;
  2783.  
  2784.   data->atomhandle = NULL;
  2785.  
  2786.     RHDFUNCI(scrnIndex);
  2787.  
  2788.     if (rhdPtr->BIOSCopy) {
  2789.         xf86DrvMsg(scrnIndex,X_INFO,"Getting BIOS copy from INT10\n");
  2790.     ptr = rhdPtr->BIOSCopy;
  2791.     rhdPtr->BIOSCopy = NULL;
  2792.  
  2793.     BIOSImageSize = ptr[2] * 512;
  2794.         if (BIOSImageSize > legacyBIOSMax) {
  2795.             xf86DrvMsg(scrnIndex,X_ERROR,"Invalid BIOS length field\n");
  2796.             return ATOM_FAILED;
  2797.     }
  2798.   }
  2799.   else
  2800.   {
  2801. //    if (!xf86IsEntityPrimary(rhdPtr->entityIndex))
  2802. //    {
  2803. //      if (!(BIOSImageSize = RHDReadPCIBios(rhdPtr, &ptr)))
  2804. //        return ATOM_FAILED;
  2805. //      unposted = TRUE;
  2806. //    }
  2807. //    else
  2808.     {
  2809.             int read_len;
  2810.             unsigned char tmp[32];
  2811.  
  2812.       DBG(dbgprintf("Getting BIOS copy from legacy VBIOS location\n"));
  2813.       memcpy(tmp,(char*)(OS_BASE+legacyBIOSLocation), 32);
  2814.             BIOSImageSize = tmp[2] * 512;
  2815.             if (BIOSImageSize > legacyBIOSMax) {
  2816.     xf86DrvMsg(0,X_ERROR,"Invalid BIOS length field\n");
  2817.         return ATOM_FAILED;
  2818.             }
  2819.       if (!(ptr = (char*)KernelAlloc(BIOSImageSize)))
  2820.       {
  2821.         DBG(dbgprintf("Cannot allocate %i bytes of memory "
  2822.                   "for BIOS image\n",BIOSImageSize));
  2823.         return ATOM_FAILED;
  2824.             }
  2825.       memcpy(ptr,(char*)(OS_BASE+legacyBIOSLocation), BIOSImageSize);
  2826.       rhdPtr->BIOSCopy = ptr;
  2827.     }
  2828.   }
  2829.  
  2830.     if (!(atomDataPtr = xcalloc(1, sizeof(atomDataTables)))) {
  2831.         xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory for "
  2832.                    "ATOM BIOS data tabes\n");
  2833.     goto error;
  2834.   }
  2835.     if (!rhdAtomGetTables(rhdPtr, ptr, atomDataPtr, &codeTable, BIOSImageSize))
  2836.     goto error1;
  2837.     if (!(handle = xcalloc(1, sizeof(atomBiosHandleRec)))) {
  2838.         xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory\n");
  2839.     goto error1;
  2840.   }
  2841.   handle->BIOSBase = ptr;
  2842.   handle->atomDataPtr = atomDataPtr;
  2843.   handle