Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1029 | serge | 1 | /* |
2 | * Copyright 2007, 2008 Egbert Eich |
||
3 | * Copyright 2007, 2008 Luc Verhaegen |
||
4 | * Copyright 2007, 2008 Matthias Hopf |
||
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->scrnIndex = scrnIndex; |
||
2844 | handle->rhdPtr = rhdPtr; |
||
2845 | handle->PciTag = rhdPtr->PciTag; |
||
2846 | handle->BIOSImageSize = BIOSImageSize; |
||
2847 | handle->codeTable = codeTable; |
||
2848 | handle->SaveListObjects = NULL; |
||
2849 | |||
2850 | # ifdef ATOM_BIOS_PARSER |
||
2851 | /* Try to find out if BIOS has been posted (either by system or int10 */ |
||
2852 | if (unposted) { |
||
2853 | /* run AsicInit */ |
||
2854 | if (!rhdAtomASICInit(handle)) |
||
2855 | xf86DrvMsg(scrnIndex, X_WARNING, |
||
2856 | "%s: AsicInit failed. Won't be able to obtain in VRAM " |
||
2857 | "FB scratch space\n",__func__); |
||
2858 | } |
||
2859 | # endif |
||
2860 | |||
2861 | data->atomhandle = handle; |
||
2862 | return ATOM_SUCCESS; |
||
2863 | |||
2864 | error1: |
||
2865 | xfree(atomDataPtr); |
||
2866 | error: |
||
2867 | xfree(ptr); |
||
2868 | return ATOM_FAILED; |
||
2869 | } |
||
2870 | |||
2871 | static AtomBiosResult |
||
2872 | rhdAtomTearDown(atomBiosHandlePtr handle, |
||
2873 | AtomBiosRequestID unused1, AtomBiosArgPtr unused2) |
||
2874 | { |
||
2875 | RHDFUNC(handle); |
||
2876 | |||
2877 | xfree(handle->BIOSBase); |
||
2878 | xfree(handle->atomDataPtr); |
||
2879 | if (handle->scratchBase) xfree(handle->scratchBase); |
||
2880 | xfree(handle); |
||
2881 | return ATOM_SUCCESS; |
||
2882 | } |
||
2883 | |||
2884 | static AtomBiosResult |
||
2885 | rhdAtomVramInfoQuery(atomBiosHandlePtr handle, AtomBiosRequestID func, |
||
2886 | AtomBiosArgPtr data) |
||
2887 | { |
||
2888 | atomDataTablesPtr atomDataPtr; |
||
2889 | CARD32 *val = &data->val; |
||
2890 | RHDFUNC(handle); |
||
2891 | |||
2892 | atomDataPtr = handle->atomDataPtr; |
||
2893 | |||
2894 | switch (func) { |
||
2895 | case GET_FW_FB_START: |
||
2896 | *val = atomDataPtr->VRAM_UsageByFirmware |
||
2897 | ->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; |
||
2898 | break; |
||
2899 | case GET_FW_FB_SIZE: |
||
2900 | *val = atomDataPtr->VRAM_UsageByFirmware |
||
2901 | ->asFirmwareVramReserveInfo[0].usFirmwareUseInKb; |
||
2902 | break; |
||
2903 | default: |
||
2904 | return ATOM_NOT_IMPLEMENTED; |
||
2905 | } |
||
2906 | return ATOM_SUCCESS; |
||
2907 | } |
||
2908 | |||
2909 | static AtomBiosResult |
||
2910 | rhdAtomTmdsInfoQuery(atomBiosHandlePtr handle, |
||
2911 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
2912 | { |
||
2913 | atomDataTablesPtr atomDataPtr; |
||
2914 | CARD32 *val = &data->val; |
||
2915 | int i = 0, clock = *val; |
||
2916 | |||
2917 | atomDataPtr = handle->atomDataPtr; |
||
2918 | if (!rhdAtomGetTableRevisionAndSize( |
||
2919 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->TMDS_Info), |
||
2920 | NULL,NULL,NULL)) { |
||
2921 | return ATOM_FAILED; |
||
2922 | } |
||
2923 | |||
2924 | RHDFUNC(handle); |
||
2925 | |||
2926 | if (func == ATOM_TMDS_MAX_FREQUENCY) |
||
2927 | *val = atomDataPtr->TMDS_Info->usMaxFrequency * 10; |
||
2928 | else { |
||
2929 | if (clock > atomDataPtr->TMDS_Info->usMaxFrequency * 10) |
||
2930 | return ATOM_FAILED; |
||
2931 | |||
2932 | for (;i < ATOM_MAX_MISC_INFO; i++) { |
||
2933 | if (clock < atomDataPtr->TMDS_Info->asMiscInfo[i].usFrequency * 10) { |
||
2934 | switch (func) { |
||
2935 | case ATOM_TMDS_PLL_CHARGE_PUMP: |
||
2936 | *val = atomDataPtr->TMDS_Info->asMiscInfo[i].ucPLL_ChargePump; |
||
2937 | break; |
||
2938 | case ATOM_TMDS_PLL_DUTY_CYCLE: |
||
2939 | *val = atomDataPtr->TMDS_Info->asMiscInfo[i].ucPLL_DutyCycle; |
||
2940 | break; |
||
2941 | case ATOM_TMDS_PLL_VCO_GAIN: |
||
2942 | *val = atomDataPtr->TMDS_Info->asMiscInfo[i].ucPLL_VCO_Gain; |
||
2943 | break; |
||
2944 | case ATOM_TMDS_PLL_VOLTAGE_SWING: |
||
2945 | *val = atomDataPtr->TMDS_Info->asMiscInfo[i].ucPLL_VoltageSwing; |
||
2946 | break; |
||
2947 | default: |
||
2948 | return ATOM_NOT_IMPLEMENTED; |
||
2949 | } |
||
2950 | break; |
||
2951 | } |
||
2952 | } |
||
2953 | } |
||
2954 | |||
2955 | if (i > ATOM_MAX_MISC_INFO) |
||
2956 | return ATOM_FAILED; |
||
2957 | |||
2958 | return ATOM_SUCCESS; |
||
2959 | } |
||
2960 | |||
2961 | static DisplayModePtr |
||
2962 | rhdAtomLvdsTimings(atomBiosHandlePtr handle, ATOM_DTD_FORMAT *dtd) |
||
2963 | { |
||
2964 | DisplayModePtr mode; |
||
2965 | #define NAME_LEN 16 |
||
2966 | char name[NAME_LEN]; |
||
2967 | |||
2968 | RHDFUNC(handle); |
||
2969 | |||
2970 | if (!(mode = (DisplayModePtr)xcalloc(1,sizeof(DisplayModeRec)))) |
||
2971 | return NULL; |
||
2972 | |||
2973 | mode->CrtcHDisplay = mode->HDisplay = dtd->usHActive; |
||
2974 | mode->CrtcVDisplay = mode->VDisplay = dtd->usVActive; |
||
2975 | mode->CrtcHBlankStart = dtd->usHActive + dtd->ucHBorder; |
||
2976 | mode->CrtcHBlankEnd = mode->CrtcHBlankStart + dtd->usHBlanking_Time; |
||
2977 | mode->CrtcHTotal = mode->HTotal = mode->CrtcHBlankEnd + dtd->ucHBorder; |
||
2978 | mode->CrtcVBlankStart = dtd->usVActive + dtd->ucVBorder; |
||
2979 | mode->CrtcVBlankEnd = mode->CrtcVBlankStart + dtd->usVBlanking_Time; |
||
2980 | mode->CrtcVTotal = mode->VTotal = mode->CrtcVBlankEnd + dtd->ucVBorder; |
||
2981 | mode->CrtcHSyncStart = mode->HSyncStart = dtd->usHActive + dtd->usHSyncOffset; |
||
2982 | mode->CrtcHSyncEnd = mode->HSyncEnd = mode->HSyncStart + dtd->usHSyncWidth; |
||
2983 | mode->CrtcVSyncStart = mode->VSyncStart = dtd->usVActive + dtd->usVSyncOffset; |
||
2984 | mode->CrtcVSyncEnd = mode->VSyncEnd = mode->VSyncStart + dtd->usVSyncWidth; |
||
2985 | |||
2986 | mode->SynthClock = mode->Clock = dtd->usPixClk * 10; |
||
2987 | |||
2988 | mode->HSync = ((float) mode->Clock) / ((float)mode->HTotal); |
||
2989 | mode->VRefresh = (1000.0 * ((float) mode->Clock)) |
||
2990 | / ((float)(((float)mode->HTotal) * ((float)mode->VTotal))); |
||
2991 | |||
2992 | snprintf(name, NAME_LEN, "%dx%d", |
||
2993 | mode->HDisplay, mode->VDisplay); |
||
2994 | mode->name = strdup(name); |
||
2995 | |||
2996 | RHDDebug(handle->scrnIndex,"%s: LVDS Modeline: %s " |
||
2997 | "%2.d %i (%i) %i %i (%i) %i %i (%i) %i %i (%i) %i\n", |
||
2998 | __func__, mode->name, mode->Clock, |
||
2999 | mode->HDisplay, mode->CrtcHBlankStart, mode->HSyncStart, mode->CrtcHSyncEnd, |
||
3000 | mode->CrtcHBlankEnd, mode->HTotal, |
||
3001 | mode->VDisplay, mode->CrtcVBlankStart, mode->VSyncStart, mode->VSyncEnd, |
||
3002 | mode->CrtcVBlankEnd, mode->VTotal); |
||
3003 | #undef NAME_LEN |
||
3004 | return mode; |
||
3005 | } |
||
3006 | |||
3007 | static unsigned char* |
||
3008 | rhdAtomLvdsDDC(atomBiosHandlePtr handle, CARD32 offset, unsigned char *record) |
||
3009 | { |
||
3010 | unsigned char *EDIDBlock; |
||
3011 | |||
3012 | RHDFUNC(handle); |
||
3013 | |||
3014 | while (*record != ATOM_RECORD_END_TYPE) { |
||
3015 | |||
3016 | switch (*record) { |
||
3017 | case LCD_MODE_PATCH_RECORD_MODE_TYPE: |
||
3018 | offset += sizeof(ATOM_PATCH_RECORD_MODE); |
||
3019 | if (offset > handle->BIOSImageSize) break; |
||
3020 | record += sizeof(ATOM_PATCH_RECORD_MODE); |
||
3021 | break; |
||
3022 | |||
3023 | case LCD_RTS_RECORD_TYPE: |
||
3024 | offset += sizeof(ATOM_LCD_RTS_RECORD); |
||
3025 | if (offset > handle->BIOSImageSize) break; |
||
3026 | record += sizeof(ATOM_LCD_RTS_RECORD); |
||
3027 | break; |
||
3028 | |||
3029 | case LCD_CAP_RECORD_TYPE: |
||
3030 | offset += sizeof(ATOM_LCD_MODE_CONTROL_CAP); |
||
3031 | if (offset > handle->BIOSImageSize) break; |
||
3032 | record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); |
||
3033 | break; |
||
3034 | |||
3035 | case LCD_FAKE_EDID_PATCH_RECORD_TYPE: |
||
3036 | offset += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); |
||
3037 | /* check if the structure still fully lives in the BIOS image */ |
||
3038 | if (offset > handle->BIOSImageSize) break; |
||
3039 | offset += ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength |
||
3040 | - sizeof(UCHAR); |
||
3041 | if (offset > handle->BIOSImageSize) break; |
||
3042 | /* dup string as we free it later */ |
||
3043 | if (!(EDIDBlock = (unsigned char *)xalloc( |
||
3044 | ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength))) |
||
3045 | return NULL; |
||
3046 | memcpy(EDIDBlock,&((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDString, |
||
3047 | ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength); |
||
3048 | |||
3049 | /* for testing */ |
||
3050 | { |
||
3051 | // xf86MonPtr mon = xf86InterpretEDID(handle->scrnIndex,EDIDBlock); |
||
3052 | // xf86PrintEDID(mon); |
||
3053 | // kfree(mon); |
||
3054 | } |
||
3055 | return EDIDBlock; |
||
3056 | |||
3057 | case LCD_PANEL_RESOLUTION_RECORD_TYPE: |
||
3058 | offset += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); |
||
3059 | if (offset > handle->BIOSImageSize) break; |
||
3060 | record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); |
||
3061 | break; |
||
3062 | |||
3063 | default: |
||
3064 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
3065 | "%s: unknown record type: %x\n",__func__,*record); |
||
3066 | return NULL; |
||
3067 | } |
||
3068 | } |
||
3069 | |||
3070 | return NULL; |
||
3071 | } |
||
3072 | |||
3073 | static AtomBiosResult |
||
3074 | rhdAtomLvdsGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func, |
||
3075 | AtomBiosArgPtr data) |
||
3076 | { |
||
3077 | atomDataTablesPtr atomDataPtr; |
||
3078 | CARD8 crev, frev; |
||
3079 | unsigned long offset; |
||
3080 | |||
3081 | RHDFUNC(handle); |
||
3082 | |||
3083 | atomDataPtr = handle->atomDataPtr; |
||
3084 | |||
3085 | if (!rhdAtomGetTableRevisionAndSize( |
||
3086 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base), |
||
3087 | &crev,&frev,NULL)) { |
||
3088 | return ATOM_FAILED; |
||
3089 | } |
||
3090 | |||
3091 | switch (crev) { |
||
3092 | |||
3093 | case 1: |
||
3094 | switch (func) { |
||
3095 | case ATOMBIOS_GET_PANEL_MODE: |
||
3096 | data->mode = rhdAtomLvdsTimings(handle, |
||
3097 | &atomDataPtr->LVDS_Info |
||
3098 | .LVDS_Info->sLCDTiming); |
||
3099 | if (data->mode) |
||
3100 | return ATOM_SUCCESS; |
||
3101 | default: |
||
3102 | return ATOM_FAILED; |
||
3103 | } |
||
3104 | case 2: |
||
3105 | switch (func) { |
||
3106 | case ATOMBIOS_GET_PANEL_MODE: |
||
3107 | data->mode = rhdAtomLvdsTimings(handle, |
||
3108 | &atomDataPtr->LVDS_Info |
||
3109 | .LVDS_Info_v12->sLCDTiming); |
||
3110 | if (data->mode) |
||
3111 | return ATOM_SUCCESS; |
||
3112 | return ATOM_FAILED; |
||
3113 | |||
3114 | case ATOMBIOS_GET_PANEL_EDID: |
||
3115 | offset = (unsigned long)&atomDataPtr->LVDS_Info.base |
||
3116 | - (unsigned long)handle->BIOSBase |
||
3117 | + atomDataPtr->LVDS_Info |
||
3118 | .LVDS_Info_v12->usExtInfoTableOffset; |
||
3119 | |||
3120 | data->EDIDBlock |
||
3121 | = rhdAtomLvdsDDC(handle, offset, |
||
3122 | (unsigned char *) |
||
3123 | &atomDataPtr->LVDS_Info.base |
||
3124 | + atomDataPtr->LVDS_Info |
||
3125 | .LVDS_Info_v12->usExtInfoTableOffset); |
||
3126 | if (data->EDIDBlock) |
||
3127 | return ATOM_SUCCESS; |
||
3128 | default: |
||
3129 | return ATOM_FAILED; |
||
3130 | } |
||
3131 | default: |
||
3132 | return ATOM_NOT_IMPLEMENTED; |
||
3133 | } |
||
3134 | /*NOTREACHED*/ |
||
3135 | } |
||
3136 | |||
3137 | static AtomBiosResult |
||
3138 | rhdAtomLvdsInfoQuery(atomBiosHandlePtr handle, |
||
3139 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3140 | { |
||
3141 | atomDataTablesPtr atomDataPtr; |
||
3142 | CARD8 crev, frev; |
||
3143 | CARD32 *val = &data->val; |
||
3144 | |||
3145 | RHDFUNC(handle); |
||
3146 | |||
3147 | atomDataPtr = handle->atomDataPtr; |
||
3148 | |||
3149 | if (!rhdAtomGetTableRevisionAndSize( |
||
3150 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base), |
||
3151 | &crev,&frev,NULL)) { |
||
3152 | return ATOM_FAILED; |
||
3153 | } |
||
3154 | |||
3155 | switch (crev) { |
||
3156 | case 1: |
||
3157 | switch (func) { |
||
3158 | case ATOM_LVDS_SUPPORTED_REFRESH_RATE: |
||
3159 | *val = atomDataPtr->LVDS_Info |
||
3160 | .LVDS_Info->usSupportedRefreshRate; |
||
3161 | break; |
||
3162 | case ATOM_LVDS_OFF_DELAY: |
||
3163 | *val = atomDataPtr->LVDS_Info |
||
3164 | .LVDS_Info->usOffDelayInMs; |
||
3165 | break; |
||
3166 | case ATOM_LVDS_SEQ_DIG_ONTO_DE: |
||
3167 | *val = atomDataPtr->LVDS_Info |
||
3168 | .LVDS_Info->ucPowerSequenceDigOntoDEin10Ms * 10; |
||
3169 | break; |
||
3170 | case ATOM_LVDS_SEQ_DE_TO_BL: |
||
3171 | *val = atomDataPtr->LVDS_Info |
||
3172 | .LVDS_Info->ucPowerSequenceDEtoBLOnin10Ms * 10; |
||
3173 | break; |
||
3174 | case ATOM_LVDS_TEMPORAL_DITHER: |
||
3175 | *val = (atomDataPtr->LVDS_Info |
||
3176 | .LVDS_Info->ucLVDS_Misc & 0x40) != 0; |
||
3177 | break; |
||
3178 | case ATOM_LVDS_SPATIAL_DITHER: |
||
3179 | *val = (atomDataPtr->LVDS_Info |
||
3180 | .LVDS_Info->ucLVDS_Misc & 0x20) != 0; |
||
3181 | break; |
||
3182 | case ATOM_LVDS_FPDI: |
||
3183 | *val = (atomDataPtr->LVDS_Info |
||
3184 | .LVDS_Info->ucLVDS_Misc & 0x10) != 0; |
||
3185 | break; |
||
3186 | case ATOM_LVDS_DUALLINK: |
||
3187 | *val = (atomDataPtr->LVDS_Info |
||
3188 | .LVDS_Info->ucLVDS_Misc & 0x01) != 0; |
||
3189 | break; |
||
3190 | case ATOM_LVDS_24BIT: |
||
3191 | *val = (atomDataPtr->LVDS_Info |
||
3192 | .LVDS_Info->ucLVDS_Misc & 0x02) != 0; |
||
3193 | break; |
||
3194 | case ATOM_LVDS_GREYLVL: |
||
3195 | *val = (atomDataPtr->LVDS_Info |
||
3196 | .LVDS_Info->ucLVDS_Misc & ATOM_PANEL_MISC_GREY_LEVEL) |
||
3197 | >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT ; |
||
3198 | break; |
||
3199 | default: |
||
3200 | return ATOM_NOT_IMPLEMENTED; |
||
3201 | } |
||
3202 | break; |
||
3203 | case 2: |
||
3204 | switch (func) { |
||
3205 | case ATOM_LVDS_SUPPORTED_REFRESH_RATE: |
||
3206 | *val = atomDataPtr->LVDS_Info |
||
3207 | .LVDS_Info_v12->usSupportedRefreshRate; |
||
3208 | break; |
||
3209 | case ATOM_LVDS_OFF_DELAY: |
||
3210 | *val = atomDataPtr->LVDS_Info |
||
3211 | .LVDS_Info_v12->usOffDelayInMs; |
||
3212 | break; |
||
3213 | case ATOM_LVDS_SEQ_DIG_ONTO_DE: |
||
3214 | *val = atomDataPtr->LVDS_Info |
||
3215 | .LVDS_Info_v12->ucPowerSequenceDigOntoDEin10Ms * 10; |
||
3216 | break; |
||
3217 | case ATOM_LVDS_SEQ_DE_TO_BL: |
||
3218 | *val = atomDataPtr->LVDS_Info |
||
3219 | .LVDS_Info_v12->ucPowerSequenceDEtoBLOnin10Ms * 10; |
||
3220 | break; |
||
3221 | case ATOM_LVDS_FPDI: |
||
3222 | *val = (atomDataPtr->LVDS_Info |
||
3223 | .LVDS_Info_v12->ucLVDS_Misc * 0x10) != 0; |
||
3224 | break; |
||
3225 | case ATOM_LVDS_SPATIAL_DITHER: |
||
3226 | *val = (atomDataPtr->LVDS_Info |
||
3227 | .LVDS_Info_v12->ucLVDS_Misc & 0x20) != 0; |
||
3228 | break; |
||
3229 | case ATOM_LVDS_TEMPORAL_DITHER: |
||
3230 | *val = (atomDataPtr->LVDS_Info |
||
3231 | .LVDS_Info_v12->ucLVDS_Misc & 0x40) != 0; |
||
3232 | break; |
||
3233 | case ATOM_LVDS_DUALLINK: |
||
3234 | *val = (atomDataPtr->LVDS_Info |
||
3235 | .LVDS_Info_v12->ucLVDS_Misc & 0x01) != 0; |
||
3236 | break; |
||
3237 | case ATOM_LVDS_24BIT: |
||
3238 | *val = (atomDataPtr->LVDS_Info |
||
3239 | .LVDS_Info_v12->ucLVDS_Misc & 0x02) != 0; |
||
3240 | break; |
||
3241 | case ATOM_LVDS_GREYLVL: |
||
3242 | *val = (atomDataPtr->LVDS_Info |
||
3243 | .LVDS_Info_v12->ucLVDS_Misc & 0x0C) >> 2; |
||
3244 | break; |
||
3245 | default: |
||
3246 | return ATOM_NOT_IMPLEMENTED; |
||
3247 | } |
||
3248 | break; |
||
3249 | default: |
||
3250 | return ATOM_NOT_IMPLEMENTED; |
||
3251 | } |
||
3252 | |||
3253 | return ATOM_SUCCESS; |
||
3254 | } |
||
3255 | |||
3256 | static AtomBiosResult |
||
3257 | rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle, |
||
3258 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3259 | { |
||
3260 | atomDataTablesPtr atomDataPtr; |
||
3261 | CARD8 crev, frev; |
||
3262 | CARD32 *val = &data->val; |
||
3263 | |||
3264 | RHDFUNC(handle); |
||
3265 | |||
3266 | atomDataPtr = handle->atomDataPtr; |
||
3267 | |||
3268 | if (!rhdAtomGetTableRevisionAndSize( |
||
3269 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->CompassionateData), |
||
3270 | &crev,&frev,NULL)) { |
||
3271 | return ATOM_FAILED; |
||
3272 | } |
||
3273 | |||
3274 | switch (func) { |
||
3275 | case ATOM_DAC1_BG_ADJ: |
||
3276 | *val = atomDataPtr->CompassionateData-> |
||
3277 | ucDAC1_BG_Adjustment; |
||
3278 | break; |
||
3279 | case ATOM_DAC1_DAC_ADJ: |
||
3280 | *val = atomDataPtr->CompassionateData-> |
||
3281 | ucDAC1_DAC_Adjustment; |
||
3282 | break; |
||
3283 | case ATOM_DAC1_FORCE: |
||
3284 | *val = atomDataPtr->CompassionateData-> |
||
3285 | usDAC1_FORCE_Data; |
||
3286 | break; |
||
3287 | case ATOM_DAC2_CRTC2_BG_ADJ: |
||
3288 | *val = atomDataPtr->CompassionateData-> |
||
3289 | ucDAC2_CRT2_BG_Adjustment; |
||
3290 | break; |
||
3291 | case ATOM_DAC2_NTSC_BG_ADJ: |
||
3292 | *val = atomDataPtr->CompassionateData-> |
||
3293 | ucDAC2_NTSC_BG_Adjustment; |
||
3294 | break; |
||
3295 | case ATOM_DAC2_PAL_BG_ADJ: |
||
3296 | *val = atomDataPtr->CompassionateData-> |
||
3297 | ucDAC2_PAL_BG_Adjustment; |
||
3298 | break; |
||
3299 | case ATOM_DAC2_CV_BG_ADJ: |
||
3300 | *val = atomDataPtr->CompassionateData-> |
||
3301 | ucDAC2_CV_BG_Adjustment; |
||
3302 | break; |
||
3303 | case ATOM_DAC2_CRTC2_DAC_ADJ: |
||
3304 | *val = atomDataPtr->CompassionateData-> |
||
3305 | ucDAC2_CRT2_DAC_Adjustment; |
||
3306 | break; |
||
3307 | case ATOM_DAC2_NTSC_DAC_ADJ: |
||
3308 | *val = atomDataPtr->CompassionateData-> |
||
3309 | ucDAC2_NTSC_DAC_Adjustment; |
||
3310 | break; |
||
3311 | case ATOM_DAC2_PAL_DAC_ADJ: |
||
3312 | *val = atomDataPtr->CompassionateData-> |
||
3313 | ucDAC2_PAL_DAC_Adjustment; |
||
3314 | break; |
||
3315 | case ATOM_DAC2_CV_DAC_ADJ: |
||
3316 | *val = atomDataPtr->CompassionateData-> |
||
3317 | ucDAC2_CV_DAC_Adjustment; |
||
3318 | break; |
||
3319 | case ATOM_DAC2_CRTC2_FORCE: |
||
3320 | *val = atomDataPtr->CompassionateData-> |
||
3321 | usDAC2_CRT2_FORCE_Data; |
||
3322 | break; |
||
3323 | case ATOM_DAC2_CRTC2_MUX_REG_IND: |
||
3324 | *val = atomDataPtr->CompassionateData-> |
||
3325 | usDAC2_CRT2_MUX_RegisterIndex; |
||
3326 | break; |
||
3327 | case ATOM_DAC2_CRTC2_MUX_REG_INFO: |
||
3328 | *val = atomDataPtr->CompassionateData-> |
||
3329 | ucDAC2_CRT2_MUX_RegisterInfo; |
||
3330 | break; |
||
3331 | default: |
||
3332 | return ATOM_NOT_IMPLEMENTED; |
||
3333 | } |
||
3334 | return ATOM_SUCCESS; |
||
3335 | } |
||
3336 | |||
3337 | /* |
||
3338 | * |
||
3339 | */ |
||
3340 | enum atomPCIELanes atomPCIELanesMap[] = { |
||
3341 | atomPCIELaneNONE, |
||
3342 | atomPCIELane0_3, |
||
3343 | atomPCIELane4_7, |
||
3344 | atomPCIELane0_7, |
||
3345 | atomPCIELane8_11, |
||
3346 | atomPCIELaneNONE, |
||
3347 | atomPCIELaneNONE, |
||
3348 | atomPCIELaneNONE, |
||
3349 | atomPCIELane12_15, |
||
3350 | atomPCIELaneNONE, |
||
3351 | atomPCIELaneNONE, |
||
3352 | atomPCIELaneNONE, |
||
3353 | atomPCIELane8_15, |
||
3354 | atomPCIELaneNONE, |
||
3355 | atomPCIELaneNONE, |
||
3356 | atomPCIELaneNONE, |
||
3357 | atomPCIELaneNONE |
||
3358 | }; |
||
3359 | |||
3360 | static AtomBiosResult |
||
3361 | rhdAtomIntegratedSystemInfoQuery(atomBiosHandlePtr handle, |
||
3362 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3363 | { |
||
3364 | atomDataTablesPtr atomDataPtr; |
||
3365 | CARD8 crev, frev; |
||
3366 | CARD32 *val = &data->val; |
||
3367 | |||
3368 | RHDFUNC(handle); |
||
3369 | |||
3370 | atomDataPtr = handle->atomDataPtr; |
||
3371 | |||
3372 | if (!rhdAtomGetTableRevisionAndSize( |
||
3373 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->IntegratedSystemInfo.base), |
||
3374 | &crev,&frev,NULL)) { |
||
3375 | return ATOM_FAILED; |
||
3376 | } |
||
3377 | |||
3378 | switch (crev) { |
||
3379 | case 1: |
||
3380 | switch (func) { |
||
3381 | case ATOM_GET_PCIENB_CFG_REG7: |
||
3382 | *val = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->usPCIENBCfgReg7; |
||
3383 | break; |
||
3384 | case ATOM_GET_CAPABILITY_FLAG: |
||
3385 | *val = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->usCapabilityFlag; |
||
3386 | break; |
||
3387 | default: |
||
3388 | return ATOM_NOT_IMPLEMENTED; |
||
3389 | } |
||
3390 | break; |
||
3391 | case 2: |
||
3392 | switch (func) { |
||
3393 | case ATOM_GET_PCIE_LANES: |
||
3394 | { |
||
3395 | CARD32 n; |
||
3396 | switch (*val) { |
||
3397 | case 1: |
||
3398 | n = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulDDISlot1Config; |
||
3399 | break; |
||
3400 | case 2: |
||
3401 | n = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulDDISlot2Config; |
||
3402 | break; |
||
3403 | default: |
||
3404 | return ATOM_FAILED; |
||
3405 | } |
||
3406 | data->pcieLanes.Chassis = atomPCIELanesMap[n & 0xf]; |
||
3407 | data->pcieLanes.Docking = atomPCIELanesMap[(n >> 4) & 0xf]; |
||
3408 | RHDDebug(handle->scrnIndex, "AtomBIOS IntegratedSystemInfo PCIELanes: Chassis=%x Docking=%x\n", |
||
3409 | data->pcieLanes.Chassis, data->pcieLanes.Docking); |
||
3410 | return ATOM_SUCCESS; |
||
3411 | } |
||
3412 | break; |
||
3413 | default: |
||
3414 | return ATOM_NOT_IMPLEMENTED; |
||
3415 | } |
||
3416 | return ATOM_NOT_IMPLEMENTED; |
||
3417 | } |
||
3418 | |||
3419 | return ATOM_SUCCESS; |
||
3420 | } |
||
3421 | |||
3422 | static DisplayModePtr |
||
3423 | rhdAtomAnalogTVTimings(atomBiosHandlePtr handle, |
||
3424 | ATOM_ANALOG_TV_INFO *tv_info, |
||
3425 | enum RHD_TV_MODE tvMode) |
||
3426 | { |
||
3427 | atomDataTablesPtr atomDataPtr; |
||
3428 | DisplayModePtr mode; |
||
3429 | int mode_n; |
||
3430 | char *name; |
||
3431 | ATOM_MODE_TIMING *amt; |
||
3432 | |||
3433 | RHDFUNC(handle); |
||
3434 | |||
3435 | atomDataPtr = handle->atomDataPtr; |
||
3436 | |||
3437 | switch (tvMode) { |
||
3438 | case NTSC_SUPPORT: |
||
3439 | case NTSCJ_SUPPORT: |
||
3440 | mode_n = 0; |
||
3441 | name = "TV_NTSC"; |
||
3442 | break; |
||
3443 | case PAL_SUPPORT: |
||
3444 | case PALM_SUPPORT: |
||
3445 | case PALCN_SUPPORT: |
||
3446 | case PALN_SUPPORT: |
||
3447 | case PAL60_SUPPORT: |
||
3448 | case SECAM_SUPPORT: |
||
3449 | mode_n = 1; |
||
3450 | name = "TV_PAL/SECAM"; |
||
3451 | break; |
||
3452 | default: |
||
3453 | return NULL; |
||
3454 | } |
||
3455 | |||
3456 | |||
3457 | if (!(tv_info->ucTV_SupportedStandard & (tvMode))) |
||
3458 | return NULL; |
||
3459 | |||
3460 | if (!(mode = (DisplayModePtr)xcalloc(1,sizeof(DisplayModeRec)))) |
||
3461 | return NULL; |
||
3462 | |||
3463 | amt = &tv_info->aModeTimings[mode_n]; |
||
3464 | |||
3465 | mode->CrtcHDisplay = mode->HDisplay = amt->usCRTC_H_Disp; |
||
3466 | mode->CrtcHSyncStart = mode->HSyncStart = amt->usCRTC_H_SyncStart; |
||
3467 | mode->CrtcHSyncEnd = mode->HSyncEnd = mode->HSyncStart + amt->usCRTC_H_SyncWidth; |
||
3468 | mode->CrtcHTotal = mode->HTotal = amt->usCRTC_H_Total; |
||
3469 | mode->CrtcHBlankStart = mode->HDisplay + amt->usCRTC_OverscanRight; |
||
3470 | mode->CrtcHBlankEnd = mode->HTotal - amt->usCRTC_OverscanLeft; |
||
3471 | |||
3472 | mode->CrtcVDisplay = mode->VDisplay = amt->usCRTC_V_Disp; |
||
3473 | mode->CrtcVSyncStart = mode->VSyncStart = amt->usCRTC_V_SyncStart; |
||
3474 | mode->CrtcVSyncEnd = mode->VSyncEnd = mode->VSyncStart + amt->usCRTC_V_SyncWidth; |
||
3475 | mode->CrtcVTotal = mode->VTotal = amt->usCRTC_V_Total; |
||
3476 | mode->CrtcVBlankStart = mode->VDisplay + amt->usCRTC_OverscanBottom; |
||
3477 | mode->CrtcVBlankEnd = mode->CrtcVTotal - amt->usCRTC_OverscanTop; |
||
3478 | |||
3479 | mode->SynthClock = mode->Clock = amt->usPixelClock * 10; |
||
3480 | if (amt->susModeMiscInfo.usAccess & ATOM_HSYNC_POLARITY) |
||
3481 | mode->Flags |= V_NHSYNC; |
||
3482 | else |
||
3483 | mode->Flags |= V_PHSYNC; |
||
3484 | if (amt->susModeMiscInfo.usAccess & ATOM_VSYNC_POLARITY) |
||
3485 | mode->Flags |= V_NVSYNC; |
||
3486 | else |
||
3487 | mode->Flags |= V_PVSYNC; |
||
3488 | if (amt->susModeMiscInfo.usAccess & ATOM_INTERLACE) |
||
3489 | mode->Flags |= V_INTERLACE; |
||
3490 | if (amt->susModeMiscInfo.usAccess & ATOM_COMPOSITESYNC) |
||
3491 | mode->Flags |= V_CSYNC; |
||
3492 | if (amt->susModeMiscInfo.usAccess & ATOM_DOUBLE_CLOCK_MODE) |
||
3493 | mode->Flags |= V_DBLCLK; |
||
3494 | |||
3495 | mode->HSync = ((float) mode->Clock) / ((float)mode->HTotal); |
||
3496 | mode->VRefresh = (1000.0 * ((float) mode->Clock)) |
||
3497 | / ((float)(((float)mode->HTotal) * ((float)mode->VTotal))); |
||
3498 | |||
3499 | mode->name = strdup(name); |
||
3500 | |||
3501 | RHDDebug(handle->scrnIndex,"%s: TV Modeline: %s " |
||
3502 | "%2.d %i (%i) %i %i (%i) %i %i (%i) %i %i (%i) %i\n", |
||
3503 | __func__, mode->name, mode->Clock, |
||
3504 | mode->HDisplay, mode->CrtcHBlankStart, mode->HSyncStart, mode->CrtcHSyncEnd, |
||
3505 | mode->CrtcHBlankEnd, mode->HTotal, |
||
3506 | mode->VDisplay, mode->CrtcVBlankStart, mode->VSyncStart, mode->VSyncEnd, |
||
3507 | mode->CrtcVBlankEnd, mode->VTotal); |
||
3508 | |||
3509 | |||
3510 | return mode; |
||
3511 | } |
||
3512 | |||
3513 | static AtomBiosResult |
||
3514 | rhdAtomAnalogTVInfoQuery(atomBiosHandlePtr handle, |
||
3515 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3516 | { |
||
3517 | CARD8 crev, frev; |
||
3518 | atomDataTablesPtr atomDataPtr = handle->atomDataPtr; |
||
3519 | int mode = 0, i; |
||
3520 | struct { enum RHD_TV_MODE rhd_mode; int atomMode; } |
||
3521 | tv_modes[] = { |
||
3522 | { RHD_TV_NTSC, NTSC_SUPPORT }, |
||
3523 | { RHD_TV_NTSCJ, NTSCJ_SUPPORT}, |
||
3524 | { RHD_TV_PAL, PAL_SUPPORT }, |
||
3525 | { RHD_TV_PALM, PALM_SUPPORT }, |
||
3526 | { RHD_TV_PALCN, PALCN_SUPPORT}, |
||
3527 | { RHD_TV_PALN, PALN_SUPPORT }, |
||
3528 | { RHD_TV_PAL60, PAL60_SUPPORT}, |
||
3529 | { RHD_TV_SECAM, SECAM_SUPPORT}, |
||
3530 | { RHD_TV_NONE, 0 } |
||
3531 | }; |
||
3532 | |||
3533 | |||
3534 | RHDFUNC(handle); |
||
3535 | |||
3536 | if (!rhdAtomGetTableRevisionAndSize( |
||
3537 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->AnalogTV_Info), |
||
3538 | &crev,&frev,NULL)) { |
||
3539 | return ATOM_FAILED; |
||
3540 | } |
||
3541 | switch (func) { |
||
3542 | case ATOM_ANALOG_TV_MODE: |
||
3543 | for (i = 0; tv_modes[i].atomMode; i++) { |
||
3544 | if (data->tvMode == tv_modes[i].rhd_mode) { |
||
3545 | mode = tv_modes[i].atomMode; |
||
3546 | break; |
||
3547 | } |
||
3548 | } |
||
3549 | data->mode = rhdAtomAnalogTVTimings(handle, |
||
3550 | atomDataPtr->AnalogTV_Info, |
||
3551 | mode); |
||
3552 | if (!data->mode) |
||
3553 | return ATOM_FAILED; |
||
3554 | return ATOM_SUCCESS; |
||
3555 | case ATOM_ANALOG_TV_DEFAULT_MODE: |
||
3556 | data->tvMode = tv_modes[atomDataPtr->AnalogTV_Info->ucTV_BootUpDefaultStandard - 1].rhd_mode; |
||
3557 | break; |
||
3558 | case ATOM_ANALOG_TV_SUPPORTED_MODES: |
||
3559 | mode = (CARD32)atomDataPtr->AnalogTV_Info->ucTV_SupportedStandard; |
||
3560 | data->val = 0; |
||
3561 | for (i = 0; tv_modes[i].atomMode; i++) { |
||
3562 | if (tv_modes[i].atomMode & mode) { |
||
3563 | data->val |= tv_modes[i].rhd_mode; |
||
3564 | } |
||
3565 | } |
||
3566 | break; |
||
3567 | default: |
||
3568 | return ATOM_NOT_IMPLEMENTED; |
||
3569 | } |
||
3570 | |||
3571 | return ATOM_SUCCESS; |
||
3572 | } |
||
3573 | |||
3574 | static AtomBiosResult |
||
3575 | rhdAtomGPIOI2CInfoQuery(atomBiosHandlePtr handle, |
||
3576 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3577 | { |
||
3578 | atomDataTablesPtr atomDataPtr; |
||
3579 | CARD8 crev, frev; |
||
3580 | CARD32 *val = &data->val; |
||
3581 | unsigned short size; |
||
3582 | |||
3583 | RHDFUNC(handle); |
||
3584 | |||
3585 | atomDataPtr = handle->atomDataPtr; |
||
3586 | |||
3587 | if (!rhdAtomGetTableRevisionAndSize( |
||
3588 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->GPIO_I2C_Info), |
||
3589 | &crev,&frev,&size)) { |
||
3590 | return ATOM_FAILED; |
||
3591 | } |
||
3592 | |||
3593 | if ((sizeof(ATOM_COMMON_TABLE_HEADER) |
||
3594 | + (*val * sizeof(ATOM_GPIO_I2C_ASSIGMENT))) > size) { |
||
3595 | xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: GPIO_I2C Device " |
||
3596 | "num %lu exeeds table size %u\n",__func__, |
||
3597 | (unsigned long)val, |
||
3598 | size); |
||
3599 | return ATOM_FAILED; |
||
3600 | } |
||
3601 | |||
3602 | switch (func) { |
||
3603 | case ATOM_GPIO_I2C_DATA_MASK: |
||
3604 | *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] |
||
3605 | .usDataMaskRegisterIndex; |
||
3606 | break; |
||
3607 | |||
3608 | case ATOM_GPIO_I2C_DATA_MASK_SHIFT: |
||
3609 | *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] |
||
3610 | .ucDataMaskShift; |
||
3611 | break; |
||
3612 | |||
3613 | case ATOM_GPIO_I2C_CLK_MASK: |
||
3614 | *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] |
||
3615 | .usClkMaskRegisterIndex; |
||
3616 | break; |
||
3617 | |||
3618 | case ATOM_GPIO_I2C_CLK_MASK_SHIFT: |
||
3619 | *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] |
||
3620 | .ucClkMaskShift; |
||
3621 | break; |
||
3622 | |||
3623 | default: |
||
3624 | return ATOM_NOT_IMPLEMENTED; |
||
3625 | } |
||
3626 | return ATOM_SUCCESS; |
||
3627 | } |
||
3628 | |||
3629 | static AtomBiosResult |
||
3630 | rhdAtomFirmwareInfoQuery(atomBiosHandlePtr handle, |
||
3631 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3632 | { |
||
3633 | atomDataTablesPtr atomDataPtr; |
||
3634 | CARD8 crev, frev; |
||
3635 | CARD32 *val = &data->val; |
||
3636 | |||
3637 | RHDFUNC(handle); |
||
3638 | |||
3639 | atomDataPtr = handle->atomDataPtr; |
||
3640 | |||
3641 | if (!rhdAtomGetTableRevisionAndSize( |
||
3642 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->FirmwareInfo.base), |
||
3643 | &crev,&frev,NULL)) { |
||
3644 | return ATOM_FAILED; |
||
3645 | } |
||
3646 | |||
3647 | switch (crev) { |
||
3648 | case 1: |
||
3649 | switch (func) { |
||
3650 | case GET_DEFAULT_ENGINE_CLOCK: |
||
3651 | *val = atomDataPtr->FirmwareInfo |
||
3652 | .FirmwareInfo->ulDefaultEngineClock * 10; |
||
3653 | break; |
||
3654 | case GET_DEFAULT_MEMORY_CLOCK: |
||
3655 | *val = atomDataPtr->FirmwareInfo |
||
3656 | .FirmwareInfo->ulDefaultMemoryClock * 10; |
||
3657 | break; |
||
3658 | case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT: |
||
3659 | *val = atomDataPtr->FirmwareInfo |
||
3660 | .FirmwareInfo->ulMaxPixelClockPLL_Output * 10; |
||
3661 | break; |
||
3662 | case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT: |
||
3663 | *val = atomDataPtr->FirmwareInfo |
||
3664 | .FirmwareInfo->usMinPixelClockPLL_Output * 10; |
||
3665 | case GET_MAX_PIXEL_CLOCK_PLL_INPUT: |
||
3666 | *val = atomDataPtr->FirmwareInfo |
||
3667 | .FirmwareInfo->usMaxPixelClockPLL_Input * 10; |
||
3668 | break; |
||
3669 | case GET_MIN_PIXEL_CLOCK_PLL_INPUT: |
||
3670 | *val = atomDataPtr->FirmwareInfo |
||
3671 | .FirmwareInfo->usMinPixelClockPLL_Input * 10; |
||
3672 | break; |
||
3673 | case GET_MAX_PIXEL_CLK: |
||
3674 | *val = atomDataPtr->FirmwareInfo |
||
3675 | .FirmwareInfo->usMaxPixelClock * 10; |
||
3676 | break; |
||
3677 | case GET_REF_CLOCK: |
||
3678 | *val = atomDataPtr->FirmwareInfo |
||
3679 | .FirmwareInfo->usReferenceClock * 10; |
||
3680 | break; |
||
3681 | default: |
||
3682 | return ATOM_NOT_IMPLEMENTED; |
||
3683 | } |
||
3684 | case 2: |
||
3685 | switch (func) { |
||
3686 | case GET_DEFAULT_ENGINE_CLOCK: |
||
3687 | *val = atomDataPtr->FirmwareInfo |
||
3688 | .FirmwareInfo_V_1_2->ulDefaultEngineClock * 10; |
||
3689 | break; |
||
3690 | case GET_DEFAULT_MEMORY_CLOCK: |
||
3691 | *val = atomDataPtr->FirmwareInfo |
||
3692 | .FirmwareInfo_V_1_2->ulDefaultMemoryClock * 10; |
||
3693 | break; |
||
3694 | case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT: |
||
3695 | *val = atomDataPtr->FirmwareInfo |
||
3696 | .FirmwareInfo_V_1_2->ulMaxPixelClockPLL_Output * 10; |
||
3697 | break; |
||
3698 | case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT: |
||
3699 | *val = atomDataPtr->FirmwareInfo |
||
3700 | .FirmwareInfo_V_1_2->usMinPixelClockPLL_Output * 10; |
||
3701 | break; |
||
3702 | case GET_MAX_PIXEL_CLOCK_PLL_INPUT: |
||
3703 | *val = atomDataPtr->FirmwareInfo |
||
3704 | .FirmwareInfo_V_1_2->usMaxPixelClockPLL_Input * 10; |
||
3705 | break; |
||
3706 | case GET_MIN_PIXEL_CLOCK_PLL_INPUT: |
||
3707 | *val = atomDataPtr->FirmwareInfo |
||
3708 | .FirmwareInfo_V_1_2->usMinPixelClockPLL_Input * 10; |
||
3709 | break; |
||
3710 | case GET_MAX_PIXEL_CLK: |
||
3711 | *val = atomDataPtr->FirmwareInfo |
||
3712 | .FirmwareInfo_V_1_2->usMaxPixelClock * 10; |
||
3713 | break; |
||
3714 | case GET_REF_CLOCK: |
||
3715 | *val = atomDataPtr->FirmwareInfo |
||
3716 | .FirmwareInfo_V_1_2->usReferenceClock * 10; |
||
3717 | break; |
||
3718 | default: |
||
3719 | return ATOM_NOT_IMPLEMENTED; |
||
3720 | } |
||
3721 | break; |
||
3722 | case 3: |
||
3723 | switch (func) { |
||
3724 | case GET_DEFAULT_ENGINE_CLOCK: |
||
3725 | *val = atomDataPtr->FirmwareInfo |
||
3726 | .FirmwareInfo_V_1_3->ulDefaultEngineClock * 10; |
||
3727 | break; |
||
3728 | case GET_DEFAULT_MEMORY_CLOCK: |
||
3729 | *val = atomDataPtr->FirmwareInfo |
||
3730 | .FirmwareInfo_V_1_3->ulDefaultMemoryClock * 10; |
||
3731 | break; |
||
3732 | case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT: |
||
3733 | *val = atomDataPtr->FirmwareInfo |
||
3734 | .FirmwareInfo_V_1_3->ulMaxPixelClockPLL_Output * 10; |
||
3735 | break; |
||
3736 | case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT: |
||
3737 | *val = atomDataPtr->FirmwareInfo |
||
3738 | .FirmwareInfo_V_1_3->usMinPixelClockPLL_Output * 10; |
||
3739 | break; |
||
3740 | case GET_MAX_PIXEL_CLOCK_PLL_INPUT: |
||
3741 | *val = atomDataPtr->FirmwareInfo |
||
3742 | .FirmwareInfo_V_1_3->usMaxPixelClockPLL_Input * 10; |
||
3743 | break; |
||
3744 | case GET_MIN_PIXEL_CLOCK_PLL_INPUT: |
||
3745 | *val = atomDataPtr->FirmwareInfo |
||
3746 | .FirmwareInfo_V_1_3->usMinPixelClockPLL_Input * 10; |
||
3747 | break; |
||
3748 | case GET_MAX_PIXEL_CLK: |
||
3749 | *val = atomDataPtr->FirmwareInfo |
||
3750 | .FirmwareInfo_V_1_3->usMaxPixelClock * 10; |
||
3751 | break; |
||
3752 | case GET_REF_CLOCK: |
||
3753 | *val = atomDataPtr->FirmwareInfo |
||
3754 | .FirmwareInfo_V_1_3->usReferenceClock * 10; |
||
3755 | break; |
||
3756 | default: |
||
3757 | return ATOM_NOT_IMPLEMENTED; |
||
3758 | } |
||
3759 | break; |
||
3760 | case 4: |
||
3761 | switch (func) { |
||
3762 | case GET_DEFAULT_ENGINE_CLOCK: |
||
3763 | *val = atomDataPtr->FirmwareInfo |
||
3764 | .FirmwareInfo_V_1_4->ulDefaultEngineClock * 10; |
||
3765 | break; |
||
3766 | case GET_DEFAULT_MEMORY_CLOCK: |
||
3767 | *val = atomDataPtr->FirmwareInfo |
||
3768 | .FirmwareInfo_V_1_4->ulDefaultMemoryClock * 10; |
||
3769 | break; |
||
3770 | case GET_MAX_PIXEL_CLOCK_PLL_INPUT: |
||
3771 | *val = atomDataPtr->FirmwareInfo |
||
3772 | .FirmwareInfo_V_1_4->usMaxPixelClockPLL_Input * 10; |
||
3773 | break; |
||
3774 | case GET_MIN_PIXEL_CLOCK_PLL_INPUT: |
||
3775 | *val = atomDataPtr->FirmwareInfo |
||
3776 | .FirmwareInfo_V_1_4->usMinPixelClockPLL_Input * 10; |
||
3777 | break; |
||
3778 | case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT: |
||
3779 | *val = atomDataPtr->FirmwareInfo |
||
3780 | .FirmwareInfo_V_1_4->ulMaxPixelClockPLL_Output * 10; |
||
3781 | break; |
||
3782 | case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT: |
||
3783 | *val = atomDataPtr->FirmwareInfo |
||
3784 | .FirmwareInfo_V_1_4->usMinPixelClockPLL_Output * 10; |
||
3785 | break; |
||
3786 | case GET_MAX_PIXEL_CLK: |
||
3787 | *val = atomDataPtr->FirmwareInfo |
||
3788 | .FirmwareInfo_V_1_4->usMaxPixelClock * 10; |
||
3789 | break; |
||
3790 | case GET_REF_CLOCK: |
||
3791 | *val = atomDataPtr->FirmwareInfo |
||
3792 | .FirmwareInfo_V_1_4->usReferenceClock * 10; |
||
3793 | break; |
||
3794 | default: |
||
3795 | return ATOM_NOT_IMPLEMENTED; |
||
3796 | } |
||
3797 | break; |
||
3798 | default: |
||
3799 | return ATOM_NOT_IMPLEMENTED; |
||
3800 | } |
||
3801 | return ATOM_SUCCESS; |
||
3802 | } |
||
3803 | |||
3804 | /* |
||
3805 | * |
||
3806 | */ |
||
3807 | static AtomBiosResult |
||
3808 | rhdAtomGetConditionalGoldenSetting(atomBiosHandlePtr handle, |
||
3809 | AtomBiosRequestID func, AtomBiosArgPtr data) |
||
3810 | { |
||
3811 | unsigned short *table = (unsigned short *)data->GoldenSettings.BIOSPtr; |
||
3812 | unsigned short entry_size = *(table++); |
||
3813 | |||
3814 | RHDFUNC(handle); |
||
3815 | |||
3816 | RHDDebug(handle->scrnIndex, "%s: testing 0x%4.4x\n",__func__, |
||
3817 | data->GoldenSettings.value); |
||
3818 | |||
3819 | /* @@@ endian! */ |
||
3820 | while (table < (unsigned short *)data->GoldenSettings.End) { |
||
3821 | RHDDebugCont("\t\t against: 0x%8.8x\n", table[1] << 16 | table[0]); |
||
3822 | if ((data->GoldenSettings.value >> 16) == table[1]) { |
||
3823 | if ((data->GoldenSettings.value & 0xffff) <= table[0]) { |
||
3824 | data->GoldenSettings.BIOSPtr = (unsigned char *)(table + 2); |
||
3825 | return ATOM_SUCCESS; |
||
3826 | } |
||
3827 | } |
||
3828 | table = (unsigned short *)(((unsigned char *)table) + entry_size); |
||
3829 | } |
||
3830 | return ATOM_FAILED; |
||
3831 | } |
||
3832 | |||
3833 | #define Limit(n,max,name) ((n >= max) ? ( \ |
||
3834 | dbgprintf(handle->scrnIndex,X_ERROR,"%s: %s %i exceeds maximum %i\n", \ |
||
3835 | __func__,name,n,max), TRUE) : FALSE) |
||
3836 | |||
3837 | static const struct _rhd_connector_objs |
||
3838 | { |
||
3839 | char *name; |
||
3840 | rhdConnectorType con; |
||
3841 | } rhd_connector_objs[] = { |
||
3842 | { "NONE", RHD_CONNECTOR_NONE }, |
||
3843 | { "SINGLE_LINK_DVI_I", RHD_CONNECTOR_DVI_SINGLE }, |
||
3844 | { "DUAL_LINK_DVI_I", RHD_CONNECTOR_DVI }, |
||
3845 | { "SINGLE_LINK_DVI_D", RHD_CONNECTOR_DVI_SINGLE }, |
||
3846 | { "DUAL_LINK_DVI_D", RHD_CONNECTOR_DVI }, |
||
3847 | { "VGA", RHD_CONNECTOR_VGA }, |
||
3848 | { "COMPOSITE", RHD_CONNECTOR_TV }, |
||
3849 | { "SVIDEO", RHD_CONNECTOR_TV, }, |
||
3850 | { "YPrPb", RHD_CONNECTOR_TV, }, |
||
3851 | { "D_CONNECTOR", RHD_CONNECTOR_NONE, }, |
||
3852 | { "9PIN_DIN", RHD_CONNECTOR_NONE }, |
||
3853 | { "SCART", RHD_CONNECTOR_TV }, |
||
3854 | { "HDMI_TYPE_A", RHD_CONNECTOR_DVI_SINGLE }, |
||
3855 | { "HDMI_TYPE_B", RHD_CONNECTOR_DVI }, |
||
3856 | { "LVDS", RHD_CONNECTOR_PANEL }, |
||
3857 | { "7PIN_DIN", RHD_CONNECTOR_TV }, |
||
3858 | { "PCIE_CONNECTOR", RHD_CONNECTOR_PCIE }, |
||
3859 | { "CROSSFIRE", RHD_CONNECTOR_NONE }, |
||
3860 | { "HARDCODE_DVI", RHD_CONNECTOR_NONE }, |
||
3861 | { "DISPLAYPORT", RHD_CONNECTOR_NONE} |
||
3862 | }; |
||
3863 | static const int n_rhd_connector_objs = sizeof (rhd_connector_objs) / sizeof(struct _rhd_connector_objs); |
||
3864 | |||
3865 | static const struct _rhd_encoders |
||
3866 | { |
||
3867 | char *name; |
||
3868 | rhdOutputType ot[2]; |
||
3869 | } rhd_encoders[] = { |
||
3870 | { "NONE", {RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3871 | { "INTERNAL_LVDS", { RHD_OUTPUT_LVDS, RHD_OUTPUT_NONE }}, |
||
3872 | { "INTERNAL_TMDS1", { RHD_OUTPUT_TMDSA, RHD_OUTPUT_NONE }}, |
||
3873 | { "INTERNAL_TMDS2", { RHD_OUTPUT_TMDSB, RHD_OUTPUT_NONE }}, |
||
3874 | { "INTERNAL_DAC1", { RHD_OUTPUT_DACA, RHD_OUTPUT_NONE }}, |
||
3875 | { "INTERNAL_DAC2", { RHD_OUTPUT_DACB, RHD_OUTPUT_NONE }}, |
||
3876 | { "INTERNAL_SDVOA", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3877 | { "INTERNAL_SDVOB", { RHD_OUTPUT_NONE , RHD_OUTPUT_NONE }}, |
||
3878 | { "SI170B", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3879 | { "CH7303", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3880 | { "CH7301", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3881 | { "INTERNAL_DVO1", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3882 | { "EXTERNAL_SDVOA", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3883 | { "EXTERNAL_SDVOB", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3884 | { "TITFP513", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3885 | { "INTERNAL_LVTM1", { RHD_OUTPUT_LVTMA, RHD_OUTPUT_NONE }}, |
||
3886 | { "VT1623", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3887 | { "HDMI_SI1930", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3888 | { "HDMI_INTERNAL", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3889 | { "INTERNAL_KLDSCP_TMDS1", { RHD_OUTPUT_TMDSA, RHD_OUTPUT_NONE }}, |
||
3890 | { "INTERNAL_KLDSCP_DVO1", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3891 | { "INTERNAL_KLDSCP_DAC1", { RHD_OUTPUT_DACA, RHD_OUTPUT_NONE }}, |
||
3892 | { "INTERNAL_KLDSCP_DAC2", { RHD_OUTPUT_DACB, RHD_OUTPUT_NONE }}, |
||
3893 | { "SI178", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3894 | { "MVPU_FPGA", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3895 | { "INTERNAL_DDI", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3896 | { "VT1625", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3897 | { "HDMI_SI1932", {RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3898 | { "AN9801", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3899 | { "DP501", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }}, |
||
3900 | { "UNIPHY", { RHD_OUTPUT_UNIPHYA, RHD_OUTPUT_UNIPHYB }}, |
||
3901 | { "KLDSCP_LVTMA", { RHD_OUTPUT_KLDSKP_LVTMA, RHD_OUTPUT_NONE }}, |
||
3902 | { "UNIPHY1", { RHD_OUTPUT_UNIPHYC, RHD_OUTPUT_UNIPHYD }}, |
||
3903 | { "UNIPHY2", { RHD_OUTPUT_UNIPHYE, RHD_OUTPUT_UNIPHYF }} |
||
3904 | }; |
||
3905 | static const int n_rhd_encoders = sizeof (rhd_encoders) / sizeof(struct _rhd_encoders); |
||
3906 | |||
3907 | static const struct _rhd_connectors |
||
3908 | { |
||
3909 | char *name; |
||
3910 | rhdConnectorType con; |
||
3911 | Bool dual; |
||
3912 | } rhd_connectors[] = { |
||
3913 | {"NONE", RHD_CONNECTOR_NONE, FALSE }, |
||
3914 | {"VGA", RHD_CONNECTOR_VGA, FALSE }, |
||
3915 | {"DVI-I", RHD_CONNECTOR_DVI, TRUE }, |
||
3916 | {"DVI-D", RHD_CONNECTOR_DVI, FALSE }, |
||
3917 | {"DVI-A", RHD_CONNECTOR_DVI, FALSE }, |
||
3918 | {"SVIDEO", RHD_CONNECTOR_TV, FALSE }, |
||
3919 | {"COMPOSITE", RHD_CONNECTOR_TV, FALSE }, |
||
3920 | {"PANEL", RHD_CONNECTOR_PANEL, FALSE }, |
||
3921 | {"DIGITAL_LINK", RHD_CONNECTOR_NONE, FALSE }, |
||
3922 | {"SCART", RHD_CONNECTOR_TV, FALSE }, |
||
3923 | {"HDMI Type A", RHD_CONNECTOR_DVI_SINGLE, FALSE }, |
||
3924 | {"HDMI Type B", RHD_CONNECTOR_DVI, FALSE }, |
||
3925 | {"UNKNOWN", RHD_CONNECTOR_NONE, FALSE }, |
||
3926 | {"UNKNOWN", RHD_CONNECTOR_NONE, FALSE }, |
||
3927 | {"DVI+DIN", RHD_CONNECTOR_NONE, FALSE } |
||
3928 | }; |
||
3929 | static const int n_rhd_connectors = sizeof(rhd_connectors) / sizeof(struct _rhd_connectors); |
||
3930 | |||
3931 | static const struct _rhd_devices |
||
3932 | { |
||
3933 | char *name; |
||
3934 | rhdOutputType ot[2]; |
||
3935 | enum atomDevice atomDevID; |
||
3936 | } rhd_devices[] = { /* { RHD_CHIP_EXTERNAL, RHD_CHIP_IGP } */ |
||
3937 | {" CRT1", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomCRT1 }, |
||
3938 | {" LCD1", { RHD_OUTPUT_LVTMA, RHD_OUTPUT_LVTMA }, atomLCD1 }, |
||
3939 | {" TV1", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomTV1 }, |
||
3940 | {" DFP1", { RHD_OUTPUT_TMDSA, RHD_OUTPUT_NONE }, atomDFP1 }, |
||
3941 | {" CRT2", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomCRT2 }, |
||
3942 | {" LCD2", { RHD_OUTPUT_LVTMA, RHD_OUTPUT_NONE }, atomLCD2 }, |
||
3943 | {" TV2", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomTV2 }, |
||
3944 | {" DFP2", { RHD_OUTPUT_LVTMA, RHD_OUTPUT_DVO }, atomDFP2 }, |
||
3945 | {" CV", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomCV }, |
||
3946 | {" DFP3", { RHD_OUTPUT_LVTMA, RHD_OUTPUT_LVTMA }, atomDFP3 }, |
||
3947 | {" DFP4", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomDFP4 }, |
||
3948 | {" DFP5", { RHD_OUTPUT_NONE, RHD_OUTPUT_NONE }, atomDFP5 } |
||
3949 | }; |
||
3950 | static const int n_rhd_devices = sizeof(rhd_devices) / sizeof(struct _rhd_devices); |
||
3951 | |||
3952 | static const rhdDDC hwddc[] = { RHD_DDC_0, RHD_DDC_1, RHD_DDC_2, RHD_DDC_3, RHD_DDC_4 }; |
||
3953 | static const int n_hwddc = sizeof(hwddc) / sizeof(rhdDDC); |
||
3954 | |||
3955 | static const rhdOutputType acc_dac[] = { RHD_OUTPUT_NONE, RHD_OUTPUT_DACA, |
||
3956 | RHD_OUTPUT_DACB, RHD_OUTPUT_DAC_EXTERNAL }; |
||
3957 | static const int n_acc_dac = sizeof(acc_dac) / sizeof (rhdOutputType); |
||
3958 | |||
3959 | /* |
||
3960 | * |
||
3961 | */ |
||
3962 | static Bool |
||
3963 | rhdAtomInterpretObjectID(atomBiosHandlePtr handle, |
||
3964 | CARD16 id, CARD8 *obj_type, CARD8 *obj_id, |
||
3965 | CARD8 *num, char **name) |
||
3966 | { |
||
3967 | *obj_id = (id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; |
||
3968 | *num = (id & ENUM_ID_MASK) >> ENUM_ID_SHIFT; |
||
3969 | *obj_type = (id & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
||
3970 | |||
3971 | *name = NULL; |
||
3972 | |||
3973 | switch (*obj_type) { |
||
3974 | case GRAPH_OBJECT_TYPE_CONNECTOR: |
||
3975 | if (!Limit(*obj_id, n_rhd_connector_objs, "connector_obj")) |
||
3976 | *name = rhd_connector_objs[*obj_id].name; |
||
3977 | break; |
||
3978 | case GRAPH_OBJECT_TYPE_ENCODER: |
||
3979 | if (!Limit(*obj_id, n_rhd_encoders, "encoder_obj")) |
||
3980 | *name = rhd_encoders[*obj_id].name; |
||
3981 | break; |
||
3982 | default: |
||
3983 | break; |
||
3984 | } |
||
3985 | return TRUE; |
||
3986 | } |
||
3987 | |||
3988 | /* |
||
3989 | * |
||
3990 | */ |
||
3991 | static AtomBiosResult |
||
3992 | rhdAtomGetDDCIndex(atomBiosHandlePtr handle, |
||
3993 | rhdDDC *DDC, unsigned char i2c) |
||
3994 | { |
||
3995 | atomDataTablesPtr atomDataPtr; |
||
3996 | CARD8 crev, frev; |
||
3997 | int i; |
||
3998 | |||
3999 | RHDFUNC(handle); |
||
4000 | |||
4001 | atomDataPtr = handle->atomDataPtr; |
||
4002 | |||
4003 | if (!rhdAtomGetTableRevisionAndSize( |
||
4004 | &(atomDataPtr->GPIO_I2C_Info->sHeader), &crev,&frev,NULL)) { |
||
4005 | return ATOM_NOT_IMPLEMENTED; |
||
4006 | } |
||
4007 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
||
4008 | if (atomDataPtr->GPIO_I2C_Info->asGPIO_Info[i].sucI2cId.ucAccess == i2c) { |
||
4009 | RHDDebug(handle->scrnIndex, " Found DDC GPIO Index: %i\n",i); |
||
4010 | if (Limit(i, n_hwddc, "GPIO_DDC Index")) |
||
4011 | return ATOM_FAILED; |
||
4012 | *DDC = hwddc[i]; |
||
4013 | return ATOM_SUCCESS; |
||
4014 | } |
||
4015 | } |
||
4016 | return ATOM_FAILED; |
||
4017 | } |
||
4018 | |||
4019 | /* |
||
4020 | * |
||
4021 | */ |
||
4022 | static void |
||
4023 | rhdAtomDDCFromI2CRecord(atomBiosHandlePtr handle, |
||
4024 | ATOM_I2C_RECORD *Record, rhdDDC *DDC) |
||
4025 | { |
||
4026 | RHDDebug(handle->scrnIndex, |
||
4027 | " %s: I2C Record: %s[%x] EngineID: %x I2CAddr: %x\n", |
||
4028 | __func__, |
||
4029 | Record->sucI2cId.bfHW_Capable ? "HW_Line" : "GPIO_ID", |
||
4030 | Record->sucI2cId.bfI2C_LineMux, |
||
4031 | Record->sucI2cId.bfHW_EngineID, |
||
4032 | Record->ucI2CAddr); |
||
4033 | |||
4034 | if (!*(unsigned char *)&(Record->sucI2cId)) |
||
4035 | *DDC = RHD_DDC_NONE; |
||
4036 | else { |
||
4037 | union { |
||
4038 | ATOM_I2C_ID_CONFIG i2cId; |
||
4039 | unsigned char i2cChar; |
||
4040 | } u; |
||
4041 | if (Record->ucI2CAddr != 0) |
||
4042 | return; |
||
4043 | u.i2cId = Record->sucI2cId; |
||
4044 | if (!u.i2cChar |
||
4045 | || rhdAtomGetDDCIndex(handle, DDC, u.i2cChar) != ATOM_SUCCESS) |
||
4046 | *DDC = RHD_DDC_NONE; |
||
4047 | } |
||
4048 | } |
||
4049 | |||
4050 | /* |
||
4051 | * |
||
4052 | */ |
||
4053 | static void |
||
4054 | rhdAtomParseGPIOLutForHPD(atomBiosHandlePtr handle, |
||
4055 | CARD8 pinID, rhdHPD *HPD) |
||
4056 | { |
||
4057 | atomDataTablesPtr atomDataPtr; |
||
4058 | ATOM_GPIO_PIN_LUT *gpio_pin_lut; |
||
4059 | unsigned short size; |
||
4060 | int i = 0; |
||
4061 | |||
4062 | RHDFUNC(handle); |
||
4063 | |||
4064 | atomDataPtr = handle->atomDataPtr; |
||
4065 | |||
4066 | *HPD = RHD_HPD_NONE; |
||
4067 | |||
4068 | if (!rhdAtomGetTableRevisionAndSize( |
||
4069 | &atomDataPtr->GPIO_Pin_LUT->sHeader, NULL, NULL, &size)) { |
||
4070 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4071 | "%s: No valid GPIO pin LUT in AtomBIOS\n",__func__); |
||
4072 | return; |
||
4073 | } |
||
4074 | gpio_pin_lut = atomDataPtr->GPIO_Pin_LUT; |
||
4075 | |||
4076 | while (1) { |
||
4077 | if (gpio_pin_lut->asGPIO_Pin[i].ucGPIO_ID == pinID) { |
||
4078 | |||
4079 | if ((sizeof(ATOM_COMMON_TABLE_HEADER) |
||
4080 | + (i * sizeof(ATOM_GPIO_PIN_ASSIGNMENT))) > size) |
||
4081 | return; |
||
4082 | |||
4083 | RHDDebug(handle->scrnIndex, |
||
4084 | " %s: GPIO PinID: %i Index: %x Shift: %i\n", |
||
4085 | __func__, |
||
4086 | pinID, |
||
4087 | gpio_pin_lut->asGPIO_Pin[i].usGpioPin_AIndex, |
||
4088 | gpio_pin_lut->asGPIO_Pin[i].ucGpioPinBitShift); |
||
4089 | |||
4090 | /* grr... map backwards: register indices -> line numbers */ |
||
4091 | if (gpio_pin_lut->asGPIO_Pin[i].usGpioPin_AIndex |
||
4092 | == (DC_GPIO_HPD_A >> 2)) { |
||
4093 | switch (gpio_pin_lut->asGPIO_Pin[i].ucGpioPinBitShift) { |
||
4094 | case 0: |
||
4095 | *HPD = RHD_HPD_0; |
||
4096 | return; |
||
4097 | case 8: |
||
4098 | *HPD = RHD_HPD_1; |
||
4099 | return; |
||
4100 | case 16: |
||
4101 | *HPD = RHD_HPD_2; |
||
4102 | return; |
||
4103 | case 24: |
||
4104 | *HPD = RHD_HPD_3; |
||
4105 | return; |
||
4106 | } |
||
4107 | } |
||
4108 | } |
||
4109 | i++; |
||
4110 | } |
||
4111 | } |
||
4112 | |||
4113 | /* |
||
4114 | * |
||
4115 | */ |
||
4116 | static void |
||
4117 | rhdAtomHPDFromRecord(atomBiosHandlePtr handle, |
||
4118 | ATOM_HPD_INT_RECORD *Record, rhdHPD *HPD) |
||
4119 | { |
||
4120 | RHDDebug(handle->scrnIndex, |
||
4121 | " %s: HPD Record: GPIO ID: %x Plugged_PinState: %x\n", |
||
4122 | __func__, |
||
4123 | Record->ucHPDIntGPIOID, |
||
4124 | Record->ucPluggged_PinState); |
||
4125 | rhdAtomParseGPIOLutForHPD(handle, Record->ucHPDIntGPIOID, HPD); |
||
4126 | } |
||
4127 | |||
4128 | /* |
||
4129 | * |
||
4130 | */ |
||
4131 | static char * |
||
4132 | rhdAtomDeviceTagsFromRecord(atomBiosHandlePtr handle, |
||
4133 | ATOM_CONNECTOR_DEVICE_TAG_RECORD *Record) |
||
4134 | { |
||
4135 | int i, j, k; |
||
4136 | char *devices; |
||
4137 | |||
4138 | RHDFUNC(handle); |
||
4139 | |||
4140 | RHDDebug(handle->scrnIndex," NumberOfDevice: %i\n", |
||
4141 | Record->ucNumberOfDevice); |
||
4142 | |||
4143 | if (!Record->ucNumberOfDevice) return NULL; |
||
4144 | |||
4145 | devices = (char *)xcalloc(Record->ucNumberOfDevice * 4 + 1,1); |
||
4146 | |||
4147 | for (i = 0; i < Record->ucNumberOfDevice; i++) { |
||
4148 | k = 0; |
||
4149 | j = Record->asDeviceTag[i].usDeviceID; |
||
4150 | |||
4151 | if (!j) continue; |
||
4152 | |||
4153 | while (!(j & 0x1)) { j >>= 1; k++; }; |
||
4154 | |||
4155 | if (!Limit(k,n_rhd_devices,"usDeviceID")) |
||
4156 | strcat(devices, rhd_devices[k].name); |
||
4157 | } |
||
4158 | |||
4159 | RHDDebug(handle->scrnIndex," Devices:%s\n",devices); |
||
4160 | |||
4161 | return devices; |
||
4162 | } |
||
4163 | |||
4164 | /* |
||
4165 | * |
||
4166 | */ |
||
4167 | static rhdConnectorType |
||
4168 | rhdAtomGetConnectorID(atomBiosHandlePtr handle, rhdConnectorType connector, int num) |
||
4169 | { |
||
4170 | RHDFUNC(handle); |
||
4171 | |||
4172 | switch (connector) { |
||
4173 | case RHD_CONNECTOR_PCIE: |
||
4174 | { |
||
4175 | atomDataTablesPtr atomDataPtr; |
||
4176 | CARD8 crev, frev; |
||
4177 | CARD32 val; |
||
4178 | |||
4179 | atomDataPtr = handle->atomDataPtr; |
||
4180 | |||
4181 | if (!rhdAtomGetTableRevisionAndSize( |
||
4182 | (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->IntegratedSystemInfo.base), |
||
4183 | &crev,&frev,NULL) || crev != 2) { |
||
4184 | return RHD_CONNECTOR_NONE; /* sorry, we can't do any better */ |
||
4185 | } |
||
4186 | RHDDebug(handle->scrnIndex,"PCIE[%i]", num); |
||
4187 | switch (num) { |
||
4188 | case 1: |
||
4189 | val = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulDDISlot1Config; |
||
4190 | break; |
||
4191 | case 2: |
||
4192 | val = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulDDISlot2Config; |
||
4193 | break; |
||
4194 | default: |
||
4195 | RHDDebugCont("\n"); |
||
4196 | return RHD_CONNECTOR_NONE; |
||
4197 | } |
||
4198 | val >>= 16; |
||
4199 | val &= 0xff; |
||
4200 | RHDDebugCont(" ObjectID: %i",val); |
||
4201 | if (Limit((int)val, n_rhd_connector_objs, "obj_id")) { |
||
4202 | RHDDebugCont("\n"); |
||
4203 | return RHD_CONNECTOR_NONE; |
||
4204 | } |
||
4205 | |||
4206 | RHDDebugCont(" ConnectorName: %s\n",rhd_connector_objs[val].name); |
||
4207 | return rhd_connector_objs[val].con; |
||
4208 | } |
||
4209 | default: |
||
4210 | return connector; |
||
4211 | } |
||
4212 | } |
||
4213 | |||
4214 | /* |
||
4215 | * |
||
4216 | */ |
||
4217 | static AtomBiosResult |
||
4218 | rhdAtomOutputDeviceListFromObjectHeader(atomBiosHandlePtr handle, |
||
4219 | struct rhdAtomOutputDeviceList **ptr) |
||
4220 | { |
||
4221 | atomDataTablesPtr atomDataPtr; |
||
4222 | CARD8 crev, frev; |
||
4223 | ATOM_DISPLAY_OBJECT_PATH_TABLE *disObjPathTable; |
||
4224 | ATOM_DISPLAY_OBJECT_PATH *disObjPath; |
||
4225 | rhdConnectorInfoPtr cp; |
||
4226 | unsigned long object_header_end; |
||
4227 | unsigned int i,j; |
||
4228 | unsigned short object_header_size; |
||
4229 | struct rhdAtomOutputDeviceList *DeviceList = NULL; |
||
4230 | int cnt = 0; |
||
4231 | |||
4232 | RHDFUNC(handle); |
||
4233 | |||
4234 | atomDataPtr = handle->atomDataPtr; |
||
4235 | |||
4236 | if (!rhdAtomGetTableRevisionAndSize( |
||
4237 | &atomDataPtr->Object_Header->sHeader, |
||
4238 | &crev,&frev,&object_header_size)) { |
||
4239 | return ATOM_NOT_IMPLEMENTED; |
||
4240 | } |
||
4241 | |||
4242 | if (crev < 2) /* don't bother with anything below rev 2 */ |
||
4243 | return ATOM_NOT_IMPLEMENTED; |
||
4244 | |||
4245 | if (!(cp = (rhdConnectorInfoPtr)xcalloc(sizeof(struct rhdConnectorInfo), |
||
4246 | RHD_CONNECTORS_MAX))) |
||
4247 | return ATOM_FAILED; |
||
4248 | |||
4249 | object_header_end = |
||
4250 | atomDataPtr->Object_Header->usConnectorObjectTableOffset |
||
4251 | + object_header_size; |
||
4252 | |||
4253 | RHDDebug(handle->scrnIndex,"ObjectTable - size: %u, BIOS - size: %u " |
||
4254 | "TableOffset: %u object_header_end: %u\n", |
||
4255 | object_header_size, handle->BIOSImageSize, |
||
4256 | atomDataPtr->Object_Header->usConnectorObjectTableOffset, |
||
4257 | object_header_end); |
||
4258 | |||
4259 | if ((object_header_size > handle->BIOSImageSize) |
||
4260 | || (atomDataPtr->Object_Header->usConnectorObjectTableOffset |
||
4261 | > handle->BIOSImageSize) |
||
4262 | || object_header_end > handle->BIOSImageSize) { |
||
4263 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4264 | "%s: Object table information is bogus\n",__func__); |
||
4265 | return ATOM_FAILED; |
||
4266 | } |
||
4267 | |||
4268 | if (((unsigned long)&atomDataPtr->Object_Header->sHeader |
||
4269 | + object_header_end) > ((unsigned long)handle->BIOSBase |
||
4270 | + handle->BIOSImageSize)) { |
||
4271 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4272 | "%s: Object table extends beyond BIOS Image\n",__func__); |
||
4273 | return ATOM_FAILED; |
||
4274 | } |
||
4275 | disObjPathTable = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) |
||
4276 | ((char *)&atomDataPtr->Object_Header->sHeader + |
||
4277 | atomDataPtr->Object_Header->usDisplayPathTableOffset); |
||
4278 | RHDDebug(handle->scrnIndex, "DisplayPathObjectTable: entries: %i version: %i\n", |
||
4279 | disObjPathTable->ucNumOfDispPath, disObjPathTable->ucVersion); |
||
4280 | |||
4281 | disObjPath = &disObjPathTable->asDispPath[0]; |
||
4282 | for (i = 0; i < disObjPathTable->ucNumOfDispPath; i++) { |
||
4283 | CARD8 objNum, cObjNum; |
||
4284 | CARD8 objId; |
||
4285 | CARD8 objType; |
||
4286 | rhdConnectorType ct; |
||
4287 | char *name; |
||
4288 | |||
4289 | rhdAtomInterpretObjectID(handle, disObjPath->usConnObjectId, &objType, &objId, &objNum, &name); |
||
4290 | RHDDebug(handle->scrnIndex, " DisplaPathTable[%i]: size: %i DeviceTag: 0x%x ConnObjId: 0x%x NAME: %s GPUObjId: 0x%x\n", |
||
4291 | i, disObjPath->usSize, disObjPath->usDeviceTag, disObjPath->usConnObjectId, name, disObjPath->usGPUObjectId); |
||
4292 | |||
4293 | if (objType != GRAPH_OBJECT_TYPE_CONNECTOR) |
||
4294 | continue; |
||
4295 | |||
4296 | ct = rhd_connector_objs[objId].con; |
||
4297 | cObjNum = objNum; |
||
4298 | |||
4299 | for (j = 0; j < disObjPath->usSize / sizeof(USHORT) - 4; j++) { |
||
4300 | int k = 0,l; |
||
4301 | |||
4302 | rhdAtomInterpretObjectID(handle, disObjPath->usGraphicObjIds[j], &objType, &objId, &objNum, &name); |
||
4303 | RHDDebug(handle->scrnIndex, " GraphicsObj[%i] ID: 0x%x Type: 0x%x ObjID: 0x%x ENUM: 0x%x NAME: %s\n", |
||
4304 | j, disObjPath->usGraphicObjIds[j], objType, objId, objNum, name); |
||
4305 | |||
4306 | if (objType != GRAPH_OBJECT_TYPE_ENCODER) |
||
4307 | continue; |
||
4308 | |||
4309 | Limit(objId, n_rhd_encoders, "usGraphicsObjId"); |
||
4310 | |||
4311 | l = disObjPath->usDeviceTag; |
||
4312 | if (!l) continue; |
||
4313 | |||
4314 | while (!(l & 0x1)) { l >>= 1; k++; }; |
||
4315 | if (!Limit(k,n_rhd_devices,"usDeviceID")) { |
||
4316 | if (!(DeviceList = (struct rhdAtomOutputDeviceList *)xrealloc(DeviceList, sizeof (struct rhdAtomOutputDeviceList) * (cnt + 1)))) |
||
4317 | return ATOM_FAILED; |
||
4318 | |||
4319 | DeviceList[cnt].DeviceId = rhd_devices[k].atomDevID; |
||
4320 | DeviceList[cnt].ConnectorType = rhdAtomGetConnectorID(handle, ct, cObjNum); |
||
4321 | DeviceList[cnt].OutputType = rhd_encoders[objId].ot[objNum - 1]; |
||
4322 | cnt++; |
||
4323 | RHDDebug(handle->scrnIndex, " DeviceIndex: 0x%x\n",k); |
||
4324 | } |
||
4325 | } |
||
4326 | disObjPath = (ATOM_DISPLAY_OBJECT_PATH*)(((char *)disObjPath) + disObjPath->usSize); |
||
4327 | if ((((unsigned long)&atomDataPtr->Object_Header->sHeader + object_header_end) |
||
4328 | < (((unsigned long) disObjPath) + sizeof(ATOM_DISPLAY_OBJECT_PATH))) |
||
4329 | || (((unsigned long)&atomDataPtr->Object_Header->sHeader + object_header_end) |
||
4330 | < (((unsigned long) disObjPath) + disObjPath->usSize))) |
||
4331 | break; |
||
4332 | } |
||
4333 | DeviceList = xrealloc(DeviceList, sizeof(struct rhdAtomOutputDeviceList) * (cnt + 1)); |
||
4334 | DeviceList[cnt].DeviceId = atomNone; |
||
4335 | |||
4336 | *ptr = DeviceList; |
||
4337 | |||
4338 | return ATOM_SUCCESS; |
||
4339 | } |
||
4340 | |||
4341 | /* |
||
4342 | * |
||
4343 | */ |
||
4344 | static AtomBiosResult |
||
4345 | rhdAtomConnectorInfoFromObjectHeader(atomBiosHandlePtr handle, |
||
4346 | rhdConnectorInfoPtr *ptr) |
||
4347 | { |
||
4348 | atomDataTablesPtr atomDataPtr; |
||
4349 | CARD8 crev, frev; |
||
4350 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
||
4351 | rhdConnectorInfoPtr cp; |
||
4352 | unsigned long object_header_end; |
||
4353 | int ncon = 0; |
||
4354 | int i,j; |
||
4355 | unsigned short object_header_size; |
||
4356 | |||
4357 | RHDFUNC(handle); |
||
4358 | |||
4359 | atomDataPtr = handle->atomDataPtr; |
||
4360 | |||
4361 | if (!rhdAtomGetTableRevisionAndSize( |
||
4362 | &atomDataPtr->Object_Header->sHeader, |
||
4363 | &crev,&frev,&object_header_size)) { |
||
4364 | return ATOM_NOT_IMPLEMENTED; |
||
4365 | } |
||
4366 | |||
4367 | if (crev < 2) /* don't bother with anything below rev 2 */ |
||
4368 | return ATOM_NOT_IMPLEMENTED; |
||
4369 | |||
4370 | if (!(cp = (rhdConnectorInfoPtr)xcalloc(sizeof(struct rhdConnectorInfo), |
||
4371 | RHD_CONNECTORS_MAX))) |
||
4372 | return ATOM_FAILED; |
||
4373 | |||
4374 | object_header_end = |
||
4375 | atomDataPtr->Object_Header->usConnectorObjectTableOffset |
||
4376 | + object_header_size; |
||
4377 | |||
4378 | RHDDebug(handle->scrnIndex,"ObjectTable - size: %u, BIOS - size: %u " |
||
4379 | "TableOffset: %u object_header_end: %u\n", |
||
4380 | object_header_size, handle->BIOSImageSize, |
||
4381 | atomDataPtr->Object_Header->usConnectorObjectTableOffset, |
||
4382 | object_header_end); |
||
4383 | |||
4384 | if ((object_header_size > handle->BIOSImageSize) |
||
4385 | || (atomDataPtr->Object_Header->usConnectorObjectTableOffset |
||
4386 | > handle->BIOSImageSize) |
||
4387 | || object_header_end > handle->BIOSImageSize) { |
||
4388 | xfree(cp); |
||
4389 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4390 | "%s: Object table information is bogus\n",__func__); |
||
4391 | return ATOM_FAILED; |
||
4392 | } |
||
4393 | |||
4394 | if (((unsigned long)&atomDataPtr->Object_Header->sHeader |
||
4395 | + object_header_end) > ((unsigned long)handle->BIOSBase |
||
4396 | + handle->BIOSImageSize)) { |
||
4397 | xfree(cp); |
||
4398 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4399 | "%s: Object table extends beyond BIOS Image\n",__func__); |
||
4400 | return ATOM_FAILED; |
||
4401 | } |
||
4402 | |||
4403 | con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) |
||
4404 | ((char *)&atomDataPtr->Object_Header->sHeader + |
||
4405 | atomDataPtr->Object_Header->usConnectorObjectTableOffset); |
||
4406 | |||
4407 | for (i = 0; i < con_obj->ucNumberOfObjects; i++) { |
||
4408 | ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable; |
||
4409 | ATOM_COMMON_RECORD_HEADER *Record; |
||
4410 | int record_base; |
||
4411 | CARD8 obj_type, obj_id, num; |
||
4412 | char *name; |
||
4413 | |||
4414 | rhdAtomInterpretObjectID(handle, con_obj->asObjects[i].usObjectID, |
||
4415 | &obj_type, &obj_id, &num, &name); |
||
4416 | |||
4417 | RHDDebug(handle->scrnIndex, "Object: ID: %x name: %s type: %x id: %x\n", |
||
4418 | con_obj->asObjects[i].usObjectID, name ? name : "", |
||
4419 | obj_type, obj_id); |
||
4420 | |||
4421 | |||
4422 | if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR) |
||
4423 | continue; |
||
4424 | |||
4425 | SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) |
||
4426 | ((char *)&atomDataPtr->Object_Header->sHeader |
||
4427 | + con_obj->asObjects[i].usSrcDstTableOffset); |
||
4428 | |||
4429 | if (con_obj->asObjects[i].usSrcDstTableOffset |
||
4430 | + (SrcDstTable->ucNumberOfSrc |
||
4431 | * sizeof(ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT)) |
||
4432 | > handle->BIOSImageSize) { |
||
4433 | xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: SrcDstTable[%i] extends " |
||
4434 | "beyond Object_Header table\n",__func__,i); |
||
4435 | continue; |
||
4436 | } |
||
4437 | cp[ncon].Type = rhdAtomGetConnectorID(handle, rhd_connector_objs[obj_id].con, num); |
||
4438 | cp[ncon].Name = RhdAppendString(cp[ncon].Name,name); |
||
4439 | |||
4440 | for (j = 0; ((j < SrcDstTable->ucNumberOfSrc) && |
||
4441 | (j < MAX_OUTPUTS_PER_CONNECTOR)); j++) { |
||
4442 | CARD8 stype, sobj_id, snum; |
||
4443 | char *sname; |
||
4444 | |||
4445 | rhdAtomInterpretObjectID(handle, SrcDstTable->usSrcObjectID[j], |
||
4446 | &stype, &sobj_id, &snum, &sname); |
||
4447 | |||
4448 | RHDDebug(handle->scrnIndex, " * SrcObject: ID: %x name: %s enum: %i\n", |
||
4449 | SrcDstTable->usSrcObjectID[j], sname, snum); |
||
4450 | |||
4451 | if (snum <= 2) |
||
4452 | cp[ncon].Output[j] = rhd_encoders[sobj_id].ot[snum - 1]; |
||
4453 | } |
||
4454 | |||
4455 | Record = (ATOM_COMMON_RECORD_HEADER *) |
||
4456 | ((char *)&atomDataPtr->Object_Header->sHeader |
||
4457 | + con_obj->asObjects[i].usRecordOffset); |
||
4458 | |||
4459 | record_base = con_obj->asObjects[i].usRecordOffset; |
||
4460 | |||
4461 | while (Record->ucRecordType > 0 |
||
4462 | && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) { |
||
4463 | char *taglist; |
||
4464 | |||
4465 | if ((record_base += Record->ucRecordSize) |
||
4466 | > object_header_size) { |
||
4467 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4468 | "%s: Object Records extend beyond Object Table\n", |
||
4469 | __func__); |
||
4470 | break; |
||
4471 | } |
||
4472 | |||
4473 | RHDDebug(handle->scrnIndex, " - Record Type: %x\n", |
||
4474 | Record->ucRecordType); |
||
4475 | |||
4476 | switch (Record->ucRecordType) { |
||
4477 | |||
4478 | case ATOM_I2C_RECORD_TYPE: |
||
4479 | rhdAtomDDCFromI2CRecord(handle, |
||
4480 | (ATOM_I2C_RECORD *)Record, |
||
4481 | &cp[ncon].DDC); |
||
4482 | break; |
||
4483 | |||
4484 | case ATOM_HPD_INT_RECORD_TYPE: |
||
4485 | rhdAtomHPDFromRecord(handle, |
||
4486 | (ATOM_HPD_INT_RECORD *)Record, |
||
4487 | &cp[ncon].HPD); |
||
4488 | break; |
||
4489 | |||
4490 | case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: |
||
4491 | taglist = rhdAtomDeviceTagsFromRecord(handle, |
||
4492 | (ATOM_CONNECTOR_DEVICE_TAG_RECORD *)Record); |
||
4493 | if (taglist) { |
||
4494 | cp[ncon].Name = RhdAppendString(cp[ncon].Name,taglist); |
||
4495 | xfree(taglist); |
||
4496 | } |
||
4497 | break; |
||
4498 | |||
4499 | default: |
||
4500 | break; |
||
4501 | } |
||
4502 | |||
4503 | Record = (ATOM_COMMON_RECORD_HEADER*) |
||
4504 | ((char *)Record + Record->ucRecordSize); |
||
4505 | |||
4506 | } |
||
4507 | |||
4508 | if ((++ncon) == RHD_CONNECTORS_MAX) |
||
4509 | break; |
||
4510 | } |
||
4511 | *ptr = cp; |
||
4512 | |||
4513 | RhdPrintConnectorInfo(handle->rhdPtr, cp); |
||
4514 | |||
4515 | return ATOM_SUCCESS; |
||
4516 | } |
||
4517 | |||
4518 | /* |
||
4519 | * |
||
4520 | */ |
||
4521 | static AtomBiosResult |
||
4522 | rhdAtomOutputDeviceListFromSupportedDevices(atomBiosHandlePtr handle, |
||
4523 | Bool igp, |
||
4524 | struct rhdAtomOutputDeviceList **Ptr) |
||
4525 | { |
||
4526 | atomDataTablesPtr atomDataPtr; |
||
4527 | CARD8 crev, frev; |
||
4528 | int n; |
||
4529 | int cnt = 0; |
||
4530 | struct rhdAtomOutputDeviceList *DeviceList = NULL; |
||
4531 | struct rhdConnectorInfo *cp; |
||
4532 | |||
4533 | RHDFUNC(handle); |
||
4534 | |||
4535 | atomDataPtr = handle->atomDataPtr; |
||
4536 | |||
4537 | if (!rhdAtomGetTableRevisionAndSize( |
||
4538 | &(atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->sHeader), |
||
4539 | &crev,&frev,NULL)) { |
||
4540 | return ATOM_NOT_IMPLEMENTED; |
||
4541 | } |
||
4542 | |||
4543 | if (!(cp = (rhdConnectorInfoPtr)xcalloc(RHD_CONNECTORS_MAX, |
||
4544 | sizeof(struct rhdConnectorInfo)))) |
||
4545 | return ATOM_FAILED; |
||
4546 | |||
4547 | for (n = 0; n < ATOM_MAX_SUPPORTED_DEVICE; n++) { |
||
4548 | ATOM_CONNECTOR_INFO_I2C ci |
||
4549 | = atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->asConnInfo[n]; |
||
4550 | |||
4551 | if (!(atomDataPtr->SupportedDevicesInfo |
||
4552 | .SupportedDevicesInfo->usDeviceSupport & (1 << n))) |
||
4553 | continue; |
||
4554 | |||
4555 | if (Limit(ci.sucConnectorInfo.sbfAccess.bfConnectorType, |
||
4556 | n_rhd_connectors, "bfConnectorType")) |
||
4557 | continue; |
||
4558 | |||
4559 | if (!(DeviceList = (struct rhdAtomOutputDeviceList *)xrealloc(DeviceList, sizeof(struct rhdAtomOutputDeviceList) * (cnt + 1)))) |
||
4560 | return ATOM_FAILED; |
||
4561 | |||
4562 | DeviceList[cnt].ConnectorType = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].con; |
||
4563 | DeviceList[cnt].DeviceId = rhd_devices[n].atomDevID; |
||
4564 | |||
4565 | if (!Limit(ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC, |
||
4566 | n_acc_dac, "bfAssociatedDAC")) { |
||
4567 | if ((DeviceList[cnt].OutputType |
||
4568 | = acc_dac[ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC]) |
||
4569 | == RHD_OUTPUT_NONE) { |
||
4570 | DeviceList[cnt].OutputType = rhd_devices[n].ot[igp ? 1 : 0]; |
||
4571 | } |
||
4572 | cnt++; |
||
4573 | } |
||
4574 | } |
||
4575 | DeviceList = (struct rhdAtomOutputDeviceList *)xrealloc(DeviceList, sizeof(struct rhdAtomOutputDeviceList) * (cnt + 1)); |
||
4576 | DeviceList[cnt].DeviceId = atomNone; |
||
4577 | |||
4578 | *Ptr = DeviceList; |
||
4579 | |||
4580 | return ATOM_SUCCESS; |
||
4581 | } |
||
4582 | |||
4583 | /* |
||
4584 | * |
||
4585 | */ |
||
4586 | static AtomBiosResult |
||
4587 | rhdAtomConnectorInfoFromSupportedDevices(atomBiosHandlePtr handle, |
||
4588 | Bool igp, |
||
4589 | rhdConnectorInfoPtr *ptr) |
||
4590 | { |
||
4591 | atomDataTablesPtr atomDataPtr; |
||
4592 | CARD8 crev, frev; |
||
4593 | rhdConnectorInfoPtr cp; |
||
4594 | struct { |
||
4595 | rhdOutputType ot; |
||
4596 | rhdConnectorType con; |
||
4597 | rhdDDC ddc; |
||
4598 | rhdHPD hpd; |
||
4599 | Bool dual; |
||
4600 | char *name; |
||
4601 | char *outputName; |
||
4602 | } devices[ATOM_MAX_SUPPORTED_DEVICE]; |
||
4603 | int ncon = 0; |
||
4604 | int n; |
||
4605 | |||
4606 | RHDFUNC(handle); |
||
4607 | |||
4608 | atomDataPtr = handle->atomDataPtr; |
||
4609 | |||
4610 | if (!rhdAtomGetTableRevisionAndSize( |
||
4611 | &(atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->sHeader), |
||
4612 | &crev,&frev,NULL)) { |
||
4613 | return ATOM_NOT_IMPLEMENTED; |
||
4614 | } |
||
4615 | |||
4616 | if (!(cp = (rhdConnectorInfoPtr)xcalloc(RHD_CONNECTORS_MAX, |
||
4617 | sizeof(struct rhdConnectorInfo)))) |
||
4618 | return ATOM_FAILED; |
||
4619 | |||
4620 | for (n = 0; n < ATOM_MAX_SUPPORTED_DEVICE; n++) { |
||
4621 | ATOM_CONNECTOR_INFO_I2C ci |
||
4622 | = atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->asConnInfo[n]; |
||
4623 | |||
4624 | devices[n].ot = RHD_OUTPUT_NONE; |
||
4625 | |||
4626 | if (!(atomDataPtr->SupportedDevicesInfo |
||
4627 | .SupportedDevicesInfo->usDeviceSupport & (1 << n))) |
||
4628 | continue; |
||
4629 | |||
4630 | if (Limit(ci.sucConnectorInfo.sbfAccess.bfConnectorType, |
||
4631 | n_rhd_connectors, "bfConnectorType")) |
||
4632 | continue; |
||
4633 | |||
4634 | devices[n].con |
||
4635 | = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].con; |
||
4636 | if (devices[n].con == RHD_CONNECTOR_NONE) |
||
4637 | continue; |
||
4638 | |||
4639 | devices[n].dual |
||
4640 | = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].dual; |
||
4641 | devices[n].name |
||
4642 | = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].name; |
||
4643 | |||
4644 | RHDDebug(handle->scrnIndex,"AtomBIOS Connector[%i]: %s Device:%s ",n, |
||
4645 | rhd_connectors[ci.sucConnectorInfo |
||
4646 | .sbfAccess.bfConnectorType].name, |
||
4647 | rhd_devices[n].name); |
||
4648 | |||
4649 | devices[n].outputName = rhd_devices[n].name; |
||
4650 | |||
4651 | if (!Limit(ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC, |
||
4652 | n_acc_dac, "bfAssociatedDAC")) { |
||
4653 | if ((devices[n].ot |
||
4654 | = acc_dac[ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC]) |
||
4655 | == RHD_OUTPUT_NONE) { |
||
4656 | devices[n].ot = rhd_devices[n].ot[igp ? 1 : 0]; |
||
4657 | } |
||
4658 | } else |
||
4659 | devices[n].ot = RHD_OUTPUT_NONE; |
||
4660 | |||
4661 | RHDDebugCont("Output: %x ",devices[n].ot); |
||
4662 | |||
4663 | if (!ci.sucI2cId.ucAccess |
||
4664 | || rhdAtomGetDDCIndex(handle, &devices[n].ddc, ci.sucI2cId.ucAccess) != ATOM_SUCCESS) { |
||
4665 | RHDDebugCont("NO DDC "); |
||
4666 | devices[n].ddc = RHD_DDC_NONE; |
||
4667 | } else |
||
4668 | RHDDebugCont("HW DDC %i ", |
||
4669 | ci.sucI2cId.sbfAccess.bfI2C_LineMux); |
||
4670 | |||
4671 | if (crev > 1) { |
||
4672 | ATOM_CONNECTOR_INC_SRC_BITMAP isb |
||
4673 | = atomDataPtr->SupportedDevicesInfo |
||
4674 | .SupportedDevicesInfo_HD->asIntSrcInfo[n]; |
||
4675 | |||
4676 | switch (isb.ucIntSrcBitmap) { |
||
4677 | case 0x4: |
||
4678 | RHDDebugCont("HPD 0\n"); |
||
4679 | devices[n].hpd = RHD_HPD_0; |
||
4680 | break; |
||
4681 | case 0xa: |
||
4682 | RHDDebugCont("HPD 1\n"); |
||
4683 | devices[n].hpd = RHD_HPD_1; |
||
4684 | break; |
||
4685 | default: |
||
4686 | RHDDebugCont("NO HPD\n"); |
||
4687 | devices[n].hpd = RHD_HPD_NONE; |
||
4688 | break; |
||
4689 | } |
||
4690 | } else { |
||
4691 | RHDDebugCont("NO HPD\n"); |
||
4692 | devices[n].hpd = RHD_HPD_NONE; |
||
4693 | } |
||
4694 | } |
||
4695 | /* sort devices for connectors */ |
||
4696 | for (n = 0; n < ATOM_MAX_SUPPORTED_DEVICE; n++) { |
||
4697 | int i; |
||
4698 | |||
4699 | if (devices[n].ot == RHD_OUTPUT_NONE) |
||
4700 | continue; |
||
4701 | if (devices[n].con == RHD_CONNECTOR_NONE) |
||
4702 | continue; |
||
4703 | |||
4704 | cp[ncon].DDC = devices[n].ddc; |
||
4705 | cp[ncon].HPD = devices[n].hpd; |
||
4706 | cp[ncon].Output[0] = devices[n].ot; |
||
4707 | cp[ncon].Output[1] = RHD_OUTPUT_NONE; |
||
4708 | cp[ncon].Type = devices[n].con; |
||
4709 | cp[ncon].Name = strdup(devices[n].name); |
||
4710 | cp[ncon].Name = RhdAppendString(cp[ncon].Name, devices[n].outputName); |
||
4711 | |||
4712 | if (devices[n].dual) { |
||
4713 | if (devices[n].ddc == RHD_DDC_NONE) |
||
4714 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4715 | "No DDC channel for device %s found." |
||
4716 | " Cannot find matching device.\n",devices[n].name); |
||
4717 | else { |
||
4718 | for (i = n + 1; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
||
4719 | |||
4720 | if (!devices[i].dual) |
||
4721 | continue; |
||
4722 | |||
4723 | if (devices[n].ddc != devices[i].ddc) |
||
4724 | continue; |
||
4725 | |||
4726 | if (((devices[n].ot == RHD_OUTPUT_DACA |
||
4727 | || devices[n].ot == RHD_OUTPUT_DACB) |
||
4728 | && (devices[i].ot == RHD_OUTPUT_LVTMA |
||
4729 | || devices[i].ot == RHD_OUTPUT_TMDSA)) |
||
4730 | || ((devices[i].ot == RHD_OUTPUT_DACA |
||
4731 | || devices[i].ot == RHD_OUTPUT_DACB) |
||
4732 | && (devices[n].ot == RHD_OUTPUT_LVTMA |
||
4733 | || devices[n].ot == RHD_OUTPUT_TMDSA))) { |
||
4734 | |||
4735 | cp[ncon].Output[1] = devices[i].ot; |
||
4736 | |||
4737 | if (cp[ncon].HPD == RHD_HPD_NONE) |
||
4738 | cp[ncon].HPD = devices[i].hpd; |
||
4739 | |||
4740 | cp[ncon].Name = RhdAppendString(cp[ncon].Name, |
||
4741 | devices[i].outputName); |
||
4742 | devices[i].ot = RHD_OUTPUT_NONE; /* zero the device */ |
||
4743 | } |
||
4744 | } |
||
4745 | } |
||
4746 | } |
||
4747 | /* Some connector table mark a VGA as DVI-X. This heuristic fixes it */ |
||
4748 | if (cp[ncon].Type == RHD_CONNECTOR_DVI) { |
||
4749 | if ( ((cp[ncon].Output[0] == RHD_OUTPUT_NONE |
||
4750 | && (cp[ncon].Output[1] == RHD_OUTPUT_DACA |
||
4751 | || cp[ncon].Output[1] == RHD_OUTPUT_DACB)) |
||
4752 | || (cp[ncon].Output[1] == RHD_OUTPUT_NONE |
||
4753 | && (cp[ncon].Output[0] == RHD_OUTPUT_DACA |
||
4754 | || cp[ncon].Output[0] == RHD_OUTPUT_DACB))) |
||
4755 | && cp[ncon].HPD == RHD_HPD_NONE) |
||
4756 | cp[ncon].Type = RHD_CONNECTOR_VGA; |
||
4757 | } |
||
4758 | |||
4759 | if ((++ncon) == RHD_CONNECTORS_MAX) |
||
4760 | break; |
||
4761 | } |
||
4762 | *ptr = cp; |
||
4763 | |||
4764 | RhdPrintConnectorInfo(handle->rhdPtr, cp); |
||
4765 | |||
4766 | return ATOM_SUCCESS; |
||
4767 | } |
||
4768 | |||
4769 | /* |
||
4770 | * |
||
4771 | */ |
||
4772 | static AtomBiosResult |
||
4773 | rhdAtomConnectorInfo(atomBiosHandlePtr handle, |
||
4774 | AtomBiosRequestID unused, AtomBiosArgPtr data) |
||
4775 | { |
||
4776 | int chipset = data->chipset; |
||
4777 | |||
4778 | RHDFUNC(handle); |
||
4779 | |||
4780 | if (rhdAtomConnectorInfoFromObjectHeader(handle,&data->ConnectorInfo) |
||
4781 | == ATOM_SUCCESS) |
||
4782 | return ATOM_SUCCESS; |
||
4783 | else { |
||
4784 | Bool igp = RHDIsIGP(chipset); |
||
4785 | return rhdAtomConnectorInfoFromSupportedDevices(handle, igp, |
||
4786 | &data->ConnectorInfo); |
||
4787 | } |
||
4788 | } |
||
4789 | |||
4790 | /* |
||
4791 | * |
||
4792 | */ |
||
4793 | static AtomBiosResult |
||
4794 | rhdAtomOutputDeviceList(atomBiosHandlePtr handle, |
||
4795 | AtomBiosRequestID unused, AtomBiosArgPtr data) |
||
4796 | { |
||
4797 | int chipset = data->chipset; |
||
4798 | |||
4799 | RHDFUNC(handle); |
||
4800 | |||
4801 | if (rhdAtomOutputDeviceListFromObjectHeader(handle, &data->OutputDeviceList) |
||
4802 | == ATOM_SUCCESS) { |
||
4803 | return ATOM_SUCCESS; |
||
4804 | } else { |
||
4805 | Bool igp = RHDIsIGP(chipset); |
||
4806 | return rhdAtomOutputDeviceListFromSupportedDevices(handle, igp, &data->OutputDeviceList); |
||
4807 | } |
||
4808 | } |
||
4809 | |||
4810 | /* |
||
4811 | * |
||
4812 | */ |
||
4813 | struct atomCodeDataTableHeader |
||
4814 | { |
||
4815 | unsigned char signature; |
||
4816 | unsigned short size; |
||
4817 | }; |
||
4818 | |||
4819 | #define CODE_DATA_TABLE_SIGNATURE 0x7a |
||
4820 | #define ATOM_EOT_COMMAND 0x5b |
||
4821 | |||
4822 | static AtomBiosResult |
||
4823 | rhdAtomGetDataInCodeTable(atomBiosHandlePtr handle, |
||
4824 | AtomBiosRequestID unused, AtomBiosArgPtr data) |
||
4825 | { |
||
4826 | unsigned char *command_table; |
||
4827 | unsigned short size; |
||
4828 | unsigned short offset; |
||
4829 | |||
4830 | int i; |
||
4831 | |||
4832 | RHDFUNC(handle); |
||
4833 | |||
4834 | if (data->val > sizeof (struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES) / sizeof (USHORT)) |
||
4835 | return ATOM_FAILED; |
||
4836 | |||
4837 | if ((offset = ((USHORT *)&(((ATOM_MASTER_COMMAND_TABLE *)handle->codeTable) |
||
4838 | ->ListOfCommandTables))[data->val])) |
||
4839 | command_table = handle->BIOSBase + offset; |
||
4840 | else |
||
4841 | return ATOM_FAILED; |
||
4842 | |||
4843 | if (!rhdAtomGetTableRevisionAndSize(&(((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *) |
||
4844 | command_table)->CommonHeader), |
||
4845 | NULL, NULL, &size)) |
||
4846 | return ATOM_FAILED; |
||
4847 | |||
4848 | for (i = sizeof(ATOM_COMMON_ROM_COMMAND_TABLE_HEADER); i < size - 1; i++) { |
||
4849 | |||
4850 | if (command_table[i] == ATOM_EOT_COMMAND |
||
4851 | && command_table[i+1] == CODE_DATA_TABLE_SIGNATURE) { |
||
4852 | unsigned short *dt_size = (unsigned short*)(command_table + i + 2); |
||
4853 | |||
4854 | int diff; |
||
4855 | |||
4856 | diff = size - (i + 1) + sizeof(struct atomCodeDataTableHeader) + *dt_size; |
||
4857 | |||
4858 | DBG(dbgprintf("Table[0x%2.2x] = 0x%4.4x -> data_size: 0x%x\n",data->val, size, *dt_size)); |
||
4859 | |||
4860 | if (diff < 0) { |
||
4861 | xf86DrvMsg(handle->scrnIndex, X_ERROR, |
||
4862 | "Data table in command table %li extends %i bytes " |
||
4863 | "beyond command table size\n", |
||
4864 | (unsigned long) data->val, -diff); |
||
4865 | |||
4866 | return ATOM_FAILED; |
||
4867 | } |
||
4868 | data->CommandDataTable.loc = |
||
4869 | command_table + i + 2 + sizeof(unsigned short); |
||
4870 | |||
4871 | data->CommandDataTable.size = *dt_size; |
||
4872 | // DEBUGP(RhdDebugDump(handle->scrnIndex, data->CommandDataTable.loc, *dt_size)); |
||
4873 | |||
4874 | return ATOM_SUCCESS; |
||
4875 | } |
||
4876 | } |
||
4877 | |||
4878 | return ATOM_FAILED; |
||
4879 | } |
||
4880 | |||
4881 | # ifdef ATOM_BIOS_PARSER |
||
4882 | static AtomBiosResult |
||
4883 | rhdAtomExec (atomBiosHandlePtr handle, |
||
4884 | AtomBiosRequestID unused, AtomBiosArgPtr data) |
||
4885 | { |
||
4886 | RHDPtr rhdPtr = handle->rhdPtr; |
||
4887 | Bool ret = FALSE; |
||
4888 | char *msg; |
||
4889 | int idx = data->exec.index; |
||
4890 | void *pspace = data->exec.pspace; |
||
4891 | pointer *dataSpace = data->exec.dataSpace; |
||
4892 | |||
4893 | RHDFUNCI(handle->scrnIndex); |
||
4894 | |||
4895 | if (dataSpace) { |
||
4896 | if (!handle->fbBase && !handle->scratchBase) |
||
4897 | return ATOM_FAILED; |
||
4898 | if (handle->fbBase) { |
||
4899 | if (!rhdPtr->FbBase) { |
||
4900 | xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: " |
||
4901 | "Cannot exec AtomBIOS: framebuffer not mapped\n", |
||
4902 | __func__); |
||
4903 | return ATOM_FAILED; |
||
4904 | } |
||
4905 | *dataSpace = (CARD8*)rhdPtr->FbBase + handle->fbBase; |
||
4906 | } else |
||
4907 | *dataSpace = (CARD8*)handle->scratchBase; |
||
4908 | } |
||
4909 | ret = ParseTableWrapper(pspace, idx, handle, |
||
4910 | handle->BIOSBase, |
||
4911 | &msg); |
||
4912 | if (!ret) |
||
4913 | xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s\n",msg); |
||
4914 | else |
||
4915 | xf86DrvMsgVerb(handle->scrnIndex, X_INFO, 5, "%s\n",msg); |
||
4916 | |||
4917 | return (ret) ? ATOM_SUCCESS : ATOM_FAILED; |
||
4918 | } |
||
4919 | # endif |
||
4920 | |||
4921 | AtomBiosResult |
||
4922 | RHDAtomBiosFunc(RHDPtr rhdPtr, atomBiosHandlePtr handle, |
||
4923 | AtomBiosRequestID id, AtomBiosArgPtr data) |
||
4924 | { |
||
4925 | AtomBiosResult ret = ATOM_FAILED; |
||
4926 | int scrnIndex = rhdPtr->scrnIndex; |
||
4927 | int i; |
||
4928 | char *msg = NULL; |
||
4929 | enum msgDataFormat msg_f = MSG_FORMAT_NONE; |
||
4930 | AtomBiosRequestFunc req_func = NULL; |
||
4931 | |||
4932 | RHDFUNCI(scrnIndex); |
||
4933 | |||
4934 | for (i = 0; AtomBiosRequestList[i].id != FUNC_END; i++) { |
||
4935 | if (id == AtomBiosRequestList[i].id) { |
||
4936 | req_func = AtomBiosRequestList[i].request; |
||
4937 | msg = AtomBiosRequestList[i].message; |
||
4938 | msg_f = AtomBiosRequestList[i].message_format; |
||
4939 | break; |
||
4940 | } |
||
4941 | } |
||
4942 | |||
4943 | if (req_func == NULL) { |
||
4944 | xf86DrvMsg(scrnIndex, X_ERROR, "Unknown AtomBIOS request: %i\n",id); |
||
4945 | return ATOM_NOT_IMPLEMENTED; |
||
4946 | } |
||
4947 | /* Hack for now */ |
||
4948 | if (id == ATOMBIOS_INIT) |
||
4949 | data->val = (CARD32)rhdPtr; |
||
4950 | |||
4951 | if (id == ATOMBIOS_INIT || handle) |
||
4952 | ret = req_func(handle, id, data); |
||
4953 | |||
4954 | if (ret == ATOM_SUCCESS) { |
||
4955 | |||
4956 | switch (msg_f) { |
||
4957 | case MSG_FORMAT_DEC: |
||
4958 | xf86DrvMsg(scrnIndex,X_INFO,"%s: %li\n", msg, |
||
4959 | (unsigned long) data->val); |
||
4960 | break; |
||
4961 | case MSG_FORMAT_HEX: |
||
4962 | xf86DrvMsg(scrnIndex,X_INFO,"%s: 0x%lx\n",msg , |
||
4963 | (unsigned long) data->val); |
||
4964 | break; |
||
4965 | case MSG_FORMAT_NONE: |
||
4966 | xf86DrvMsgVerb(scrnIndex, 7, X_INFO, |
||
4967 | "Call to %s succeeded\n", msg); |
||
4968 | break; |
||
4969 | } |
||
4970 | |||
4971 | } else { |
||
4972 | |||
4973 | char *result = (ret == ATOM_FAILED) ? "failed" |
||
4974 | : "not implemented"; |
||
4975 | switch (msg_f) { |
||
4976 | case MSG_FORMAT_DEC: |
||
4977 | case MSG_FORMAT_HEX: |
||
4978 | xf86DrvMsgVerb(scrnIndex, 1, X_WARNING, |
||
4979 | "Call to %s %s\n", msg, result); |
||
4980 | break; |
||
4981 | case MSG_FORMAT_NONE: |
||
4982 | xf86DrvMsg(scrnIndex,X_INFO,"Query for %s: %s\n", msg, result); |
||
4983 | break; |
||
4984 | } |
||
4985 | } |
||
4986 | return ret; |
||
4987 | } |
||
4988 | |||
4989 | /* |
||
4990 | * |
||
4991 | */ |
||
4992 | static void |
||
4993 | atomRegisterSaveList(atomBiosHandlePtr handle, struct atomSaveListRecord **SaveList) |
||
4994 | { |
||
4995 | struct atomSaveListObject *ListObject = handle->SaveListObjects; |
||
4996 | RHDFUNC(handle); |
||
4997 | |||
4998 | while (ListObject) { |
||
4999 | if (ListObject->SaveList == SaveList) |
||
5000 | return; |
||
5001 | ListObject = ListObject->next; |
||
5002 | } |
||
5003 | if (!(ListObject = (struct atomSaveListObject *)xcalloc(1,sizeof (struct atomSaveListObject)))) |
||
5004 | return; |
||
5005 | ListObject->next = handle->SaveListObjects; |
||
5006 | ListObject->SaveList = SaveList; |
||
5007 | handle->SaveListObjects = ListObject; |
||
5008 | } |
||
5009 | |||
5010 | /* |
||
5011 | * |
||
5012 | */ |
||
5013 | static void |
||
5014 | atomUnregisterSaveList(atomBiosHandlePtr handle, struct atomSaveListRecord **SaveList) |
||
5015 | { |
||
5016 | struct atomSaveListObject **ListObject; |
||
5017 | RHDFUNC(handle); |
||
5018 | |||
5019 | if (!handle->SaveListObjects) |
||
5020 | return; |
||
5021 | ListObject = &handle->SaveListObjects; |
||
5022 | |||
5023 | while (1) { |
||
5024 | if ((*ListObject)->SaveList == SaveList) { |
||
5025 | struct atomSaveListObject *tmp = *ListObject; |
||
5026 | *ListObject = ((*ListObject)->next); |
||
5027 | xfree(tmp); |
||
5028 | } |
||
5029 | if (!(*ListObject) || !(*ListObject)->next) |
||
5030 | return; |
||
5031 | ListObject = &((*ListObject)->next); |
||
5032 | } |
||
5033 | } |
||
5034 | |||
5035 | /* |
||
5036 | * |
||
5037 | */ |
||
5038 | static AtomBiosResult |
||
5039 | atomSetRegisterListLocation(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data) |
||
5040 | { |
||
5041 | RHDFUNC(handle); |
||
5042 | |||
5043 | handle->SaveList = (struct atomSaveListRecord **)data->Address; |
||
5044 | if (handle->SaveList) |
||
5045 | atomRegisterSaveList(handle, handle->SaveList); |
||
5046 | |||
5047 | return ATOM_SUCCESS; |
||
5048 | } |
||
5049 | |||
5050 | /* |
||
5051 | * |
||
5052 | */ |
||
5053 | static AtomBiosResult |
||
5054 | atomRestoreRegisters(atomBiosHandlePtr handle, AtomBiosRequestID func, AtomBiosArgPtr data) |
||
5055 | { |
||
5056 | struct atomSaveListRecord *List = *(data->Address); |
||
5057 | int i; |
||
5058 | |||
5059 | RHDFUNC(handle); |
||
5060 | |||
5061 | if (!List) |
||
5062 | return ATOM_FAILED; |
||
5063 | |||
5064 | for (i = 0; i < List->Last; i++) { |
||
5065 | switch ( List->RegisterList[i].Type) { |
||
5066 | case atomRegisterMMIO: |
||
5067 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: MMIO(0x%4.4x) = 0x%4.4x\n",__func__, List->Last, |
||
5068 | List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5069 | RHDRegWrite(handle, List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5070 | break; |
||
5071 | case atomRegisterMC: |
||
5072 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: MC(0x%4.4x) = 0x%4.4x\n",__func__, List->Last, |
||
5073 | List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5074 | RHDWriteMC(handle, List->RegisterList[i].Address | MC_IND_ALL | MC_IND_WR_EN, |
||
5075 | List->RegisterList[i].Value); |
||
5076 | break; |
||
5077 | case atomRegisterPLL: |
||
5078 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: PLL(0x%4.4x) = 0x%4.4x\n",__func__, List->Last, |
||
5079 | List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5080 | _RHDWritePLL(handle->scrnIndex, List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5081 | break; |
||
5082 | case atomRegisterPCICFG: |
||
5083 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: PCICFG(0x%4.4x) = 0x%4.4x\n",__func__,List->Last, |
||
5084 | List->RegisterList[i].Address, List->RegisterList[i].Value); |
||
5085 | #ifdef XSERVER_LIBPCIACCESS |
||
5086 | pci_device_cfg_write(RHDPTRI(handle)->PciInfo, |
||
5087 | &List->RegisterList[i].Value, |
||
5088 | List->RegisterList[i].Address, 4, NULL); |
||
5089 | #else |
||
5090 | { |
||
5091 | PCITAG tag = RHDPTRI(handle)->PciTag; |
||
5092 | pciWriteLong(tag, List->RegisterList[i].Address, |
||
5093 | List->RegisterList[i].Value); |
||
5094 | } |
||
5095 | #endif |
||
5096 | break; |
||
5097 | } |
||
5098 | } |
||
5099 | |||
5100 | /* deallocate list */ |
||
5101 | atomUnregisterSaveList(handle, (struct atomSaveListRecord **)data->Address); |
||
5102 | xfree(List); |
||
5103 | *(data->Address) = NULL; |
||
5104 | |||
5105 | return ATOM_SUCCESS; |
||
5106 | } |
||
5107 | |||
5108 | # ifdef ATOM_BIOS_PARSER |
||
5109 | |||
5110 | #define ALLOC_CNT 25 |
||
5111 | |||
5112 | /* |
||
5113 | * |
||
5114 | */ |
||
5115 | static void |
||
5116 | atomSaveRegisters(atomBiosHandlePtr handle, enum atomRegisterType Type, CARD32 address) |
||
5117 | { |
||
5118 | struct atomSaveListRecord *List; |
||
5119 | CARD32 val = 0; |
||
5120 | int i; |
||
5121 | struct atomSaveListObject *SaveListObj = handle->SaveListObjects; |
||
5122 | |||
5123 | RHDFUNC(handle); |
||
5124 | |||
5125 | if (!handle->SaveList) |
||
5126 | return; |
||
5127 | |||
5128 | if (!(*(handle->SaveList))) { |
||
5129 | if (!(*handle->SaveList = (struct atomSaveListRecord *)xalloc(sizeof(struct atomSaveListRecord) |
||
5130 | + sizeof(struct atomRegisterList) * (ALLOC_CNT - 1)))) |
||
5131 | return; |
||
5132 | (*(handle->SaveList))->Length = ALLOC_CNT; |
||
5133 | (*(handle->SaveList))->Last = 0; |
||
5134 | } else if ((*(handle->SaveList))->Length == (*(handle->SaveList))->Last) { |
||
5135 | if (!(List = (struct atomSaveListRecord *)xrealloc(*handle->SaveList, |
||
5136 | sizeof(struct atomSaveListRecord) |
||
5137 | + (sizeof(struct atomRegisterList) |
||
5138 | * ((*(handle->SaveList))->Length + ALLOC_CNT - 1))))) |
||
5139 | return; |
||
5140 | *handle->SaveList = List; |
||
5141 | List->Length = (*(handle->SaveList))->Length + ALLOC_CNT; |
||
5142 | } |
||
5143 | List = *handle->SaveList; |
||
5144 | |||
5145 | while (SaveListObj) { |
||
5146 | struct atomSaveListRecord *ListFromObj = *(SaveListObj->SaveList); |
||
5147 | |||
5148 | if (ListFromObj) { |
||
5149 | for (i = 0; i < ListFromObj->Last; i++) |
||
5150 | if (ListFromObj->RegisterList[i].Address == address |
||
5151 | && ListFromObj->RegisterList[i].Type == Type) |
||
5152 | return; |
||
5153 | } |
||
5154 | SaveListObj = SaveListObj->next; |
||
5155 | } |
||
5156 | |||
5157 | switch (Type) { |
||
5158 | case atomRegisterMMIO: |
||
5159 | val = RHDRegRead(handle, address); |
||
5160 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: MMIO(0x%4.4x) = 0x%4.4x\n",__func__,List->Last,address,val); |
||
5161 | break; |
||
5162 | case atomRegisterMC: |
||
5163 | val = RHDReadMC(handle, address | MC_IND_ALL); |
||
5164 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: MC(0x%4.4x) = 0x%4.4x\n",__func__,List->Last,address,val); |
||
5165 | break; |
||
5166 | case atomRegisterPLL: |
||
5167 | val = _RHDReadPLL(handle->scrnIndex, address); |
||
5168 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: PLL(0x%4.4x) = 0x%4.4x\n",__func__,List->Last,address,val); |
||
5169 | break; |
||
5170 | case atomRegisterPCICFG: |
||
5171 | #ifdef XSERVER_LIBPCIACCESS |
||
5172 | val = pci_device_cfg_write(RHDPTRI(handle)->PciInfo, |
||
5173 | &val, address, 4, NULL); |
||
5174 | #else |
||
5175 | { |
||
5176 | PCITAG tag = RHDPTRI(handle)->PciTag; |
||
5177 | val = pciReadLong(tag, address); |
||
5178 | } |
||
5179 | #endif |
||
5180 | RHDDebugVerb(handle->scrnIndex,1, "%s[%i]: PCICFG(0x%4.4x) = 0x%4.4x\n",__func__,List->Last,address,val); |
||
5181 | break; |
||
5182 | } |
||
5183 | List->RegisterList[List->Last].Address = address; |
||
5184 | List->RegisterList[List->Last].Value = val; |
||
5185 | List->RegisterList[List->Last].Type = Type; |
||
5186 | List->Last++; |
||
5187 | } |
||
5188 | |||
5189 | /* |
||
5190 | * |
||
5191 | */ |
||
5192 | VOID* |
||
5193 | CailAllocateMemory(VOID *CAIL,UINT16 size) |
||
5194 | { |
||
5195 | CAILFUNC(CAIL); |
||
5196 | |||
5197 | return malloc(size); |
||
5198 | } |
||
5199 | |||
5200 | VOID |
||
5201 | CailReleaseMemory(VOID *CAIL, VOID *addr) |
||
5202 | { |
||
5203 | CAILFUNC(CAIL); |
||
5204 | |||
5205 | free(addr); |
||
5206 | } |
||
5207 | |||
5208 | VOID |
||
5209 | CailDelayMicroSeconds(VOID *CAIL, UINT32 delay) |
||
5210 | { |
||
5211 | CAILFUNC(CAIL); |
||
5212 | |||
5213 | usleep(delay); |
||
5214 | |||
5215 | // DEBUGP(xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_INFO,"Delay %i usec\n",delay)); |
||
5216 | } |
||
5217 | |||
5218 | UINT32 |
||
5219 | CailReadATIRegister(VOID* CAIL, UINT32 idx) |
||
5220 | { |
||
5221 | UINT32 ret; |
||
5222 | CAILFUNC(CAIL); |
||
5223 | |||
5224 | ret = RHDRegRead(((atomBiosHandlePtr)CAIL), idx << 2); |
||
5225 | // DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx << 2,ret)); |
||
5226 | return ret; |
||
5227 | } |
||
5228 | |||
5229 | VOID |
||
5230 | CailWriteATIRegister(VOID *CAIL, UINT32 idx, UINT32 data) |
||
5231 | { |
||
5232 | CAILFUNC(CAIL); |
||
5233 | |||
5234 | atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterMMIO, idx << 2); |
||
5235 | |||
5236 | RHDRegWrite(((atomBiosHandlePtr)CAIL),idx << 2,data); |
||
5237 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x,%x)\n",__func__,idx << 2,data); |
||
5238 | } |
||
5239 | |||
5240 | UINT32 |
||
5241 | CailReadFBData(VOID* CAIL, UINT32 idx) |
||
5242 | { |
||
5243 | UINT32 ret; |
||
5244 | |||
5245 | CAILFUNC(CAIL); |
||
5246 | |||
5247 | if (((atomBiosHandlePtr)CAIL)->fbBase) { |
||
5248 | CARD8 *FBBase = (CARD8*) |
||
5249 | RHDPTRI((atomBiosHandlePtr)CAIL)->FbBase; |
||
5250 | ret = *((CARD32*)(FBBase + (((atomBiosHandlePtr)CAIL)->fbBase) + idx)); |
||
5251 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x) = %x\n",__func__,idx,ret); |
||
5252 | } else if (((atomBiosHandlePtr)CAIL)->scratchBase) { |
||
5253 | ret = *(CARD32*)((CARD8*)(((atomBiosHandlePtr)CAIL)->scratchBase) + idx); |
||
5254 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x) = %x\n",__func__,idx,ret); |
||
5255 | } else { |
||
5256 | xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR, |
||
5257 | "%s: no fbbase set\n",__func__); |
||
5258 | return 0; |
||
5259 | } |
||
5260 | return ret; |
||
5261 | } |
||
5262 | |||
5263 | VOID |
||
5264 | CailWriteFBData(VOID *CAIL, UINT32 idx, UINT32 data) |
||
5265 | { |
||
5266 | CAILFUNC(CAIL); |
||
5267 | |||
5268 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x,%x)\n",__func__,idx,data); |
||
5269 | if (((atomBiosHandlePtr)CAIL)->fbBase) { |
||
5270 | CARD8 *FBBase = (CARD8*) |
||
5271 | RHDPTRI((atomBiosHandlePtr)CAIL)->FbBase; |
||
5272 | *((CARD32*)(FBBase + (((atomBiosHandlePtr)CAIL)->fbBase) + idx)) = data; |
||
5273 | } else if (((atomBiosHandlePtr)CAIL)->scratchBase) { |
||
5274 | *(CARD32*)((CARD8*)(((atomBiosHandlePtr)CAIL)->scratchBase) + idx) = data; |
||
5275 | } else |
||
5276 | xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR, |
||
5277 | "%s: no fbbase set\n",__func__); |
||
5278 | } |
||
5279 | |||
5280 | ULONG |
||
5281 | CailReadMC(VOID *CAIL, ULONG Address) |
||
5282 | { |
||
5283 | ULONG ret; |
||
5284 | |||
5285 | CAILFUNC(CAIL); |
||
5286 | |||
5287 | ret = RHDReadMC(((atomBiosHandlePtr)CAIL)->rhdPtr, Address | MC_IND_ALL); |
||
5288 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x) = %x\n",__func__,Address,ret); |
||
5289 | return ret; |
||
5290 | } |
||
5291 | |||
5292 | VOID |
||
5293 | CailWriteMC(VOID *CAIL, ULONG Address, ULONG data) |
||
5294 | { |
||
5295 | CAILFUNC(CAIL); |
||
5296 | |||
5297 | |||
5298 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x,%x)\n",__func__,Address,data); |
||
5299 | |||
5300 | atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterMC, Address); |
||
5301 | |||
5302 | RHDWriteMC(((atomBiosHandlePtr)CAIL)->rhdPtr, Address | MC_IND_ALL | MC_IND_WR_EN, data); |
||
5303 | } |
||
5304 | |||
5305 | #ifdef XSERVER_LIBPCIACCESS |
||
5306 | |||
5307 | VOID |
||
5308 | CailReadPCIConfigData(VOID*CAIL, VOID* ret, UINT32 idx,UINT16 size) |
||
5309 | { |
||
5310 | pci_device_cfg_read(RHDPTRI((atomBiosHandlePtr)CAIL)->PciInfo, |
||
5311 | ret,idx << 2 , size >> 3, NULL); |
||
5312 | } |
||
5313 | |||
5314 | VOID |
||
5315 | CailWritePCIConfigData(VOID*CAIL,VOID*src,UINT32 idx,UINT16 size) |
||
5316 | { |
||
5317 | atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterPCICFG, idx << 2); |
||
5318 | pci_device_cfg_write(RHDPTRI((atomBiosHandlePtr)CAIL)->PciInfo, |
||
5319 | src, idx << 2, size >> 3, NULL); |
||
5320 | } |
||
5321 | |||
5322 | #else |
||
5323 | |||
5324 | VOID |
||
5325 | CailReadPCIConfigData(VOID*CAIL, VOID* ret, UINT32 idx,UINT16 size) |
||
5326 | { u32_t bus, devfn; |
||
5327 | PCITAG tag = ((atomBiosHandlePtr)CAIL)->PciTag; |
||
5328 | |||
5329 | CAILFUNC(CAIL); |
||
5330 | bus = PCI_BUS_FROM_TAG(tag); |
||
5331 | devfn = PCI_DFN_FROM_TAG(tag); |
||
5332 | |||
5333 | switch (size) { |
||
5334 | case 8: |
||
5335 | *(CARD8*)ret = PciRead8(bus,devfn,idx << 2); |
||
5336 | break; |
||
5337 | case 16: |
||
5338 | *(CARD16*)ret = PciRead16(bus,devfn,idx << 2); |
||
5339 | break; |
||
5340 | case 32: |
||
5341 | *(CARD32*)ret = PciRead32(bus,devfn,idx << 2); |
||
5342 | break; |
||
5343 | default: |
||
5344 | xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex, |
||
5345 | X_ERROR,"%s: Unsupported size: %i\n", |
||
5346 | __func__,(int)size); |
||
5347 | return; |
||
5348 | break; |
||
5349 | } |
||
5350 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x) = %x\n",__func__,idx,*(unsigned int*)ret); |
||
5351 | |||
5352 | } |
||
5353 | |||
5354 | VOID |
||
5355 | CailWritePCIConfigData(VOID*CAIL,VOID*src,UINT32 idx,UINT16 size) |
||
5356 | { |
||
5357 | u32_t bus, devfn; |
||
5358 | PCITAG tag = ((atomBiosHandlePtr)CAIL)->PciTag; |
||
5359 | bus = PCI_BUS_FROM_TAG(tag); |
||
5360 | devfn = PCI_DFN_FROM_TAG(tag); |
||
5361 | |||
5362 | CAILFUNC(CAIL); |
||
5363 | |||
5364 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x,%x)\n",__func__,idx,(*(unsigned int*)src)); |
||
5365 | |||
5366 | atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterPCICFG, idx << 2); |
||
5367 | switch (size) { |
||
5368 | case 8: |
||
5369 | PciWrite8(bus,devfn, idx << 2,*(CARD8*)src); |
||
5370 | break; |
||
5371 | case 16: |
||
5372 | PciWrite16(bus,devfn,idx << 2,*(CARD16*)src); |
||
5373 | break; |
||
5374 | case 32: |
||
5375 | PciWrite32(bus,devfn,idx << 2,*(CARD32*)src); |
||
5376 | break; |
||
5377 | default: |
||
5378 | xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR, |
||
5379 | "%s: Unsupported size: %i\n",__func__,(int)size); |
||
5380 | break; |
||
5381 | } |
||
5382 | } |
||
5383 | #endif |
||
5384 | |||
5385 | ULONG |
||
5386 | CailReadPLL(VOID *CAIL, ULONG Address) |
||
5387 | { |
||
5388 | ULONG ret; |
||
5389 | |||
5390 | CAILFUNC(CAIL); |
||
5391 | |||
5392 | ret = _RHDReadPLL(((atomBiosHandlePtr)CAIL)->rhdPtr, Address); |
||
5393 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x) = %x\n",__func__,Address,ret); |
||
5394 | return ret; |
||
5395 | } |
||
5396 | |||
5397 | VOID |
||
5398 | CailWritePLL(VOID *CAIL, ULONG Address,ULONG Data) |
||
5399 | { |
||
5400 | CAILFUNC(CAIL); |
||
5401 | |||
5402 | RHDDebugVerb(((atomBiosHandlePtr)CAIL)->scrnIndex,1,"%s(%x,%x)\n",__func__,Address,Data); |
||
5403 | atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterPLL, Address); |
||
5404 | _RHDWritePLL(((atomBiosHandlePtr)CAIL)->scrnIndex, Address, Data); |
||
5405 | } |
||
5406 | |||
5407 | # endif |
||
5408 | |||
5409 | #endif /* ATOM_BIOS */><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>>>>>>>><>>><>>=>=>>>>>>>>>>>>=>><>>>>><>><>>> |