1771fe6b9SJerome Glisse /*
2771fe6b9SJerome Glisse * Copyright 2004 ATI Technologies Inc., Markham, Ontario
3771fe6b9SJerome Glisse * Copyright 2007-8 Advanced Micro Devices, Inc.
4771fe6b9SJerome Glisse * Copyright 2008 Red Hat Inc.
5771fe6b9SJerome Glisse *
6771fe6b9SJerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a
7771fe6b9SJerome Glisse * copy of this software and associated documentation files (the "Software"),
8771fe6b9SJerome Glisse * to deal in the Software without restriction, including without limitation
9771fe6b9SJerome Glisse * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10771fe6b9SJerome Glisse * and/or sell copies of the Software, and to permit persons to whom the
11771fe6b9SJerome Glisse * Software is furnished to do so, subject to the following conditions:
12771fe6b9SJerome Glisse *
13771fe6b9SJerome Glisse * The above copyright notice and this permission notice shall be included in
14771fe6b9SJerome Glisse * all copies or substantial portions of the Software.
15771fe6b9SJerome Glisse *
16771fe6b9SJerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17771fe6b9SJerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18771fe6b9SJerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19771fe6b9SJerome Glisse * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20771fe6b9SJerome Glisse * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21771fe6b9SJerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22771fe6b9SJerome Glisse * OTHER DEALINGS IN THE SOFTWARE.
23771fe6b9SJerome Glisse *
24771fe6b9SJerome Glisse * Authors: Dave Airlie
25771fe6b9SJerome Glisse * Alex Deucher
26771fe6b9SJerome Glisse */
27f9183127SSam Ravnborg
282ef79416SThomas Zimmermann #include <linux/pci.h>
292ef79416SThomas Zimmermann
30f9183127SSam Ravnborg #include <drm/drm_device.h>
31e747235eSJani Nikula #include <drm/drm_edid.h>
32760285e7SDavid Howells #include <drm/radeon_drm.h>
33f9183127SSam Ravnborg
34771fe6b9SJerome Glisse #include "radeon.h"
357ddfba01SLee Jones #include "radeon_legacy_encoders.h"
36771fe6b9SJerome Glisse #include "atom.h"
37771fe6b9SJerome Glisse
38771fe6b9SJerome Glisse #ifdef CONFIG_PPC_PMAC
39771fe6b9SJerome Glisse /* not sure which of these are needed */
40771fe6b9SJerome Glisse #include <asm/machdep.h>
41771fe6b9SJerome Glisse #include <asm/pmac_feature.h>
42771fe6b9SJerome Glisse #include <asm/prom.h>
43771fe6b9SJerome Glisse #endif /* CONFIG_PPC_PMAC */
44771fe6b9SJerome Glisse
45771fe6b9SJerome Glisse /* old legacy ATI BIOS routines */
46771fe6b9SJerome Glisse
47771fe6b9SJerome Glisse /* COMBIOS table offsets */
48771fe6b9SJerome Glisse enum radeon_combios_table_offset {
49771fe6b9SJerome Glisse /* absolute offset tables */
50771fe6b9SJerome Glisse COMBIOS_ASIC_INIT_1_TABLE,
51771fe6b9SJerome Glisse COMBIOS_BIOS_SUPPORT_TABLE,
52771fe6b9SJerome Glisse COMBIOS_DAC_PROGRAMMING_TABLE,
53771fe6b9SJerome Glisse COMBIOS_MAX_COLOR_DEPTH_TABLE,
54771fe6b9SJerome Glisse COMBIOS_CRTC_INFO_TABLE,
55771fe6b9SJerome Glisse COMBIOS_PLL_INFO_TABLE,
56771fe6b9SJerome Glisse COMBIOS_TV_INFO_TABLE,
57771fe6b9SJerome Glisse COMBIOS_DFP_INFO_TABLE,
58771fe6b9SJerome Glisse COMBIOS_HW_CONFIG_INFO_TABLE,
59771fe6b9SJerome Glisse COMBIOS_MULTIMEDIA_INFO_TABLE,
60771fe6b9SJerome Glisse COMBIOS_TV_STD_PATCH_TABLE,
61771fe6b9SJerome Glisse COMBIOS_LCD_INFO_TABLE,
62771fe6b9SJerome Glisse COMBIOS_MOBILE_INFO_TABLE,
63771fe6b9SJerome Glisse COMBIOS_PLL_INIT_TABLE,
64771fe6b9SJerome Glisse COMBIOS_MEM_CONFIG_TABLE,
65771fe6b9SJerome Glisse COMBIOS_SAVE_MASK_TABLE,
66771fe6b9SJerome Glisse COMBIOS_HARDCODED_EDID_TABLE,
67771fe6b9SJerome Glisse COMBIOS_ASIC_INIT_2_TABLE,
68771fe6b9SJerome Glisse COMBIOS_CONNECTOR_INFO_TABLE,
69771fe6b9SJerome Glisse COMBIOS_DYN_CLK_1_TABLE,
70771fe6b9SJerome Glisse COMBIOS_RESERVED_MEM_TABLE,
71771fe6b9SJerome Glisse COMBIOS_EXT_TMDS_INFO_TABLE,
72771fe6b9SJerome Glisse COMBIOS_MEM_CLK_INFO_TABLE,
73771fe6b9SJerome Glisse COMBIOS_EXT_DAC_INFO_TABLE,
74771fe6b9SJerome Glisse COMBIOS_MISC_INFO_TABLE,
75771fe6b9SJerome Glisse COMBIOS_CRT_INFO_TABLE,
76771fe6b9SJerome Glisse COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
77771fe6b9SJerome Glisse COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
78771fe6b9SJerome Glisse COMBIOS_FAN_SPEED_INFO_TABLE,
79771fe6b9SJerome Glisse COMBIOS_OVERDRIVE_INFO_TABLE,
80771fe6b9SJerome Glisse COMBIOS_OEM_INFO_TABLE,
81771fe6b9SJerome Glisse COMBIOS_DYN_CLK_2_TABLE,
82771fe6b9SJerome Glisse COMBIOS_POWER_CONNECTOR_INFO_TABLE,
83771fe6b9SJerome Glisse COMBIOS_I2C_INFO_TABLE,
84771fe6b9SJerome Glisse /* relative offset tables */
85771fe6b9SJerome Glisse COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */
86771fe6b9SJerome Glisse COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */
87771fe6b9SJerome Glisse COMBIOS_DETECTED_MEM_TABLE, /* offset from misc info */
88771fe6b9SJerome Glisse COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */
89771fe6b9SJerome Glisse COMBIOS_RAM_RESET_TABLE, /* offset from mem config */
90771fe6b9SJerome Glisse COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */
91771fe6b9SJerome Glisse COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */
92771fe6b9SJerome Glisse COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */
93771fe6b9SJerome Glisse COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */
94771fe6b9SJerome Glisse COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */
95771fe6b9SJerome Glisse COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */
96771fe6b9SJerome Glisse };
97771fe6b9SJerome Glisse
98771fe6b9SJerome Glisse enum radeon_combios_ddc {
99771fe6b9SJerome Glisse DDC_NONE_DETECTED,
100771fe6b9SJerome Glisse DDC_MONID,
101771fe6b9SJerome Glisse DDC_DVI,
102771fe6b9SJerome Glisse DDC_VGA,
103771fe6b9SJerome Glisse DDC_CRT2,
104771fe6b9SJerome Glisse DDC_LCD,
105771fe6b9SJerome Glisse DDC_GPIO,
106771fe6b9SJerome Glisse };
107771fe6b9SJerome Glisse
108771fe6b9SJerome Glisse enum radeon_combios_connector {
109771fe6b9SJerome Glisse CONNECTOR_NONE_LEGACY,
110771fe6b9SJerome Glisse CONNECTOR_PROPRIETARY_LEGACY,
111771fe6b9SJerome Glisse CONNECTOR_CRT_LEGACY,
112771fe6b9SJerome Glisse CONNECTOR_DVI_I_LEGACY,
113771fe6b9SJerome Glisse CONNECTOR_DVI_D_LEGACY,
114771fe6b9SJerome Glisse CONNECTOR_CTV_LEGACY,
115771fe6b9SJerome Glisse CONNECTOR_STV_LEGACY,
116771fe6b9SJerome Glisse CONNECTOR_UNSUPPORTED_LEGACY
117771fe6b9SJerome Glisse };
118771fe6b9SJerome Glisse
119080cbcb4SMichele Curti static const int legacy_connector_convert[] = {
120771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_Unknown,
121771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_DVID,
122771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_VGA,
123771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_DVII,
124771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_DVID,
125771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_Composite,
126771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
127771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_Unknown,
128771fe6b9SJerome Glisse };
129771fe6b9SJerome Glisse
combios_get_table_offset(struct drm_device * dev,enum radeon_combios_table_offset table)130771fe6b9SJerome Glisse static uint16_t combios_get_table_offset(struct drm_device *dev,
131771fe6b9SJerome Glisse enum radeon_combios_table_offset table)
132771fe6b9SJerome Glisse {
133771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
134cef1d00cSMark Kettenis int rev, size;
135771fe6b9SJerome Glisse uint16_t offset = 0, check_offset;
136771fe6b9SJerome Glisse
13703047cdfSMichel Dänzer if (!rdev->bios)
13803047cdfSMichel Dänzer return 0;
13903047cdfSMichel Dänzer
140771fe6b9SJerome Glisse switch (table) {
141771fe6b9SJerome Glisse /* absolute offset tables */
142771fe6b9SJerome Glisse case COMBIOS_ASIC_INIT_1_TABLE:
143cef1d00cSMark Kettenis check_offset = 0xc;
144771fe6b9SJerome Glisse break;
145771fe6b9SJerome Glisse case COMBIOS_BIOS_SUPPORT_TABLE:
146cef1d00cSMark Kettenis check_offset = 0x14;
147771fe6b9SJerome Glisse break;
148771fe6b9SJerome Glisse case COMBIOS_DAC_PROGRAMMING_TABLE:
149cef1d00cSMark Kettenis check_offset = 0x2a;
150771fe6b9SJerome Glisse break;
151771fe6b9SJerome Glisse case COMBIOS_MAX_COLOR_DEPTH_TABLE:
152cef1d00cSMark Kettenis check_offset = 0x2c;
153771fe6b9SJerome Glisse break;
154771fe6b9SJerome Glisse case COMBIOS_CRTC_INFO_TABLE:
155cef1d00cSMark Kettenis check_offset = 0x2e;
156771fe6b9SJerome Glisse break;
157771fe6b9SJerome Glisse case COMBIOS_PLL_INFO_TABLE:
158cef1d00cSMark Kettenis check_offset = 0x30;
159771fe6b9SJerome Glisse break;
160771fe6b9SJerome Glisse case COMBIOS_TV_INFO_TABLE:
161cef1d00cSMark Kettenis check_offset = 0x32;
162771fe6b9SJerome Glisse break;
163771fe6b9SJerome Glisse case COMBIOS_DFP_INFO_TABLE:
164cef1d00cSMark Kettenis check_offset = 0x34;
165771fe6b9SJerome Glisse break;
166771fe6b9SJerome Glisse case COMBIOS_HW_CONFIG_INFO_TABLE:
167cef1d00cSMark Kettenis check_offset = 0x36;
168771fe6b9SJerome Glisse break;
169771fe6b9SJerome Glisse case COMBIOS_MULTIMEDIA_INFO_TABLE:
170cef1d00cSMark Kettenis check_offset = 0x38;
171771fe6b9SJerome Glisse break;
172771fe6b9SJerome Glisse case COMBIOS_TV_STD_PATCH_TABLE:
173cef1d00cSMark Kettenis check_offset = 0x3e;
174771fe6b9SJerome Glisse break;
175771fe6b9SJerome Glisse case COMBIOS_LCD_INFO_TABLE:
176cef1d00cSMark Kettenis check_offset = 0x40;
177771fe6b9SJerome Glisse break;
178771fe6b9SJerome Glisse case COMBIOS_MOBILE_INFO_TABLE:
179cef1d00cSMark Kettenis check_offset = 0x42;
180771fe6b9SJerome Glisse break;
181771fe6b9SJerome Glisse case COMBIOS_PLL_INIT_TABLE:
182cef1d00cSMark Kettenis check_offset = 0x46;
183771fe6b9SJerome Glisse break;
184771fe6b9SJerome Glisse case COMBIOS_MEM_CONFIG_TABLE:
185cef1d00cSMark Kettenis check_offset = 0x48;
186771fe6b9SJerome Glisse break;
187771fe6b9SJerome Glisse case COMBIOS_SAVE_MASK_TABLE:
188cef1d00cSMark Kettenis check_offset = 0x4a;
189771fe6b9SJerome Glisse break;
190771fe6b9SJerome Glisse case COMBIOS_HARDCODED_EDID_TABLE:
191cef1d00cSMark Kettenis check_offset = 0x4c;
192771fe6b9SJerome Glisse break;
193771fe6b9SJerome Glisse case COMBIOS_ASIC_INIT_2_TABLE:
194cef1d00cSMark Kettenis check_offset = 0x4e;
195771fe6b9SJerome Glisse break;
196771fe6b9SJerome Glisse case COMBIOS_CONNECTOR_INFO_TABLE:
197cef1d00cSMark Kettenis check_offset = 0x50;
198771fe6b9SJerome Glisse break;
199771fe6b9SJerome Glisse case COMBIOS_DYN_CLK_1_TABLE:
200cef1d00cSMark Kettenis check_offset = 0x52;
201771fe6b9SJerome Glisse break;
202771fe6b9SJerome Glisse case COMBIOS_RESERVED_MEM_TABLE:
203cef1d00cSMark Kettenis check_offset = 0x54;
204771fe6b9SJerome Glisse break;
205771fe6b9SJerome Glisse case COMBIOS_EXT_TMDS_INFO_TABLE:
206cef1d00cSMark Kettenis check_offset = 0x58;
207771fe6b9SJerome Glisse break;
208771fe6b9SJerome Glisse case COMBIOS_MEM_CLK_INFO_TABLE:
209cef1d00cSMark Kettenis check_offset = 0x5a;
210771fe6b9SJerome Glisse break;
211771fe6b9SJerome Glisse case COMBIOS_EXT_DAC_INFO_TABLE:
212cef1d00cSMark Kettenis check_offset = 0x5c;
213771fe6b9SJerome Glisse break;
214771fe6b9SJerome Glisse case COMBIOS_MISC_INFO_TABLE:
215cef1d00cSMark Kettenis check_offset = 0x5e;
216771fe6b9SJerome Glisse break;
217771fe6b9SJerome Glisse case COMBIOS_CRT_INFO_TABLE:
218cef1d00cSMark Kettenis check_offset = 0x60;
219771fe6b9SJerome Glisse break;
220771fe6b9SJerome Glisse case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
221cef1d00cSMark Kettenis check_offset = 0x62;
222771fe6b9SJerome Glisse break;
223771fe6b9SJerome Glisse case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
224cef1d00cSMark Kettenis check_offset = 0x64;
225771fe6b9SJerome Glisse break;
226771fe6b9SJerome Glisse case COMBIOS_FAN_SPEED_INFO_TABLE:
227cef1d00cSMark Kettenis check_offset = 0x66;
228771fe6b9SJerome Glisse break;
229771fe6b9SJerome Glisse case COMBIOS_OVERDRIVE_INFO_TABLE:
230cef1d00cSMark Kettenis check_offset = 0x68;
231771fe6b9SJerome Glisse break;
232771fe6b9SJerome Glisse case COMBIOS_OEM_INFO_TABLE:
233cef1d00cSMark Kettenis check_offset = 0x6a;
234771fe6b9SJerome Glisse break;
235771fe6b9SJerome Glisse case COMBIOS_DYN_CLK_2_TABLE:
236cef1d00cSMark Kettenis check_offset = 0x6c;
237771fe6b9SJerome Glisse break;
238771fe6b9SJerome Glisse case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
239cef1d00cSMark Kettenis check_offset = 0x6e;
240771fe6b9SJerome Glisse break;
241771fe6b9SJerome Glisse case COMBIOS_I2C_INFO_TABLE:
242cef1d00cSMark Kettenis check_offset = 0x70;
243771fe6b9SJerome Glisse break;
244771fe6b9SJerome Glisse /* relative offset tables */
245771fe6b9SJerome Glisse case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */
246771fe6b9SJerome Glisse check_offset =
247771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
248771fe6b9SJerome Glisse if (check_offset) {
249771fe6b9SJerome Glisse rev = RBIOS8(check_offset);
250771fe6b9SJerome Glisse if (rev > 0) {
251771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x3);
252771fe6b9SJerome Glisse if (check_offset)
253771fe6b9SJerome Glisse offset = check_offset;
254771fe6b9SJerome Glisse }
255771fe6b9SJerome Glisse }
256771fe6b9SJerome Glisse break;
257771fe6b9SJerome Glisse case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */
258771fe6b9SJerome Glisse check_offset =
259771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
260771fe6b9SJerome Glisse if (check_offset) {
261771fe6b9SJerome Glisse rev = RBIOS8(check_offset);
262771fe6b9SJerome Glisse if (rev > 0) {
263771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x5);
264771fe6b9SJerome Glisse if (check_offset)
265771fe6b9SJerome Glisse offset = check_offset;
266771fe6b9SJerome Glisse }
267771fe6b9SJerome Glisse }
268771fe6b9SJerome Glisse break;
269771fe6b9SJerome Glisse case COMBIOS_DETECTED_MEM_TABLE: /* offset from misc info */
270771fe6b9SJerome Glisse check_offset =
271771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
272771fe6b9SJerome Glisse if (check_offset) {
273771fe6b9SJerome Glisse rev = RBIOS8(check_offset);
274771fe6b9SJerome Glisse if (rev > 0) {
275771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x7);
276771fe6b9SJerome Glisse if (check_offset)
277771fe6b9SJerome Glisse offset = check_offset;
278771fe6b9SJerome Glisse }
279771fe6b9SJerome Glisse }
280771fe6b9SJerome Glisse break;
281771fe6b9SJerome Glisse case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */
282771fe6b9SJerome Glisse check_offset =
283771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
284771fe6b9SJerome Glisse if (check_offset) {
285771fe6b9SJerome Glisse rev = RBIOS8(check_offset);
286771fe6b9SJerome Glisse if (rev == 2) {
287771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x9);
288771fe6b9SJerome Glisse if (check_offset)
289771fe6b9SJerome Glisse offset = check_offset;
290771fe6b9SJerome Glisse }
291771fe6b9SJerome Glisse }
292771fe6b9SJerome Glisse break;
293771fe6b9SJerome Glisse case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */
294771fe6b9SJerome Glisse check_offset =
295771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
296771fe6b9SJerome Glisse if (check_offset) {
297771fe6b9SJerome Glisse while (RBIOS8(check_offset++));
298771fe6b9SJerome Glisse check_offset += 2;
299771fe6b9SJerome Glisse if (check_offset)
300771fe6b9SJerome Glisse offset = check_offset;
301771fe6b9SJerome Glisse }
302771fe6b9SJerome Glisse break;
303771fe6b9SJerome Glisse case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */
304771fe6b9SJerome Glisse check_offset =
305771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
306771fe6b9SJerome Glisse if (check_offset) {
307771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x11);
308771fe6b9SJerome Glisse if (check_offset)
309771fe6b9SJerome Glisse offset = check_offset;
310771fe6b9SJerome Glisse }
311771fe6b9SJerome Glisse break;
312771fe6b9SJerome Glisse case COMBIOS_GPIO_INFO_TABLE: /* offset from mobile info */
313771fe6b9SJerome Glisse check_offset =
314771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
315771fe6b9SJerome Glisse if (check_offset) {
316771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x13);
317771fe6b9SJerome Glisse if (check_offset)
318771fe6b9SJerome Glisse offset = check_offset;
319771fe6b9SJerome Glisse }
320771fe6b9SJerome Glisse break;
321771fe6b9SJerome Glisse case COMBIOS_LCD_DDC_INFO_TABLE: /* offset from mobile info */
322771fe6b9SJerome Glisse check_offset =
323771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
324771fe6b9SJerome Glisse if (check_offset) {
325771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x15);
326771fe6b9SJerome Glisse if (check_offset)
327771fe6b9SJerome Glisse offset = check_offset;
328771fe6b9SJerome Glisse }
329771fe6b9SJerome Glisse break;
330771fe6b9SJerome Glisse case COMBIOS_TMDS_POWER_TABLE: /* offset from mobile info */
331771fe6b9SJerome Glisse check_offset =
332771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
333771fe6b9SJerome Glisse if (check_offset) {
334771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x17);
335771fe6b9SJerome Glisse if (check_offset)
336771fe6b9SJerome Glisse offset = check_offset;
337771fe6b9SJerome Glisse }
338771fe6b9SJerome Glisse break;
339771fe6b9SJerome Glisse case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */
340771fe6b9SJerome Glisse check_offset =
341771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
342771fe6b9SJerome Glisse if (check_offset) {
343771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x2);
344771fe6b9SJerome Glisse if (check_offset)
345771fe6b9SJerome Glisse offset = check_offset;
346771fe6b9SJerome Glisse }
347771fe6b9SJerome Glisse break;
348771fe6b9SJerome Glisse case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */
349771fe6b9SJerome Glisse check_offset =
350771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
351771fe6b9SJerome Glisse if (check_offset) {
352771fe6b9SJerome Glisse check_offset = RBIOS16(check_offset + 0x4);
353771fe6b9SJerome Glisse if (check_offset)
354771fe6b9SJerome Glisse offset = check_offset;
355771fe6b9SJerome Glisse }
356771fe6b9SJerome Glisse break;
357771fe6b9SJerome Glisse default:
358cef1d00cSMark Kettenis check_offset = 0;
359771fe6b9SJerome Glisse break;
360771fe6b9SJerome Glisse }
361771fe6b9SJerome Glisse
362cef1d00cSMark Kettenis size = RBIOS8(rdev->bios_header_start + 0x6);
363cef1d00cSMark Kettenis /* check absolute offset tables */
364cef1d00cSMark Kettenis if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size)
365cef1d00cSMark Kettenis offset = RBIOS16(rdev->bios_header_start + check_offset);
366771fe6b9SJerome Glisse
367cef1d00cSMark Kettenis return offset;
368771fe6b9SJerome Glisse }
369771fe6b9SJerome Glisse
radeon_combios_check_hardcoded_edid(struct radeon_device * rdev)3703c537889SAlex Deucher bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
3713c537889SAlex Deucher {
372fafcf94eSAlex Deucher int edid_info, size;
373*c6bb3acfSThomas Weißschuh const struct drm_edid *edid;
3747466f4ccSAdam Jackson unsigned char *raw;
375fb1b5e1dSWu Hoi Pok edid_info = combios_get_table_offset(rdev_to_drm(rdev), COMBIOS_HARDCODED_EDID_TABLE);
3763c537889SAlex Deucher if (!edid_info)
3773c537889SAlex Deucher return false;
3783c537889SAlex Deucher
3797466f4ccSAdam Jackson raw = rdev->bios + edid_info;
380fafcf94eSAlex Deucher size = EDID_LENGTH * (raw[0x7e] + 1);
381*c6bb3acfSThomas Weißschuh edid = drm_edid_alloc(raw, size);
3823c537889SAlex Deucher
383*c6bb3acfSThomas Weißschuh if (!drm_edid_valid(edid)) {
384*c6bb3acfSThomas Weißschuh drm_edid_free(edid);
3853c537889SAlex Deucher return false;
3863c537889SAlex Deucher }
3873c537889SAlex Deucher
3883c537889SAlex Deucher rdev->mode_info.bios_hardcoded_edid = edid;
3893c537889SAlex Deucher return true;
3903c537889SAlex Deucher }
3913c537889SAlex Deucher
392c324acd5SAlex Deucher /* this is used for atom LCDs as well */
3933c537889SAlex Deucher struct edid *
radeon_bios_get_hardcoded_edid(struct radeon_device * rdev)394c324acd5SAlex Deucher radeon_bios_get_hardcoded_edid(struct radeon_device *rdev)
3953c537889SAlex Deucher {
396*c6bb3acfSThomas Weißschuh return drm_edid_duplicate(drm_edid_raw(rdev->mode_info.bios_hardcoded_edid));
3973c537889SAlex Deucher }
3983c537889SAlex Deucher
combios_setup_i2c_bus(struct radeon_device * rdev,enum radeon_combios_ddc ddc,u32 clk_mask,u32 data_mask)3996a93cb25SAlex Deucher static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
400179e8078SAlex Deucher enum radeon_combios_ddc ddc,
401179e8078SAlex Deucher u32 clk_mask,
402179e8078SAlex Deucher u32 data_mask)
403771fe6b9SJerome Glisse {
404771fe6b9SJerome Glisse struct radeon_i2c_bus_rec i2c;
405179e8078SAlex Deucher int ddc_line = 0;
406179e8078SAlex Deucher
407179e8078SAlex Deucher /* ddc id = mask reg
408179e8078SAlex Deucher * DDC_NONE_DETECTED = none
409179e8078SAlex Deucher * DDC_DVI = RADEON_GPIO_DVI_DDC
410179e8078SAlex Deucher * DDC_VGA = RADEON_GPIO_VGA_DDC
411179e8078SAlex Deucher * DDC_LCD = RADEON_GPIOPAD_MASK
412179e8078SAlex Deucher * DDC_GPIO = RADEON_MDGPIO_MASK
413508c8d60SAlex Deucher * r1xx
414179e8078SAlex Deucher * DDC_MONID = RADEON_GPIO_MONID
415179e8078SAlex Deucher * DDC_CRT2 = RADEON_GPIO_CRT2_DDC
416508c8d60SAlex Deucher * r200
417179e8078SAlex Deucher * DDC_MONID = RADEON_GPIO_MONID
418179e8078SAlex Deucher * DDC_CRT2 = RADEON_GPIO_DVI_DDC
419508c8d60SAlex Deucher * r300/r350
420508c8d60SAlex Deucher * DDC_MONID = RADEON_GPIO_DVI_DDC
421508c8d60SAlex Deucher * DDC_CRT2 = RADEON_GPIO_DVI_DDC
422508c8d60SAlex Deucher * rv2xx/rv3xx
423508c8d60SAlex Deucher * DDC_MONID = RADEON_GPIO_MONID
424508c8d60SAlex Deucher * DDC_CRT2 = RADEON_GPIO_MONID
425179e8078SAlex Deucher * rs3xx/rs4xx
426179e8078SAlex Deucher * DDC_MONID = RADEON_GPIOPAD_MASK
427179e8078SAlex Deucher * DDC_CRT2 = RADEON_GPIO_MONID
428179e8078SAlex Deucher */
429179e8078SAlex Deucher switch (ddc) {
430179e8078SAlex Deucher case DDC_NONE_DETECTED:
431179e8078SAlex Deucher default:
432179e8078SAlex Deucher ddc_line = 0;
433179e8078SAlex Deucher break;
434179e8078SAlex Deucher case DDC_DVI:
435179e8078SAlex Deucher ddc_line = RADEON_GPIO_DVI_DDC;
436179e8078SAlex Deucher break;
437179e8078SAlex Deucher case DDC_VGA:
438179e8078SAlex Deucher ddc_line = RADEON_GPIO_VGA_DDC;
439179e8078SAlex Deucher break;
440179e8078SAlex Deucher case DDC_LCD:
441179e8078SAlex Deucher ddc_line = RADEON_GPIOPAD_MASK;
442179e8078SAlex Deucher break;
443179e8078SAlex Deucher case DDC_GPIO:
444179e8078SAlex Deucher ddc_line = RADEON_MDGPIO_MASK;
445179e8078SAlex Deucher break;
446179e8078SAlex Deucher case DDC_MONID:
447179e8078SAlex Deucher if (rdev->family == CHIP_RS300 ||
448179e8078SAlex Deucher rdev->family == CHIP_RS400 ||
449179e8078SAlex Deucher rdev->family == CHIP_RS480)
450179e8078SAlex Deucher ddc_line = RADEON_GPIOPAD_MASK;
451508c8d60SAlex Deucher else if (rdev->family == CHIP_R300 ||
452776f2b7cSAlex Deucher rdev->family == CHIP_R350) {
453508c8d60SAlex Deucher ddc_line = RADEON_GPIO_DVI_DDC;
454776f2b7cSAlex Deucher ddc = DDC_DVI;
455776f2b7cSAlex Deucher } else
456179e8078SAlex Deucher ddc_line = RADEON_GPIO_MONID;
457179e8078SAlex Deucher break;
458179e8078SAlex Deucher case DDC_CRT2:
459508c8d60SAlex Deucher if (rdev->family == CHIP_R200 ||
460508c8d60SAlex Deucher rdev->family == CHIP_R300 ||
461776f2b7cSAlex Deucher rdev->family == CHIP_R350) {
462179e8078SAlex Deucher ddc_line = RADEON_GPIO_DVI_DDC;
463776f2b7cSAlex Deucher ddc = DDC_DVI;
464776f2b7cSAlex Deucher } else if (rdev->family == CHIP_RS300 ||
465776f2b7cSAlex Deucher rdev->family == CHIP_RS400 ||
466776f2b7cSAlex Deucher rdev->family == CHIP_RS480)
467508c8d60SAlex Deucher ddc_line = RADEON_GPIO_MONID;
468776f2b7cSAlex Deucher else if (rdev->family >= CHIP_RV350) {
469776f2b7cSAlex Deucher ddc_line = RADEON_GPIO_MONID;
470776f2b7cSAlex Deucher ddc = DDC_MONID;
471776f2b7cSAlex Deucher } else
472179e8078SAlex Deucher ddc_line = RADEON_GPIO_CRT2_DDC;
473179e8078SAlex Deucher break;
474179e8078SAlex Deucher }
475771fe6b9SJerome Glisse
4766a93cb25SAlex Deucher if (ddc_line == RADEON_GPIOPAD_MASK) {
4776a93cb25SAlex Deucher i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
4786a93cb25SAlex Deucher i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
4796a93cb25SAlex Deucher i2c.a_clk_reg = RADEON_GPIOPAD_A;
4806a93cb25SAlex Deucher i2c.a_data_reg = RADEON_GPIOPAD_A;
4816a93cb25SAlex Deucher i2c.en_clk_reg = RADEON_GPIOPAD_EN;
4826a93cb25SAlex Deucher i2c.en_data_reg = RADEON_GPIOPAD_EN;
4836a93cb25SAlex Deucher i2c.y_clk_reg = RADEON_GPIOPAD_Y;
4846a93cb25SAlex Deucher i2c.y_data_reg = RADEON_GPIOPAD_Y;
4856a93cb25SAlex Deucher } else if (ddc_line == RADEON_MDGPIO_MASK) {
4866a93cb25SAlex Deucher i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
4876a93cb25SAlex Deucher i2c.mask_data_reg = RADEON_MDGPIO_MASK;
4886a93cb25SAlex Deucher i2c.a_clk_reg = RADEON_MDGPIO_A;
4896a93cb25SAlex Deucher i2c.a_data_reg = RADEON_MDGPIO_A;
4906a93cb25SAlex Deucher i2c.en_clk_reg = RADEON_MDGPIO_EN;
4916a93cb25SAlex Deucher i2c.en_data_reg = RADEON_MDGPIO_EN;
4926a93cb25SAlex Deucher i2c.y_clk_reg = RADEON_MDGPIO_Y;
4936a93cb25SAlex Deucher i2c.y_data_reg = RADEON_MDGPIO_Y;
4946a93cb25SAlex Deucher } else {
495771fe6b9SJerome Glisse i2c.mask_clk_reg = ddc_line;
496771fe6b9SJerome Glisse i2c.mask_data_reg = ddc_line;
497771fe6b9SJerome Glisse i2c.a_clk_reg = ddc_line;
498771fe6b9SJerome Glisse i2c.a_data_reg = ddc_line;
4999b9fe724SAlex Deucher i2c.en_clk_reg = ddc_line;
5009b9fe724SAlex Deucher i2c.en_data_reg = ddc_line;
5019b9fe724SAlex Deucher i2c.y_clk_reg = ddc_line;
5029b9fe724SAlex Deucher i2c.y_data_reg = ddc_line;
503771fe6b9SJerome Glisse }
504771fe6b9SJerome Glisse
505179e8078SAlex Deucher if (clk_mask && data_mask) {
506be663057SAlex Deucher /* system specific masks */
507179e8078SAlex Deucher i2c.mask_clk_mask = clk_mask;
508179e8078SAlex Deucher i2c.mask_data_mask = data_mask;
509179e8078SAlex Deucher i2c.a_clk_mask = clk_mask;
510179e8078SAlex Deucher i2c.a_data_mask = data_mask;
511179e8078SAlex Deucher i2c.en_clk_mask = clk_mask;
512179e8078SAlex Deucher i2c.en_data_mask = data_mask;
513179e8078SAlex Deucher i2c.y_clk_mask = clk_mask;
514179e8078SAlex Deucher i2c.y_data_mask = data_mask;
515be663057SAlex Deucher } else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
516be663057SAlex Deucher (ddc_line == RADEON_MDGPIO_MASK)) {
517be663057SAlex Deucher /* default gpiopad masks */
518be663057SAlex Deucher i2c.mask_clk_mask = (0x20 << 8);
519be663057SAlex Deucher i2c.mask_data_mask = 0x80;
520be663057SAlex Deucher i2c.a_clk_mask = (0x20 << 8);
521be663057SAlex Deucher i2c.a_data_mask = 0x80;
522be663057SAlex Deucher i2c.en_clk_mask = (0x20 << 8);
523be663057SAlex Deucher i2c.en_data_mask = 0x80;
524be663057SAlex Deucher i2c.y_clk_mask = (0x20 << 8);
525be663057SAlex Deucher i2c.y_data_mask = 0x80;
526179e8078SAlex Deucher } else {
527be663057SAlex Deucher /* default masks for ddc pads */
528286e0c94SJean Delvare i2c.mask_clk_mask = RADEON_GPIO_MASK_1;
529286e0c94SJean Delvare i2c.mask_data_mask = RADEON_GPIO_MASK_0;
530179e8078SAlex Deucher i2c.a_clk_mask = RADEON_GPIO_A_1;
531179e8078SAlex Deucher i2c.a_data_mask = RADEON_GPIO_A_0;
532179e8078SAlex Deucher i2c.en_clk_mask = RADEON_GPIO_EN_1;
533179e8078SAlex Deucher i2c.en_data_mask = RADEON_GPIO_EN_0;
534179e8078SAlex Deucher i2c.y_clk_mask = RADEON_GPIO_Y_1;
535179e8078SAlex Deucher i2c.y_data_mask = RADEON_GPIO_Y_0;
536179e8078SAlex Deucher }
537179e8078SAlex Deucher
53840bacf16SAlex Deucher switch (rdev->family) {
53940bacf16SAlex Deucher case CHIP_R100:
54040bacf16SAlex Deucher case CHIP_RV100:
54140bacf16SAlex Deucher case CHIP_RS100:
54240bacf16SAlex Deucher case CHIP_RV200:
54340bacf16SAlex Deucher case CHIP_RS200:
54440bacf16SAlex Deucher case CHIP_RS300:
54540bacf16SAlex Deucher switch (ddc_line) {
54640bacf16SAlex Deucher case RADEON_GPIO_DVI_DDC:
547b28ea411SAlex Deucher i2c.hw_capable = true;
54840bacf16SAlex Deucher break;
54940bacf16SAlex Deucher default:
55040bacf16SAlex Deucher i2c.hw_capable = false;
55140bacf16SAlex Deucher break;
55240bacf16SAlex Deucher }
55340bacf16SAlex Deucher break;
55440bacf16SAlex Deucher case CHIP_R200:
55540bacf16SAlex Deucher switch (ddc_line) {
55640bacf16SAlex Deucher case RADEON_GPIO_DVI_DDC:
55740bacf16SAlex Deucher case RADEON_GPIO_MONID:
55840bacf16SAlex Deucher i2c.hw_capable = true;
55940bacf16SAlex Deucher break;
56040bacf16SAlex Deucher default:
56140bacf16SAlex Deucher i2c.hw_capable = false;
56240bacf16SAlex Deucher break;
56340bacf16SAlex Deucher }
56440bacf16SAlex Deucher break;
56540bacf16SAlex Deucher case CHIP_RV250:
56640bacf16SAlex Deucher case CHIP_RV280:
56740bacf16SAlex Deucher switch (ddc_line) {
56840bacf16SAlex Deucher case RADEON_GPIO_VGA_DDC:
56940bacf16SAlex Deucher case RADEON_GPIO_DVI_DDC:
57040bacf16SAlex Deucher case RADEON_GPIO_CRT2_DDC:
57140bacf16SAlex Deucher i2c.hw_capable = true;
57240bacf16SAlex Deucher break;
57340bacf16SAlex Deucher default:
57440bacf16SAlex Deucher i2c.hw_capable = false;
57540bacf16SAlex Deucher break;
57640bacf16SAlex Deucher }
57740bacf16SAlex Deucher break;
57840bacf16SAlex Deucher case CHIP_R300:
57940bacf16SAlex Deucher case CHIP_R350:
58040bacf16SAlex Deucher switch (ddc_line) {
58140bacf16SAlex Deucher case RADEON_GPIO_VGA_DDC:
58240bacf16SAlex Deucher case RADEON_GPIO_DVI_DDC:
58340bacf16SAlex Deucher i2c.hw_capable = true;
58440bacf16SAlex Deucher break;
58540bacf16SAlex Deucher default:
58640bacf16SAlex Deucher i2c.hw_capable = false;
58740bacf16SAlex Deucher break;
58840bacf16SAlex Deucher }
58940bacf16SAlex Deucher break;
59040bacf16SAlex Deucher case CHIP_RV350:
59140bacf16SAlex Deucher case CHIP_RV380:
59240bacf16SAlex Deucher case CHIP_RS400:
59340bacf16SAlex Deucher case CHIP_RS480:
5946a93cb25SAlex Deucher switch (ddc_line) {
5956a93cb25SAlex Deucher case RADEON_GPIO_VGA_DDC:
5966a93cb25SAlex Deucher case RADEON_GPIO_DVI_DDC:
5976a93cb25SAlex Deucher i2c.hw_capable = true;
5986a93cb25SAlex Deucher break;
5996a93cb25SAlex Deucher case RADEON_GPIO_MONID:
6006a93cb25SAlex Deucher /* hw i2c on RADEON_GPIO_MONID doesn't seem to work
6016a93cb25SAlex Deucher * reliably on some pre-r4xx hardware; not sure why.
6026a93cb25SAlex Deucher */
6036a93cb25SAlex Deucher i2c.hw_capable = false;
6046a93cb25SAlex Deucher break;
6056a93cb25SAlex Deucher default:
6066a93cb25SAlex Deucher i2c.hw_capable = false;
6076a93cb25SAlex Deucher break;
6086a93cb25SAlex Deucher }
60940bacf16SAlex Deucher break;
61040bacf16SAlex Deucher default:
61140bacf16SAlex Deucher i2c.hw_capable = false;
61240bacf16SAlex Deucher break;
6136a93cb25SAlex Deucher }
6146a93cb25SAlex Deucher i2c.mm_i2c = false;
615f376b94fSAlex Deucher
616179e8078SAlex Deucher i2c.i2c_id = ddc;
6178e36ed00SAlex Deucher i2c.hpd = RADEON_HPD_NONE;
6186a93cb25SAlex Deucher
619771fe6b9SJerome Glisse if (ddc_line)
620771fe6b9SJerome Glisse i2c.valid = true;
621771fe6b9SJerome Glisse else
622771fe6b9SJerome Glisse i2c.valid = false;
623771fe6b9SJerome Glisse
624771fe6b9SJerome Glisse return i2c;
625771fe6b9SJerome Glisse }
626771fe6b9SJerome Glisse
radeon_combios_get_i2c_info_from_table(struct radeon_device * rdev)6273d61bd42SAlex Deucher static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
6283d61bd42SAlex Deucher {
629fb1b5e1dSWu Hoi Pok struct drm_device *dev = rdev_to_drm(rdev);
6303d61bd42SAlex Deucher struct radeon_i2c_bus_rec i2c;
6313d61bd42SAlex Deucher u16 offset;
6323d61bd42SAlex Deucher u8 id, blocks, clk, data;
6333d61bd42SAlex Deucher int i;
6343d61bd42SAlex Deucher
6353d61bd42SAlex Deucher i2c.valid = false;
6363d61bd42SAlex Deucher
6373d61bd42SAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
6383d61bd42SAlex Deucher if (offset) {
6393d61bd42SAlex Deucher blocks = RBIOS8(offset + 2);
6403d61bd42SAlex Deucher for (i = 0; i < blocks; i++) {
6413d61bd42SAlex Deucher id = RBIOS8(offset + 3 + (i * 5) + 0);
6423d61bd42SAlex Deucher if (id == 136) {
6433d61bd42SAlex Deucher clk = RBIOS8(offset + 3 + (i * 5) + 3);
6443d61bd42SAlex Deucher data = RBIOS8(offset + 3 + (i * 5) + 4);
6453d61bd42SAlex Deucher /* gpiopad */
6463d61bd42SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
6473d61bd42SAlex Deucher (1 << clk), (1 << data));
6483d61bd42SAlex Deucher break;
6493d61bd42SAlex Deucher }
6503d61bd42SAlex Deucher }
6513d61bd42SAlex Deucher }
6523d61bd42SAlex Deucher return i2c;
6533d61bd42SAlex Deucher }
6543d61bd42SAlex Deucher
radeon_combios_i2c_init(struct radeon_device * rdev)655f376b94fSAlex Deucher void radeon_combios_i2c_init(struct radeon_device *rdev)
656f376b94fSAlex Deucher {
657fb1b5e1dSWu Hoi Pok struct drm_device *dev = rdev_to_drm(rdev);
658f376b94fSAlex Deucher struct radeon_i2c_bus_rec i2c;
659f376b94fSAlex Deucher
660508c8d60SAlex Deucher /* actual hw pads
661508c8d60SAlex Deucher * r1xx/rs2xx/rs3xx
662508c8d60SAlex Deucher * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm
663508c8d60SAlex Deucher * r200
664508c8d60SAlex Deucher * 0x60, 0x64, 0x68, mm
665508c8d60SAlex Deucher * r300/r350
666508c8d60SAlex Deucher * 0x60, 0x64, mm
667508c8d60SAlex Deucher * rv2xx/rv3xx/rs4xx
668508c8d60SAlex Deucher * 0x60, 0x64, 0x68, gpiopads, mm
669508c8d60SAlex Deucher */
670f376b94fSAlex Deucher
671508c8d60SAlex Deucher /* 0x60 */
672179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
673179e8078SAlex Deucher rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
674508c8d60SAlex Deucher /* 0x64 */
675179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
676179e8078SAlex Deucher rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
677f376b94fSAlex Deucher
678508c8d60SAlex Deucher /* mm i2c */
679f376b94fSAlex Deucher i2c.valid = true;
680f376b94fSAlex Deucher i2c.hw_capable = true;
681f376b94fSAlex Deucher i2c.mm_i2c = true;
682179e8078SAlex Deucher i2c.i2c_id = 0xa0;
683179e8078SAlex Deucher rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C");
684179e8078SAlex Deucher
685508c8d60SAlex Deucher if (rdev->family == CHIP_R300 ||
686508c8d60SAlex Deucher rdev->family == CHIP_R350) {
687508c8d60SAlex Deucher /* only 2 sw i2c pads */
688508c8d60SAlex Deucher } else if (rdev->family == CHIP_RS300 ||
689179e8078SAlex Deucher rdev->family == CHIP_RS400 ||
690179e8078SAlex Deucher rdev->family == CHIP_RS480) {
691508c8d60SAlex Deucher /* 0x68 */
692179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
693179e8078SAlex Deucher rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
694179e8078SAlex Deucher
695508c8d60SAlex Deucher /* gpiopad */
6963d61bd42SAlex Deucher i2c = radeon_combios_get_i2c_info_from_table(rdev);
6973d61bd42SAlex Deucher if (i2c.valid)
698179e8078SAlex Deucher rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
6996dd66633SAlex Deucher } else if ((rdev->family == CHIP_R200) ||
7006dd66633SAlex Deucher (rdev->family >= CHIP_R300)) {
701508c8d60SAlex Deucher /* 0x68 */
702179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
703179e8078SAlex Deucher rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
704179e8078SAlex Deucher } else {
705508c8d60SAlex Deucher /* 0x68 */
706179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
707179e8078SAlex Deucher rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
708508c8d60SAlex Deucher /* 0x6c */
709179e8078SAlex Deucher i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
710179e8078SAlex Deucher rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
711179e8078SAlex Deucher }
712f376b94fSAlex Deucher }
713f376b94fSAlex Deucher
radeon_combios_get_clock_info(struct drm_device * dev)714771fe6b9SJerome Glisse bool radeon_combios_get_clock_info(struct drm_device *dev)
715771fe6b9SJerome Glisse {
716771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
717771fe6b9SJerome Glisse uint16_t pll_info;
718771fe6b9SJerome Glisse struct radeon_pll *p1pll = &rdev->clock.p1pll;
719771fe6b9SJerome Glisse struct radeon_pll *p2pll = &rdev->clock.p2pll;
720771fe6b9SJerome Glisse struct radeon_pll *spll = &rdev->clock.spll;
721771fe6b9SJerome Glisse struct radeon_pll *mpll = &rdev->clock.mpll;
722771fe6b9SJerome Glisse int8_t rev;
723771fe6b9SJerome Glisse uint16_t sclk, mclk;
724771fe6b9SJerome Glisse
725771fe6b9SJerome Glisse pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
726771fe6b9SJerome Glisse if (pll_info) {
727771fe6b9SJerome Glisse rev = RBIOS8(pll_info);
728771fe6b9SJerome Glisse
729771fe6b9SJerome Glisse /* pixel clocks */
730771fe6b9SJerome Glisse p1pll->reference_freq = RBIOS16(pll_info + 0xe);
731771fe6b9SJerome Glisse p1pll->reference_div = RBIOS16(pll_info + 0x10);
732771fe6b9SJerome Glisse p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
733771fe6b9SJerome Glisse p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
73486cb2bbfSAlex Deucher p1pll->lcd_pll_out_min = p1pll->pll_out_min;
73586cb2bbfSAlex Deucher p1pll->lcd_pll_out_max = p1pll->pll_out_max;
736771fe6b9SJerome Glisse
737771fe6b9SJerome Glisse if (rev > 9) {
738771fe6b9SJerome Glisse p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
739771fe6b9SJerome Glisse p1pll->pll_in_max = RBIOS32(pll_info + 0x3a);
740771fe6b9SJerome Glisse } else {
741771fe6b9SJerome Glisse p1pll->pll_in_min = 40;
742771fe6b9SJerome Glisse p1pll->pll_in_max = 500;
743771fe6b9SJerome Glisse }
744771fe6b9SJerome Glisse *p2pll = *p1pll;
745771fe6b9SJerome Glisse
746771fe6b9SJerome Glisse /* system clock */
747771fe6b9SJerome Glisse spll->reference_freq = RBIOS16(pll_info + 0x1a);
748771fe6b9SJerome Glisse spll->reference_div = RBIOS16(pll_info + 0x1c);
749771fe6b9SJerome Glisse spll->pll_out_min = RBIOS32(pll_info + 0x1e);
750771fe6b9SJerome Glisse spll->pll_out_max = RBIOS32(pll_info + 0x22);
751771fe6b9SJerome Glisse
752771fe6b9SJerome Glisse if (rev > 10) {
753771fe6b9SJerome Glisse spll->pll_in_min = RBIOS32(pll_info + 0x48);
754771fe6b9SJerome Glisse spll->pll_in_max = RBIOS32(pll_info + 0x4c);
755771fe6b9SJerome Glisse } else {
756771fe6b9SJerome Glisse /* ??? */
757771fe6b9SJerome Glisse spll->pll_in_min = 40;
758771fe6b9SJerome Glisse spll->pll_in_max = 500;
759771fe6b9SJerome Glisse }
760771fe6b9SJerome Glisse
761771fe6b9SJerome Glisse /* memory clock */
762771fe6b9SJerome Glisse mpll->reference_freq = RBIOS16(pll_info + 0x26);
763771fe6b9SJerome Glisse mpll->reference_div = RBIOS16(pll_info + 0x28);
764771fe6b9SJerome Glisse mpll->pll_out_min = RBIOS32(pll_info + 0x2a);
765771fe6b9SJerome Glisse mpll->pll_out_max = RBIOS32(pll_info + 0x2e);
766771fe6b9SJerome Glisse
767771fe6b9SJerome Glisse if (rev > 10) {
768771fe6b9SJerome Glisse mpll->pll_in_min = RBIOS32(pll_info + 0x5a);
769771fe6b9SJerome Glisse mpll->pll_in_max = RBIOS32(pll_info + 0x5e);
770771fe6b9SJerome Glisse } else {
771771fe6b9SJerome Glisse /* ??? */
772771fe6b9SJerome Glisse mpll->pll_in_min = 40;
773771fe6b9SJerome Glisse mpll->pll_in_max = 500;
774771fe6b9SJerome Glisse }
775771fe6b9SJerome Glisse
776771fe6b9SJerome Glisse /* default sclk/mclk */
777771fe6b9SJerome Glisse sclk = RBIOS16(pll_info + 0xa);
778771fe6b9SJerome Glisse mclk = RBIOS16(pll_info + 0x8);
779771fe6b9SJerome Glisse if (sclk == 0)
780771fe6b9SJerome Glisse sclk = 200 * 100;
781771fe6b9SJerome Glisse if (mclk == 0)
782771fe6b9SJerome Glisse mclk = 200 * 100;
783771fe6b9SJerome Glisse
784771fe6b9SJerome Glisse rdev->clock.default_sclk = sclk;
785771fe6b9SJerome Glisse rdev->clock.default_mclk = mclk;
786771fe6b9SJerome Glisse
787b20f9befSAlex Deucher if (RBIOS32(pll_info + 0x16))
788b20f9befSAlex Deucher rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
789b20f9befSAlex Deucher else
790b20f9befSAlex Deucher rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
791b20f9befSAlex Deucher
792771fe6b9SJerome Glisse return true;
793771fe6b9SJerome Glisse }
794771fe6b9SJerome Glisse return false;
795771fe6b9SJerome Glisse }
796771fe6b9SJerome Glisse
radeon_combios_sideport_present(struct radeon_device * rdev)79706b6476dSAlex Deucher bool radeon_combios_sideport_present(struct radeon_device *rdev)
79806b6476dSAlex Deucher {
799fb1b5e1dSWu Hoi Pok struct drm_device *dev = rdev_to_drm(rdev);
80006b6476dSAlex Deucher u16 igp_info;
80106b6476dSAlex Deucher
8024c70b2eaSAlex Deucher /* sideport is AMD only */
8034c70b2eaSAlex Deucher if (rdev->family == CHIP_RS400)
8044c70b2eaSAlex Deucher return false;
8054c70b2eaSAlex Deucher
80606b6476dSAlex Deucher igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
80706b6476dSAlex Deucher
80806b6476dSAlex Deucher if (igp_info) {
80906b6476dSAlex Deucher if (RBIOS16(igp_info + 0x4))
81006b6476dSAlex Deucher return true;
81106b6476dSAlex Deucher }
81206b6476dSAlex Deucher return false;
81306b6476dSAlex Deucher }
81406b6476dSAlex Deucher
815246263ccSAlex Deucher static const uint32_t default_primarydac_adj[CHIP_LAST] = {
816246263ccSAlex Deucher 0x00000808, /* r100 */
817246263ccSAlex Deucher 0x00000808, /* rv100 */
818246263ccSAlex Deucher 0x00000808, /* rs100 */
819246263ccSAlex Deucher 0x00000808, /* rv200 */
820246263ccSAlex Deucher 0x00000808, /* rs200 */
821246263ccSAlex Deucher 0x00000808, /* r200 */
822246263ccSAlex Deucher 0x00000808, /* rv250 */
823246263ccSAlex Deucher 0x00000000, /* rs300 */
824246263ccSAlex Deucher 0x00000808, /* rv280 */
825246263ccSAlex Deucher 0x00000808, /* r300 */
826246263ccSAlex Deucher 0x00000808, /* r350 */
827246263ccSAlex Deucher 0x00000808, /* rv350 */
828246263ccSAlex Deucher 0x00000808, /* rv380 */
829246263ccSAlex Deucher 0x00000808, /* r420 */
830246263ccSAlex Deucher 0x00000808, /* r423 */
831246263ccSAlex Deucher 0x00000808, /* rv410 */
832246263ccSAlex Deucher 0x00000000, /* rs400 */
833246263ccSAlex Deucher 0x00000000, /* rs480 */
834246263ccSAlex Deucher };
835246263ccSAlex Deucher
radeon_legacy_get_primary_dac_info_from_table(struct radeon_device * rdev,struct radeon_encoder_primary_dac * p_dac)836246263ccSAlex Deucher static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev,
837246263ccSAlex Deucher struct radeon_encoder_primary_dac *p_dac)
838246263ccSAlex Deucher {
839246263ccSAlex Deucher p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family];
840246263ccSAlex Deucher return;
841246263ccSAlex Deucher }
842246263ccSAlex Deucher
radeon_combios_get_primary_dac_info(struct radeon_encoder * encoder)843771fe6b9SJerome Glisse struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
844771fe6b9SJerome Glisse radeon_encoder
845771fe6b9SJerome Glisse *encoder)
846771fe6b9SJerome Glisse {
847771fe6b9SJerome Glisse struct drm_device *dev = encoder->base.dev;
848771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
849771fe6b9SJerome Glisse uint16_t dac_info;
850771fe6b9SJerome Glisse uint8_t rev, bg, dac;
8513cc0f8f4SRuan Jinjie struct radeon_encoder_primary_dac *p_dac;
852246263ccSAlex Deucher int found = 0;
853771fe6b9SJerome Glisse
854246263ccSAlex Deucher p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac),
855771fe6b9SJerome Glisse GFP_KERNEL);
856771fe6b9SJerome Glisse
857771fe6b9SJerome Glisse if (!p_dac)
858771fe6b9SJerome Glisse return NULL;
859771fe6b9SJerome Glisse
860246263ccSAlex Deucher /* check CRT table */
861246263ccSAlex Deucher dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
862246263ccSAlex Deucher if (dac_info) {
863771fe6b9SJerome Glisse rev = RBIOS8(dac_info) & 0x3;
864771fe6b9SJerome Glisse if (rev < 2) {
865771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0x2) & 0xf;
866771fe6b9SJerome Glisse dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf;
867771fe6b9SJerome Glisse p_dac->ps2_pdac_adj = (bg << 8) | (dac);
868771fe6b9SJerome Glisse } else {
869771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0x2) & 0xf;
870771fe6b9SJerome Glisse dac = RBIOS8(dac_info + 0x3) & 0xf;
871771fe6b9SJerome Glisse p_dac->ps2_pdac_adj = (bg << 8) | (dac);
872771fe6b9SJerome Glisse }
87303ed8cf9SAlex Deucher /* if the values are zeros, use the table */
87403ed8cf9SAlex Deucher if ((dac == 0) || (bg == 0))
87503ed8cf9SAlex Deucher found = 0;
87603ed8cf9SAlex Deucher else
877246263ccSAlex Deucher found = 1;
878771fe6b9SJerome Glisse }
879771fe6b9SJerome Glisse
880e8fc4137SAlex Deucher /* quirks */
881f7929f34SOndrej Zary /* Radeon 7000 (RV100) */
882d86a4126SThomas Zimmermann if (((rdev->pdev->device == 0x5159) &&
883d86a4126SThomas Zimmermann (rdev->pdev->subsystem_vendor == 0x174B) &&
884d86a4126SThomas Zimmermann (rdev->pdev->subsystem_device == 0x7c28)) ||
885f7929f34SOndrej Zary /* Radeon 9100 (R200) */
886d86a4126SThomas Zimmermann ((rdev->pdev->device == 0x514D) &&
887d86a4126SThomas Zimmermann (rdev->pdev->subsystem_vendor == 0x174B) &&
888d86a4126SThomas Zimmermann (rdev->pdev->subsystem_device == 0x7149))) {
889e8fc4137SAlex Deucher /* vbios value is bad, use the default */
890e8fc4137SAlex Deucher found = 0;
891e8fc4137SAlex Deucher }
892e8fc4137SAlex Deucher
893246263ccSAlex Deucher if (!found) /* fallback to defaults */
894246263ccSAlex Deucher radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
895246263ccSAlex Deucher
896771fe6b9SJerome Glisse return p_dac;
897771fe6b9SJerome Glisse }
898771fe6b9SJerome Glisse
899d79766faSAlex Deucher enum radeon_tv_std
radeon_combios_get_tv_info(struct radeon_device * rdev)900d79766faSAlex Deucher radeon_combios_get_tv_info(struct radeon_device *rdev)
901771fe6b9SJerome Glisse {
902fb1b5e1dSWu Hoi Pok struct drm_device *dev = rdev_to_drm(rdev);
903771fe6b9SJerome Glisse uint16_t tv_info;
904771fe6b9SJerome Glisse enum radeon_tv_std tv_std = TV_STD_NTSC;
905771fe6b9SJerome Glisse
906771fe6b9SJerome Glisse tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
907771fe6b9SJerome Glisse if (tv_info) {
908771fe6b9SJerome Glisse if (RBIOS8(tv_info + 6) == 'T') {
909771fe6b9SJerome Glisse switch (RBIOS8(tv_info + 7) & 0xf) {
910771fe6b9SJerome Glisse case 1:
911771fe6b9SJerome Glisse tv_std = TV_STD_NTSC;
91240f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: NTSC\n");
913771fe6b9SJerome Glisse break;
914771fe6b9SJerome Glisse case 2:
915771fe6b9SJerome Glisse tv_std = TV_STD_PAL;
91640f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: PAL\n");
917771fe6b9SJerome Glisse break;
918771fe6b9SJerome Glisse case 3:
919771fe6b9SJerome Glisse tv_std = TV_STD_PAL_M;
92040f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
921771fe6b9SJerome Glisse break;
922771fe6b9SJerome Glisse case 4:
923771fe6b9SJerome Glisse tv_std = TV_STD_PAL_60;
92440f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
925771fe6b9SJerome Glisse break;
926771fe6b9SJerome Glisse case 5:
927771fe6b9SJerome Glisse tv_std = TV_STD_NTSC_J;
92840f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
929771fe6b9SJerome Glisse break;
930771fe6b9SJerome Glisse case 6:
931771fe6b9SJerome Glisse tv_std = TV_STD_SCART_PAL;
93240f76d81SAlex Deucher DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n");
933771fe6b9SJerome Glisse break;
934771fe6b9SJerome Glisse default:
935771fe6b9SJerome Glisse tv_std = TV_STD_NTSC;
93640f76d81SAlex Deucher DRM_DEBUG_KMS
937771fe6b9SJerome Glisse ("Unknown TV standard; defaulting to NTSC\n");
938771fe6b9SJerome Glisse break;
939771fe6b9SJerome Glisse }
940771fe6b9SJerome Glisse
941771fe6b9SJerome Glisse switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) {
942771fe6b9SJerome Glisse case 0:
94340f76d81SAlex Deucher DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n");
944771fe6b9SJerome Glisse break;
945771fe6b9SJerome Glisse case 1:
94640f76d81SAlex Deucher DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n");
947771fe6b9SJerome Glisse break;
948771fe6b9SJerome Glisse case 2:
94940f76d81SAlex Deucher DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n");
950771fe6b9SJerome Glisse break;
951771fe6b9SJerome Glisse case 3:
95240f76d81SAlex Deucher DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n");
953771fe6b9SJerome Glisse break;
954771fe6b9SJerome Glisse default:
955771fe6b9SJerome Glisse break;
956771fe6b9SJerome Glisse }
957771fe6b9SJerome Glisse }
958771fe6b9SJerome Glisse }
959771fe6b9SJerome Glisse return tv_std;
960771fe6b9SJerome Glisse }
961771fe6b9SJerome Glisse
962771fe6b9SJerome Glisse static const uint32_t default_tvdac_adj[CHIP_LAST] = {
963771fe6b9SJerome Glisse 0x00000000, /* r100 */
964771fe6b9SJerome Glisse 0x00280000, /* rv100 */
965771fe6b9SJerome Glisse 0x00000000, /* rs100 */
966771fe6b9SJerome Glisse 0x00880000, /* rv200 */
967771fe6b9SJerome Glisse 0x00000000, /* rs200 */
968771fe6b9SJerome Glisse 0x00000000, /* r200 */
969771fe6b9SJerome Glisse 0x00770000, /* rv250 */
970771fe6b9SJerome Glisse 0x00290000, /* rs300 */
971771fe6b9SJerome Glisse 0x00560000, /* rv280 */
972771fe6b9SJerome Glisse 0x00780000, /* r300 */
973771fe6b9SJerome Glisse 0x00770000, /* r350 */
974771fe6b9SJerome Glisse 0x00780000, /* rv350 */
975771fe6b9SJerome Glisse 0x00780000, /* rv380 */
976771fe6b9SJerome Glisse 0x01080000, /* r420 */
977771fe6b9SJerome Glisse 0x01080000, /* r423 */
978771fe6b9SJerome Glisse 0x01080000, /* rv410 */
979771fe6b9SJerome Glisse 0x00780000, /* rs400 */
980771fe6b9SJerome Glisse 0x00780000, /* rs480 */
981771fe6b9SJerome Glisse };
982771fe6b9SJerome Glisse
radeon_legacy_get_tv_dac_info_from_table(struct radeon_device * rdev,struct radeon_encoder_tv_dac * tv_dac)9836a719e05SDave Airlie static void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev,
9846a719e05SDave Airlie struct radeon_encoder_tv_dac *tv_dac)
985771fe6b9SJerome Glisse {
986771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family];
987771fe6b9SJerome Glisse if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250))
988771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj = 0x00880000;
989771fe6b9SJerome Glisse tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
990771fe6b9SJerome Glisse tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
9916a719e05SDave Airlie return;
992771fe6b9SJerome Glisse }
993771fe6b9SJerome Glisse
radeon_combios_get_tv_dac_info(struct radeon_encoder * encoder)994771fe6b9SJerome Glisse struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
995771fe6b9SJerome Glisse radeon_encoder
996771fe6b9SJerome Glisse *encoder)
997771fe6b9SJerome Glisse {
998771fe6b9SJerome Glisse struct drm_device *dev = encoder->base.dev;
999771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
1000771fe6b9SJerome Glisse uint16_t dac_info;
1001771fe6b9SJerome Glisse uint8_t rev, bg, dac;
10023cc0f8f4SRuan Jinjie struct radeon_encoder_tv_dac *tv_dac;
10036a719e05SDave Airlie int found = 0;
10046a719e05SDave Airlie
10056a719e05SDave Airlie tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
10066a719e05SDave Airlie if (!tv_dac)
10076a719e05SDave Airlie return NULL;
1008771fe6b9SJerome Glisse
1009771fe6b9SJerome Glisse /* first check TV table */
1010771fe6b9SJerome Glisse dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
1011771fe6b9SJerome Glisse if (dac_info) {
1012771fe6b9SJerome Glisse rev = RBIOS8(dac_info + 0x3);
1013771fe6b9SJerome Glisse if (rev > 4) {
1014771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0xc) & 0xf;
1015771fe6b9SJerome Glisse dac = RBIOS8(dac_info + 0xd) & 0xf;
1016771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1017771fe6b9SJerome Glisse
1018771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0xe) & 0xf;
1019771fe6b9SJerome Glisse dac = RBIOS8(dac_info + 0xf) & 0xf;
1020771fe6b9SJerome Glisse tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1021771fe6b9SJerome Glisse
1022771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0x10) & 0xf;
1023771fe6b9SJerome Glisse dac = RBIOS8(dac_info + 0x11) & 0xf;
1024771fe6b9SJerome Glisse tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
10253a89b4a9SAlex Deucher /* if the values are all zeros, use the table */
10263a89b4a9SAlex Deucher if (tv_dac->ps2_tvdac_adj)
10276a719e05SDave Airlie found = 1;
1028771fe6b9SJerome Glisse } else if (rev > 1) {
1029771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0xc) & 0xf;
1030771fe6b9SJerome Glisse dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
1031771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1032771fe6b9SJerome Glisse
1033771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0xd) & 0xf;
1034771fe6b9SJerome Glisse dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf;
1035771fe6b9SJerome Glisse tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1036771fe6b9SJerome Glisse
1037771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0xe) & 0xf;
1038771fe6b9SJerome Glisse dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
1039771fe6b9SJerome Glisse tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
10403a89b4a9SAlex Deucher /* if the values are all zeros, use the table */
10413a89b4a9SAlex Deucher if (tv_dac->ps2_tvdac_adj)
10426a719e05SDave Airlie found = 1;
1043771fe6b9SJerome Glisse }
1044d79766faSAlex Deucher tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
10456a719e05SDave Airlie }
10466a719e05SDave Airlie if (!found) {
1047771fe6b9SJerome Glisse /* then check CRT table */
1048771fe6b9SJerome Glisse dac_info =
1049771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
1050771fe6b9SJerome Glisse if (dac_info) {
1051771fe6b9SJerome Glisse rev = RBIOS8(dac_info) & 0x3;
1052771fe6b9SJerome Glisse if (rev < 2) {
1053771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0x3) & 0xf;
1054771fe6b9SJerome Glisse dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf;
1055771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj =
1056771fe6b9SJerome Glisse (bg << 16) | (dac << 20);
1057771fe6b9SJerome Glisse tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
1058771fe6b9SJerome Glisse tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
10593a89b4a9SAlex Deucher /* if the values are all zeros, use the table */
10603a89b4a9SAlex Deucher if (tv_dac->ps2_tvdac_adj)
10616a719e05SDave Airlie found = 1;
1062771fe6b9SJerome Glisse } else {
1063771fe6b9SJerome Glisse bg = RBIOS8(dac_info + 0x4) & 0xf;
1064771fe6b9SJerome Glisse dac = RBIOS8(dac_info + 0x5) & 0xf;
1065771fe6b9SJerome Glisse tv_dac->ps2_tvdac_adj =
1066771fe6b9SJerome Glisse (bg << 16) | (dac << 20);
1067771fe6b9SJerome Glisse tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
1068771fe6b9SJerome Glisse tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
10693a89b4a9SAlex Deucher /* if the values are all zeros, use the table */
10703a89b4a9SAlex Deucher if (tv_dac->ps2_tvdac_adj)
10716a719e05SDave Airlie found = 1;
1072771fe6b9SJerome Glisse }
10736fe7ac3fSAlex Deucher } else {
10746fe7ac3fSAlex Deucher DRM_INFO("No TV DAC info found in BIOS\n");
1075771fe6b9SJerome Glisse }
1076771fe6b9SJerome Glisse }
1077771fe6b9SJerome Glisse
10786a719e05SDave Airlie if (!found) /* fallback to defaults */
10796a719e05SDave Airlie radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac);
10806a719e05SDave Airlie
1081771fe6b9SJerome Glisse return tv_dac;
1082771fe6b9SJerome Glisse }
1083771fe6b9SJerome Glisse
radeon_legacy_get_lvds_info_from_regs(struct radeon_device * rdev)1084771fe6b9SJerome Glisse static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
1085771fe6b9SJerome Glisse radeon_device
1086771fe6b9SJerome Glisse *rdev)
1087771fe6b9SJerome Glisse {
10883cc0f8f4SRuan Jinjie struct radeon_encoder_lvds *lvds;
1089771fe6b9SJerome Glisse uint32_t fp_vert_stretch, fp_horz_stretch;
1090771fe6b9SJerome Glisse uint32_t ppll_div_sel, ppll_val;
10918b5c7444SMichel Dänzer uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
1092771fe6b9SJerome Glisse
1093771fe6b9SJerome Glisse lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
1094771fe6b9SJerome Glisse
1095771fe6b9SJerome Glisse if (!lvds)
1096771fe6b9SJerome Glisse return NULL;
1097771fe6b9SJerome Glisse
1098771fe6b9SJerome Glisse fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH);
1099771fe6b9SJerome Glisse fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH);
1100771fe6b9SJerome Glisse
11018b5c7444SMichel Dänzer /* These should be fail-safe defaults, fingers crossed */
11028b5c7444SMichel Dänzer lvds->panel_pwr_delay = 200;
11038b5c7444SMichel Dänzer lvds->panel_vcc_delay = 2000;
11048b5c7444SMichel Dänzer
11058b5c7444SMichel Dänzer lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
11068b5c7444SMichel Dänzer lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf;
11078b5c7444SMichel Dänzer lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
11088b5c7444SMichel Dänzer
1109771fe6b9SJerome Glisse if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
1110de2103e4SAlex Deucher lvds->native_mode.vdisplay =
1111771fe6b9SJerome Glisse ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
1112771fe6b9SJerome Glisse RADEON_VERT_PANEL_SHIFT) + 1;
1113771fe6b9SJerome Glisse else
1114de2103e4SAlex Deucher lvds->native_mode.vdisplay =
1115771fe6b9SJerome Glisse (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
1116771fe6b9SJerome Glisse
1117771fe6b9SJerome Glisse if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
1118de2103e4SAlex Deucher lvds->native_mode.hdisplay =
1119771fe6b9SJerome Glisse (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
1120771fe6b9SJerome Glisse RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
1121771fe6b9SJerome Glisse else
1122de2103e4SAlex Deucher lvds->native_mode.hdisplay =
1123771fe6b9SJerome Glisse ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
1124771fe6b9SJerome Glisse
1125de2103e4SAlex Deucher if ((lvds->native_mode.hdisplay < 640) ||
1126de2103e4SAlex Deucher (lvds->native_mode.vdisplay < 480)) {
1127de2103e4SAlex Deucher lvds->native_mode.hdisplay = 640;
1128de2103e4SAlex Deucher lvds->native_mode.vdisplay = 480;
1129771fe6b9SJerome Glisse }
1130771fe6b9SJerome Glisse
1131771fe6b9SJerome Glisse ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
1132771fe6b9SJerome Glisse ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel);
1133771fe6b9SJerome Glisse if ((ppll_val & 0x000707ff) == 0x1bb)
1134771fe6b9SJerome Glisse lvds->use_bios_dividers = false;
1135771fe6b9SJerome Glisse else {
1136771fe6b9SJerome Glisse lvds->panel_ref_divider =
1137771fe6b9SJerome Glisse RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
1138771fe6b9SJerome Glisse lvds->panel_post_divider = (ppll_val >> 16) & 0x7;
1139771fe6b9SJerome Glisse lvds->panel_fb_divider = ppll_val & 0x7ff;
1140771fe6b9SJerome Glisse
1141771fe6b9SJerome Glisse if ((lvds->panel_ref_divider != 0) &&
1142771fe6b9SJerome Glisse (lvds->panel_fb_divider > 3))
1143771fe6b9SJerome Glisse lvds->use_bios_dividers = true;
1144771fe6b9SJerome Glisse }
1145771fe6b9SJerome Glisse lvds->panel_vcc_delay = 200;
1146771fe6b9SJerome Glisse
1147771fe6b9SJerome Glisse DRM_INFO("Panel info derived from registers\n");
1148de2103e4SAlex Deucher DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
1149de2103e4SAlex Deucher lvds->native_mode.vdisplay);
1150771fe6b9SJerome Glisse
1151771fe6b9SJerome Glisse return lvds;
1152771fe6b9SJerome Glisse }
1153771fe6b9SJerome Glisse
radeon_combios_get_lvds_info(struct radeon_encoder * encoder)1154771fe6b9SJerome Glisse struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
1155771fe6b9SJerome Glisse *encoder)
1156771fe6b9SJerome Glisse {
1157771fe6b9SJerome Glisse struct drm_device *dev = encoder->base.dev;
1158771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
1159771fe6b9SJerome Glisse uint16_t lcd_info;
1160771fe6b9SJerome Glisse uint32_t panel_setup;
1161771fe6b9SJerome Glisse char stmp[30];
1162771fe6b9SJerome Glisse int tmp, i;
1163771fe6b9SJerome Glisse struct radeon_encoder_lvds *lvds = NULL;
1164771fe6b9SJerome Glisse
1165771fe6b9SJerome Glisse lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
1166771fe6b9SJerome Glisse
1167771fe6b9SJerome Glisse if (lcd_info) {
1168771fe6b9SJerome Glisse lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
1169771fe6b9SJerome Glisse
1170771fe6b9SJerome Glisse if (!lvds)
1171771fe6b9SJerome Glisse return NULL;
1172771fe6b9SJerome Glisse
1173771fe6b9SJerome Glisse for (i = 0; i < 24; i++)
1174771fe6b9SJerome Glisse stmp[i] = RBIOS8(lcd_info + i + 1);
1175771fe6b9SJerome Glisse stmp[24] = 0;
1176771fe6b9SJerome Glisse
1177771fe6b9SJerome Glisse DRM_INFO("Panel ID String: %s\n", stmp);
1178771fe6b9SJerome Glisse
1179de2103e4SAlex Deucher lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
1180de2103e4SAlex Deucher lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
1181771fe6b9SJerome Glisse
1182de2103e4SAlex Deucher DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
1183de2103e4SAlex Deucher lvds->native_mode.vdisplay);
1184771fe6b9SJerome Glisse
1185771fe6b9SJerome Glisse lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
118694cf6434SAndrew Morton lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000);
1187771fe6b9SJerome Glisse
1188771fe6b9SJerome Glisse lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24);
1189771fe6b9SJerome Glisse lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf;
1190771fe6b9SJerome Glisse lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf;
1191771fe6b9SJerome Glisse
1192771fe6b9SJerome Glisse lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e);
1193771fe6b9SJerome Glisse lvds->panel_post_divider = RBIOS8(lcd_info + 0x30);
1194771fe6b9SJerome Glisse lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31);
1195771fe6b9SJerome Glisse if ((lvds->panel_ref_divider != 0) &&
1196771fe6b9SJerome Glisse (lvds->panel_fb_divider > 3))
1197771fe6b9SJerome Glisse lvds->use_bios_dividers = true;
1198771fe6b9SJerome Glisse
1199771fe6b9SJerome Glisse panel_setup = RBIOS32(lcd_info + 0x39);
1200771fe6b9SJerome Glisse lvds->lvds_gen_cntl = 0xff00;
1201771fe6b9SJerome Glisse if (panel_setup & 0x1)
1202771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT;
1203771fe6b9SJerome Glisse
1204771fe6b9SJerome Glisse if ((panel_setup >> 4) & 0x1)
1205771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE;
1206771fe6b9SJerome Glisse
1207771fe6b9SJerome Glisse switch ((panel_setup >> 8) & 0x7) {
1208771fe6b9SJerome Glisse case 0:
1209771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM;
1210771fe6b9SJerome Glisse break;
1211771fe6b9SJerome Glisse case 1:
1212771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY;
1213771fe6b9SJerome Glisse break;
1214771fe6b9SJerome Glisse case 2:
1215771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY;
1216771fe6b9SJerome Glisse break;
1217771fe6b9SJerome Glisse default:
1218771fe6b9SJerome Glisse break;
1219771fe6b9SJerome Glisse }
1220771fe6b9SJerome Glisse
1221771fe6b9SJerome Glisse if ((panel_setup >> 16) & 0x1)
1222771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW;
1223771fe6b9SJerome Glisse
1224771fe6b9SJerome Glisse if ((panel_setup >> 17) & 0x1)
1225771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW;
1226771fe6b9SJerome Glisse
1227771fe6b9SJerome Glisse if ((panel_setup >> 18) & 0x1)
1228771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW;
1229771fe6b9SJerome Glisse
1230771fe6b9SJerome Glisse if ((panel_setup >> 23) & 0x1)
1231771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL;
1232771fe6b9SJerome Glisse
1233771fe6b9SJerome Glisse lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000);
1234771fe6b9SJerome Glisse
1235771fe6b9SJerome Glisse for (i = 0; i < 32; i++) {
1236771fe6b9SJerome Glisse tmp = RBIOS16(lcd_info + 64 + i * 2);
1237771fe6b9SJerome Glisse if (tmp == 0)
1238771fe6b9SJerome Glisse break;
1239771fe6b9SJerome Glisse
1240de2103e4SAlex Deucher if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
124168b61a7fSAlex Deucher (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) {
12420a90a0cfSAlex Deucher u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
12430a90a0cfSAlex Deucher
12440a90a0cfSAlex Deucher if (hss > lvds->native_mode.hdisplay)
12450a90a0cfSAlex Deucher hss = (10 - 1) * 8;
12460a90a0cfSAlex Deucher
124768b61a7fSAlex Deucher lvds->native_mode.htotal = lvds->native_mode.hdisplay +
124868b61a7fSAlex Deucher (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
124968b61a7fSAlex Deucher lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
12500a90a0cfSAlex Deucher hss;
125168b61a7fSAlex Deucher lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
125268b61a7fSAlex Deucher (RBIOS8(tmp + 23) * 8);
1253771fe6b9SJerome Glisse
125468b61a7fSAlex Deucher lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
125568b61a7fSAlex Deucher (RBIOS16(tmp + 24) - RBIOS16(tmp + 26));
125668b61a7fSAlex Deucher lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
125768b61a7fSAlex Deucher ((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26));
125868b61a7fSAlex Deucher lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
125968b61a7fSAlex Deucher ((RBIOS16(tmp + 28) & 0xf800) >> 11);
1260de2103e4SAlex Deucher
1261de2103e4SAlex Deucher lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
1262771fe6b9SJerome Glisse lvds->native_mode.flags = 0;
1263de2103e4SAlex Deucher /* set crtc values */
1264de2103e4SAlex Deucher drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
1265de2103e4SAlex Deucher
1266771fe6b9SJerome Glisse }
1267771fe6b9SJerome Glisse }
12686fe7ac3fSAlex Deucher } else {
1269771fe6b9SJerome Glisse DRM_INFO("No panel info found in BIOS\n");
12708dfaa8a7SMichel Dänzer lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
12716fe7ac3fSAlex Deucher }
127203047cdfSMichel Dänzer
12738dfaa8a7SMichel Dänzer if (lvds)
12748dfaa8a7SMichel Dänzer encoder->native_mode = lvds->native_mode;
1275771fe6b9SJerome Glisse return lvds;
1276771fe6b9SJerome Glisse }
1277771fe6b9SJerome Glisse
1278771fe6b9SJerome Glisse static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
1279771fe6b9SJerome Glisse {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R100 */
1280771fe6b9SJerome Glisse {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV100 */
1281771fe6b9SJerome Glisse {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS100 */
1282771fe6b9SJerome Glisse {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV200 */
1283771fe6b9SJerome Glisse {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RS200 */
1284771fe6b9SJerome Glisse {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R200 */
1285771fe6b9SJerome Glisse {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /* CHIP_RV250 */
1286771fe6b9SJerome Glisse {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS300 */
1287771fe6b9SJerome Glisse {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /* CHIP_RV280 */
1288771fe6b9SJerome Glisse {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R300 */
1289771fe6b9SJerome Glisse {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R350 */
1290771fe6b9SJerome Glisse {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV350 */
1291771fe6b9SJerome Glisse {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV380 */
1292771fe6b9SJerome Glisse {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
1293771fe6b9SJerome Glisse {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
1294771fe6b9SJerome Glisse {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
1295fcec570bSAlex Deucher { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
1296fcec570bSAlex Deucher { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
1297771fe6b9SJerome Glisse };
1298771fe6b9SJerome Glisse
radeon_legacy_get_tmds_info_from_table(struct radeon_encoder * encoder,struct radeon_encoder_int_tmds * tmds)1299445282dbSDave Airlie bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
1300445282dbSDave Airlie struct radeon_encoder_int_tmds *tmds)
1301771fe6b9SJerome Glisse {
1302445282dbSDave Airlie struct drm_device *dev = encoder->base.dev;
1303445282dbSDave Airlie struct radeon_device *rdev = dev->dev_private;
1304771fe6b9SJerome Glisse int i;
1305771fe6b9SJerome Glisse
1306771fe6b9SJerome Glisse for (i = 0; i < 4; i++) {
1307771fe6b9SJerome Glisse tmds->tmds_pll[i].value =
1308771fe6b9SJerome Glisse default_tmds_pll[rdev->family][i].value;
1309771fe6b9SJerome Glisse tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
1310771fe6b9SJerome Glisse }
1311771fe6b9SJerome Glisse
1312445282dbSDave Airlie return true;
1313771fe6b9SJerome Glisse }
1314771fe6b9SJerome Glisse
radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder * encoder,struct radeon_encoder_int_tmds * tmds)1315445282dbSDave Airlie bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1316445282dbSDave Airlie struct radeon_encoder_int_tmds *tmds)
1317771fe6b9SJerome Glisse {
1318771fe6b9SJerome Glisse struct drm_device *dev = encoder->base.dev;
1319771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
1320771fe6b9SJerome Glisse uint16_t tmds_info;
1321771fe6b9SJerome Glisse int i, n;
1322771fe6b9SJerome Glisse uint8_t ver;
1323771fe6b9SJerome Glisse
1324771fe6b9SJerome Glisse tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
1325771fe6b9SJerome Glisse
1326771fe6b9SJerome Glisse if (tmds_info) {
1327771fe6b9SJerome Glisse ver = RBIOS8(tmds_info);
132840f76d81SAlex Deucher DRM_DEBUG_KMS("DFP table revision: %d\n", ver);
1329771fe6b9SJerome Glisse if (ver == 3) {
1330771fe6b9SJerome Glisse n = RBIOS8(tmds_info + 5) + 1;
1331771fe6b9SJerome Glisse if (n > 4)
1332771fe6b9SJerome Glisse n = 4;
1333771fe6b9SJerome Glisse for (i = 0; i < n; i++) {
1334771fe6b9SJerome Glisse tmds->tmds_pll[i].value =
1335771fe6b9SJerome Glisse RBIOS32(tmds_info + i * 10 + 0x08);
1336771fe6b9SJerome Glisse tmds->tmds_pll[i].freq =
1337771fe6b9SJerome Glisse RBIOS16(tmds_info + i * 10 + 0x10);
1338d9fdaafbSDave Airlie DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
1339771fe6b9SJerome Glisse tmds->tmds_pll[i].freq,
1340771fe6b9SJerome Glisse tmds->tmds_pll[i].value);
1341771fe6b9SJerome Glisse }
1342771fe6b9SJerome Glisse } else if (ver == 4) {
1343771fe6b9SJerome Glisse int stride = 0;
1344771fe6b9SJerome Glisse n = RBIOS8(tmds_info + 5) + 1;
1345771fe6b9SJerome Glisse if (n > 4)
1346771fe6b9SJerome Glisse n = 4;
1347771fe6b9SJerome Glisse for (i = 0; i < n; i++) {
1348771fe6b9SJerome Glisse tmds->tmds_pll[i].value =
1349771fe6b9SJerome Glisse RBIOS32(tmds_info + stride + 0x08);
1350771fe6b9SJerome Glisse tmds->tmds_pll[i].freq =
1351771fe6b9SJerome Glisse RBIOS16(tmds_info + stride + 0x10);
1352771fe6b9SJerome Glisse if (i == 0)
1353771fe6b9SJerome Glisse stride += 10;
1354771fe6b9SJerome Glisse else
1355771fe6b9SJerome Glisse stride += 6;
1356d9fdaafbSDave Airlie DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
1357771fe6b9SJerome Glisse tmds->tmds_pll[i].freq,
1358771fe6b9SJerome Glisse tmds->tmds_pll[i].value);
1359771fe6b9SJerome Glisse }
1360771fe6b9SJerome Glisse }
1361fcec570bSAlex Deucher } else {
1362771fe6b9SJerome Glisse DRM_INFO("No TMDS info found in BIOS\n");
1363fcec570bSAlex Deucher return false;
1364fcec570bSAlex Deucher }
1365445282dbSDave Airlie return true;
1366445282dbSDave Airlie }
1367445282dbSDave Airlie
radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder * encoder,struct radeon_encoder_ext_tmds * tmds)1368fcec570bSAlex Deucher bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
1369fcec570bSAlex Deucher struct radeon_encoder_ext_tmds *tmds)
1370771fe6b9SJerome Glisse {
1371771fe6b9SJerome Glisse struct drm_device *dev = encoder->base.dev;
1372771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
1373fcec570bSAlex Deucher struct radeon_i2c_bus_rec i2c_bus;
1374fcec570bSAlex Deucher
1375fcec570bSAlex Deucher /* default for macs */
1376179e8078SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1377f376b94fSAlex Deucher tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1378fcec570bSAlex Deucher
1379fcec570bSAlex Deucher /* XXX some macs have duallink chips */
1380fcec570bSAlex Deucher switch (rdev->mode_info.connector_table) {
1381fcec570bSAlex Deucher case CT_POWERBOOK_EXTERNAL:
1382fcec570bSAlex Deucher case CT_MINI_EXTERNAL:
1383fcec570bSAlex Deucher default:
1384fcec570bSAlex Deucher tmds->dvo_chip = DVO_SIL164;
1385fcec570bSAlex Deucher tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1386fcec570bSAlex Deucher break;
1387fcec570bSAlex Deucher }
1388fcec570bSAlex Deucher
1389fcec570bSAlex Deucher return true;
1390fcec570bSAlex Deucher }
1391fcec570bSAlex Deucher
radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder * encoder,struct radeon_encoder_ext_tmds * tmds)1392fcec570bSAlex Deucher bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
1393fcec570bSAlex Deucher struct radeon_encoder_ext_tmds *tmds)
1394fcec570bSAlex Deucher {
1395fcec570bSAlex Deucher struct drm_device *dev = encoder->base.dev;
1396fcec570bSAlex Deucher struct radeon_device *rdev = dev->dev_private;
1397fcec570bSAlex Deucher uint16_t offset;
1398179e8078SAlex Deucher uint8_t ver;
1399fcec570bSAlex Deucher enum radeon_combios_ddc gpio;
1400fcec570bSAlex Deucher struct radeon_i2c_bus_rec i2c_bus;
1401771fe6b9SJerome Glisse
1402fcec570bSAlex Deucher tmds->i2c_bus = NULL;
1403fcec570bSAlex Deucher if (rdev->flags & RADEON_IS_IGP) {
1404179e8078SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1405f376b94fSAlex Deucher tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1406fcec570bSAlex Deucher tmds->dvo_chip = DVO_SIL164;
1407fcec570bSAlex Deucher tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1408fcec570bSAlex Deucher } else {
1409fcec570bSAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
1410fcec570bSAlex Deucher if (offset) {
1411fcec570bSAlex Deucher ver = RBIOS8(offset);
141240f76d81SAlex Deucher DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver);
1413fcec570bSAlex Deucher tmds->slave_addr = RBIOS8(offset + 4 + 2);
1414fcec570bSAlex Deucher tmds->slave_addr >>= 1; /* 7 bit addressing */
1415fcec570bSAlex Deucher gpio = RBIOS8(offset + 4 + 3);
1416179e8078SAlex Deucher if (gpio == DDC_LCD) {
1417179e8078SAlex Deucher /* MM i2c */
141840bacf16SAlex Deucher i2c_bus.valid = true;
141940bacf16SAlex Deucher i2c_bus.hw_capable = true;
142040bacf16SAlex Deucher i2c_bus.mm_i2c = true;
1421179e8078SAlex Deucher i2c_bus.i2c_id = 0xa0;
1422179e8078SAlex Deucher } else
1423179e8078SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
1424f376b94fSAlex Deucher tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1425fcec570bSAlex Deucher }
1426fcec570bSAlex Deucher }
1427fcec570bSAlex Deucher
1428fcec570bSAlex Deucher if (!tmds->i2c_bus) {
1429fcec570bSAlex Deucher DRM_INFO("No valid Ext TMDS info found in BIOS\n");
1430fcec570bSAlex Deucher return false;
1431fcec570bSAlex Deucher }
1432fcec570bSAlex Deucher
1433fcec570bSAlex Deucher return true;
1434fcec570bSAlex Deucher }
1435771fe6b9SJerome Glisse
radeon_get_legacy_connector_info_from_table(struct drm_device * dev)1436771fe6b9SJerome Glisse bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
1437771fe6b9SJerome Glisse {
1438771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
1439771fe6b9SJerome Glisse struct radeon_i2c_bus_rec ddc_i2c;
1440eed45b30SAlex Deucher struct radeon_hpd hpd;
1441771fe6b9SJerome Glisse
1442771fe6b9SJerome Glisse rdev->mode_info.connector_table = radeon_connector_table;
1443771fe6b9SJerome Glisse if (rdev->mode_info.connector_table == CT_NONE) {
1444771fe6b9SJerome Glisse #ifdef CONFIG_PPC_PMAC
144571a157e8SGrant Likely if (of_machine_is_compatible("PowerBook3,3")) {
1446771fe6b9SJerome Glisse /* powerbook with VGA */
1447771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_POWERBOOK_VGA;
144871a157e8SGrant Likely } else if (of_machine_is_compatible("PowerBook3,4") ||
144971a157e8SGrant Likely of_machine_is_compatible("PowerBook3,5")) {
1450771fe6b9SJerome Glisse /* powerbook with internal tmds */
1451771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL;
145271a157e8SGrant Likely } else if (of_machine_is_compatible("PowerBook5,1") ||
145371a157e8SGrant Likely of_machine_is_compatible("PowerBook5,2") ||
145471a157e8SGrant Likely of_machine_is_compatible("PowerBook5,3") ||
145571a157e8SGrant Likely of_machine_is_compatible("PowerBook5,4") ||
145671a157e8SGrant Likely of_machine_is_compatible("PowerBook5,5")) {
1457771fe6b9SJerome Glisse /* powerbook with external single link tmds (sil164) */
1458771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
145971a157e8SGrant Likely } else if (of_machine_is_compatible("PowerBook5,6")) {
1460771fe6b9SJerome Glisse /* powerbook with external dual or single link tmds */
1461771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
146271a157e8SGrant Likely } else if (of_machine_is_compatible("PowerBook5,7") ||
146371a157e8SGrant Likely of_machine_is_compatible("PowerBook5,8") ||
146471a157e8SGrant Likely of_machine_is_compatible("PowerBook5,9")) {
1465771fe6b9SJerome Glisse /* PowerBook6,2 ? */
1466771fe6b9SJerome Glisse /* powerbook with external dual link tmds (sil1178?) */
1467771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
146871a157e8SGrant Likely } else if (of_machine_is_compatible("PowerBook4,1") ||
146971a157e8SGrant Likely of_machine_is_compatible("PowerBook4,2") ||
147071a157e8SGrant Likely of_machine_is_compatible("PowerBook4,3") ||
147171a157e8SGrant Likely of_machine_is_compatible("PowerBook6,3") ||
147271a157e8SGrant Likely of_machine_is_compatible("PowerBook6,5") ||
147371a157e8SGrant Likely of_machine_is_compatible("PowerBook6,7")) {
1474771fe6b9SJerome Glisse /* ibook */
1475771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_IBOOK;
1476cafa59b9SAlex Deucher } else if (of_machine_is_compatible("PowerMac3,5")) {
1477cafa59b9SAlex Deucher /* PowerMac G4 Silver radeon 7500 */
1478cafa59b9SAlex Deucher rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
147971a157e8SGrant Likely } else if (of_machine_is_compatible("PowerMac4,4")) {
1480771fe6b9SJerome Glisse /* emac */
1481771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_EMAC;
148271a157e8SGrant Likely } else if (of_machine_is_compatible("PowerMac10,1")) {
1483771fe6b9SJerome Glisse /* mini with internal tmds */
1484771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_MINI_INTERNAL;
148571a157e8SGrant Likely } else if (of_machine_is_compatible("PowerMac10,2")) {
1486771fe6b9SJerome Glisse /* mini with external tmds */
1487771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_MINI_EXTERNAL;
148871a157e8SGrant Likely } else if (of_machine_is_compatible("PowerMac12,1")) {
1489771fe6b9SJerome Glisse /* PowerMac8,1 ? */
1490771fe6b9SJerome Glisse /* imac g5 isight */
1491771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
1492aa74fbb4SAlex Deucher } else if ((rdev->pdev->device == 0x4a48) &&
1493aa74fbb4SAlex Deucher (rdev->pdev->subsystem_vendor == 0x1002) &&
1494aa74fbb4SAlex Deucher (rdev->pdev->subsystem_device == 0x4a48)) {
1495aa74fbb4SAlex Deucher /* Mac X800 */
1496aa74fbb4SAlex Deucher rdev->mode_info.connector_table = CT_MAC_X800;
14977c88d2b8SAlex Deucher } else if ((of_machine_is_compatible("PowerMac7,2") ||
14987c88d2b8SAlex Deucher of_machine_is_compatible("PowerMac7,3")) &&
14997c88d2b8SAlex Deucher (rdev->pdev->device == 0x4150) &&
15007c88d2b8SAlex Deucher (rdev->pdev->subsystem_vendor == 0x1002) &&
15017c88d2b8SAlex Deucher (rdev->pdev->subsystem_device == 0x4150)) {
15027c88d2b8SAlex Deucher /* Mac G5 tower 9600 */
15039fad321aSAlex Deucher rdev->mode_info.connector_table = CT_MAC_G5_9600;
15046a556039SAlex Deucher } else if ((rdev->pdev->device == 0x4c66) &&
15056a556039SAlex Deucher (rdev->pdev->subsystem_vendor == 0x1002) &&
15066a556039SAlex Deucher (rdev->pdev->subsystem_device == 0x4c66)) {
15076a556039SAlex Deucher /* SAM440ep RV250 embedded board */
15086a556039SAlex Deucher rdev->mode_info.connector_table = CT_SAM440EP;
1509771fe6b9SJerome Glisse } else
1510771fe6b9SJerome Glisse #endif /* CONFIG_PPC_PMAC */
151176a7142aSDave Airlie #ifdef CONFIG_PPC64
151276a7142aSDave Airlie if (ASIC_IS_RN50(rdev))
151376a7142aSDave Airlie rdev->mode_info.connector_table = CT_RN50_POWER;
151476a7142aSDave Airlie else
151576a7142aSDave Airlie #endif
1516771fe6b9SJerome Glisse rdev->mode_info.connector_table = CT_GENERIC;
1517771fe6b9SJerome Glisse }
1518771fe6b9SJerome Glisse
1519771fe6b9SJerome Glisse switch (rdev->mode_info.connector_table) {
1520771fe6b9SJerome Glisse case CT_GENERIC:
1521771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (generic)\n",
1522771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1523771fe6b9SJerome Glisse /* these are the most common settings */
1524771fe6b9SJerome Glisse if (rdev->flags & RADEON_SINGLE_CRTC) {
1525771fe6b9SJerome Glisse /* VGA - primary dac */
1526179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1527eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1528771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15295137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1530771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1531771fe6b9SJerome Glisse 1),
1532771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1533771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0,
1534771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1535771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_VGA,
1536b75fad06SAlex Deucher &ddc_i2c,
1537eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1538eed45b30SAlex Deucher &hpd);
1539771fe6b9SJerome Glisse } else if (rdev->flags & RADEON_IS_MOBILITY) {
1540771fe6b9SJerome Glisse /* LVDS */
1541179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
1542eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1543771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15445137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1545771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1546771fe6b9SJerome Glisse 0),
1547771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
1548771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0,
1549771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1550771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_LVDS,
1551b75fad06SAlex Deucher &ddc_i2c,
1552eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
1553eed45b30SAlex Deucher &hpd);
1554771fe6b9SJerome Glisse
1555771fe6b9SJerome Glisse /* VGA - primary dac */
1556179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1557eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1558771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15595137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1560771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1561771fe6b9SJerome Glisse 1),
1562771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1563771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1,
1564771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1565771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_VGA,
1566b75fad06SAlex Deucher &ddc_i2c,
1567eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1568eed45b30SAlex Deucher &hpd);
1569771fe6b9SJerome Glisse } else {
1570771fe6b9SJerome Glisse /* DVI-I - tv dac, int tmds */
1571179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1572eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_1;
1573771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15745137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1575771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
1576771fe6b9SJerome Glisse 0),
1577771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
1578771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15795137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1580771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1581771fe6b9SJerome Glisse 2),
1582771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1583771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0,
1584771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT |
1585771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1586771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_DVII,
1587b75fad06SAlex Deucher &ddc_i2c,
1588eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1589eed45b30SAlex Deucher &hpd);
1590771fe6b9SJerome Glisse
1591771fe6b9SJerome Glisse /* VGA - primary dac */
1592179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1593eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1594771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
15955137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1596771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1597771fe6b9SJerome Glisse 1),
1598771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1599771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1,
1600771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1601771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_VGA,
1602b75fad06SAlex Deucher &ddc_i2c,
1603eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1604eed45b30SAlex Deucher &hpd);
1605771fe6b9SJerome Glisse }
1606771fe6b9SJerome Glisse
1607771fe6b9SJerome Glisse if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
1608771fe6b9SJerome Glisse /* TV - tv dac */
1609eed45b30SAlex Deucher ddc_i2c.valid = false;
1610eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1611771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16125137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1613771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1614771fe6b9SJerome Glisse 2),
1615771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1616771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2,
1617771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1618771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1619b75fad06SAlex Deucher &ddc_i2c,
1620eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1621eed45b30SAlex Deucher &hpd);
1622771fe6b9SJerome Glisse }
1623771fe6b9SJerome Glisse break;
1624771fe6b9SJerome Glisse case CT_IBOOK:
1625771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (ibook)\n",
1626771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1627771fe6b9SJerome Glisse /* LVDS */
1628179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1629eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1630771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16315137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1632771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1633771fe6b9SJerome Glisse 0),
1634771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
1635771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1636b75fad06SAlex Deucher DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1637eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
1638eed45b30SAlex Deucher &hpd);
1639771fe6b9SJerome Glisse /* VGA - TV DAC */
1640179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1641eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1642771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16435137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1644771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1645771fe6b9SJerome Glisse 2),
1646771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1647771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1648b75fad06SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1649eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1650eed45b30SAlex Deucher &hpd);
1651771fe6b9SJerome Glisse /* TV - TV DAC */
1652eed45b30SAlex Deucher ddc_i2c.valid = false;
1653eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1654771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16555137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1656771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1657771fe6b9SJerome Glisse 2),
1658771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1659771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1660771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1661b75fad06SAlex Deucher &ddc_i2c,
1662eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1663eed45b30SAlex Deucher &hpd);
1664771fe6b9SJerome Glisse break;
1665771fe6b9SJerome Glisse case CT_POWERBOOK_EXTERNAL:
1666771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
1667771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1668771fe6b9SJerome Glisse /* LVDS */
1669179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1670eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1671771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16725137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1673771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1674771fe6b9SJerome Glisse 0),
1675771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
1676771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1677b75fad06SAlex Deucher DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1678eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
1679eed45b30SAlex Deucher &hpd);
1680771fe6b9SJerome Glisse /* DVI-I - primary dac, ext tmds */
1681179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1682eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_2; /* ??? */
1683771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16845137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1685771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT,
1686771fe6b9SJerome Glisse 0),
1687771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT);
1688771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
16895137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1690771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1691771fe6b9SJerome Glisse 1),
1692771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1693b75fad06SAlex Deucher /* XXX some are SL */
1694771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1,
1695771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT |
1696771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1697b75fad06SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1698eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
1699eed45b30SAlex Deucher &hpd);
1700771fe6b9SJerome Glisse /* TV - TV DAC */
1701eed45b30SAlex Deucher ddc_i2c.valid = false;
1702eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1703771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17045137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1705771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1706771fe6b9SJerome Glisse 2),
1707771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1708771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1709771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1710b75fad06SAlex Deucher &ddc_i2c,
1711eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1712eed45b30SAlex Deucher &hpd);
1713771fe6b9SJerome Glisse break;
1714771fe6b9SJerome Glisse case CT_POWERBOOK_INTERNAL:
1715771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
1716771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1717771fe6b9SJerome Glisse /* LVDS */
1718179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1719eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1720771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17215137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1722771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1723771fe6b9SJerome Glisse 0),
1724771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
1725771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1726b75fad06SAlex Deucher DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1727eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
1728eed45b30SAlex Deucher &hpd);
1729771fe6b9SJerome Glisse /* DVI-I - primary dac, int tmds */
1730179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1731eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
1732771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17335137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1734771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
1735771fe6b9SJerome Glisse 0),
1736771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
1737771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17385137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1739771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1740771fe6b9SJerome Glisse 1),
1741771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1742771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1,
1743771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT |
1744771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1745b75fad06SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1746eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1747eed45b30SAlex Deucher &hpd);
1748771fe6b9SJerome Glisse /* TV - TV DAC */
1749eed45b30SAlex Deucher ddc_i2c.valid = false;
1750eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1751771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17525137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1753771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1754771fe6b9SJerome Glisse 2),
1755771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1756771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1757771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1758b75fad06SAlex Deucher &ddc_i2c,
1759eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1760eed45b30SAlex Deucher &hpd);
1761771fe6b9SJerome Glisse break;
1762771fe6b9SJerome Glisse case CT_POWERBOOK_VGA:
1763771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (powerbook vga)\n",
1764771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1765771fe6b9SJerome Glisse /* LVDS */
1766179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1767eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1768771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17695137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1770771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
1771771fe6b9SJerome Glisse 0),
1772771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
1773771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1774b75fad06SAlex Deucher DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1775eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
1776eed45b30SAlex Deucher &hpd);
1777771fe6b9SJerome Glisse /* VGA - primary dac */
1778179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1779eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1780771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17815137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1782771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1783771fe6b9SJerome Glisse 1),
1784771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1785771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
1786b75fad06SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1787eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1788eed45b30SAlex Deucher &hpd);
1789771fe6b9SJerome Glisse /* TV - TV DAC */
1790eed45b30SAlex Deucher ddc_i2c.valid = false;
1791eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1792771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
17935137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1794771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1795771fe6b9SJerome Glisse 2),
1796771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1797771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1798771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1799b75fad06SAlex Deucher &ddc_i2c,
1800eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1801eed45b30SAlex Deucher &hpd);
1802771fe6b9SJerome Glisse break;
1803771fe6b9SJerome Glisse case CT_MINI_EXTERNAL:
1804771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (mini external tmds)\n",
1805771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1806771fe6b9SJerome Glisse /* DVI-I - tv dac, ext tmds */
1807179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1808eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_2; /* ??? */
1809771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18105137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1811771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT,
1812771fe6b9SJerome Glisse 0),
1813771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT);
1814771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18155137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1816771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1817771fe6b9SJerome Glisse 2),
1818771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1819b75fad06SAlex Deucher /* XXX are any DL? */
1820771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0,
1821771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT |
1822771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1823b75fad06SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1824eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1825eed45b30SAlex Deucher &hpd);
1826771fe6b9SJerome Glisse /* TV - TV DAC */
1827eed45b30SAlex Deucher ddc_i2c.valid = false;
1828eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1829771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18305137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1831771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1832771fe6b9SJerome Glisse 2),
1833771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1834771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
1835771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1836b75fad06SAlex Deucher &ddc_i2c,
1837eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1838eed45b30SAlex Deucher &hpd);
1839771fe6b9SJerome Glisse break;
1840771fe6b9SJerome Glisse case CT_MINI_INTERNAL:
1841771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (mini internal tmds)\n",
1842771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1843771fe6b9SJerome Glisse /* DVI-I - tv dac, int tmds */
1844179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1845eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
1846771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18475137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1848771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
1849771fe6b9SJerome Glisse 0),
1850771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
1851771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18525137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1853771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1854771fe6b9SJerome Glisse 2),
1855771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1856771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0,
1857771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT |
1858771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1859b75fad06SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1860eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1861eed45b30SAlex Deucher &hpd);
1862771fe6b9SJerome Glisse /* TV - TV DAC */
1863eed45b30SAlex Deucher ddc_i2c.valid = false;
1864eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1865771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18665137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1867771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1868771fe6b9SJerome Glisse 2),
1869771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1870771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
1871771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1872b75fad06SAlex Deucher &ddc_i2c,
1873eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1874eed45b30SAlex Deucher &hpd);
1875771fe6b9SJerome Glisse break;
1876771fe6b9SJerome Glisse case CT_IMAC_G5_ISIGHT:
1877771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (imac g5 isight)\n",
1878771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1879771fe6b9SJerome Glisse /* DVI-D - int tmds */
1880179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1881eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
1882771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18835137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1884771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
1885771fe6b9SJerome Glisse 0),
1886771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
1887771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
1888b75fad06SAlex Deucher DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
1889eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
1890eed45b30SAlex Deucher &hpd);
1891771fe6b9SJerome Glisse /* VGA - tv dac */
1892179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1893eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1894771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
18955137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1896771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1897771fe6b9SJerome Glisse 2),
1898771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1899771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1900b75fad06SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1901eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1902eed45b30SAlex Deucher &hpd);
1903771fe6b9SJerome Glisse /* TV - TV DAC */
1904eed45b30SAlex Deucher ddc_i2c.valid = false;
1905eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1906771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
19075137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1908771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1909771fe6b9SJerome Glisse 2),
1910771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1911771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1912771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1913b75fad06SAlex Deucher &ddc_i2c,
1914eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1915eed45b30SAlex Deucher &hpd);
1916771fe6b9SJerome Glisse break;
1917771fe6b9SJerome Glisse case CT_EMAC:
1918771fe6b9SJerome Glisse DRM_INFO("Connector Table: %d (emac)\n",
1919771fe6b9SJerome Glisse rdev->mode_info.connector_table);
1920771fe6b9SJerome Glisse /* VGA - primary dac */
1921179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1922eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1923771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
19245137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1925771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
1926771fe6b9SJerome Glisse 1),
1927771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
1928771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
1929b75fad06SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1930eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1931eed45b30SAlex Deucher &hpd);
1932771fe6b9SJerome Glisse /* VGA - tv dac */
1933179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1934eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1935771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
19365137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1937771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
1938771fe6b9SJerome Glisse 2),
1939771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
1940771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1941b75fad06SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1942eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
1943eed45b30SAlex Deucher &hpd);
1944771fe6b9SJerome Glisse /* TV - TV DAC */
1945eed45b30SAlex Deucher ddc_i2c.valid = false;
1946eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
1947771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
19485137ee94SAlex Deucher radeon_get_encoder_enum(dev,
1949771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
1950771fe6b9SJerome Glisse 2),
1951771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
1952771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1953771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
1954b75fad06SAlex Deucher &ddc_i2c,
1955eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
1956eed45b30SAlex Deucher &hpd);
1957771fe6b9SJerome Glisse break;
195876a7142aSDave Airlie case CT_RN50_POWER:
195976a7142aSDave Airlie DRM_INFO("Connector Table: %d (rn50-power)\n",
196076a7142aSDave Airlie rdev->mode_info.connector_table);
196176a7142aSDave Airlie /* VGA - primary dac */
1962179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
196376a7142aSDave Airlie hpd.hpd = RADEON_HPD_NONE;
196476a7142aSDave Airlie radeon_add_legacy_encoder(dev,
19655137ee94SAlex Deucher radeon_get_encoder_enum(dev,
196676a7142aSDave Airlie ATOM_DEVICE_CRT1_SUPPORT,
196776a7142aSDave Airlie 1),
196876a7142aSDave Airlie ATOM_DEVICE_CRT1_SUPPORT);
196976a7142aSDave Airlie radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
197076a7142aSDave Airlie DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
197176a7142aSDave Airlie CONNECTOR_OBJECT_ID_VGA,
197276a7142aSDave Airlie &hpd);
1973179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
197476a7142aSDave Airlie hpd.hpd = RADEON_HPD_NONE;
197576a7142aSDave Airlie radeon_add_legacy_encoder(dev,
19765137ee94SAlex Deucher radeon_get_encoder_enum(dev,
197776a7142aSDave Airlie ATOM_DEVICE_CRT2_SUPPORT,
197876a7142aSDave Airlie 2),
197976a7142aSDave Airlie ATOM_DEVICE_CRT2_SUPPORT);
198076a7142aSDave Airlie radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
198176a7142aSDave Airlie DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
198276a7142aSDave Airlie CONNECTOR_OBJECT_ID_VGA,
198376a7142aSDave Airlie &hpd);
198476a7142aSDave Airlie break;
1985aa74fbb4SAlex Deucher case CT_MAC_X800:
1986aa74fbb4SAlex Deucher DRM_INFO("Connector Table: %d (mac x800)\n",
1987aa74fbb4SAlex Deucher rdev->mode_info.connector_table);
1988aa74fbb4SAlex Deucher /* DVI - primary dac, internal tmds */
1989aa74fbb4SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1990aa74fbb4SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
1991aa74fbb4SAlex Deucher radeon_add_legacy_encoder(dev,
1992aa74fbb4SAlex Deucher radeon_get_encoder_enum(dev,
1993aa74fbb4SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT,
1994aa74fbb4SAlex Deucher 0),
1995aa74fbb4SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT);
1996aa74fbb4SAlex Deucher radeon_add_legacy_encoder(dev,
1997aa74fbb4SAlex Deucher radeon_get_encoder_enum(dev,
1998aa74fbb4SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
1999aa74fbb4SAlex Deucher 1),
2000aa74fbb4SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT);
2001aa74fbb4SAlex Deucher radeon_add_legacy_connector(dev, 0,
2002aa74fbb4SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT |
2003aa74fbb4SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
2004aa74fbb4SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2005aa74fbb4SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2006aa74fbb4SAlex Deucher &hpd);
2007aa74fbb4SAlex Deucher /* DVI - tv dac, dvo */
2008aa74fbb4SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
2009aa74fbb4SAlex Deucher hpd.hpd = RADEON_HPD_2; /* ??? */
2010aa74fbb4SAlex Deucher radeon_add_legacy_encoder(dev,
2011aa74fbb4SAlex Deucher radeon_get_encoder_enum(dev,
2012aa74fbb4SAlex Deucher ATOM_DEVICE_DFP2_SUPPORT,
2013aa74fbb4SAlex Deucher 0),
2014aa74fbb4SAlex Deucher ATOM_DEVICE_DFP2_SUPPORT);
2015aa74fbb4SAlex Deucher radeon_add_legacy_encoder(dev,
2016aa74fbb4SAlex Deucher radeon_get_encoder_enum(dev,
2017aa74fbb4SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
2018aa74fbb4SAlex Deucher 2),
2019aa74fbb4SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT);
2020aa74fbb4SAlex Deucher radeon_add_legacy_connector(dev, 1,
2021aa74fbb4SAlex Deucher ATOM_DEVICE_DFP2_SUPPORT |
2022aa74fbb4SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
2023aa74fbb4SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2024aa74fbb4SAlex Deucher CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
2025aa74fbb4SAlex Deucher &hpd);
2026aa74fbb4SAlex Deucher break;
20279fad321aSAlex Deucher case CT_MAC_G5_9600:
20289fad321aSAlex Deucher DRM_INFO("Connector Table: %d (mac g5 9600)\n",
20299fad321aSAlex Deucher rdev->mode_info.connector_table);
20309fad321aSAlex Deucher /* DVI - tv dac, dvo */
20319fad321aSAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
20329fad321aSAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
20339fad321aSAlex Deucher radeon_add_legacy_encoder(dev,
20349fad321aSAlex Deucher radeon_get_encoder_enum(dev,
20359fad321aSAlex Deucher ATOM_DEVICE_DFP2_SUPPORT,
20369fad321aSAlex Deucher 0),
20379fad321aSAlex Deucher ATOM_DEVICE_DFP2_SUPPORT);
20389fad321aSAlex Deucher radeon_add_legacy_encoder(dev,
20399fad321aSAlex Deucher radeon_get_encoder_enum(dev,
20409fad321aSAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
20419fad321aSAlex Deucher 2),
20429fad321aSAlex Deucher ATOM_DEVICE_CRT2_SUPPORT);
20439fad321aSAlex Deucher radeon_add_legacy_connector(dev, 0,
20449fad321aSAlex Deucher ATOM_DEVICE_DFP2_SUPPORT |
20459fad321aSAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
20469fad321aSAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20479fad321aSAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
20489fad321aSAlex Deucher &hpd);
20499fad321aSAlex Deucher /* ADC - primary dac, internal tmds */
20509fad321aSAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
20519fad321aSAlex Deucher hpd.hpd = RADEON_HPD_2; /* ??? */
20529fad321aSAlex Deucher radeon_add_legacy_encoder(dev,
20539fad321aSAlex Deucher radeon_get_encoder_enum(dev,
20549fad321aSAlex Deucher ATOM_DEVICE_DFP1_SUPPORT,
20559fad321aSAlex Deucher 0),
20569fad321aSAlex Deucher ATOM_DEVICE_DFP1_SUPPORT);
20579fad321aSAlex Deucher radeon_add_legacy_encoder(dev,
20589fad321aSAlex Deucher radeon_get_encoder_enum(dev,
20599fad321aSAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
20609fad321aSAlex Deucher 1),
20619fad321aSAlex Deucher ATOM_DEVICE_CRT1_SUPPORT);
20629fad321aSAlex Deucher radeon_add_legacy_connector(dev, 1,
20639fad321aSAlex Deucher ATOM_DEVICE_DFP1_SUPPORT |
20649fad321aSAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
20659fad321aSAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20669fad321aSAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
20679fad321aSAlex Deucher &hpd);
2068beb47274SAlex Deucher /* TV - TV DAC */
2069beb47274SAlex Deucher ddc_i2c.valid = false;
2070beb47274SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2071beb47274SAlex Deucher radeon_add_legacy_encoder(dev,
2072beb47274SAlex Deucher radeon_get_encoder_enum(dev,
2073beb47274SAlex Deucher ATOM_DEVICE_TV1_SUPPORT,
2074beb47274SAlex Deucher 2),
2075beb47274SAlex Deucher ATOM_DEVICE_TV1_SUPPORT);
2076beb47274SAlex Deucher radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
2077beb47274SAlex Deucher DRM_MODE_CONNECTOR_SVIDEO,
2078beb47274SAlex Deucher &ddc_i2c,
2079beb47274SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
2080beb47274SAlex Deucher &hpd);
20819fad321aSAlex Deucher break;
20826a556039SAlex Deucher case CT_SAM440EP:
20836a556039SAlex Deucher DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
20846a556039SAlex Deucher rdev->mode_info.connector_table);
20856a556039SAlex Deucher /* LVDS */
20866a556039SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
20876a556039SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
20886a556039SAlex Deucher radeon_add_legacy_encoder(dev,
20896a556039SAlex Deucher radeon_get_encoder_enum(dev,
20906a556039SAlex Deucher ATOM_DEVICE_LCD1_SUPPORT,
20916a556039SAlex Deucher 0),
20926a556039SAlex Deucher ATOM_DEVICE_LCD1_SUPPORT);
20936a556039SAlex Deucher radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
20946a556039SAlex Deucher DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
20956a556039SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
20966a556039SAlex Deucher &hpd);
20976a556039SAlex Deucher /* DVI-I - secondary dac, int tmds */
20986a556039SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
20996a556039SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
21006a556039SAlex Deucher radeon_add_legacy_encoder(dev,
21016a556039SAlex Deucher radeon_get_encoder_enum(dev,
21026a556039SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT,
21036a556039SAlex Deucher 0),
21046a556039SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT);
21056a556039SAlex Deucher radeon_add_legacy_encoder(dev,
21066a556039SAlex Deucher radeon_get_encoder_enum(dev,
21076a556039SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
21086a556039SAlex Deucher 2),
21096a556039SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT);
21106a556039SAlex Deucher radeon_add_legacy_connector(dev, 1,
21116a556039SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT |
21126a556039SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
21136a556039SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
21146a556039SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
21156a556039SAlex Deucher &hpd);
21166a556039SAlex Deucher /* VGA - primary dac */
21176a556039SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
21186a556039SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
21196a556039SAlex Deucher radeon_add_legacy_encoder(dev,
21206a556039SAlex Deucher radeon_get_encoder_enum(dev,
21216a556039SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
21226a556039SAlex Deucher 1),
21236a556039SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT);
21246a556039SAlex Deucher radeon_add_legacy_connector(dev, 2,
21256a556039SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
21266a556039SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
21276a556039SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
21286a556039SAlex Deucher &hpd);
21296a556039SAlex Deucher /* TV - TV DAC */
21306a556039SAlex Deucher ddc_i2c.valid = false;
21316a556039SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
21326a556039SAlex Deucher radeon_add_legacy_encoder(dev,
21336a556039SAlex Deucher radeon_get_encoder_enum(dev,
21346a556039SAlex Deucher ATOM_DEVICE_TV1_SUPPORT,
21356a556039SAlex Deucher 2),
21366a556039SAlex Deucher ATOM_DEVICE_TV1_SUPPORT);
21376a556039SAlex Deucher radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT,
21386a556039SAlex Deucher DRM_MODE_CONNECTOR_SVIDEO,
21396a556039SAlex Deucher &ddc_i2c,
21406a556039SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
21416a556039SAlex Deucher &hpd);
21426a556039SAlex Deucher break;
2143cafa59b9SAlex Deucher case CT_MAC_G4_SILVER:
2144cafa59b9SAlex Deucher DRM_INFO("Connector Table: %d (mac g4 silver)\n",
2145cafa59b9SAlex Deucher rdev->mode_info.connector_table);
2146cafa59b9SAlex Deucher /* DVI-I - tv dac, int tmds */
2147cafa59b9SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2148cafa59b9SAlex Deucher hpd.hpd = RADEON_HPD_1; /* ??? */
2149cafa59b9SAlex Deucher radeon_add_legacy_encoder(dev,
2150cafa59b9SAlex Deucher radeon_get_encoder_enum(dev,
2151cafa59b9SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT,
2152cafa59b9SAlex Deucher 0),
2153cafa59b9SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT);
2154cafa59b9SAlex Deucher radeon_add_legacy_encoder(dev,
2155cafa59b9SAlex Deucher radeon_get_encoder_enum(dev,
2156cafa59b9SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
2157cafa59b9SAlex Deucher 2),
2158cafa59b9SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT);
2159cafa59b9SAlex Deucher radeon_add_legacy_connector(dev, 0,
2160cafa59b9SAlex Deucher ATOM_DEVICE_DFP1_SUPPORT |
2161cafa59b9SAlex Deucher ATOM_DEVICE_CRT2_SUPPORT,
2162cafa59b9SAlex Deucher DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2163cafa59b9SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2164cafa59b9SAlex Deucher &hpd);
2165cafa59b9SAlex Deucher /* VGA - primary dac */
2166cafa59b9SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2167cafa59b9SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2168cafa59b9SAlex Deucher radeon_add_legacy_encoder(dev,
2169cafa59b9SAlex Deucher radeon_get_encoder_enum(dev,
2170cafa59b9SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
2171cafa59b9SAlex Deucher 1),
2172cafa59b9SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT);
2173cafa59b9SAlex Deucher radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
2174cafa59b9SAlex Deucher DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
2175cafa59b9SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
2176cafa59b9SAlex Deucher &hpd);
2177cafa59b9SAlex Deucher /* TV - TV DAC */
2178cafa59b9SAlex Deucher ddc_i2c.valid = false;
2179cafa59b9SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2180cafa59b9SAlex Deucher radeon_add_legacy_encoder(dev,
2181cafa59b9SAlex Deucher radeon_get_encoder_enum(dev,
2182cafa59b9SAlex Deucher ATOM_DEVICE_TV1_SUPPORT,
2183cafa59b9SAlex Deucher 2),
2184cafa59b9SAlex Deucher ATOM_DEVICE_TV1_SUPPORT);
2185cafa59b9SAlex Deucher radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
2186cafa59b9SAlex Deucher DRM_MODE_CONNECTOR_SVIDEO,
2187cafa59b9SAlex Deucher &ddc_i2c,
2188cafa59b9SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
2189cafa59b9SAlex Deucher &hpd);
2190cafa59b9SAlex Deucher break;
2191771fe6b9SJerome Glisse default:
2192771fe6b9SJerome Glisse DRM_INFO("Connector table: %d (invalid)\n",
2193771fe6b9SJerome Glisse rdev->mode_info.connector_table);
2194771fe6b9SJerome Glisse return false;
2195771fe6b9SJerome Glisse }
2196771fe6b9SJerome Glisse
2197771fe6b9SJerome Glisse radeon_link_encoder_connector(dev);
2198771fe6b9SJerome Glisse
2199771fe6b9SJerome Glisse return true;
2200771fe6b9SJerome Glisse }
2201771fe6b9SJerome Glisse
radeon_apply_legacy_quirks(struct drm_device * dev,int bios_index,enum radeon_combios_connector * legacy_connector,struct radeon_i2c_bus_rec * ddc_i2c,struct radeon_hpd * hpd)2202771fe6b9SJerome Glisse static bool radeon_apply_legacy_quirks(struct drm_device *dev,
2203771fe6b9SJerome Glisse int bios_index,
2204771fe6b9SJerome Glisse enum radeon_combios_connector
2205771fe6b9SJerome Glisse *legacy_connector,
2206eed45b30SAlex Deucher struct radeon_i2c_bus_rec *ddc_i2c,
2207eed45b30SAlex Deucher struct radeon_hpd *hpd)
2208771fe6b9SJerome Glisse {
2209d86a4126SThomas Zimmermann struct radeon_device *rdev = dev->dev_private;
2210fcec570bSAlex Deucher
2211771fe6b9SJerome Glisse /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
2212771fe6b9SJerome Glisse one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
2213d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x515e &&
2214d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x1014) {
2215771fe6b9SJerome Glisse if (*legacy_connector == CONNECTOR_CRT_LEGACY &&
2216771fe6b9SJerome Glisse ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
2217771fe6b9SJerome Glisse return false;
2218771fe6b9SJerome Glisse }
2219771fe6b9SJerome Glisse
2220771fe6b9SJerome Glisse /* X300 card with extra non-existent DVI port */
2221d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x5B60 &&
2222d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x17af &&
2223d86a4126SThomas Zimmermann rdev->pdev->subsystem_device == 0x201e && bios_index == 2) {
2224771fe6b9SJerome Glisse if (*legacy_connector == CONNECTOR_DVI_I_LEGACY)
2225771fe6b9SJerome Glisse return false;
2226771fe6b9SJerome Glisse }
2227771fe6b9SJerome Glisse
2228771fe6b9SJerome Glisse return true;
2229771fe6b9SJerome Glisse }
2230771fe6b9SJerome Glisse
radeon_apply_legacy_tv_quirks(struct drm_device * dev)2231790cfb34SAlex Deucher static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
2232790cfb34SAlex Deucher {
2233d86a4126SThomas Zimmermann struct radeon_device *rdev = dev->dev_private;
2234d86a4126SThomas Zimmermann
2235790cfb34SAlex Deucher /* Acer 5102 has non-existent TV port */
2236d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x5975 &&
2237d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x1025 &&
2238d86a4126SThomas Zimmermann rdev->pdev->subsystem_device == 0x009f)
2239790cfb34SAlex Deucher return false;
2240790cfb34SAlex Deucher
2241fc7f7119SAlex Deucher /* HP dc5750 has non-existent TV port */
2242d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x5974 &&
2243d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x103c &&
2244d86a4126SThomas Zimmermann rdev->pdev->subsystem_device == 0x280a)
2245fc7f7119SAlex Deucher return false;
2246fc7f7119SAlex Deucher
2247fd874ad0SAlex Deucher /* MSI S270 has non-existent TV port */
2248d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x5955 &&
2249d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x1462 &&
2250d86a4126SThomas Zimmermann rdev->pdev->subsystem_device == 0x0131)
2251fd874ad0SAlex Deucher return false;
2252fd874ad0SAlex Deucher
2253790cfb34SAlex Deucher return true;
2254790cfb34SAlex Deucher }
2255790cfb34SAlex Deucher
combios_check_dl_dvi(struct drm_device * dev,int is_dvi_d)2256b75fad06SAlex Deucher static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
2257b75fad06SAlex Deucher {
2258b75fad06SAlex Deucher struct radeon_device *rdev = dev->dev_private;
2259b75fad06SAlex Deucher uint32_t ext_tmds_info;
2260b75fad06SAlex Deucher
2261b75fad06SAlex Deucher if (rdev->flags & RADEON_IS_IGP) {
2262b75fad06SAlex Deucher if (is_dvi_d)
2263b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
2264b75fad06SAlex Deucher else
2265b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2266b75fad06SAlex Deucher }
2267b75fad06SAlex Deucher ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
2268b75fad06SAlex Deucher if (ext_tmds_info) {
2269b75fad06SAlex Deucher uint8_t rev = RBIOS8(ext_tmds_info);
2270b75fad06SAlex Deucher uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
2271b75fad06SAlex Deucher if (rev >= 3) {
2272b75fad06SAlex Deucher if (is_dvi_d)
2273b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
2274b75fad06SAlex Deucher else
2275b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
2276b75fad06SAlex Deucher } else {
2277b75fad06SAlex Deucher if (flags & 1) {
2278b75fad06SAlex Deucher if (is_dvi_d)
2279b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
2280b75fad06SAlex Deucher else
2281b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
2282b75fad06SAlex Deucher }
2283b75fad06SAlex Deucher }
2284b75fad06SAlex Deucher }
2285b75fad06SAlex Deucher if (is_dvi_d)
2286b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
2287b75fad06SAlex Deucher else
2288b75fad06SAlex Deucher return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2289b75fad06SAlex Deucher }
2290b75fad06SAlex Deucher
radeon_get_legacy_connector_info_from_bios(struct drm_device * dev)2291771fe6b9SJerome Glisse bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
2292771fe6b9SJerome Glisse {
2293771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
2294771fe6b9SJerome Glisse uint32_t conn_info, entry, devices;
2295b75fad06SAlex Deucher uint16_t tmp, connector_object_id;
2296771fe6b9SJerome Glisse enum radeon_combios_ddc ddc_type;
2297771fe6b9SJerome Glisse enum radeon_combios_connector connector;
2298771fe6b9SJerome Glisse int i = 0;
2299771fe6b9SJerome Glisse struct radeon_i2c_bus_rec ddc_i2c;
2300eed45b30SAlex Deucher struct radeon_hpd hpd;
2301771fe6b9SJerome Glisse
2302771fe6b9SJerome Glisse conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
2303771fe6b9SJerome Glisse if (conn_info) {
2304771fe6b9SJerome Glisse for (i = 0; i < 4; i++) {
2305771fe6b9SJerome Glisse entry = conn_info + 2 + i * 2;
2306771fe6b9SJerome Glisse
2307771fe6b9SJerome Glisse if (!RBIOS16(entry))
2308771fe6b9SJerome Glisse break;
2309771fe6b9SJerome Glisse
2310771fe6b9SJerome Glisse tmp = RBIOS16(entry);
2311771fe6b9SJerome Glisse
2312771fe6b9SJerome Glisse connector = (tmp >> 12) & 0xf;
2313771fe6b9SJerome Glisse
2314771fe6b9SJerome Glisse ddc_type = (tmp >> 8) & 0xf;
23153d61bd42SAlex Deucher if (ddc_type == 5)
23163d61bd42SAlex Deucher ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
23173d61bd42SAlex Deucher else
2318179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
2319771fe6b9SJerome Glisse
2320eed45b30SAlex Deucher switch (connector) {
2321eed45b30SAlex Deucher case CONNECTOR_PROPRIETARY_LEGACY:
2322eed45b30SAlex Deucher case CONNECTOR_DVI_I_LEGACY:
2323eed45b30SAlex Deucher case CONNECTOR_DVI_D_LEGACY:
2324eed45b30SAlex Deucher if ((tmp >> 4) & 0x1)
2325eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_2;
2326eed45b30SAlex Deucher else
2327eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_1;
2328eed45b30SAlex Deucher break;
2329eed45b30SAlex Deucher default:
2330eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2331eed45b30SAlex Deucher break;
2332eed45b30SAlex Deucher }
2333eed45b30SAlex Deucher
23342d152c6bSAlex Deucher if (!radeon_apply_legacy_quirks(dev, i, &connector,
2335eed45b30SAlex Deucher &ddc_i2c, &hpd))
23362d152c6bSAlex Deucher continue;
2337771fe6b9SJerome Glisse
2338771fe6b9SJerome Glisse switch (connector) {
2339771fe6b9SJerome Glisse case CONNECTOR_PROPRIETARY_LEGACY:
2340771fe6b9SJerome Glisse if ((tmp >> 4) & 0x1)
2341771fe6b9SJerome Glisse devices = ATOM_DEVICE_DFP2_SUPPORT;
2342771fe6b9SJerome Glisse else
2343771fe6b9SJerome Glisse devices = ATOM_DEVICE_DFP1_SUPPORT;
2344771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
23455137ee94SAlex Deucher radeon_get_encoder_enum
2346771fe6b9SJerome Glisse (dev, devices, 0),
2347771fe6b9SJerome Glisse devices);
2348771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, i, devices,
2349771fe6b9SJerome Glisse legacy_connector_convert
2350771fe6b9SJerome Glisse [connector],
2351b75fad06SAlex Deucher &ddc_i2c,
2352eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
2353eed45b30SAlex Deucher &hpd);
2354771fe6b9SJerome Glisse break;
2355771fe6b9SJerome Glisse case CONNECTOR_CRT_LEGACY:
2356771fe6b9SJerome Glisse if (tmp & 0x1) {
2357771fe6b9SJerome Glisse devices = ATOM_DEVICE_CRT2_SUPPORT;
2358771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
23595137ee94SAlex Deucher radeon_get_encoder_enum
2360771fe6b9SJerome Glisse (dev,
2361771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
2362771fe6b9SJerome Glisse 2),
2363771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
2364771fe6b9SJerome Glisse } else {
2365771fe6b9SJerome Glisse devices = ATOM_DEVICE_CRT1_SUPPORT;
2366771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
23675137ee94SAlex Deucher radeon_get_encoder_enum
2368771fe6b9SJerome Glisse (dev,
2369771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
2370771fe6b9SJerome Glisse 1),
2371771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
2372771fe6b9SJerome Glisse }
2373771fe6b9SJerome Glisse radeon_add_legacy_connector(dev,
2374771fe6b9SJerome Glisse i,
2375771fe6b9SJerome Glisse devices,
2376771fe6b9SJerome Glisse legacy_connector_convert
2377771fe6b9SJerome Glisse [connector],
2378b75fad06SAlex Deucher &ddc_i2c,
2379eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
2380eed45b30SAlex Deucher &hpd);
2381771fe6b9SJerome Glisse break;
2382771fe6b9SJerome Glisse case CONNECTOR_DVI_I_LEGACY:
2383771fe6b9SJerome Glisse devices = 0;
2384771fe6b9SJerome Glisse if (tmp & 0x1) {
2385771fe6b9SJerome Glisse devices |= ATOM_DEVICE_CRT2_SUPPORT;
2386771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
23875137ee94SAlex Deucher radeon_get_encoder_enum
2388771fe6b9SJerome Glisse (dev,
2389771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT,
2390771fe6b9SJerome Glisse 2),
2391771fe6b9SJerome Glisse ATOM_DEVICE_CRT2_SUPPORT);
2392771fe6b9SJerome Glisse } else {
2393771fe6b9SJerome Glisse devices |= ATOM_DEVICE_CRT1_SUPPORT;
2394771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
23955137ee94SAlex Deucher radeon_get_encoder_enum
2396771fe6b9SJerome Glisse (dev,
2397771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
2398771fe6b9SJerome Glisse 1),
2399771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
2400771fe6b9SJerome Glisse }
24019200ee49SAlex Deucher /* RV100 board with external TDMS bit mis-set.
24029200ee49SAlex Deucher * Actually uses internal TMDS, clear the bit.
24039200ee49SAlex Deucher */
2404d86a4126SThomas Zimmermann if (rdev->pdev->device == 0x5159 &&
2405d86a4126SThomas Zimmermann rdev->pdev->subsystem_vendor == 0x1014 &&
2406d86a4126SThomas Zimmermann rdev->pdev->subsystem_device == 0x029A) {
24079200ee49SAlex Deucher tmp &= ~(1 << 4);
24089200ee49SAlex Deucher }
2409771fe6b9SJerome Glisse if ((tmp >> 4) & 0x1) {
2410771fe6b9SJerome Glisse devices |= ATOM_DEVICE_DFP2_SUPPORT;
2411771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24125137ee94SAlex Deucher radeon_get_encoder_enum
2413771fe6b9SJerome Glisse (dev,
2414771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT,
2415771fe6b9SJerome Glisse 0),
2416771fe6b9SJerome Glisse ATOM_DEVICE_DFP2_SUPPORT);
2417b75fad06SAlex Deucher connector_object_id = combios_check_dl_dvi(dev, 0);
2418771fe6b9SJerome Glisse } else {
2419771fe6b9SJerome Glisse devices |= ATOM_DEVICE_DFP1_SUPPORT;
2420771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24215137ee94SAlex Deucher radeon_get_encoder_enum
2422771fe6b9SJerome Glisse (dev,
2423771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
2424771fe6b9SJerome Glisse 0),
2425771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
2426b75fad06SAlex Deucher connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2427771fe6b9SJerome Glisse }
2428771fe6b9SJerome Glisse radeon_add_legacy_connector(dev,
2429771fe6b9SJerome Glisse i,
2430771fe6b9SJerome Glisse devices,
2431771fe6b9SJerome Glisse legacy_connector_convert
2432771fe6b9SJerome Glisse [connector],
2433b75fad06SAlex Deucher &ddc_i2c,
2434eed45b30SAlex Deucher connector_object_id,
2435eed45b30SAlex Deucher &hpd);
2436771fe6b9SJerome Glisse break;
2437771fe6b9SJerome Glisse case CONNECTOR_DVI_D_LEGACY:
2438b75fad06SAlex Deucher if ((tmp >> 4) & 0x1) {
2439771fe6b9SJerome Glisse devices = ATOM_DEVICE_DFP2_SUPPORT;
2440b75fad06SAlex Deucher connector_object_id = combios_check_dl_dvi(dev, 1);
2441b75fad06SAlex Deucher } else {
2442771fe6b9SJerome Glisse devices = ATOM_DEVICE_DFP1_SUPPORT;
2443b75fad06SAlex Deucher connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2444b75fad06SAlex Deucher }
2445771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24465137ee94SAlex Deucher radeon_get_encoder_enum
2447771fe6b9SJerome Glisse (dev, devices, 0),
2448771fe6b9SJerome Glisse devices);
2449771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, i, devices,
2450771fe6b9SJerome Glisse legacy_connector_convert
2451771fe6b9SJerome Glisse [connector],
2452b75fad06SAlex Deucher &ddc_i2c,
2453eed45b30SAlex Deucher connector_object_id,
2454eed45b30SAlex Deucher &hpd);
2455771fe6b9SJerome Glisse break;
2456771fe6b9SJerome Glisse case CONNECTOR_CTV_LEGACY:
2457771fe6b9SJerome Glisse case CONNECTOR_STV_LEGACY:
2458771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24595137ee94SAlex Deucher radeon_get_encoder_enum
2460771fe6b9SJerome Glisse (dev,
2461771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
2462771fe6b9SJerome Glisse 2),
2463771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
2464771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, i,
2465771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
2466771fe6b9SJerome Glisse legacy_connector_convert
2467771fe6b9SJerome Glisse [connector],
2468b75fad06SAlex Deucher &ddc_i2c,
2469eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
2470eed45b30SAlex Deucher &hpd);
2471771fe6b9SJerome Glisse break;
2472771fe6b9SJerome Glisse default:
2473771fe6b9SJerome Glisse DRM_ERROR("Unknown connector type: %d\n",
2474771fe6b9SJerome Glisse connector);
2475771fe6b9SJerome Glisse continue;
2476771fe6b9SJerome Glisse }
2477771fe6b9SJerome Glisse
2478771fe6b9SJerome Glisse }
2479771fe6b9SJerome Glisse } else {
2480771fe6b9SJerome Glisse uint16_t tmds_info =
2481771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
2482771fe6b9SJerome Glisse if (tmds_info) {
2483d9fdaafbSDave Airlie DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
2484771fe6b9SJerome Glisse
2485771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24865137ee94SAlex Deucher radeon_get_encoder_enum(dev,
2487771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT,
2488771fe6b9SJerome Glisse 1),
2489771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT);
2490771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
24915137ee94SAlex Deucher radeon_get_encoder_enum(dev,
2492771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
2493771fe6b9SJerome Glisse 0),
2494771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT);
2495771fe6b9SJerome Glisse
2496179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
24978e36ed00SAlex Deucher hpd.hpd = RADEON_HPD_1;
2498771fe6b9SJerome Glisse radeon_add_legacy_connector(dev,
2499771fe6b9SJerome Glisse 0,
2500771fe6b9SJerome Glisse ATOM_DEVICE_CRT1_SUPPORT |
2501771fe6b9SJerome Glisse ATOM_DEVICE_DFP1_SUPPORT,
2502771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_DVII,
2503b75fad06SAlex Deucher &ddc_i2c,
2504eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2505eed45b30SAlex Deucher &hpd);
2506771fe6b9SJerome Glisse } else {
2507d0c403e9SAlex Deucher uint16_t crt_info =
2508d0c403e9SAlex Deucher combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
2509d9fdaafbSDave Airlie DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
2510d0c403e9SAlex Deucher if (crt_info) {
2511d0c403e9SAlex Deucher radeon_add_legacy_encoder(dev,
25125137ee94SAlex Deucher radeon_get_encoder_enum(dev,
2513d0c403e9SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
2514d0c403e9SAlex Deucher 1),
2515d0c403e9SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT);
2516179e8078SAlex Deucher ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2517eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2518d0c403e9SAlex Deucher radeon_add_legacy_connector(dev,
2519d0c403e9SAlex Deucher 0,
2520d0c403e9SAlex Deucher ATOM_DEVICE_CRT1_SUPPORT,
2521d0c403e9SAlex Deucher DRM_MODE_CONNECTOR_VGA,
2522b75fad06SAlex Deucher &ddc_i2c,
2523eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_VGA,
2524eed45b30SAlex Deucher &hpd);
2525d0c403e9SAlex Deucher } else {
2526d9fdaafbSDave Airlie DRM_DEBUG_KMS("No connector info found\n");
2527771fe6b9SJerome Glisse return false;
2528771fe6b9SJerome Glisse }
2529771fe6b9SJerome Glisse }
2530d0c403e9SAlex Deucher }
2531771fe6b9SJerome Glisse
2532771fe6b9SJerome Glisse if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) {
2533771fe6b9SJerome Glisse uint16_t lcd_info =
2534771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
2535771fe6b9SJerome Glisse if (lcd_info) {
2536771fe6b9SJerome Glisse uint16_t lcd_ddc_info =
2537771fe6b9SJerome Glisse combios_get_table_offset(dev,
2538771fe6b9SJerome Glisse COMBIOS_LCD_DDC_INFO_TABLE);
2539771fe6b9SJerome Glisse
2540771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
25415137ee94SAlex Deucher radeon_get_encoder_enum(dev,
2542771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
2543771fe6b9SJerome Glisse 0),
2544771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT);
2545771fe6b9SJerome Glisse
2546771fe6b9SJerome Glisse if (lcd_ddc_info) {
2547771fe6b9SJerome Glisse ddc_type = RBIOS8(lcd_ddc_info + 2);
2548771fe6b9SJerome Glisse switch (ddc_type) {
2549771fe6b9SJerome Glisse case DDC_LCD:
2550771fe6b9SJerome Glisse ddc_i2c =
2551179e8078SAlex Deucher combios_setup_i2c_bus(rdev,
2552179e8078SAlex Deucher DDC_LCD,
2553179e8078SAlex Deucher RBIOS32(lcd_ddc_info + 3),
2554179e8078SAlex Deucher RBIOS32(lcd_ddc_info + 7));
2555f376b94fSAlex Deucher radeon_i2c_add(rdev, &ddc_i2c, "LCD");
2556771fe6b9SJerome Glisse break;
2557771fe6b9SJerome Glisse case DDC_GPIO:
2558771fe6b9SJerome Glisse ddc_i2c =
2559179e8078SAlex Deucher combios_setup_i2c_bus(rdev,
2560179e8078SAlex Deucher DDC_GPIO,
2561179e8078SAlex Deucher RBIOS32(lcd_ddc_info + 3),
2562179e8078SAlex Deucher RBIOS32(lcd_ddc_info + 7));
2563f376b94fSAlex Deucher radeon_i2c_add(rdev, &ddc_i2c, "LCD");
2564771fe6b9SJerome Glisse break;
2565771fe6b9SJerome Glisse default:
2566179e8078SAlex Deucher ddc_i2c =
2567179e8078SAlex Deucher combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
2568771fe6b9SJerome Glisse break;
2569771fe6b9SJerome Glisse }
2570d9fdaafbSDave Airlie DRM_DEBUG_KMS("LCD DDC Info Table found!\n");
2571771fe6b9SJerome Glisse } else
2572771fe6b9SJerome Glisse ddc_i2c.valid = false;
2573771fe6b9SJerome Glisse
2574eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2575771fe6b9SJerome Glisse radeon_add_legacy_connector(dev,
2576771fe6b9SJerome Glisse 5,
2577771fe6b9SJerome Glisse ATOM_DEVICE_LCD1_SUPPORT,
2578771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_LVDS,
2579b75fad06SAlex Deucher &ddc_i2c,
2580eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_LVDS,
2581eed45b30SAlex Deucher &hpd);
2582771fe6b9SJerome Glisse }
2583771fe6b9SJerome Glisse }
2584771fe6b9SJerome Glisse
2585771fe6b9SJerome Glisse /* check TV table */
2586771fe6b9SJerome Glisse if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
2587771fe6b9SJerome Glisse uint32_t tv_info =
2588771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
2589771fe6b9SJerome Glisse if (tv_info) {
2590771fe6b9SJerome Glisse if (RBIOS8(tv_info + 6) == 'T') {
2591790cfb34SAlex Deucher if (radeon_apply_legacy_tv_quirks(dev)) {
2592eed45b30SAlex Deucher hpd.hpd = RADEON_HPD_NONE;
2593d294ed69SDave Airlie ddc_i2c.valid = false;
2594771fe6b9SJerome Glisse radeon_add_legacy_encoder(dev,
25955137ee94SAlex Deucher radeon_get_encoder_enum
2596771fe6b9SJerome Glisse (dev,
2597771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
2598771fe6b9SJerome Glisse 2),
2599771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT);
2600771fe6b9SJerome Glisse radeon_add_legacy_connector(dev, 6,
2601771fe6b9SJerome Glisse ATOM_DEVICE_TV1_SUPPORT,
2602771fe6b9SJerome Glisse DRM_MODE_CONNECTOR_SVIDEO,
2603b75fad06SAlex Deucher &ddc_i2c,
2604eed45b30SAlex Deucher CONNECTOR_OBJECT_ID_SVIDEO,
2605eed45b30SAlex Deucher &hpd);
2606771fe6b9SJerome Glisse }
2607771fe6b9SJerome Glisse }
2608771fe6b9SJerome Glisse }
2609790cfb34SAlex Deucher }
2610771fe6b9SJerome Glisse
2611771fe6b9SJerome Glisse radeon_link_encoder_connector(dev);
2612771fe6b9SJerome Glisse
2613771fe6b9SJerome Glisse return true;
2614771fe6b9SJerome Glisse }
2615771fe6b9SJerome Glisse
261663f7d982SAlex Deucher static const char *thermal_controller_names[] = {
261763f7d982SAlex Deucher "NONE",
261863f7d982SAlex Deucher "lm63",
261963f7d982SAlex Deucher "adm1032",
262063f7d982SAlex Deucher };
262163f7d982SAlex Deucher
radeon_combios_get_power_modes(struct radeon_device * rdev)262256278a8eSAlex Deucher void radeon_combios_get_power_modes(struct radeon_device *rdev)
262356278a8eSAlex Deucher {
2624fb1b5e1dSWu Hoi Pok struct drm_device *dev = rdev_to_drm(rdev);
262556278a8eSAlex Deucher u16 offset, misc, misc2 = 0;
262677441f77Szhengbin u8 rev, tmp;
262756278a8eSAlex Deucher int state_index = 0;
2628c41b9ee9SAlex Deucher struct radeon_i2c_bus_rec i2c_bus;
262956278a8eSAlex Deucher
2630a48b9b4eSAlex Deucher rdev->pm.default_power_state_index = -1;
263156278a8eSAlex Deucher
26320975b162SAlex Deucher /* allocate 2 power states */
26336396bb22SKees Cook rdev->pm.power_state = kcalloc(2, sizeof(struct radeon_power_state),
26346396bb22SKees Cook GFP_KERNEL);
2635a7c36fd8SAlex Deucher if (rdev->pm.power_state) {
2636a7c36fd8SAlex Deucher /* allocate 1 clock mode per state */
2637a7c36fd8SAlex Deucher rdev->pm.power_state[0].clock_info =
26386396bb22SKees Cook kcalloc(1, sizeof(struct radeon_pm_clock_info),
26396396bb22SKees Cook GFP_KERNEL);
2640a7c36fd8SAlex Deucher rdev->pm.power_state[1].clock_info =
26416396bb22SKees Cook kcalloc(1, sizeof(struct radeon_pm_clock_info),
26426396bb22SKees Cook GFP_KERNEL);
2643a7c36fd8SAlex Deucher if (!rdev->pm.power_state[0].clock_info ||
2644a7c36fd8SAlex Deucher !rdev->pm.power_state[1].clock_info)
2645a7c36fd8SAlex Deucher goto pm_failed;
2646a7c36fd8SAlex Deucher } else
2647a7c36fd8SAlex Deucher goto pm_failed;
26480975b162SAlex Deucher
264963f7d982SAlex Deucher /* check for a thermal chip */
265063f7d982SAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
265163f7d982SAlex Deucher if (offset) {
265263f7d982SAlex Deucher u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
265363f7d982SAlex Deucher
265463f7d982SAlex Deucher rev = RBIOS8(offset);
265563f7d982SAlex Deucher
265663f7d982SAlex Deucher if (rev == 0) {
265763f7d982SAlex Deucher thermal_controller = RBIOS8(offset + 3);
265863f7d982SAlex Deucher gpio = RBIOS8(offset + 4) & 0x3f;
265963f7d982SAlex Deucher i2c_addr = RBIOS8(offset + 5);
266063f7d982SAlex Deucher } else if (rev == 1) {
266163f7d982SAlex Deucher thermal_controller = RBIOS8(offset + 4);
266263f7d982SAlex Deucher gpio = RBIOS8(offset + 5) & 0x3f;
266363f7d982SAlex Deucher i2c_addr = RBIOS8(offset + 6);
266463f7d982SAlex Deucher } else if (rev == 2) {
266563f7d982SAlex Deucher thermal_controller = RBIOS8(offset + 4);
266663f7d982SAlex Deucher gpio = RBIOS8(offset + 5) & 0x3f;
266763f7d982SAlex Deucher i2c_addr = RBIOS8(offset + 6);
266863f7d982SAlex Deucher clk_bit = RBIOS8(offset + 0xa);
266963f7d982SAlex Deucher data_bit = RBIOS8(offset + 0xb);
267063f7d982SAlex Deucher }
267163f7d982SAlex Deucher if ((thermal_controller > 0) && (thermal_controller < 3)) {
267263f7d982SAlex Deucher DRM_INFO("Possible %s thermal controller at 0x%02x\n",
267363f7d982SAlex Deucher thermal_controller_names[thermal_controller],
267463f7d982SAlex Deucher i2c_addr >> 1);
267563f7d982SAlex Deucher if (gpio == DDC_LCD) {
267663f7d982SAlex Deucher /* MM i2c */
267763f7d982SAlex Deucher i2c_bus.valid = true;
267863f7d982SAlex Deucher i2c_bus.hw_capable = true;
267963f7d982SAlex Deucher i2c_bus.mm_i2c = true;
268063f7d982SAlex Deucher i2c_bus.i2c_id = 0xa0;
268163f7d982SAlex Deucher } else if (gpio == DDC_GPIO)
268263f7d982SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
268363f7d982SAlex Deucher else
268463f7d982SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
268563f7d982SAlex Deucher rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
268663f7d982SAlex Deucher if (rdev->pm.i2c_bus) {
268763f7d982SAlex Deucher struct i2c_board_info info = { };
268863f7d982SAlex Deucher const char *name = thermal_controller_names[thermal_controller];
268963f7d982SAlex Deucher info.addr = i2c_addr >> 1;
2690992b8fe1SAzeem Shaikh strscpy(info.type, name, sizeof(info.type));
2691c7ccc1b7SWolfram Sang i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
269263f7d982SAlex Deucher }
269363f7d982SAlex Deucher }
2694c41b9ee9SAlex Deucher } else {
2695c41b9ee9SAlex Deucher /* boards with a thermal chip, but no overdrive table */
2696c41b9ee9SAlex Deucher
2697c41b9ee9SAlex Deucher /* Asus 9600xt has an f75375 on the monid bus */
2698d86a4126SThomas Zimmermann if ((rdev->pdev->device == 0x4152) &&
2699d86a4126SThomas Zimmermann (rdev->pdev->subsystem_vendor == 0x1043) &&
2700d86a4126SThomas Zimmermann (rdev->pdev->subsystem_device == 0xc002)) {
2701c41b9ee9SAlex Deucher i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
2702c41b9ee9SAlex Deucher rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2703c41b9ee9SAlex Deucher if (rdev->pm.i2c_bus) {
2704c41b9ee9SAlex Deucher struct i2c_board_info info = { };
2705c41b9ee9SAlex Deucher const char *name = "f75375";
2706c41b9ee9SAlex Deucher info.addr = 0x28;
2707992b8fe1SAzeem Shaikh strscpy(info.type, name, sizeof(info.type));
2708c7ccc1b7SWolfram Sang i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
2709c41b9ee9SAlex Deucher DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2710c41b9ee9SAlex Deucher name, info.addr);
2711c41b9ee9SAlex Deucher }
2712c41b9ee9SAlex Deucher }
271363f7d982SAlex Deucher }
271463f7d982SAlex Deucher
271556278a8eSAlex Deucher if (rdev->flags & RADEON_IS_MOBILITY) {
271656278a8eSAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
271756278a8eSAlex Deucher if (offset) {
271856278a8eSAlex Deucher rev = RBIOS8(offset);
271956278a8eSAlex Deucher /* power mode 0 tends to be the only valid one */
272056278a8eSAlex Deucher rdev->pm.power_state[state_index].num_clock_modes = 1;
272156278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
272256278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
272356278a8eSAlex Deucher if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
272456278a8eSAlex Deucher (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
272556278a8eSAlex Deucher goto default_mode;
27260ec0e74fSAlex Deucher rdev->pm.power_state[state_index].type =
27270ec0e74fSAlex Deucher POWER_STATE_TYPE_BATTERY;
272856278a8eSAlex Deucher misc = RBIOS16(offset + 0x5 + 0x0);
272956278a8eSAlex Deucher if (rev > 4)
273056278a8eSAlex Deucher misc2 = RBIOS16(offset + 0x5 + 0xe);
273179daedc9SAlex Deucher rdev->pm.power_state[state_index].misc = misc;
273279daedc9SAlex Deucher rdev->pm.power_state[state_index].misc2 = misc2;
273356278a8eSAlex Deucher if (misc & 0x4) {
273456278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
273556278a8eSAlex Deucher if (misc & 0x8)
273656278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
273756278a8eSAlex Deucher true;
273856278a8eSAlex Deucher else
273956278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
274056278a8eSAlex Deucher false;
274156278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
274256278a8eSAlex Deucher if (rev < 6) {
274356278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
274456278a8eSAlex Deucher RBIOS16(offset + 0x5 + 0xb) * 4;
274556278a8eSAlex Deucher tmp = RBIOS8(offset + 0x5 + 0xd);
274656278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
274756278a8eSAlex Deucher } else {
274856278a8eSAlex Deucher u8 entries = RBIOS8(offset + 0x5 + 0xb);
274956278a8eSAlex Deucher u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
275056278a8eSAlex Deucher if (entries && voltage_table_offset) {
275156278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
275256278a8eSAlex Deucher RBIOS16(voltage_table_offset) * 4;
275356278a8eSAlex Deucher tmp = RBIOS8(voltage_table_offset + 0x2);
275456278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
275556278a8eSAlex Deucher } else
275656278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
275756278a8eSAlex Deucher }
275856278a8eSAlex Deucher switch ((misc2 & 0x700) >> 8) {
275956278a8eSAlex Deucher case 0:
276056278a8eSAlex Deucher default:
276156278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
276256278a8eSAlex Deucher break;
276356278a8eSAlex Deucher case 1:
276456278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
276556278a8eSAlex Deucher break;
276656278a8eSAlex Deucher case 2:
276756278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
276856278a8eSAlex Deucher break;
276956278a8eSAlex Deucher case 3:
277056278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
277156278a8eSAlex Deucher break;
277256278a8eSAlex Deucher case 4:
277356278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
277456278a8eSAlex Deucher break;
277556278a8eSAlex Deucher }
277656278a8eSAlex Deucher } else
277756278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
277856278a8eSAlex Deucher if (rev > 6)
277979daedc9SAlex Deucher rdev->pm.power_state[state_index].pcie_lanes =
278056278a8eSAlex Deucher RBIOS8(offset + 0x5 + 0x10);
2781d7311171SAlex Deucher rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
278256278a8eSAlex Deucher state_index++;
278356278a8eSAlex Deucher } else {
278456278a8eSAlex Deucher /* XXX figure out some good default low power mode for mobility cards w/out power tables */
278556278a8eSAlex Deucher }
278656278a8eSAlex Deucher } else {
278756278a8eSAlex Deucher /* XXX figure out some good default low power mode for desktop cards */
278856278a8eSAlex Deucher }
278956278a8eSAlex Deucher
279056278a8eSAlex Deucher default_mode:
279156278a8eSAlex Deucher /* add the default mode */
27920ec0e74fSAlex Deucher rdev->pm.power_state[state_index].type =
27930ec0e74fSAlex Deucher POWER_STATE_TYPE_DEFAULT;
279456278a8eSAlex Deucher rdev->pm.power_state[state_index].num_clock_modes = 1;
279556278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
279656278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
279756278a8eSAlex Deucher rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
279884d88f4cSAlex Deucher if ((state_index > 0) &&
27998de016e2SAlex Deucher (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO))
280084d88f4cSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage =
280184d88f4cSAlex Deucher rdev->pm.power_state[0].clock_info[0].voltage;
280284d88f4cSAlex Deucher else
280356278a8eSAlex Deucher rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
280479daedc9SAlex Deucher rdev->pm.power_state[state_index].pcie_lanes = 16;
2805a48b9b4eSAlex Deucher rdev->pm.power_state[state_index].flags = 0;
2806a48b9b4eSAlex Deucher rdev->pm.default_power_state_index = state_index;
280756278a8eSAlex Deucher rdev->pm.num_power_states = state_index + 1;
28089038dfdfSRafał Miłecki
2809a48b9b4eSAlex Deucher rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2810a48b9b4eSAlex Deucher rdev->pm.current_clock_mode_index = 0;
2811a7c36fd8SAlex Deucher return;
2812a7c36fd8SAlex Deucher
2813a7c36fd8SAlex Deucher pm_failed:
2814a7c36fd8SAlex Deucher rdev->pm.default_power_state_index = state_index;
2815a7c36fd8SAlex Deucher rdev->pm.num_power_states = 0;
2816a7c36fd8SAlex Deucher
2817a7c36fd8SAlex Deucher rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2818a7c36fd8SAlex Deucher rdev->pm.current_clock_mode_index = 0;
281956278a8eSAlex Deucher }
282056278a8eSAlex Deucher
radeon_external_tmds_setup(struct drm_encoder * encoder)2821fcec570bSAlex Deucher void radeon_external_tmds_setup(struct drm_encoder *encoder)
2822fcec570bSAlex Deucher {
2823fcec570bSAlex Deucher struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2824fcec570bSAlex Deucher struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2825fcec570bSAlex Deucher
2826fcec570bSAlex Deucher if (!tmds)
2827fcec570bSAlex Deucher return;
2828fcec570bSAlex Deucher
2829fcec570bSAlex Deucher switch (tmds->dvo_chip) {
2830fcec570bSAlex Deucher case DVO_SIL164:
2831fcec570bSAlex Deucher /* sil 164 */
28325a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2833fcec570bSAlex Deucher tmds->slave_addr,
2834fcec570bSAlex Deucher 0x08, 0x30);
28355a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2836fcec570bSAlex Deucher tmds->slave_addr,
2837fcec570bSAlex Deucher 0x09, 0x00);
28385a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2839fcec570bSAlex Deucher tmds->slave_addr,
2840fcec570bSAlex Deucher 0x0a, 0x90);
28415a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2842fcec570bSAlex Deucher tmds->slave_addr,
2843fcec570bSAlex Deucher 0x0c, 0x89);
28445a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2845fcec570bSAlex Deucher tmds->slave_addr,
2846fcec570bSAlex Deucher 0x08, 0x3b);
2847fcec570bSAlex Deucher break;
2848fcec570bSAlex Deucher case DVO_SIL1178:
2849fcec570bSAlex Deucher /* sil 1178 - untested */
2850fcec570bSAlex Deucher /*
2851fcec570bSAlex Deucher * 0x0f, 0x44
2852fcec570bSAlex Deucher * 0x0f, 0x4c
2853fcec570bSAlex Deucher * 0x0e, 0x01
2854fcec570bSAlex Deucher * 0x0a, 0x80
2855fcec570bSAlex Deucher * 0x09, 0x30
2856fcec570bSAlex Deucher * 0x0c, 0xc9
2857fcec570bSAlex Deucher * 0x0d, 0x70
2858fcec570bSAlex Deucher * 0x08, 0x32
2859fcec570bSAlex Deucher * 0x08, 0x33
2860fcec570bSAlex Deucher */
2861fcec570bSAlex Deucher break;
2862fcec570bSAlex Deucher default:
2863fcec570bSAlex Deucher break;
2864fcec570bSAlex Deucher }
2865fcec570bSAlex Deucher
2866fcec570bSAlex Deucher }
2867fcec570bSAlex Deucher
radeon_combios_external_tmds_setup(struct drm_encoder * encoder)2868fcec570bSAlex Deucher bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
2869fcec570bSAlex Deucher {
2870fcec570bSAlex Deucher struct drm_device *dev = encoder->dev;
2871fcec570bSAlex Deucher struct radeon_device *rdev = dev->dev_private;
2872fcec570bSAlex Deucher struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2873fcec570bSAlex Deucher uint16_t offset;
2874fcec570bSAlex Deucher uint8_t blocks, slave_addr, rev;
2875fcec570bSAlex Deucher uint32_t index, id;
2876fcec570bSAlex Deucher uint32_t reg, val, and_mask, or_mask;
2877fcec570bSAlex Deucher struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2878fcec570bSAlex Deucher
2879fcec570bSAlex Deucher if (!tmds)
2880fcec570bSAlex Deucher return false;
2881fcec570bSAlex Deucher
2882fcec570bSAlex Deucher if (rdev->flags & RADEON_IS_IGP) {
2883fcec570bSAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
2884fcec570bSAlex Deucher rev = RBIOS8(offset);
2885fcec570bSAlex Deucher if (offset) {
2886fcec570bSAlex Deucher rev = RBIOS8(offset);
2887fcec570bSAlex Deucher if (rev > 1) {
2888fcec570bSAlex Deucher blocks = RBIOS8(offset + 3);
2889fcec570bSAlex Deucher index = offset + 4;
2890fcec570bSAlex Deucher while (blocks > 0) {
2891fcec570bSAlex Deucher id = RBIOS16(index);
2892fcec570bSAlex Deucher index += 2;
2893fcec570bSAlex Deucher switch (id >> 13) {
2894fcec570bSAlex Deucher case 0:
2895fcec570bSAlex Deucher reg = (id & 0x1fff) * 4;
2896fcec570bSAlex Deucher val = RBIOS32(index);
2897fcec570bSAlex Deucher index += 4;
2898fcec570bSAlex Deucher WREG32(reg, val);
2899fcec570bSAlex Deucher break;
2900fcec570bSAlex Deucher case 2:
2901fcec570bSAlex Deucher reg = (id & 0x1fff) * 4;
2902fcec570bSAlex Deucher and_mask = RBIOS32(index);
2903fcec570bSAlex Deucher index += 4;
2904fcec570bSAlex Deucher or_mask = RBIOS32(index);
2905fcec570bSAlex Deucher index += 4;
2906fcec570bSAlex Deucher val = RREG32(reg);
2907fcec570bSAlex Deucher val = (val & and_mask) | or_mask;
2908fcec570bSAlex Deucher WREG32(reg, val);
2909fcec570bSAlex Deucher break;
2910fcec570bSAlex Deucher case 3:
2911fcec570bSAlex Deucher val = RBIOS16(index);
2912fcec570bSAlex Deucher index += 2;
2913fcec570bSAlex Deucher udelay(val);
2914fcec570bSAlex Deucher break;
2915fcec570bSAlex Deucher case 4:
2916fcec570bSAlex Deucher val = RBIOS16(index);
2917fcec570bSAlex Deucher index += 2;
29184de833c3SArnd Bergmann mdelay(val);
2919fcec570bSAlex Deucher break;
2920fcec570bSAlex Deucher case 6:
2921fcec570bSAlex Deucher slave_addr = id & 0xff;
2922fcec570bSAlex Deucher slave_addr >>= 1; /* 7 bit addressing */
2923fcec570bSAlex Deucher index++;
2924fcec570bSAlex Deucher reg = RBIOS8(index);
2925fcec570bSAlex Deucher index++;
2926fcec570bSAlex Deucher val = RBIOS8(index);
2927fcec570bSAlex Deucher index++;
29285a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2929fcec570bSAlex Deucher slave_addr,
2930fcec570bSAlex Deucher reg, val);
2931fcec570bSAlex Deucher break;
2932fcec570bSAlex Deucher default:
2933fcec570bSAlex Deucher DRM_ERROR("Unknown id %d\n", id >> 13);
2934fcec570bSAlex Deucher break;
2935fcec570bSAlex Deucher }
2936fcec570bSAlex Deucher blocks--;
2937fcec570bSAlex Deucher }
2938fcec570bSAlex Deucher return true;
2939fcec570bSAlex Deucher }
2940fcec570bSAlex Deucher }
2941fcec570bSAlex Deucher } else {
2942fcec570bSAlex Deucher offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
2943fcec570bSAlex Deucher if (offset) {
2944fcec570bSAlex Deucher index = offset + 10;
2945fcec570bSAlex Deucher id = RBIOS16(index);
2946fcec570bSAlex Deucher while (id != 0xffff) {
2947fcec570bSAlex Deucher index += 2;
2948fcec570bSAlex Deucher switch (id >> 13) {
2949fcec570bSAlex Deucher case 0:
2950fcec570bSAlex Deucher reg = (id & 0x1fff) * 4;
2951fcec570bSAlex Deucher val = RBIOS32(index);
2952fcec570bSAlex Deucher WREG32(reg, val);
2953fcec570bSAlex Deucher break;
2954fcec570bSAlex Deucher case 2:
2955fcec570bSAlex Deucher reg = (id & 0x1fff) * 4;
2956fcec570bSAlex Deucher and_mask = RBIOS32(index);
2957fcec570bSAlex Deucher index += 4;
2958fcec570bSAlex Deucher or_mask = RBIOS32(index);
2959fcec570bSAlex Deucher index += 4;
2960fcec570bSAlex Deucher val = RREG32(reg);
2961fcec570bSAlex Deucher val = (val & and_mask) | or_mask;
2962fcec570bSAlex Deucher WREG32(reg, val);
2963fcec570bSAlex Deucher break;
2964fcec570bSAlex Deucher case 4:
2965fcec570bSAlex Deucher val = RBIOS16(index);
2966fcec570bSAlex Deucher index += 2;
2967fcec570bSAlex Deucher udelay(val);
2968fcec570bSAlex Deucher break;
2969fcec570bSAlex Deucher case 5:
2970fcec570bSAlex Deucher reg = id & 0x1fff;
2971fcec570bSAlex Deucher and_mask = RBIOS32(index);
2972fcec570bSAlex Deucher index += 4;
2973fcec570bSAlex Deucher or_mask = RBIOS32(index);
2974fcec570bSAlex Deucher index += 4;
2975fcec570bSAlex Deucher val = RREG32_PLL(reg);
2976fcec570bSAlex Deucher val = (val & and_mask) | or_mask;
2977fcec570bSAlex Deucher WREG32_PLL(reg, val);
2978fcec570bSAlex Deucher break;
2979fcec570bSAlex Deucher case 6:
2980fcec570bSAlex Deucher reg = id & 0x1fff;
2981fcec570bSAlex Deucher val = RBIOS8(index);
2982fcec570bSAlex Deucher index += 1;
29835a6f98f5SAlex Deucher radeon_i2c_put_byte(tmds->i2c_bus,
2984fcec570bSAlex Deucher tmds->slave_addr,
2985fcec570bSAlex Deucher reg, val);
2986fcec570bSAlex Deucher break;
2987fcec570bSAlex Deucher default:
2988fcec570bSAlex Deucher DRM_ERROR("Unknown id %d\n", id >> 13);
2989fcec570bSAlex Deucher break;
2990fcec570bSAlex Deucher }
2991fcec570bSAlex Deucher id = RBIOS16(index);
2992fcec570bSAlex Deucher }
2993fcec570bSAlex Deucher return true;
2994fcec570bSAlex Deucher }
2995fcec570bSAlex Deucher }
2996fcec570bSAlex Deucher return false;
2997fcec570bSAlex Deucher }
2998fcec570bSAlex Deucher
combios_parse_mmio_table(struct drm_device * dev,uint16_t offset)2999771fe6b9SJerome Glisse static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
3000771fe6b9SJerome Glisse {
3001771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3002771fe6b9SJerome Glisse
3003771fe6b9SJerome Glisse if (offset) {
3004771fe6b9SJerome Glisse while (RBIOS16(offset)) {
3005771fe6b9SJerome Glisse uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13);
3006771fe6b9SJerome Glisse uint32_t addr = (RBIOS16(offset) & 0x1fff);
3007771fe6b9SJerome Glisse uint32_t val, and_mask, or_mask;
3008771fe6b9SJerome Glisse uint32_t tmp;
3009771fe6b9SJerome Glisse
3010771fe6b9SJerome Glisse offset += 2;
3011771fe6b9SJerome Glisse switch (cmd) {
3012771fe6b9SJerome Glisse case 0:
3013771fe6b9SJerome Glisse val = RBIOS32(offset);
3014771fe6b9SJerome Glisse offset += 4;
3015771fe6b9SJerome Glisse WREG32(addr, val);
3016771fe6b9SJerome Glisse break;
3017771fe6b9SJerome Glisse case 1:
3018771fe6b9SJerome Glisse val = RBIOS32(offset);
3019771fe6b9SJerome Glisse offset += 4;
3020771fe6b9SJerome Glisse WREG32(addr, val);
3021771fe6b9SJerome Glisse break;
3022771fe6b9SJerome Glisse case 2:
3023771fe6b9SJerome Glisse and_mask = RBIOS32(offset);
3024771fe6b9SJerome Glisse offset += 4;
3025771fe6b9SJerome Glisse or_mask = RBIOS32(offset);
3026771fe6b9SJerome Glisse offset += 4;
3027771fe6b9SJerome Glisse tmp = RREG32(addr);
3028771fe6b9SJerome Glisse tmp &= and_mask;
3029771fe6b9SJerome Glisse tmp |= or_mask;
3030771fe6b9SJerome Glisse WREG32(addr, tmp);
3031771fe6b9SJerome Glisse break;
3032771fe6b9SJerome Glisse case 3:
3033771fe6b9SJerome Glisse and_mask = RBIOS32(offset);
3034771fe6b9SJerome Glisse offset += 4;
3035771fe6b9SJerome Glisse or_mask = RBIOS32(offset);
3036771fe6b9SJerome Glisse offset += 4;
3037771fe6b9SJerome Glisse tmp = RREG32(addr);
3038771fe6b9SJerome Glisse tmp &= and_mask;
3039771fe6b9SJerome Glisse tmp |= or_mask;
3040771fe6b9SJerome Glisse WREG32(addr, tmp);
3041771fe6b9SJerome Glisse break;
3042771fe6b9SJerome Glisse case 4:
3043771fe6b9SJerome Glisse val = RBIOS16(offset);
3044771fe6b9SJerome Glisse offset += 2;
3045771fe6b9SJerome Glisse udelay(val);
3046771fe6b9SJerome Glisse break;
3047771fe6b9SJerome Glisse case 5:
3048771fe6b9SJerome Glisse val = RBIOS16(offset);
3049771fe6b9SJerome Glisse offset += 2;
3050771fe6b9SJerome Glisse switch (addr) {
3051771fe6b9SJerome Glisse case 8:
3052771fe6b9SJerome Glisse while (val--) {
3053771fe6b9SJerome Glisse if (!
3054771fe6b9SJerome Glisse (RREG32_PLL
3055771fe6b9SJerome Glisse (RADEON_CLK_PWRMGT_CNTL) &
3056771fe6b9SJerome Glisse RADEON_MC_BUSY))
3057771fe6b9SJerome Glisse break;
3058771fe6b9SJerome Glisse }
3059771fe6b9SJerome Glisse break;
3060771fe6b9SJerome Glisse case 9:
3061771fe6b9SJerome Glisse while (val--) {
3062771fe6b9SJerome Glisse if ((RREG32(RADEON_MC_STATUS) &
3063771fe6b9SJerome Glisse RADEON_MC_IDLE))
3064771fe6b9SJerome Glisse break;
3065771fe6b9SJerome Glisse }
3066771fe6b9SJerome Glisse break;
3067771fe6b9SJerome Glisse default:
3068771fe6b9SJerome Glisse break;
3069771fe6b9SJerome Glisse }
3070771fe6b9SJerome Glisse break;
3071771fe6b9SJerome Glisse default:
3072771fe6b9SJerome Glisse break;
3073771fe6b9SJerome Glisse }
3074771fe6b9SJerome Glisse }
3075771fe6b9SJerome Glisse }
3076771fe6b9SJerome Glisse }
3077771fe6b9SJerome Glisse
combios_parse_pll_table(struct drm_device * dev,uint16_t offset)3078771fe6b9SJerome Glisse static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
3079771fe6b9SJerome Glisse {
3080771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3081771fe6b9SJerome Glisse
3082771fe6b9SJerome Glisse if (offset) {
3083771fe6b9SJerome Glisse while (RBIOS8(offset)) {
3084771fe6b9SJerome Glisse uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6);
3085771fe6b9SJerome Glisse uint8_t addr = (RBIOS8(offset) & 0x3f);
3086771fe6b9SJerome Glisse uint32_t val, shift, tmp;
3087771fe6b9SJerome Glisse uint32_t and_mask, or_mask;
3088771fe6b9SJerome Glisse
3089771fe6b9SJerome Glisse offset++;
3090771fe6b9SJerome Glisse switch (cmd) {
3091771fe6b9SJerome Glisse case 0:
3092771fe6b9SJerome Glisse val = RBIOS32(offset);
3093771fe6b9SJerome Glisse offset += 4;
3094771fe6b9SJerome Glisse WREG32_PLL(addr, val);
3095771fe6b9SJerome Glisse break;
3096771fe6b9SJerome Glisse case 1:
3097771fe6b9SJerome Glisse shift = RBIOS8(offset) * 8;
3098771fe6b9SJerome Glisse offset++;
3099771fe6b9SJerome Glisse and_mask = RBIOS8(offset) << shift;
3100771fe6b9SJerome Glisse and_mask |= ~(0xff << shift);
3101771fe6b9SJerome Glisse offset++;
3102771fe6b9SJerome Glisse or_mask = RBIOS8(offset) << shift;
3103771fe6b9SJerome Glisse offset++;
3104771fe6b9SJerome Glisse tmp = RREG32_PLL(addr);
3105771fe6b9SJerome Glisse tmp &= and_mask;
3106771fe6b9SJerome Glisse tmp |= or_mask;
3107771fe6b9SJerome Glisse WREG32_PLL(addr, tmp);
3108771fe6b9SJerome Glisse break;
3109771fe6b9SJerome Glisse case 2:
3110771fe6b9SJerome Glisse case 3:
3111771fe6b9SJerome Glisse tmp = 1000;
3112771fe6b9SJerome Glisse switch (addr) {
3113771fe6b9SJerome Glisse case 1:
3114771fe6b9SJerome Glisse udelay(150);
3115771fe6b9SJerome Glisse break;
3116771fe6b9SJerome Glisse case 2:
31174de833c3SArnd Bergmann mdelay(1);
3118771fe6b9SJerome Glisse break;
3119771fe6b9SJerome Glisse case 3:
3120771fe6b9SJerome Glisse while (tmp--) {
3121771fe6b9SJerome Glisse if (!
3122771fe6b9SJerome Glisse (RREG32_PLL
3123771fe6b9SJerome Glisse (RADEON_CLK_PWRMGT_CNTL) &
3124771fe6b9SJerome Glisse RADEON_MC_BUSY))
3125771fe6b9SJerome Glisse break;
3126771fe6b9SJerome Glisse }
3127771fe6b9SJerome Glisse break;
3128771fe6b9SJerome Glisse case 4:
3129771fe6b9SJerome Glisse while (tmp--) {
3130771fe6b9SJerome Glisse if (RREG32_PLL
3131771fe6b9SJerome Glisse (RADEON_CLK_PWRMGT_CNTL) &
3132771fe6b9SJerome Glisse RADEON_DLL_READY)
3133771fe6b9SJerome Glisse break;
3134771fe6b9SJerome Glisse }
3135771fe6b9SJerome Glisse break;
3136771fe6b9SJerome Glisse case 5:
3137771fe6b9SJerome Glisse tmp =
3138771fe6b9SJerome Glisse RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
3139771fe6b9SJerome Glisse if (tmp & RADEON_CG_NO1_DEBUG_0) {
3140771fe6b9SJerome Glisse #if 0
3141771fe6b9SJerome Glisse uint32_t mclk_cntl =
3142771fe6b9SJerome Glisse RREG32_PLL
3143771fe6b9SJerome Glisse (RADEON_MCLK_CNTL);
3144771fe6b9SJerome Glisse mclk_cntl &= 0xffff0000;
3145771fe6b9SJerome Glisse /*mclk_cntl |= 0x00001111;*//* ??? */
3146771fe6b9SJerome Glisse WREG32_PLL(RADEON_MCLK_CNTL,
3147771fe6b9SJerome Glisse mclk_cntl);
31484de833c3SArnd Bergmann mdelay(10);
3149771fe6b9SJerome Glisse #endif
3150771fe6b9SJerome Glisse WREG32_PLL
3151771fe6b9SJerome Glisse (RADEON_CLK_PWRMGT_CNTL,
3152771fe6b9SJerome Glisse tmp &
3153771fe6b9SJerome Glisse ~RADEON_CG_NO1_DEBUG_0);
31544de833c3SArnd Bergmann mdelay(10);
3155771fe6b9SJerome Glisse }
3156771fe6b9SJerome Glisse break;
3157771fe6b9SJerome Glisse default:
3158771fe6b9SJerome Glisse break;
3159771fe6b9SJerome Glisse }
3160771fe6b9SJerome Glisse break;
3161771fe6b9SJerome Glisse default:
3162771fe6b9SJerome Glisse break;
3163771fe6b9SJerome Glisse }
3164771fe6b9SJerome Glisse }
3165771fe6b9SJerome Glisse }
3166771fe6b9SJerome Glisse }
3167771fe6b9SJerome Glisse
combios_parse_ram_reset_table(struct drm_device * dev,uint16_t offset)3168771fe6b9SJerome Glisse static void combios_parse_ram_reset_table(struct drm_device *dev,
3169771fe6b9SJerome Glisse uint16_t offset)
3170771fe6b9SJerome Glisse {
3171771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3172771fe6b9SJerome Glisse uint32_t tmp;
3173771fe6b9SJerome Glisse
3174771fe6b9SJerome Glisse if (offset) {
3175771fe6b9SJerome Glisse uint8_t val = RBIOS8(offset);
3176771fe6b9SJerome Glisse while (val != 0xff) {
3177771fe6b9SJerome Glisse offset++;
3178771fe6b9SJerome Glisse
3179771fe6b9SJerome Glisse if (val == 0x0f) {
3180771fe6b9SJerome Glisse uint32_t channel_complete_mask;
3181771fe6b9SJerome Glisse
3182771fe6b9SJerome Glisse if (ASIC_IS_R300(rdev))
3183771fe6b9SJerome Glisse channel_complete_mask =
3184771fe6b9SJerome Glisse R300_MEM_PWRUP_COMPLETE;
3185771fe6b9SJerome Glisse else
3186771fe6b9SJerome Glisse channel_complete_mask =
3187771fe6b9SJerome Glisse RADEON_MEM_PWRUP_COMPLETE;
3188771fe6b9SJerome Glisse tmp = 20000;
3189771fe6b9SJerome Glisse while (tmp--) {
3190771fe6b9SJerome Glisse if ((RREG32(RADEON_MEM_STR_CNTL) &
3191771fe6b9SJerome Glisse channel_complete_mask) ==
3192771fe6b9SJerome Glisse channel_complete_mask)
3193771fe6b9SJerome Glisse break;
3194771fe6b9SJerome Glisse }
3195771fe6b9SJerome Glisse } else {
3196771fe6b9SJerome Glisse uint32_t or_mask = RBIOS16(offset);
3197771fe6b9SJerome Glisse offset += 2;
3198771fe6b9SJerome Glisse
3199771fe6b9SJerome Glisse tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
3200771fe6b9SJerome Glisse tmp &= RADEON_SDRAM_MODE_MASK;
3201771fe6b9SJerome Glisse tmp |= or_mask;
3202771fe6b9SJerome Glisse WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
3203771fe6b9SJerome Glisse
3204771fe6b9SJerome Glisse or_mask = val << 24;
3205771fe6b9SJerome Glisse tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
3206771fe6b9SJerome Glisse tmp &= RADEON_B3MEM_RESET_MASK;
3207771fe6b9SJerome Glisse tmp |= or_mask;
3208771fe6b9SJerome Glisse WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
3209771fe6b9SJerome Glisse }
3210771fe6b9SJerome Glisse val = RBIOS8(offset);
3211771fe6b9SJerome Glisse }
3212771fe6b9SJerome Glisse }
3213771fe6b9SJerome Glisse }
3214771fe6b9SJerome Glisse
combios_detect_ram(struct drm_device * dev,int ram,int mem_addr_mapping)3215771fe6b9SJerome Glisse static uint32_t combios_detect_ram(struct drm_device *dev, int ram,
3216771fe6b9SJerome Glisse int mem_addr_mapping)
3217771fe6b9SJerome Glisse {
3218771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3219771fe6b9SJerome Glisse uint32_t mem_cntl;
3220771fe6b9SJerome Glisse uint32_t mem_size;
3221771fe6b9SJerome Glisse uint32_t addr = 0;
3222771fe6b9SJerome Glisse
3223771fe6b9SJerome Glisse mem_cntl = RREG32(RADEON_MEM_CNTL);
3224771fe6b9SJerome Glisse if (mem_cntl & RV100_HALF_MODE)
3225771fe6b9SJerome Glisse ram /= 2;
3226771fe6b9SJerome Glisse mem_size = ram;
3227771fe6b9SJerome Glisse mem_cntl &= ~(0xff << 8);
3228771fe6b9SJerome Glisse mem_cntl |= (mem_addr_mapping & 0xff) << 8;
3229771fe6b9SJerome Glisse WREG32(RADEON_MEM_CNTL, mem_cntl);
3230771fe6b9SJerome Glisse RREG32(RADEON_MEM_CNTL);
3231771fe6b9SJerome Glisse
3232771fe6b9SJerome Glisse /* sdram reset ? */
3233771fe6b9SJerome Glisse
3234771fe6b9SJerome Glisse /* something like this???? */
3235771fe6b9SJerome Glisse while (ram--) {
3236771fe6b9SJerome Glisse addr = ram * 1024 * 1024;
3237771fe6b9SJerome Glisse /* write to each page */
32382ef9bdfeSDaniel Vetter WREG32_IDX((addr) | RADEON_MM_APER, 0xdeadbeef);
3239771fe6b9SJerome Glisse /* read back and verify */
32402ef9bdfeSDaniel Vetter if (RREG32_IDX((addr) | RADEON_MM_APER) != 0xdeadbeef)
3241771fe6b9SJerome Glisse return 0;
3242771fe6b9SJerome Glisse }
3243771fe6b9SJerome Glisse
3244771fe6b9SJerome Glisse return mem_size;
3245771fe6b9SJerome Glisse }
3246771fe6b9SJerome Glisse
combios_write_ram_size(struct drm_device * dev)3247771fe6b9SJerome Glisse static void combios_write_ram_size(struct drm_device *dev)
3248771fe6b9SJerome Glisse {
3249771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3250771fe6b9SJerome Glisse uint8_t rev;
3251771fe6b9SJerome Glisse uint16_t offset;
3252771fe6b9SJerome Glisse uint32_t mem_size = 0;
3253771fe6b9SJerome Glisse uint32_t mem_cntl = 0;
3254771fe6b9SJerome Glisse
3255771fe6b9SJerome Glisse /* should do something smarter here I guess... */
3256771fe6b9SJerome Glisse if (rdev->flags & RADEON_IS_IGP)
3257771fe6b9SJerome Glisse return;
3258771fe6b9SJerome Glisse
3259771fe6b9SJerome Glisse /* first check detected mem table */
3260771fe6b9SJerome Glisse offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE);
3261771fe6b9SJerome Glisse if (offset) {
3262771fe6b9SJerome Glisse rev = RBIOS8(offset);
3263771fe6b9SJerome Glisse if (rev < 3) {
3264771fe6b9SJerome Glisse mem_cntl = RBIOS32(offset + 1);
3265771fe6b9SJerome Glisse mem_size = RBIOS16(offset + 5);
32664ce9198eSAlex Deucher if ((rdev->family < CHIP_R200) &&
32674ce9198eSAlex Deucher !ASIC_IS_RN50(rdev))
3268771fe6b9SJerome Glisse WREG32(RADEON_MEM_CNTL, mem_cntl);
3269771fe6b9SJerome Glisse }
3270771fe6b9SJerome Glisse }
3271771fe6b9SJerome Glisse
3272771fe6b9SJerome Glisse if (!mem_size) {
3273771fe6b9SJerome Glisse offset =
3274771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
3275771fe6b9SJerome Glisse if (offset) {
3276771fe6b9SJerome Glisse rev = RBIOS8(offset - 1);
3277771fe6b9SJerome Glisse if (rev < 1) {
32784ce9198eSAlex Deucher if ((rdev->family < CHIP_R200)
32794ce9198eSAlex Deucher && !ASIC_IS_RN50(rdev)) {
3280771fe6b9SJerome Glisse int ram = 0;
3281771fe6b9SJerome Glisse int mem_addr_mapping = 0;
3282771fe6b9SJerome Glisse
3283771fe6b9SJerome Glisse while (RBIOS8(offset)) {
3284771fe6b9SJerome Glisse ram = RBIOS8(offset);
3285771fe6b9SJerome Glisse mem_addr_mapping =
3286771fe6b9SJerome Glisse RBIOS8(offset + 1);
3287771fe6b9SJerome Glisse if (mem_addr_mapping != 0x25)
3288771fe6b9SJerome Glisse ram *= 2;
3289771fe6b9SJerome Glisse mem_size =
3290771fe6b9SJerome Glisse combios_detect_ram(dev, ram,
3291771fe6b9SJerome Glisse mem_addr_mapping);
3292771fe6b9SJerome Glisse if (mem_size)
3293771fe6b9SJerome Glisse break;
3294771fe6b9SJerome Glisse offset += 2;
3295771fe6b9SJerome Glisse }
3296771fe6b9SJerome Glisse } else
3297771fe6b9SJerome Glisse mem_size = RBIOS8(offset);
3298771fe6b9SJerome Glisse } else {
3299771fe6b9SJerome Glisse mem_size = RBIOS8(offset);
3300771fe6b9SJerome Glisse mem_size *= 2; /* convert to MB */
3301771fe6b9SJerome Glisse }
3302771fe6b9SJerome Glisse }
3303771fe6b9SJerome Glisse }
3304771fe6b9SJerome Glisse
3305771fe6b9SJerome Glisse mem_size *= (1024 * 1024); /* convert to bytes */
3306771fe6b9SJerome Glisse WREG32(RADEON_CONFIG_MEMSIZE, mem_size);
3307771fe6b9SJerome Glisse }
3308771fe6b9SJerome Glisse
radeon_combios_asic_init(struct drm_device * dev)3309771fe6b9SJerome Glisse void radeon_combios_asic_init(struct drm_device *dev)
3310771fe6b9SJerome Glisse {
3311771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3312771fe6b9SJerome Glisse uint16_t table;
3313771fe6b9SJerome Glisse
3314771fe6b9SJerome Glisse /* port hardcoded mac stuff from radeonfb */
3315771fe6b9SJerome Glisse if (rdev->bios == NULL)
3316771fe6b9SJerome Glisse return;
3317771fe6b9SJerome Glisse
3318771fe6b9SJerome Glisse /* ASIC INIT 1 */
3319771fe6b9SJerome Glisse table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE);
3320771fe6b9SJerome Glisse if (table)
3321771fe6b9SJerome Glisse combios_parse_mmio_table(dev, table);
3322771fe6b9SJerome Glisse
3323771fe6b9SJerome Glisse /* PLL INIT */
3324771fe6b9SJerome Glisse table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE);
3325771fe6b9SJerome Glisse if (table)
3326771fe6b9SJerome Glisse combios_parse_pll_table(dev, table);
3327771fe6b9SJerome Glisse
3328771fe6b9SJerome Glisse /* ASIC INIT 2 */
3329771fe6b9SJerome Glisse table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE);
3330771fe6b9SJerome Glisse if (table)
3331771fe6b9SJerome Glisse combios_parse_mmio_table(dev, table);
3332771fe6b9SJerome Glisse
3333771fe6b9SJerome Glisse if (!(rdev->flags & RADEON_IS_IGP)) {
3334771fe6b9SJerome Glisse /* ASIC INIT 4 */
3335771fe6b9SJerome Glisse table =
3336771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE);
3337771fe6b9SJerome Glisse if (table)
3338771fe6b9SJerome Glisse combios_parse_mmio_table(dev, table);
3339771fe6b9SJerome Glisse
3340771fe6b9SJerome Glisse /* RAM RESET */
3341771fe6b9SJerome Glisse table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE);
3342771fe6b9SJerome Glisse if (table)
3343771fe6b9SJerome Glisse combios_parse_ram_reset_table(dev, table);
3344771fe6b9SJerome Glisse
3345771fe6b9SJerome Glisse /* ASIC INIT 3 */
3346771fe6b9SJerome Glisse table =
3347771fe6b9SJerome Glisse combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE);
3348771fe6b9SJerome Glisse if (table)
3349771fe6b9SJerome Glisse combios_parse_mmio_table(dev, table);
3350771fe6b9SJerome Glisse
3351771fe6b9SJerome Glisse /* write CONFIG_MEMSIZE */
3352771fe6b9SJerome Glisse combios_write_ram_size(dev);
3353771fe6b9SJerome Glisse }
3354771fe6b9SJerome Glisse
3355580b4fffSDave Airlie /* quirk for rs4xx HP nx6125 laptop to make it resume
3356580b4fffSDave Airlie * - it hangs on resume inside the dynclk 1 table.
3357580b4fffSDave Airlie */
3358580b4fffSDave Airlie if (rdev->family == CHIP_RS480 &&
3359580b4fffSDave Airlie rdev->pdev->subsystem_vendor == 0x103c &&
3360580b4fffSDave Airlie rdev->pdev->subsystem_device == 0x308b)
3361580b4fffSDave Airlie return;
3362580b4fffSDave Airlie
336352fa2bbcSAlex Deucher /* quirk for rs4xx HP dv5000 laptop to make it resume
336452fa2bbcSAlex Deucher * - it hangs on resume inside the dynclk 1 table.
336552fa2bbcSAlex Deucher */
336652fa2bbcSAlex Deucher if (rdev->family == CHIP_RS480 &&
336752fa2bbcSAlex Deucher rdev->pdev->subsystem_vendor == 0x103c &&
336852fa2bbcSAlex Deucher rdev->pdev->subsystem_device == 0x30a4)
336952fa2bbcSAlex Deucher return;
337052fa2bbcSAlex Deucher
3371302a8e8bSAlex Deucher /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume
3372302a8e8bSAlex Deucher * - it hangs on resume inside the dynclk 1 table.
3373302a8e8bSAlex Deucher */
3374302a8e8bSAlex Deucher if (rdev->family == CHIP_RS480 &&
3375302a8e8bSAlex Deucher rdev->pdev->subsystem_vendor == 0x103c &&
3376302a8e8bSAlex Deucher rdev->pdev->subsystem_device == 0x30ae)
3377302a8e8bSAlex Deucher return;
3378302a8e8bSAlex Deucher
337909bfda10SJeffery Miller /* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume
338009bfda10SJeffery Miller * - it hangs on resume inside the dynclk 1 table.
338109bfda10SJeffery Miller */
338209bfda10SJeffery Miller if (rdev->family == CHIP_RS480 &&
338309bfda10SJeffery Miller rdev->pdev->subsystem_vendor == 0x103c &&
338409bfda10SJeffery Miller rdev->pdev->subsystem_device == 0x280a)
338509bfda10SJeffery Miller return;
3386acfd6ee4SAlex Deucher /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
3387acfd6ee4SAlex Deucher * - it hangs on resume inside the dynclk 1 table.
3388acfd6ee4SAlex Deucher */
3389acfd6ee4SAlex Deucher if (rdev->family == CHIP_RS400 &&
3390acfd6ee4SAlex Deucher rdev->pdev->subsystem_vendor == 0x1179 &&
3391acfd6ee4SAlex Deucher rdev->pdev->subsystem_device == 0xff31)
3392acfd6ee4SAlex Deucher return;
339309bfda10SJeffery Miller
3394771fe6b9SJerome Glisse /* DYN CLK 1 */
3395771fe6b9SJerome Glisse table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
3396771fe6b9SJerome Glisse if (table)
3397771fe6b9SJerome Glisse combios_parse_pll_table(dev, table);
3398771fe6b9SJerome Glisse
3399771fe6b9SJerome Glisse }
3400771fe6b9SJerome Glisse
radeon_combios_initialize_bios_scratch_regs(struct drm_device * dev)3401771fe6b9SJerome Glisse void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev)
3402771fe6b9SJerome Glisse {
3403771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3404771fe6b9SJerome Glisse uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch;
3405771fe6b9SJerome Glisse
3406771fe6b9SJerome Glisse bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
3407771fe6b9SJerome Glisse bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3408771fe6b9SJerome Glisse bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH);
3409771fe6b9SJerome Glisse
3410771fe6b9SJerome Glisse /* let the bios control the backlight */
3411771fe6b9SJerome Glisse bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
3412771fe6b9SJerome Glisse
3413771fe6b9SJerome Glisse /* tell the bios not to handle mode switching */
3414771fe6b9SJerome Glisse bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
3415771fe6b9SJerome Glisse RADEON_ACC_MODE_CHANGE);
3416771fe6b9SJerome Glisse
3417771fe6b9SJerome Glisse /* tell the bios a driver is loaded */
3418771fe6b9SJerome Glisse bios_7_scratch |= RADEON_DRV_LOADED;
3419771fe6b9SJerome Glisse
3420771fe6b9SJerome Glisse WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
3421771fe6b9SJerome Glisse WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3422771fe6b9SJerome Glisse WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch);
3423771fe6b9SJerome Glisse }
3424771fe6b9SJerome Glisse
radeon_combios_output_lock(struct drm_encoder * encoder,bool lock)3425771fe6b9SJerome Glisse void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock)
3426771fe6b9SJerome Glisse {
3427771fe6b9SJerome Glisse struct drm_device *dev = encoder->dev;
3428771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3429771fe6b9SJerome Glisse uint32_t bios_6_scratch;
3430771fe6b9SJerome Glisse
3431771fe6b9SJerome Glisse bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3432771fe6b9SJerome Glisse
3433771fe6b9SJerome Glisse if (lock)
3434771fe6b9SJerome Glisse bios_6_scratch |= RADEON_DRIVER_CRITICAL;
3435771fe6b9SJerome Glisse else
3436771fe6b9SJerome Glisse bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
3437771fe6b9SJerome Glisse
3438771fe6b9SJerome Glisse WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3439771fe6b9SJerome Glisse }
3440771fe6b9SJerome Glisse
3441771fe6b9SJerome Glisse void
radeon_combios_connected_scratch_regs(struct drm_connector * connector,struct drm_encoder * encoder,bool connected)3442771fe6b9SJerome Glisse radeon_combios_connected_scratch_regs(struct drm_connector *connector,
3443771fe6b9SJerome Glisse struct drm_encoder *encoder,
3444771fe6b9SJerome Glisse bool connected)
3445771fe6b9SJerome Glisse {
3446771fe6b9SJerome Glisse struct drm_device *dev = connector->dev;
3447771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3448771fe6b9SJerome Glisse struct radeon_connector *radeon_connector =
3449771fe6b9SJerome Glisse to_radeon_connector(connector);
3450771fe6b9SJerome Glisse struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3451771fe6b9SJerome Glisse uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH);
3452771fe6b9SJerome Glisse uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
3453771fe6b9SJerome Glisse
3454771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
3455771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
3456771fe6b9SJerome Glisse if (connected) {
3457d9fdaafbSDave Airlie DRM_DEBUG_KMS("TV1 connected\n");
3458771fe6b9SJerome Glisse /* fix me */
3459771fe6b9SJerome Glisse bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
3460771fe6b9SJerome Glisse /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */
3461771fe6b9SJerome Glisse bios_5_scratch |= RADEON_TV1_ON;
3462771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_TV1;
3463771fe6b9SJerome Glisse } else {
3464d9fdaafbSDave Airlie DRM_DEBUG_KMS("TV1 disconnected\n");
3465771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
3466771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_TV1_ON;
3467771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_TV1;
3468771fe6b9SJerome Glisse }
3469771fe6b9SJerome Glisse }
3470771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
3471771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
3472771fe6b9SJerome Glisse if (connected) {
3473d9fdaafbSDave Airlie DRM_DEBUG_KMS("LCD1 connected\n");
3474771fe6b9SJerome Glisse bios_4_scratch |= RADEON_LCD1_ATTACHED;
3475771fe6b9SJerome Glisse bios_5_scratch |= RADEON_LCD1_ON;
3476771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_LCD1;
3477771fe6b9SJerome Glisse } else {
3478d9fdaafbSDave Airlie DRM_DEBUG_KMS("LCD1 disconnected\n");
3479771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
3480771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_LCD1_ON;
3481771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_LCD1;
3482771fe6b9SJerome Glisse }
3483771fe6b9SJerome Glisse }
3484771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
3485771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
3486771fe6b9SJerome Glisse if (connected) {
3487d9fdaafbSDave Airlie DRM_DEBUG_KMS("CRT1 connected\n");
3488771fe6b9SJerome Glisse bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
3489771fe6b9SJerome Glisse bios_5_scratch |= RADEON_CRT1_ON;
3490771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_CRT1;
3491771fe6b9SJerome Glisse } else {
3492d9fdaafbSDave Airlie DRM_DEBUG_KMS("CRT1 disconnected\n");
3493771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
3494771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_CRT1_ON;
3495771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_CRT1;
3496771fe6b9SJerome Glisse }
3497771fe6b9SJerome Glisse }
3498771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
3499771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
3500771fe6b9SJerome Glisse if (connected) {
3501d9fdaafbSDave Airlie DRM_DEBUG_KMS("CRT2 connected\n");
3502771fe6b9SJerome Glisse bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
3503771fe6b9SJerome Glisse bios_5_scratch |= RADEON_CRT2_ON;
3504771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_CRT2;
3505771fe6b9SJerome Glisse } else {
3506d9fdaafbSDave Airlie DRM_DEBUG_KMS("CRT2 disconnected\n");
3507771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
3508771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_CRT2_ON;
3509771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_CRT2;
3510771fe6b9SJerome Glisse }
3511771fe6b9SJerome Glisse }
3512771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
3513771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
3514771fe6b9SJerome Glisse if (connected) {
3515d9fdaafbSDave Airlie DRM_DEBUG_KMS("DFP1 connected\n");
3516771fe6b9SJerome Glisse bios_4_scratch |= RADEON_DFP1_ATTACHED;
3517771fe6b9SJerome Glisse bios_5_scratch |= RADEON_DFP1_ON;
3518771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_DFP1;
3519771fe6b9SJerome Glisse } else {
3520d9fdaafbSDave Airlie DRM_DEBUG_KMS("DFP1 disconnected\n");
3521771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
3522771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_DFP1_ON;
3523771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_DFP1;
3524771fe6b9SJerome Glisse }
3525771fe6b9SJerome Glisse }
3526771fe6b9SJerome Glisse if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
3527771fe6b9SJerome Glisse (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
3528771fe6b9SJerome Glisse if (connected) {
3529d9fdaafbSDave Airlie DRM_DEBUG_KMS("DFP2 connected\n");
3530771fe6b9SJerome Glisse bios_4_scratch |= RADEON_DFP2_ATTACHED;
3531771fe6b9SJerome Glisse bios_5_scratch |= RADEON_DFP2_ON;
3532771fe6b9SJerome Glisse bios_5_scratch |= RADEON_ACC_REQ_DFP2;
3533771fe6b9SJerome Glisse } else {
3534d9fdaafbSDave Airlie DRM_DEBUG_KMS("DFP2 disconnected\n");
3535771fe6b9SJerome Glisse bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
3536771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_DFP2_ON;
3537771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_ACC_REQ_DFP2;
3538771fe6b9SJerome Glisse }
3539771fe6b9SJerome Glisse }
3540771fe6b9SJerome Glisse WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch);
3541771fe6b9SJerome Glisse WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
3542771fe6b9SJerome Glisse }
3543771fe6b9SJerome Glisse
3544771fe6b9SJerome Glisse void
radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder * encoder,int crtc)3545771fe6b9SJerome Glisse radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
3546771fe6b9SJerome Glisse {
3547771fe6b9SJerome Glisse struct drm_device *dev = encoder->dev;
3548771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3549771fe6b9SJerome Glisse struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3550771fe6b9SJerome Glisse uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
3551771fe6b9SJerome Glisse
3552771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
3553771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
3554771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT);
3555771fe6b9SJerome Glisse }
3556771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
3557771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
3558771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT);
3559771fe6b9SJerome Glisse }
3560771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
3561771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
3562771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT);
3563771fe6b9SJerome Glisse }
3564771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
3565771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
3566771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT);
3567771fe6b9SJerome Glisse }
3568771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
3569771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
3570771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT);
3571771fe6b9SJerome Glisse }
3572771fe6b9SJerome Glisse if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
3573771fe6b9SJerome Glisse bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
3574771fe6b9SJerome Glisse bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT);
3575771fe6b9SJerome Glisse }
3576771fe6b9SJerome Glisse WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
3577771fe6b9SJerome Glisse }
3578771fe6b9SJerome Glisse
3579771fe6b9SJerome Glisse void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder * encoder,bool on)3580771fe6b9SJerome Glisse radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
3581771fe6b9SJerome Glisse {
3582771fe6b9SJerome Glisse struct drm_device *dev = encoder->dev;
3583771fe6b9SJerome Glisse struct radeon_device *rdev = dev->dev_private;
3584771fe6b9SJerome Glisse struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3585771fe6b9SJerome Glisse uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3586771fe6b9SJerome Glisse
3587771fe6b9SJerome Glisse if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
3588771fe6b9SJerome Glisse if (on)
3589771fe6b9SJerome Glisse bios_6_scratch |= RADEON_TV_DPMS_ON;
3590771fe6b9SJerome Glisse else
3591771fe6b9SJerome Glisse bios_6_scratch &= ~RADEON_TV_DPMS_ON;
3592771fe6b9SJerome Glisse }
3593771fe6b9SJerome Glisse if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
3594771fe6b9SJerome Glisse if (on)
3595771fe6b9SJerome Glisse bios_6_scratch |= RADEON_CRT_DPMS_ON;
3596771fe6b9SJerome Glisse else
3597771fe6b9SJerome Glisse bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
3598771fe6b9SJerome Glisse }
3599771fe6b9SJerome Glisse if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
3600771fe6b9SJerome Glisse if (on)
3601771fe6b9SJerome Glisse bios_6_scratch |= RADEON_LCD_DPMS_ON;
3602771fe6b9SJerome Glisse else
3603771fe6b9SJerome Glisse bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
3604771fe6b9SJerome Glisse }
3605771fe6b9SJerome Glisse if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
3606771fe6b9SJerome Glisse if (on)
3607771fe6b9SJerome Glisse bios_6_scratch |= RADEON_DFP_DPMS_ON;
3608771fe6b9SJerome Glisse else
3609771fe6b9SJerome Glisse bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
3610771fe6b9SJerome Glisse }
3611771fe6b9SJerome Glisse WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3612771fe6b9SJerome Glisse }
3613