1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot * Copyright 2004 ATI Technologies Inc., Markham, Ontario
3926deccbSFrançois Tigeot * Copyright 2007-8 Advanced Micro Devices, Inc.
4926deccbSFrançois Tigeot * Copyright 2008 Red Hat Inc.
5926deccbSFrançois Tigeot *
6926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
7926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
8926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation
9926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
11926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
12926deccbSFrançois Tigeot *
13926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in
14926deccbSFrançois Tigeot * all copies or substantial portions of the Software.
15926deccbSFrançois Tigeot *
16926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE.
23926deccbSFrançois Tigeot *
24926deccbSFrançois Tigeot * Authors: Dave Airlie
25926deccbSFrançois Tigeot * Alex Deucher
26926deccbSFrançois Tigeot */
27926deccbSFrançois Tigeot #include <drm/drmP.h>
2883b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h>
29926deccbSFrançois Tigeot #include "radeon.h"
30926deccbSFrançois Tigeot #include "atom.h"
31926deccbSFrançois Tigeot
32926deccbSFrançois Tigeot #ifdef CONFIG_PPC_PMAC
33926deccbSFrançois Tigeot /* not sure which of these are needed */
34926deccbSFrançois Tigeot #include <asm/machdep.h>
35926deccbSFrançois Tigeot #include <asm/pmac_feature.h>
36926deccbSFrançois Tigeot #include <asm/prom.h>
37926deccbSFrançois Tigeot #endif /* CONFIG_PPC_PMAC */
38926deccbSFrançois Tigeot
39926deccbSFrançois Tigeot /* old legacy ATI BIOS routines */
40926deccbSFrançois Tigeot
41926deccbSFrançois Tigeot /* COMBIOS table offsets */
42926deccbSFrançois Tigeot enum radeon_combios_table_offset {
43926deccbSFrançois Tigeot /* absolute offset tables */
44926deccbSFrançois Tigeot COMBIOS_ASIC_INIT_1_TABLE,
45926deccbSFrançois Tigeot COMBIOS_BIOS_SUPPORT_TABLE,
46926deccbSFrançois Tigeot COMBIOS_DAC_PROGRAMMING_TABLE,
47926deccbSFrançois Tigeot COMBIOS_MAX_COLOR_DEPTH_TABLE,
48926deccbSFrançois Tigeot COMBIOS_CRTC_INFO_TABLE,
49926deccbSFrançois Tigeot COMBIOS_PLL_INFO_TABLE,
50926deccbSFrançois Tigeot COMBIOS_TV_INFO_TABLE,
51926deccbSFrançois Tigeot COMBIOS_DFP_INFO_TABLE,
52926deccbSFrançois Tigeot COMBIOS_HW_CONFIG_INFO_TABLE,
53926deccbSFrançois Tigeot COMBIOS_MULTIMEDIA_INFO_TABLE,
54926deccbSFrançois Tigeot COMBIOS_TV_STD_PATCH_TABLE,
55926deccbSFrançois Tigeot COMBIOS_LCD_INFO_TABLE,
56926deccbSFrançois Tigeot COMBIOS_MOBILE_INFO_TABLE,
57926deccbSFrançois Tigeot COMBIOS_PLL_INIT_TABLE,
58926deccbSFrançois Tigeot COMBIOS_MEM_CONFIG_TABLE,
59926deccbSFrançois Tigeot COMBIOS_SAVE_MASK_TABLE,
60926deccbSFrançois Tigeot COMBIOS_HARDCODED_EDID_TABLE,
61926deccbSFrançois Tigeot COMBIOS_ASIC_INIT_2_TABLE,
62926deccbSFrançois Tigeot COMBIOS_CONNECTOR_INFO_TABLE,
63926deccbSFrançois Tigeot COMBIOS_DYN_CLK_1_TABLE,
64926deccbSFrançois Tigeot COMBIOS_RESERVED_MEM_TABLE,
65926deccbSFrançois Tigeot COMBIOS_EXT_TMDS_INFO_TABLE,
66926deccbSFrançois Tigeot COMBIOS_MEM_CLK_INFO_TABLE,
67926deccbSFrançois Tigeot COMBIOS_EXT_DAC_INFO_TABLE,
68926deccbSFrançois Tigeot COMBIOS_MISC_INFO_TABLE,
69926deccbSFrançois Tigeot COMBIOS_CRT_INFO_TABLE,
70926deccbSFrançois Tigeot COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
71926deccbSFrançois Tigeot COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
72926deccbSFrançois Tigeot COMBIOS_FAN_SPEED_INFO_TABLE,
73926deccbSFrançois Tigeot COMBIOS_OVERDRIVE_INFO_TABLE,
74926deccbSFrançois Tigeot COMBIOS_OEM_INFO_TABLE,
75926deccbSFrançois Tigeot COMBIOS_DYN_CLK_2_TABLE,
76926deccbSFrançois Tigeot COMBIOS_POWER_CONNECTOR_INFO_TABLE,
77926deccbSFrançois Tigeot COMBIOS_I2C_INFO_TABLE,
78926deccbSFrançois Tigeot /* relative offset tables */
79926deccbSFrançois Tigeot COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */
80926deccbSFrançois Tigeot COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */
81926deccbSFrançois Tigeot COMBIOS_DETECTED_MEM_TABLE, /* offset from misc info */
82926deccbSFrançois Tigeot COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */
83926deccbSFrançois Tigeot COMBIOS_RAM_RESET_TABLE, /* offset from mem config */
84926deccbSFrançois Tigeot COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */
85926deccbSFrançois Tigeot COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */
86926deccbSFrançois Tigeot COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */
87926deccbSFrançois Tigeot COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */
88926deccbSFrançois Tigeot COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */
89926deccbSFrançois Tigeot COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */
90926deccbSFrançois Tigeot };
91926deccbSFrançois Tigeot
92926deccbSFrançois Tigeot enum radeon_combios_ddc {
93926deccbSFrançois Tigeot DDC_NONE_DETECTED,
94926deccbSFrançois Tigeot DDC_MONID,
95926deccbSFrançois Tigeot DDC_DVI,
96926deccbSFrançois Tigeot DDC_VGA,
97926deccbSFrançois Tigeot DDC_CRT2,
98926deccbSFrançois Tigeot DDC_LCD,
99926deccbSFrançois Tigeot DDC_GPIO,
100926deccbSFrançois Tigeot };
101926deccbSFrançois Tigeot
102926deccbSFrançois Tigeot enum radeon_combios_connector {
103926deccbSFrançois Tigeot CONNECTOR_NONE_LEGACY,
104926deccbSFrançois Tigeot CONNECTOR_PROPRIETARY_LEGACY,
105926deccbSFrançois Tigeot CONNECTOR_CRT_LEGACY,
106926deccbSFrançois Tigeot CONNECTOR_DVI_I_LEGACY,
107926deccbSFrançois Tigeot CONNECTOR_DVI_D_LEGACY,
108926deccbSFrançois Tigeot CONNECTOR_CTV_LEGACY,
109926deccbSFrançois Tigeot CONNECTOR_STV_LEGACY,
110926deccbSFrançois Tigeot CONNECTOR_UNSUPPORTED_LEGACY
111926deccbSFrançois Tigeot };
112926deccbSFrançois Tigeot
113591d5043SFrançois Tigeot static const int legacy_connector_convert[] = {
114926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_Unknown,
115926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVID,
116926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA,
117926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII,
118926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVID,
119926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_Composite,
120926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
121926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_Unknown,
122926deccbSFrançois Tigeot };
123926deccbSFrançois Tigeot
combios_get_table_offset(struct drm_device * dev,enum radeon_combios_table_offset table)124926deccbSFrançois Tigeot static uint16_t combios_get_table_offset(struct drm_device *dev,
125926deccbSFrançois Tigeot enum radeon_combios_table_offset table)
126926deccbSFrançois Tigeot {
127926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
12857e252bfSMichael Neumann int rev, size;
129926deccbSFrançois Tigeot uint16_t offset = 0, check_offset;
130926deccbSFrançois Tigeot
131926deccbSFrançois Tigeot if (!rdev->bios)
132926deccbSFrançois Tigeot return 0;
133926deccbSFrançois Tigeot
134926deccbSFrançois Tigeot switch (table) {
135926deccbSFrançois Tigeot /* absolute offset tables */
136926deccbSFrançois Tigeot case COMBIOS_ASIC_INIT_1_TABLE:
13757e252bfSMichael Neumann check_offset = 0xc;
138926deccbSFrançois Tigeot break;
139926deccbSFrançois Tigeot case COMBIOS_BIOS_SUPPORT_TABLE:
14057e252bfSMichael Neumann check_offset = 0x14;
141926deccbSFrançois Tigeot break;
142926deccbSFrançois Tigeot case COMBIOS_DAC_PROGRAMMING_TABLE:
14357e252bfSMichael Neumann check_offset = 0x2a;
144926deccbSFrançois Tigeot break;
145926deccbSFrançois Tigeot case COMBIOS_MAX_COLOR_DEPTH_TABLE:
14657e252bfSMichael Neumann check_offset = 0x2c;
147926deccbSFrançois Tigeot break;
148926deccbSFrançois Tigeot case COMBIOS_CRTC_INFO_TABLE:
14957e252bfSMichael Neumann check_offset = 0x2e;
150926deccbSFrançois Tigeot break;
151926deccbSFrançois Tigeot case COMBIOS_PLL_INFO_TABLE:
15257e252bfSMichael Neumann check_offset = 0x30;
153926deccbSFrançois Tigeot break;
154926deccbSFrançois Tigeot case COMBIOS_TV_INFO_TABLE:
15557e252bfSMichael Neumann check_offset = 0x32;
156926deccbSFrançois Tigeot break;
157926deccbSFrançois Tigeot case COMBIOS_DFP_INFO_TABLE:
15857e252bfSMichael Neumann check_offset = 0x34;
159926deccbSFrançois Tigeot break;
160926deccbSFrançois Tigeot case COMBIOS_HW_CONFIG_INFO_TABLE:
16157e252bfSMichael Neumann check_offset = 0x36;
162926deccbSFrançois Tigeot break;
163926deccbSFrançois Tigeot case COMBIOS_MULTIMEDIA_INFO_TABLE:
16457e252bfSMichael Neumann check_offset = 0x38;
165926deccbSFrançois Tigeot break;
166926deccbSFrançois Tigeot case COMBIOS_TV_STD_PATCH_TABLE:
16757e252bfSMichael Neumann check_offset = 0x3e;
168926deccbSFrançois Tigeot break;
169926deccbSFrançois Tigeot case COMBIOS_LCD_INFO_TABLE:
17057e252bfSMichael Neumann check_offset = 0x40;
171926deccbSFrançois Tigeot break;
172926deccbSFrançois Tigeot case COMBIOS_MOBILE_INFO_TABLE:
17357e252bfSMichael Neumann check_offset = 0x42;
174926deccbSFrançois Tigeot break;
175926deccbSFrançois Tigeot case COMBIOS_PLL_INIT_TABLE:
17657e252bfSMichael Neumann check_offset = 0x46;
177926deccbSFrançois Tigeot break;
178926deccbSFrançois Tigeot case COMBIOS_MEM_CONFIG_TABLE:
17957e252bfSMichael Neumann check_offset = 0x48;
180926deccbSFrançois Tigeot break;
181926deccbSFrançois Tigeot case COMBIOS_SAVE_MASK_TABLE:
18257e252bfSMichael Neumann check_offset = 0x4a;
183926deccbSFrançois Tigeot break;
184926deccbSFrançois Tigeot case COMBIOS_HARDCODED_EDID_TABLE:
18557e252bfSMichael Neumann check_offset = 0x4c;
186926deccbSFrançois Tigeot break;
187926deccbSFrançois Tigeot case COMBIOS_ASIC_INIT_2_TABLE:
18857e252bfSMichael Neumann check_offset = 0x4e;
189926deccbSFrançois Tigeot break;
190926deccbSFrançois Tigeot case COMBIOS_CONNECTOR_INFO_TABLE:
19157e252bfSMichael Neumann check_offset = 0x50;
192926deccbSFrançois Tigeot break;
193926deccbSFrançois Tigeot case COMBIOS_DYN_CLK_1_TABLE:
19457e252bfSMichael Neumann check_offset = 0x52;
195926deccbSFrançois Tigeot break;
196926deccbSFrançois Tigeot case COMBIOS_RESERVED_MEM_TABLE:
19757e252bfSMichael Neumann check_offset = 0x54;
198926deccbSFrançois Tigeot break;
199926deccbSFrançois Tigeot case COMBIOS_EXT_TMDS_INFO_TABLE:
20057e252bfSMichael Neumann check_offset = 0x58;
201926deccbSFrançois Tigeot break;
202926deccbSFrançois Tigeot case COMBIOS_MEM_CLK_INFO_TABLE:
20357e252bfSMichael Neumann check_offset = 0x5a;
204926deccbSFrançois Tigeot break;
205926deccbSFrançois Tigeot case COMBIOS_EXT_DAC_INFO_TABLE:
20657e252bfSMichael Neumann check_offset = 0x5c;
207926deccbSFrançois Tigeot break;
208926deccbSFrançois Tigeot case COMBIOS_MISC_INFO_TABLE:
20957e252bfSMichael Neumann check_offset = 0x5e;
210926deccbSFrançois Tigeot break;
211926deccbSFrançois Tigeot case COMBIOS_CRT_INFO_TABLE:
21257e252bfSMichael Neumann check_offset = 0x60;
213926deccbSFrançois Tigeot break;
214926deccbSFrançois Tigeot case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
21557e252bfSMichael Neumann check_offset = 0x62;
216926deccbSFrançois Tigeot break;
217926deccbSFrançois Tigeot case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
21857e252bfSMichael Neumann check_offset = 0x64;
219926deccbSFrançois Tigeot break;
220926deccbSFrançois Tigeot case COMBIOS_FAN_SPEED_INFO_TABLE:
22157e252bfSMichael Neumann check_offset = 0x66;
222926deccbSFrançois Tigeot break;
223926deccbSFrançois Tigeot case COMBIOS_OVERDRIVE_INFO_TABLE:
22457e252bfSMichael Neumann check_offset = 0x68;
225926deccbSFrançois Tigeot break;
226926deccbSFrançois Tigeot case COMBIOS_OEM_INFO_TABLE:
22757e252bfSMichael Neumann check_offset = 0x6a;
228926deccbSFrançois Tigeot break;
229926deccbSFrançois Tigeot case COMBIOS_DYN_CLK_2_TABLE:
23057e252bfSMichael Neumann check_offset = 0x6c;
231926deccbSFrançois Tigeot break;
232926deccbSFrançois Tigeot case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
23357e252bfSMichael Neumann check_offset = 0x6e;
234926deccbSFrançois Tigeot break;
235926deccbSFrançois Tigeot case COMBIOS_I2C_INFO_TABLE:
23657e252bfSMichael Neumann check_offset = 0x70;
237926deccbSFrançois Tigeot break;
238926deccbSFrançois Tigeot /* relative offset tables */
239926deccbSFrançois Tigeot case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */
240926deccbSFrançois Tigeot check_offset =
241926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
242926deccbSFrançois Tigeot if (check_offset) {
243926deccbSFrançois Tigeot rev = RBIOS8(check_offset);
244926deccbSFrançois Tigeot if (rev > 0) {
245926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x3);
246926deccbSFrançois Tigeot if (check_offset)
247926deccbSFrançois Tigeot offset = check_offset;
248926deccbSFrançois Tigeot }
249926deccbSFrançois Tigeot }
250926deccbSFrançois Tigeot break;
251926deccbSFrançois Tigeot case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */
252926deccbSFrançois Tigeot check_offset =
253926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
254926deccbSFrançois Tigeot if (check_offset) {
255926deccbSFrançois Tigeot rev = RBIOS8(check_offset);
256926deccbSFrançois Tigeot if (rev > 0) {
257926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x5);
258926deccbSFrançois Tigeot if (check_offset)
259926deccbSFrançois Tigeot offset = check_offset;
260926deccbSFrançois Tigeot }
261926deccbSFrançois Tigeot }
262926deccbSFrançois Tigeot break;
263926deccbSFrançois Tigeot case COMBIOS_DETECTED_MEM_TABLE: /* offset from misc info */
264926deccbSFrançois Tigeot check_offset =
265926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
266926deccbSFrançois Tigeot if (check_offset) {
267926deccbSFrançois Tigeot rev = RBIOS8(check_offset);
268926deccbSFrançois Tigeot if (rev > 0) {
269926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x7);
270926deccbSFrançois Tigeot if (check_offset)
271926deccbSFrançois Tigeot offset = check_offset;
272926deccbSFrançois Tigeot }
273926deccbSFrançois Tigeot }
274926deccbSFrançois Tigeot break;
275926deccbSFrançois Tigeot case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */
276926deccbSFrançois Tigeot check_offset =
277926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
278926deccbSFrançois Tigeot if (check_offset) {
279926deccbSFrançois Tigeot rev = RBIOS8(check_offset);
280926deccbSFrançois Tigeot if (rev == 2) {
281926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x9);
282926deccbSFrançois Tigeot if (check_offset)
283926deccbSFrançois Tigeot offset = check_offset;
284926deccbSFrançois Tigeot }
285926deccbSFrançois Tigeot }
286926deccbSFrançois Tigeot break;
287926deccbSFrançois Tigeot case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */
288926deccbSFrançois Tigeot check_offset =
289926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
290926deccbSFrançois Tigeot if (check_offset) {
291926deccbSFrançois Tigeot while (RBIOS8(check_offset++));
292926deccbSFrançois Tigeot check_offset += 2;
293926deccbSFrançois Tigeot if (check_offset)
294926deccbSFrançois Tigeot offset = check_offset;
295926deccbSFrançois Tigeot }
296926deccbSFrançois Tigeot break;
297926deccbSFrançois Tigeot case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */
298926deccbSFrançois Tigeot check_offset =
299926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
300926deccbSFrançois Tigeot if (check_offset) {
301926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x11);
302926deccbSFrançois Tigeot if (check_offset)
303926deccbSFrançois Tigeot offset = check_offset;
304926deccbSFrançois Tigeot }
305926deccbSFrançois Tigeot break;
306926deccbSFrançois Tigeot case COMBIOS_GPIO_INFO_TABLE: /* offset from mobile info */
307926deccbSFrançois Tigeot check_offset =
308926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
309926deccbSFrançois Tigeot if (check_offset) {
310926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x13);
311926deccbSFrançois Tigeot if (check_offset)
312926deccbSFrançois Tigeot offset = check_offset;
313926deccbSFrançois Tigeot }
314926deccbSFrançois Tigeot break;
315926deccbSFrançois Tigeot case COMBIOS_LCD_DDC_INFO_TABLE: /* offset from mobile info */
316926deccbSFrançois Tigeot check_offset =
317926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
318926deccbSFrançois Tigeot if (check_offset) {
319926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x15);
320926deccbSFrançois Tigeot if (check_offset)
321926deccbSFrançois Tigeot offset = check_offset;
322926deccbSFrançois Tigeot }
323926deccbSFrançois Tigeot break;
324926deccbSFrançois Tigeot case COMBIOS_TMDS_POWER_TABLE: /* offset from mobile info */
325926deccbSFrançois Tigeot check_offset =
326926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
327926deccbSFrançois Tigeot if (check_offset) {
328926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x17);
329926deccbSFrançois Tigeot if (check_offset)
330926deccbSFrançois Tigeot offset = check_offset;
331926deccbSFrançois Tigeot }
332926deccbSFrançois Tigeot break;
333926deccbSFrançois Tigeot case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */
334926deccbSFrançois Tigeot check_offset =
335926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
336926deccbSFrançois Tigeot if (check_offset) {
337926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x2);
338926deccbSFrançois Tigeot if (check_offset)
339926deccbSFrançois Tigeot offset = check_offset;
340926deccbSFrançois Tigeot }
341926deccbSFrançois Tigeot break;
342926deccbSFrançois Tigeot case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */
343926deccbSFrançois Tigeot check_offset =
344926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
345926deccbSFrançois Tigeot if (check_offset) {
346926deccbSFrançois Tigeot check_offset = RBIOS16(check_offset + 0x4);
347926deccbSFrançois Tigeot if (check_offset)
348926deccbSFrançois Tigeot offset = check_offset;
349926deccbSFrançois Tigeot }
350926deccbSFrançois Tigeot break;
351926deccbSFrançois Tigeot default:
35257e252bfSMichael Neumann check_offset = 0;
353926deccbSFrançois Tigeot break;
354926deccbSFrançois Tigeot }
355926deccbSFrançois Tigeot
35657e252bfSMichael Neumann size = RBIOS8(rdev->bios_header_start + 0x6);
35757e252bfSMichael Neumann /* check absolute offset tables */
35857e252bfSMichael Neumann if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size)
35957e252bfSMichael Neumann offset = RBIOS16(rdev->bios_header_start + check_offset);
360926deccbSFrançois Tigeot
36157e252bfSMichael Neumann return offset;
362926deccbSFrançois Tigeot }
363926deccbSFrançois Tigeot
radeon_combios_check_hardcoded_edid(struct radeon_device * rdev)364926deccbSFrançois Tigeot bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
365926deccbSFrançois Tigeot {
366926deccbSFrançois Tigeot int edid_info, size;
367926deccbSFrançois Tigeot struct edid *edid;
368926deccbSFrançois Tigeot unsigned char *raw;
369926deccbSFrançois Tigeot edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
370926deccbSFrançois Tigeot if (!edid_info)
371926deccbSFrançois Tigeot return false;
372926deccbSFrançois Tigeot
373926deccbSFrançois Tigeot raw = rdev->bios + edid_info;
374926deccbSFrançois Tigeot size = EDID_LENGTH * (raw[0x7e] + 1);
3755a3b77d5SFrançois Tigeot edid = kmalloc(size, M_DRM, M_WAITOK);
376926deccbSFrançois Tigeot if (edid == NULL)
377926deccbSFrançois Tigeot return false;
378926deccbSFrançois Tigeot
379926deccbSFrançois Tigeot memcpy((unsigned char *)edid, raw, size);
380926deccbSFrançois Tigeot
381926deccbSFrançois Tigeot if (!drm_edid_is_valid(edid)) {
382c4ef309bSzrj kfree(edid);
383926deccbSFrançois Tigeot return false;
384926deccbSFrançois Tigeot }
385926deccbSFrançois Tigeot
386926deccbSFrançois Tigeot rdev->mode_info.bios_hardcoded_edid = edid;
387926deccbSFrançois Tigeot rdev->mode_info.bios_hardcoded_edid_size = size;
388926deccbSFrançois Tigeot return true;
389926deccbSFrançois Tigeot }
390926deccbSFrançois Tigeot
391926deccbSFrançois Tigeot /* this is used for atom LCDs as well */
392926deccbSFrançois Tigeot struct edid *
radeon_bios_get_hardcoded_edid(struct radeon_device * rdev)393926deccbSFrançois Tigeot radeon_bios_get_hardcoded_edid(struct radeon_device *rdev)
394926deccbSFrançois Tigeot {
395926deccbSFrançois Tigeot struct edid *edid;
396926deccbSFrançois Tigeot
397926deccbSFrançois Tigeot if (rdev->mode_info.bios_hardcoded_edid) {
398926deccbSFrançois Tigeot edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size,
3995a3b77d5SFrançois Tigeot M_DRM, M_WAITOK);
400926deccbSFrançois Tigeot if (edid) {
401926deccbSFrançois Tigeot memcpy((unsigned char *)edid,
402926deccbSFrançois Tigeot (unsigned char *)rdev->mode_info.bios_hardcoded_edid,
403926deccbSFrançois Tigeot rdev->mode_info.bios_hardcoded_edid_size);
404926deccbSFrançois Tigeot return edid;
405926deccbSFrançois Tigeot }
406926deccbSFrançois Tigeot }
407926deccbSFrançois Tigeot return NULL;
408926deccbSFrançois Tigeot }
409926deccbSFrançois Tigeot
combios_setup_i2c_bus(struct radeon_device * rdev,enum radeon_combios_ddc ddc,u32 clk_mask,u32 data_mask)410926deccbSFrançois Tigeot static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
411926deccbSFrançois Tigeot enum radeon_combios_ddc ddc,
412926deccbSFrançois Tigeot u32 clk_mask,
413926deccbSFrançois Tigeot u32 data_mask)
414926deccbSFrançois Tigeot {
415926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c;
416926deccbSFrançois Tigeot int ddc_line = 0;
417926deccbSFrançois Tigeot
418926deccbSFrançois Tigeot /* ddc id = mask reg
419926deccbSFrançois Tigeot * DDC_NONE_DETECTED = none
420926deccbSFrançois Tigeot * DDC_DVI = RADEON_GPIO_DVI_DDC
421926deccbSFrançois Tigeot * DDC_VGA = RADEON_GPIO_VGA_DDC
422926deccbSFrançois Tigeot * DDC_LCD = RADEON_GPIOPAD_MASK
423926deccbSFrançois Tigeot * DDC_GPIO = RADEON_MDGPIO_MASK
424926deccbSFrançois Tigeot * r1xx
425926deccbSFrançois Tigeot * DDC_MONID = RADEON_GPIO_MONID
426926deccbSFrançois Tigeot * DDC_CRT2 = RADEON_GPIO_CRT2_DDC
427926deccbSFrançois Tigeot * r200
428926deccbSFrançois Tigeot * DDC_MONID = RADEON_GPIO_MONID
429926deccbSFrançois Tigeot * DDC_CRT2 = RADEON_GPIO_DVI_DDC
430926deccbSFrançois Tigeot * r300/r350
431926deccbSFrançois Tigeot * DDC_MONID = RADEON_GPIO_DVI_DDC
432926deccbSFrançois Tigeot * DDC_CRT2 = RADEON_GPIO_DVI_DDC
433926deccbSFrançois Tigeot * rv2xx/rv3xx
434926deccbSFrançois Tigeot * DDC_MONID = RADEON_GPIO_MONID
435926deccbSFrançois Tigeot * DDC_CRT2 = RADEON_GPIO_MONID
436926deccbSFrançois Tigeot * rs3xx/rs4xx
437926deccbSFrançois Tigeot * DDC_MONID = RADEON_GPIOPAD_MASK
438926deccbSFrançois Tigeot * DDC_CRT2 = RADEON_GPIO_MONID
439926deccbSFrançois Tigeot */
440926deccbSFrançois Tigeot switch (ddc) {
441926deccbSFrançois Tigeot case DDC_NONE_DETECTED:
442926deccbSFrançois Tigeot default:
443926deccbSFrançois Tigeot ddc_line = 0;
444926deccbSFrançois Tigeot break;
445926deccbSFrançois Tigeot case DDC_DVI:
446926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_DVI_DDC;
447926deccbSFrançois Tigeot break;
448926deccbSFrançois Tigeot case DDC_VGA:
449926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_VGA_DDC;
450926deccbSFrançois Tigeot break;
451926deccbSFrançois Tigeot case DDC_LCD:
452926deccbSFrançois Tigeot ddc_line = RADEON_GPIOPAD_MASK;
453926deccbSFrançois Tigeot break;
454926deccbSFrançois Tigeot case DDC_GPIO:
455926deccbSFrançois Tigeot ddc_line = RADEON_MDGPIO_MASK;
456926deccbSFrançois Tigeot break;
457926deccbSFrançois Tigeot case DDC_MONID:
458926deccbSFrançois Tigeot if (rdev->family == CHIP_RS300 ||
459926deccbSFrançois Tigeot rdev->family == CHIP_RS400 ||
460926deccbSFrançois Tigeot rdev->family == CHIP_RS480)
461926deccbSFrançois Tigeot ddc_line = RADEON_GPIOPAD_MASK;
462926deccbSFrançois Tigeot else if (rdev->family == CHIP_R300 ||
463926deccbSFrançois Tigeot rdev->family == CHIP_R350) {
464926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_DVI_DDC;
465926deccbSFrançois Tigeot ddc = DDC_DVI;
466926deccbSFrançois Tigeot } else
467926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_MONID;
468926deccbSFrançois Tigeot break;
469926deccbSFrançois Tigeot case DDC_CRT2:
470926deccbSFrançois Tigeot if (rdev->family == CHIP_R200 ||
471926deccbSFrançois Tigeot rdev->family == CHIP_R300 ||
472926deccbSFrançois Tigeot rdev->family == CHIP_R350) {
473926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_DVI_DDC;
474926deccbSFrançois Tigeot ddc = DDC_DVI;
475926deccbSFrançois Tigeot } else if (rdev->family == CHIP_RS300 ||
476926deccbSFrançois Tigeot rdev->family == CHIP_RS400 ||
477926deccbSFrançois Tigeot rdev->family == CHIP_RS480)
478926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_MONID;
479926deccbSFrançois Tigeot else if (rdev->family >= CHIP_RV350) {
480926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_MONID;
481926deccbSFrançois Tigeot ddc = DDC_MONID;
482926deccbSFrançois Tigeot } else
483926deccbSFrançois Tigeot ddc_line = RADEON_GPIO_CRT2_DDC;
484926deccbSFrançois Tigeot break;
485926deccbSFrançois Tigeot }
486926deccbSFrançois Tigeot
487926deccbSFrançois Tigeot if (ddc_line == RADEON_GPIOPAD_MASK) {
488926deccbSFrançois Tigeot i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
489926deccbSFrançois Tigeot i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
490926deccbSFrançois Tigeot i2c.a_clk_reg = RADEON_GPIOPAD_A;
491926deccbSFrançois Tigeot i2c.a_data_reg = RADEON_GPIOPAD_A;
492926deccbSFrançois Tigeot i2c.en_clk_reg = RADEON_GPIOPAD_EN;
493926deccbSFrançois Tigeot i2c.en_data_reg = RADEON_GPIOPAD_EN;
494926deccbSFrançois Tigeot i2c.y_clk_reg = RADEON_GPIOPAD_Y;
495926deccbSFrançois Tigeot i2c.y_data_reg = RADEON_GPIOPAD_Y;
496926deccbSFrançois Tigeot } else if (ddc_line == RADEON_MDGPIO_MASK) {
497926deccbSFrançois Tigeot i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
498926deccbSFrançois Tigeot i2c.mask_data_reg = RADEON_MDGPIO_MASK;
499926deccbSFrançois Tigeot i2c.a_clk_reg = RADEON_MDGPIO_A;
500926deccbSFrançois Tigeot i2c.a_data_reg = RADEON_MDGPIO_A;
501926deccbSFrançois Tigeot i2c.en_clk_reg = RADEON_MDGPIO_EN;
502926deccbSFrançois Tigeot i2c.en_data_reg = RADEON_MDGPIO_EN;
503926deccbSFrançois Tigeot i2c.y_clk_reg = RADEON_MDGPIO_Y;
504926deccbSFrançois Tigeot i2c.y_data_reg = RADEON_MDGPIO_Y;
505926deccbSFrançois Tigeot } else {
506926deccbSFrançois Tigeot i2c.mask_clk_reg = ddc_line;
507926deccbSFrançois Tigeot i2c.mask_data_reg = ddc_line;
508926deccbSFrançois Tigeot i2c.a_clk_reg = ddc_line;
509926deccbSFrançois Tigeot i2c.a_data_reg = ddc_line;
510926deccbSFrançois Tigeot i2c.en_clk_reg = ddc_line;
511926deccbSFrançois Tigeot i2c.en_data_reg = ddc_line;
512926deccbSFrançois Tigeot i2c.y_clk_reg = ddc_line;
513926deccbSFrançois Tigeot i2c.y_data_reg = ddc_line;
514926deccbSFrançois Tigeot }
515926deccbSFrançois Tigeot
516926deccbSFrançois Tigeot if (clk_mask && data_mask) {
517926deccbSFrançois Tigeot /* system specific masks */
518926deccbSFrançois Tigeot i2c.mask_clk_mask = clk_mask;
519926deccbSFrançois Tigeot i2c.mask_data_mask = data_mask;
520926deccbSFrançois Tigeot i2c.a_clk_mask = clk_mask;
521926deccbSFrançois Tigeot i2c.a_data_mask = data_mask;
522926deccbSFrançois Tigeot i2c.en_clk_mask = clk_mask;
523926deccbSFrançois Tigeot i2c.en_data_mask = data_mask;
524926deccbSFrançois Tigeot i2c.y_clk_mask = clk_mask;
525926deccbSFrançois Tigeot i2c.y_data_mask = data_mask;
526926deccbSFrançois Tigeot } else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
527926deccbSFrançois Tigeot (ddc_line == RADEON_MDGPIO_MASK)) {
528926deccbSFrançois Tigeot /* default gpiopad masks */
529926deccbSFrançois Tigeot i2c.mask_clk_mask = (0x20 << 8);
530926deccbSFrançois Tigeot i2c.mask_data_mask = 0x80;
531926deccbSFrançois Tigeot i2c.a_clk_mask = (0x20 << 8);
532926deccbSFrançois Tigeot i2c.a_data_mask = 0x80;
533926deccbSFrançois Tigeot i2c.en_clk_mask = (0x20 << 8);
534926deccbSFrançois Tigeot i2c.en_data_mask = 0x80;
535926deccbSFrançois Tigeot i2c.y_clk_mask = (0x20 << 8);
536926deccbSFrançois Tigeot i2c.y_data_mask = 0x80;
537926deccbSFrançois Tigeot } else {
538926deccbSFrançois Tigeot /* default masks for ddc pads */
539926deccbSFrançois Tigeot i2c.mask_clk_mask = RADEON_GPIO_MASK_1;
540926deccbSFrançois Tigeot i2c.mask_data_mask = RADEON_GPIO_MASK_0;
541926deccbSFrançois Tigeot i2c.a_clk_mask = RADEON_GPIO_A_1;
542926deccbSFrançois Tigeot i2c.a_data_mask = RADEON_GPIO_A_0;
543926deccbSFrançois Tigeot i2c.en_clk_mask = RADEON_GPIO_EN_1;
544926deccbSFrançois Tigeot i2c.en_data_mask = RADEON_GPIO_EN_0;
545926deccbSFrançois Tigeot i2c.y_clk_mask = RADEON_GPIO_Y_1;
546926deccbSFrançois Tigeot i2c.y_data_mask = RADEON_GPIO_Y_0;
547926deccbSFrançois Tigeot }
548926deccbSFrançois Tigeot
549926deccbSFrançois Tigeot switch (rdev->family) {
550926deccbSFrançois Tigeot case CHIP_R100:
551926deccbSFrançois Tigeot case CHIP_RV100:
552926deccbSFrançois Tigeot case CHIP_RS100:
553926deccbSFrançois Tigeot case CHIP_RV200:
554926deccbSFrançois Tigeot case CHIP_RS200:
555926deccbSFrançois Tigeot case CHIP_RS300:
556926deccbSFrançois Tigeot switch (ddc_line) {
557926deccbSFrançois Tigeot case RADEON_GPIO_DVI_DDC:
558926deccbSFrançois Tigeot i2c.hw_capable = true;
559926deccbSFrançois Tigeot break;
560926deccbSFrançois Tigeot default:
561926deccbSFrançois Tigeot i2c.hw_capable = false;
562926deccbSFrançois Tigeot break;
563926deccbSFrançois Tigeot }
564926deccbSFrançois Tigeot break;
565926deccbSFrançois Tigeot case CHIP_R200:
566926deccbSFrançois Tigeot switch (ddc_line) {
567926deccbSFrançois Tigeot case RADEON_GPIO_DVI_DDC:
568926deccbSFrançois Tigeot case RADEON_GPIO_MONID:
569926deccbSFrançois Tigeot i2c.hw_capable = true;
570926deccbSFrançois Tigeot break;
571926deccbSFrançois Tigeot default:
572926deccbSFrançois Tigeot i2c.hw_capable = false;
573926deccbSFrançois Tigeot break;
574926deccbSFrançois Tigeot }
575926deccbSFrançois Tigeot break;
576926deccbSFrançois Tigeot case CHIP_RV250:
577926deccbSFrançois Tigeot case CHIP_RV280:
578926deccbSFrançois Tigeot switch (ddc_line) {
579926deccbSFrançois Tigeot case RADEON_GPIO_VGA_DDC:
580926deccbSFrançois Tigeot case RADEON_GPIO_DVI_DDC:
581926deccbSFrançois Tigeot case RADEON_GPIO_CRT2_DDC:
582926deccbSFrançois Tigeot i2c.hw_capable = true;
583926deccbSFrançois Tigeot break;
584926deccbSFrançois Tigeot default:
585926deccbSFrançois Tigeot i2c.hw_capable = false;
586926deccbSFrançois Tigeot break;
587926deccbSFrançois Tigeot }
588926deccbSFrançois Tigeot break;
589926deccbSFrançois Tigeot case CHIP_R300:
590926deccbSFrançois Tigeot case CHIP_R350:
591926deccbSFrançois Tigeot switch (ddc_line) {
592926deccbSFrançois Tigeot case RADEON_GPIO_VGA_DDC:
593926deccbSFrançois Tigeot case RADEON_GPIO_DVI_DDC:
594926deccbSFrançois Tigeot i2c.hw_capable = true;
595926deccbSFrançois Tigeot break;
596926deccbSFrançois Tigeot default:
597926deccbSFrançois Tigeot i2c.hw_capable = false;
598926deccbSFrançois Tigeot break;
599926deccbSFrançois Tigeot }
600926deccbSFrançois Tigeot break;
601926deccbSFrançois Tigeot case CHIP_RV350:
602926deccbSFrançois Tigeot case CHIP_RV380:
603926deccbSFrançois Tigeot case CHIP_RS400:
604926deccbSFrançois Tigeot case CHIP_RS480:
605926deccbSFrançois Tigeot switch (ddc_line) {
606926deccbSFrançois Tigeot case RADEON_GPIO_VGA_DDC:
607926deccbSFrançois Tigeot case RADEON_GPIO_DVI_DDC:
608926deccbSFrançois Tigeot i2c.hw_capable = true;
609926deccbSFrançois Tigeot break;
610926deccbSFrançois Tigeot case RADEON_GPIO_MONID:
611926deccbSFrançois Tigeot /* hw i2c on RADEON_GPIO_MONID doesn't seem to work
612926deccbSFrançois Tigeot * reliably on some pre-r4xx hardware; not sure why.
613926deccbSFrançois Tigeot */
614926deccbSFrançois Tigeot i2c.hw_capable = false;
615926deccbSFrançois Tigeot break;
616926deccbSFrançois Tigeot default:
617926deccbSFrançois Tigeot i2c.hw_capable = false;
618926deccbSFrançois Tigeot break;
619926deccbSFrançois Tigeot }
620926deccbSFrançois Tigeot break;
621926deccbSFrançois Tigeot default:
622926deccbSFrançois Tigeot i2c.hw_capable = false;
623926deccbSFrançois Tigeot break;
624926deccbSFrançois Tigeot }
625926deccbSFrançois Tigeot i2c.mm_i2c = false;
626926deccbSFrançois Tigeot
627926deccbSFrançois Tigeot i2c.i2c_id = ddc;
628926deccbSFrançois Tigeot i2c.hpd = RADEON_HPD_NONE;
629926deccbSFrançois Tigeot
630926deccbSFrançois Tigeot if (ddc_line)
631926deccbSFrançois Tigeot i2c.valid = true;
632926deccbSFrançois Tigeot else
633926deccbSFrançois Tigeot i2c.valid = false;
634926deccbSFrançois Tigeot
635926deccbSFrançois Tigeot return i2c;
636926deccbSFrançois Tigeot }
637926deccbSFrançois Tigeot
radeon_combios_get_i2c_info_from_table(struct radeon_device * rdev)638926deccbSFrançois Tigeot static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
639926deccbSFrançois Tigeot {
640926deccbSFrançois Tigeot struct drm_device *dev = rdev->ddev;
641926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c;
642926deccbSFrançois Tigeot u16 offset;
643926deccbSFrançois Tigeot u8 id, blocks, clk, data;
644926deccbSFrançois Tigeot int i;
645926deccbSFrançois Tigeot
646926deccbSFrançois Tigeot i2c.valid = false;
647926deccbSFrançois Tigeot
648926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
649926deccbSFrançois Tigeot if (offset) {
650926deccbSFrançois Tigeot blocks = RBIOS8(offset + 2);
651926deccbSFrançois Tigeot for (i = 0; i < blocks; i++) {
652926deccbSFrançois Tigeot id = RBIOS8(offset + 3 + (i * 5) + 0);
653926deccbSFrançois Tigeot if (id == 136) {
654926deccbSFrançois Tigeot clk = RBIOS8(offset + 3 + (i * 5) + 3);
655926deccbSFrançois Tigeot data = RBIOS8(offset + 3 + (i * 5) + 4);
656926deccbSFrançois Tigeot /* gpiopad */
657926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
658926deccbSFrançois Tigeot (1 << clk), (1 << data));
659926deccbSFrançois Tigeot break;
660926deccbSFrançois Tigeot }
661926deccbSFrançois Tigeot }
662926deccbSFrançois Tigeot }
663926deccbSFrançois Tigeot return i2c;
664926deccbSFrançois Tigeot }
665926deccbSFrançois Tigeot
radeon_combios_i2c_init(struct radeon_device * rdev)666926deccbSFrançois Tigeot void radeon_combios_i2c_init(struct radeon_device *rdev)
667926deccbSFrançois Tigeot {
668926deccbSFrançois Tigeot struct drm_device *dev = rdev->ddev;
669926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c;
670926deccbSFrançois Tigeot
671926deccbSFrançois Tigeot /* actual hw pads
672926deccbSFrançois Tigeot * r1xx/rs2xx/rs3xx
673926deccbSFrançois Tigeot * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm
674926deccbSFrançois Tigeot * r200
675926deccbSFrançois Tigeot * 0x60, 0x64, 0x68, mm
676926deccbSFrançois Tigeot * r300/r350
677926deccbSFrançois Tigeot * 0x60, 0x64, mm
678926deccbSFrançois Tigeot * rv2xx/rv3xx/rs4xx
679926deccbSFrançois Tigeot * 0x60, 0x64, 0x68, gpiopads, mm
680926deccbSFrançois Tigeot */
681926deccbSFrançois Tigeot
682926deccbSFrançois Tigeot /* 0x60 */
683926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
684926deccbSFrançois Tigeot rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
685926deccbSFrançois Tigeot /* 0x64 */
686926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
687926deccbSFrançois Tigeot rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
688926deccbSFrançois Tigeot
689926deccbSFrançois Tigeot /* mm i2c */
690926deccbSFrançois Tigeot i2c.valid = true;
691926deccbSFrançois Tigeot i2c.hw_capable = true;
692926deccbSFrançois Tigeot i2c.mm_i2c = true;
693926deccbSFrançois Tigeot i2c.i2c_id = 0xa0;
694926deccbSFrançois Tigeot rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C");
695926deccbSFrançois Tigeot
696926deccbSFrançois Tigeot if (rdev->family == CHIP_R300 ||
697926deccbSFrançois Tigeot rdev->family == CHIP_R350) {
698926deccbSFrançois Tigeot /* only 2 sw i2c pads */
699926deccbSFrançois Tigeot } else if (rdev->family == CHIP_RS300 ||
700926deccbSFrançois Tigeot rdev->family == CHIP_RS400 ||
701926deccbSFrançois Tigeot rdev->family == CHIP_RS480) {
702926deccbSFrançois Tigeot /* 0x68 */
703926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
704926deccbSFrançois Tigeot rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
705926deccbSFrançois Tigeot
706926deccbSFrançois Tigeot /* gpiopad */
707926deccbSFrançois Tigeot i2c = radeon_combios_get_i2c_info_from_table(rdev);
708926deccbSFrançois Tigeot if (i2c.valid)
709926deccbSFrançois Tigeot rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
710926deccbSFrançois Tigeot } else if ((rdev->family == CHIP_R200) ||
711926deccbSFrançois Tigeot (rdev->family >= CHIP_R300)) {
712926deccbSFrançois Tigeot /* 0x68 */
713926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
714926deccbSFrançois Tigeot rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
715926deccbSFrançois Tigeot } else {
716926deccbSFrançois Tigeot /* 0x68 */
717926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
718926deccbSFrançois Tigeot rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
719926deccbSFrançois Tigeot /* 0x6c */
720926deccbSFrançois Tigeot i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
721926deccbSFrançois Tigeot rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
722926deccbSFrançois Tigeot }
723926deccbSFrançois Tigeot }
724926deccbSFrançois Tigeot
radeon_combios_get_clock_info(struct drm_device * dev)725926deccbSFrançois Tigeot bool radeon_combios_get_clock_info(struct drm_device *dev)
726926deccbSFrançois Tigeot {
727926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
728926deccbSFrançois Tigeot uint16_t pll_info;
729926deccbSFrançois Tigeot struct radeon_pll *p1pll = &rdev->clock.p1pll;
730926deccbSFrançois Tigeot struct radeon_pll *p2pll = &rdev->clock.p2pll;
731926deccbSFrançois Tigeot struct radeon_pll *spll = &rdev->clock.spll;
732926deccbSFrançois Tigeot struct radeon_pll *mpll = &rdev->clock.mpll;
733926deccbSFrançois Tigeot int8_t rev;
734926deccbSFrançois Tigeot uint16_t sclk, mclk;
735926deccbSFrançois Tigeot
736926deccbSFrançois Tigeot pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
737926deccbSFrançois Tigeot if (pll_info) {
738926deccbSFrançois Tigeot rev = RBIOS8(pll_info);
739926deccbSFrançois Tigeot
740926deccbSFrançois Tigeot /* pixel clocks */
741926deccbSFrançois Tigeot p1pll->reference_freq = RBIOS16(pll_info + 0xe);
742926deccbSFrançois Tigeot p1pll->reference_div = RBIOS16(pll_info + 0x10);
743926deccbSFrançois Tigeot p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
744926deccbSFrançois Tigeot p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
745926deccbSFrançois Tigeot p1pll->lcd_pll_out_min = p1pll->pll_out_min;
746926deccbSFrançois Tigeot p1pll->lcd_pll_out_max = p1pll->pll_out_max;
747926deccbSFrançois Tigeot
748926deccbSFrançois Tigeot if (rev > 9) {
749926deccbSFrançois Tigeot p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
750926deccbSFrançois Tigeot p1pll->pll_in_max = RBIOS32(pll_info + 0x3a);
751926deccbSFrançois Tigeot } else {
752926deccbSFrançois Tigeot p1pll->pll_in_min = 40;
753926deccbSFrançois Tigeot p1pll->pll_in_max = 500;
754926deccbSFrançois Tigeot }
755926deccbSFrançois Tigeot *p2pll = *p1pll;
756926deccbSFrançois Tigeot
757926deccbSFrançois Tigeot /* system clock */
758926deccbSFrançois Tigeot spll->reference_freq = RBIOS16(pll_info + 0x1a);
759926deccbSFrançois Tigeot spll->reference_div = RBIOS16(pll_info + 0x1c);
760926deccbSFrançois Tigeot spll->pll_out_min = RBIOS32(pll_info + 0x1e);
761926deccbSFrançois Tigeot spll->pll_out_max = RBIOS32(pll_info + 0x22);
762926deccbSFrançois Tigeot
763926deccbSFrançois Tigeot if (rev > 10) {
764926deccbSFrançois Tigeot spll->pll_in_min = RBIOS32(pll_info + 0x48);
765926deccbSFrançois Tigeot spll->pll_in_max = RBIOS32(pll_info + 0x4c);
766926deccbSFrançois Tigeot } else {
767926deccbSFrançois Tigeot /* ??? */
768926deccbSFrançois Tigeot spll->pll_in_min = 40;
769926deccbSFrançois Tigeot spll->pll_in_max = 500;
770926deccbSFrançois Tigeot }
771926deccbSFrançois Tigeot
772926deccbSFrançois Tigeot /* memory clock */
773926deccbSFrançois Tigeot mpll->reference_freq = RBIOS16(pll_info + 0x26);
774926deccbSFrançois Tigeot mpll->reference_div = RBIOS16(pll_info + 0x28);
775926deccbSFrançois Tigeot mpll->pll_out_min = RBIOS32(pll_info + 0x2a);
776926deccbSFrançois Tigeot mpll->pll_out_max = RBIOS32(pll_info + 0x2e);
777926deccbSFrançois Tigeot
778926deccbSFrançois Tigeot if (rev > 10) {
779926deccbSFrançois Tigeot mpll->pll_in_min = RBIOS32(pll_info + 0x5a);
780926deccbSFrançois Tigeot mpll->pll_in_max = RBIOS32(pll_info + 0x5e);
781926deccbSFrançois Tigeot } else {
782926deccbSFrançois Tigeot /* ??? */
783926deccbSFrançois Tigeot mpll->pll_in_min = 40;
784926deccbSFrançois Tigeot mpll->pll_in_max = 500;
785926deccbSFrançois Tigeot }
786926deccbSFrançois Tigeot
787926deccbSFrançois Tigeot /* default sclk/mclk */
788926deccbSFrançois Tigeot sclk = RBIOS16(pll_info + 0xa);
789926deccbSFrançois Tigeot mclk = RBIOS16(pll_info + 0x8);
790926deccbSFrançois Tigeot if (sclk == 0)
791926deccbSFrançois Tigeot sclk = 200 * 100;
792926deccbSFrançois Tigeot if (mclk == 0)
793926deccbSFrançois Tigeot mclk = 200 * 100;
794926deccbSFrançois Tigeot
795926deccbSFrançois Tigeot rdev->clock.default_sclk = sclk;
796926deccbSFrançois Tigeot rdev->clock.default_mclk = mclk;
797926deccbSFrançois Tigeot
798926deccbSFrançois Tigeot if (RBIOS32(pll_info + 0x16))
799926deccbSFrançois Tigeot rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
800926deccbSFrançois Tigeot else
801926deccbSFrançois Tigeot rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
802926deccbSFrançois Tigeot
803926deccbSFrançois Tigeot return true;
804926deccbSFrançois Tigeot }
805926deccbSFrançois Tigeot return false;
806926deccbSFrançois Tigeot }
807926deccbSFrançois Tigeot
radeon_combios_sideport_present(struct radeon_device * rdev)808926deccbSFrançois Tigeot bool radeon_combios_sideport_present(struct radeon_device *rdev)
809926deccbSFrançois Tigeot {
810926deccbSFrançois Tigeot struct drm_device *dev = rdev->ddev;
811926deccbSFrançois Tigeot u16 igp_info;
812926deccbSFrançois Tigeot
813926deccbSFrançois Tigeot /* sideport is AMD only */
814926deccbSFrançois Tigeot if (rdev->family == CHIP_RS400)
815926deccbSFrançois Tigeot return false;
816926deccbSFrançois Tigeot
817926deccbSFrançois Tigeot igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
818926deccbSFrançois Tigeot
819926deccbSFrançois Tigeot if (igp_info) {
820926deccbSFrançois Tigeot if (RBIOS16(igp_info + 0x4))
821926deccbSFrançois Tigeot return true;
822926deccbSFrançois Tigeot }
823926deccbSFrançois Tigeot return false;
824926deccbSFrançois Tigeot }
825926deccbSFrançois Tigeot
826926deccbSFrançois Tigeot static const uint32_t default_primarydac_adj[CHIP_LAST] = {
827926deccbSFrançois Tigeot 0x00000808, /* r100 */
828926deccbSFrançois Tigeot 0x00000808, /* rv100 */
829926deccbSFrançois Tigeot 0x00000808, /* rs100 */
830926deccbSFrançois Tigeot 0x00000808, /* rv200 */
831926deccbSFrançois Tigeot 0x00000808, /* rs200 */
832926deccbSFrançois Tigeot 0x00000808, /* r200 */
833926deccbSFrançois Tigeot 0x00000808, /* rv250 */
834926deccbSFrançois Tigeot 0x00000000, /* rs300 */
835926deccbSFrançois Tigeot 0x00000808, /* rv280 */
836926deccbSFrançois Tigeot 0x00000808, /* r300 */
837926deccbSFrançois Tigeot 0x00000808, /* r350 */
838926deccbSFrançois Tigeot 0x00000808, /* rv350 */
839926deccbSFrançois Tigeot 0x00000808, /* rv380 */
840926deccbSFrançois Tigeot 0x00000808, /* r420 */
841926deccbSFrançois Tigeot 0x00000808, /* r423 */
842926deccbSFrançois Tigeot 0x00000808, /* rv410 */
843926deccbSFrançois Tigeot 0x00000000, /* rs400 */
844926deccbSFrançois Tigeot 0x00000000, /* rs480 */
845926deccbSFrançois Tigeot };
846926deccbSFrançois Tigeot
radeon_legacy_get_primary_dac_info_from_table(struct radeon_device * rdev,struct radeon_encoder_primary_dac * p_dac)847926deccbSFrançois Tigeot static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev,
848926deccbSFrançois Tigeot struct radeon_encoder_primary_dac *p_dac)
849926deccbSFrançois Tigeot {
850926deccbSFrançois Tigeot p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family];
851926deccbSFrançois Tigeot return;
852926deccbSFrançois Tigeot }
853926deccbSFrançois Tigeot
radeon_combios_get_primary_dac_info(struct radeon_encoder * encoder)854926deccbSFrançois Tigeot struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
855926deccbSFrançois Tigeot radeon_encoder
856926deccbSFrançois Tigeot *encoder)
857926deccbSFrançois Tigeot {
858926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
859926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
860926deccbSFrançois Tigeot uint16_t dac_info;
861926deccbSFrançois Tigeot uint8_t rev, bg, dac;
862926deccbSFrançois Tigeot struct radeon_encoder_primary_dac *p_dac = NULL;
863926deccbSFrançois Tigeot int found = 0;
864926deccbSFrançois Tigeot
865c4ef309bSzrj p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac),
866c4ef309bSzrj GFP_KERNEL);
867926deccbSFrançois Tigeot
868926deccbSFrançois Tigeot if (!p_dac)
869926deccbSFrançois Tigeot return NULL;
870926deccbSFrançois Tigeot
871926deccbSFrançois Tigeot /* check CRT table */
872926deccbSFrançois Tigeot dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
873926deccbSFrançois Tigeot if (dac_info) {
874926deccbSFrançois Tigeot rev = RBIOS8(dac_info) & 0x3;
875926deccbSFrançois Tigeot if (rev < 2) {
876926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0x2) & 0xf;
877926deccbSFrançois Tigeot dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf;
878926deccbSFrançois Tigeot p_dac->ps2_pdac_adj = (bg << 8) | (dac);
879926deccbSFrançois Tigeot } else {
880926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0x2) & 0xf;
881926deccbSFrançois Tigeot dac = RBIOS8(dac_info + 0x3) & 0xf;
882926deccbSFrançois Tigeot p_dac->ps2_pdac_adj = (bg << 8) | (dac);
883926deccbSFrançois Tigeot }
88457e252bfSMichael Neumann /* if the values are zeros, use the table */
88557e252bfSMichael Neumann if ((dac == 0) || (bg == 0))
88657e252bfSMichael Neumann found = 0;
88757e252bfSMichael Neumann else
888926deccbSFrançois Tigeot found = 1;
889926deccbSFrançois Tigeot }
890926deccbSFrançois Tigeot
891b403bed8SMichael Neumann /* quirks */
89257e252bfSMichael Neumann /* Radeon 7000 (RV100) */
893c6f73aabSFrançois Tigeot if (((dev->pdev->device == 0x5159) &&
894c6f73aabSFrançois Tigeot (dev->pdev->subsystem_vendor == 0x174B) &&
895c6f73aabSFrançois Tigeot (dev->pdev->subsystem_device == 0x7c28)) ||
896b403bed8SMichael Neumann /* Radeon 9100 (R200) */
897c6f73aabSFrançois Tigeot ((dev->pdev->device == 0x514D) &&
898c6f73aabSFrançois Tigeot (dev->pdev->subsystem_vendor == 0x174B) &&
899c6f73aabSFrançois Tigeot (dev->pdev->subsystem_device == 0x7149))) {
900b403bed8SMichael Neumann /* vbios value is bad, use the default */
901b403bed8SMichael Neumann found = 0;
902b403bed8SMichael Neumann }
903b403bed8SMichael Neumann
904926deccbSFrançois Tigeot if (!found) /* fallback to defaults */
905926deccbSFrançois Tigeot radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
906926deccbSFrançois Tigeot
907926deccbSFrançois Tigeot return p_dac;
908926deccbSFrançois Tigeot }
909926deccbSFrançois Tigeot
910926deccbSFrançois Tigeot enum radeon_tv_std
radeon_combios_get_tv_info(struct radeon_device * rdev)911926deccbSFrançois Tigeot radeon_combios_get_tv_info(struct radeon_device *rdev)
912926deccbSFrançois Tigeot {
913926deccbSFrançois Tigeot struct drm_device *dev = rdev->ddev;
914926deccbSFrançois Tigeot uint16_t tv_info;
915926deccbSFrançois Tigeot enum radeon_tv_std tv_std = TV_STD_NTSC;
916926deccbSFrançois Tigeot
917926deccbSFrançois Tigeot tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
918926deccbSFrançois Tigeot if (tv_info) {
919926deccbSFrançois Tigeot if (RBIOS8(tv_info + 6) == 'T') {
920926deccbSFrançois Tigeot switch (RBIOS8(tv_info + 7) & 0xf) {
921926deccbSFrançois Tigeot case 1:
922926deccbSFrançois Tigeot tv_std = TV_STD_NTSC;
923926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: NTSC\n");
924926deccbSFrançois Tigeot break;
925926deccbSFrançois Tigeot case 2:
926926deccbSFrançois Tigeot tv_std = TV_STD_PAL;
927926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: PAL\n");
928926deccbSFrançois Tigeot break;
929926deccbSFrançois Tigeot case 3:
930926deccbSFrançois Tigeot tv_std = TV_STD_PAL_M;
931926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
932926deccbSFrançois Tigeot break;
933926deccbSFrançois Tigeot case 4:
934926deccbSFrançois Tigeot tv_std = TV_STD_PAL_60;
935926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
936926deccbSFrançois Tigeot break;
937926deccbSFrançois Tigeot case 5:
938926deccbSFrançois Tigeot tv_std = TV_STD_NTSC_J;
939926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
940926deccbSFrançois Tigeot break;
941926deccbSFrançois Tigeot case 6:
942926deccbSFrançois Tigeot tv_std = TV_STD_SCART_PAL;
943926deccbSFrançois Tigeot DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n");
944926deccbSFrançois Tigeot break;
945926deccbSFrançois Tigeot default:
946926deccbSFrançois Tigeot tv_std = TV_STD_NTSC;
947926deccbSFrançois Tigeot DRM_DEBUG_KMS
948926deccbSFrançois Tigeot ("Unknown TV standard; defaulting to NTSC\n");
949926deccbSFrançois Tigeot break;
950926deccbSFrançois Tigeot }
951926deccbSFrançois Tigeot
952926deccbSFrançois Tigeot switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) {
953926deccbSFrançois Tigeot case 0:
954926deccbSFrançois Tigeot DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n");
955926deccbSFrançois Tigeot break;
956926deccbSFrançois Tigeot case 1:
957926deccbSFrançois Tigeot DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n");
958926deccbSFrançois Tigeot break;
959926deccbSFrançois Tigeot case 2:
960926deccbSFrançois Tigeot DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n");
961926deccbSFrançois Tigeot break;
962926deccbSFrançois Tigeot case 3:
963926deccbSFrançois Tigeot DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n");
964926deccbSFrançois Tigeot break;
965926deccbSFrançois Tigeot default:
966926deccbSFrançois Tigeot break;
967926deccbSFrançois Tigeot }
968926deccbSFrançois Tigeot }
969926deccbSFrançois Tigeot }
970926deccbSFrançois Tigeot return tv_std;
971926deccbSFrançois Tigeot }
972926deccbSFrançois Tigeot
973926deccbSFrançois Tigeot static const uint32_t default_tvdac_adj[CHIP_LAST] = {
974926deccbSFrançois Tigeot 0x00000000, /* r100 */
975926deccbSFrançois Tigeot 0x00280000, /* rv100 */
976926deccbSFrançois Tigeot 0x00000000, /* rs100 */
977926deccbSFrançois Tigeot 0x00880000, /* rv200 */
978926deccbSFrançois Tigeot 0x00000000, /* rs200 */
979926deccbSFrançois Tigeot 0x00000000, /* r200 */
980926deccbSFrançois Tigeot 0x00770000, /* rv250 */
981926deccbSFrançois Tigeot 0x00290000, /* rs300 */
982926deccbSFrançois Tigeot 0x00560000, /* rv280 */
983926deccbSFrançois Tigeot 0x00780000, /* r300 */
984926deccbSFrançois Tigeot 0x00770000, /* r350 */
985926deccbSFrançois Tigeot 0x00780000, /* rv350 */
986926deccbSFrançois Tigeot 0x00780000, /* rv380 */
987926deccbSFrançois Tigeot 0x01080000, /* r420 */
988926deccbSFrançois Tigeot 0x01080000, /* r423 */
989926deccbSFrançois Tigeot 0x01080000, /* rv410 */
990926deccbSFrançois Tigeot 0x00780000, /* rs400 */
991926deccbSFrançois Tigeot 0x00780000, /* rs480 */
992926deccbSFrançois Tigeot };
993926deccbSFrançois Tigeot
radeon_legacy_get_tv_dac_info_from_table(struct radeon_device * rdev,struct radeon_encoder_tv_dac * tv_dac)994926deccbSFrançois Tigeot static void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev,
995926deccbSFrançois Tigeot struct radeon_encoder_tv_dac *tv_dac)
996926deccbSFrançois Tigeot {
997926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family];
998926deccbSFrançois Tigeot if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250))
999926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj = 0x00880000;
1000926deccbSFrançois Tigeot tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
1001926deccbSFrançois Tigeot tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
1002926deccbSFrançois Tigeot return;
1003926deccbSFrançois Tigeot }
1004926deccbSFrançois Tigeot
radeon_combios_get_tv_dac_info(struct radeon_encoder * encoder)1005926deccbSFrançois Tigeot struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
1006926deccbSFrançois Tigeot radeon_encoder
1007926deccbSFrançois Tigeot *encoder)
1008926deccbSFrançois Tigeot {
1009926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1010926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1011926deccbSFrançois Tigeot uint16_t dac_info;
1012926deccbSFrançois Tigeot uint8_t rev, bg, dac;
1013926deccbSFrançois Tigeot struct radeon_encoder_tv_dac *tv_dac = NULL;
1014926deccbSFrançois Tigeot int found = 0;
1015926deccbSFrançois Tigeot
1016c4ef309bSzrj tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
1017926deccbSFrançois Tigeot if (!tv_dac)
1018926deccbSFrançois Tigeot return NULL;
1019926deccbSFrançois Tigeot
1020926deccbSFrançois Tigeot /* first check TV table */
1021926deccbSFrançois Tigeot dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
1022926deccbSFrançois Tigeot if (dac_info) {
1023926deccbSFrançois Tigeot rev = RBIOS8(dac_info + 0x3);
1024926deccbSFrançois Tigeot if (rev > 4) {
1025926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0xc) & 0xf;
1026926deccbSFrançois Tigeot dac = RBIOS8(dac_info + 0xd) & 0xf;
1027926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1028926deccbSFrançois Tigeot
1029926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0xe) & 0xf;
1030926deccbSFrançois Tigeot dac = RBIOS8(dac_info + 0xf) & 0xf;
1031926deccbSFrançois Tigeot tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1032926deccbSFrançois Tigeot
1033926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0x10) & 0xf;
1034926deccbSFrançois Tigeot dac = RBIOS8(dac_info + 0x11) & 0xf;
1035926deccbSFrançois Tigeot tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
1036926deccbSFrançois Tigeot /* if the values are all zeros, use the table */
1037926deccbSFrançois Tigeot if (tv_dac->ps2_tvdac_adj)
1038926deccbSFrançois Tigeot found = 1;
1039926deccbSFrançois Tigeot } else if (rev > 1) {
1040926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0xc) & 0xf;
1041926deccbSFrançois Tigeot dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
1042926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1043926deccbSFrançois Tigeot
1044926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0xd) & 0xf;
1045926deccbSFrançois Tigeot dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf;
1046926deccbSFrançois Tigeot tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1047926deccbSFrançois Tigeot
1048926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0xe) & 0xf;
1049926deccbSFrançois Tigeot dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
1050926deccbSFrançois Tigeot tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
1051926deccbSFrançois Tigeot /* if the values are all zeros, use the table */
1052926deccbSFrançois Tigeot if (tv_dac->ps2_tvdac_adj)
1053926deccbSFrançois Tigeot found = 1;
1054926deccbSFrançois Tigeot }
1055926deccbSFrançois Tigeot tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
1056926deccbSFrançois Tigeot }
1057926deccbSFrançois Tigeot if (!found) {
1058926deccbSFrançois Tigeot /* then check CRT table */
1059926deccbSFrançois Tigeot dac_info =
1060926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
1061926deccbSFrançois Tigeot if (dac_info) {
1062926deccbSFrançois Tigeot rev = RBIOS8(dac_info) & 0x3;
1063926deccbSFrançois Tigeot if (rev < 2) {
1064926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0x3) & 0xf;
1065926deccbSFrançois Tigeot dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf;
1066926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj =
1067926deccbSFrançois Tigeot (bg << 16) | (dac << 20);
1068926deccbSFrançois Tigeot tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
1069926deccbSFrançois Tigeot tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
1070926deccbSFrançois Tigeot /* if the values are all zeros, use the table */
1071926deccbSFrançois Tigeot if (tv_dac->ps2_tvdac_adj)
1072926deccbSFrançois Tigeot found = 1;
1073926deccbSFrançois Tigeot } else {
1074926deccbSFrançois Tigeot bg = RBIOS8(dac_info + 0x4) & 0xf;
1075926deccbSFrançois Tigeot dac = RBIOS8(dac_info + 0x5) & 0xf;
1076926deccbSFrançois Tigeot tv_dac->ps2_tvdac_adj =
1077926deccbSFrançois Tigeot (bg << 16) | (dac << 20);
1078926deccbSFrançois Tigeot tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
1079926deccbSFrançois Tigeot tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
1080926deccbSFrançois Tigeot /* if the values are all zeros, use the table */
1081926deccbSFrançois Tigeot if (tv_dac->ps2_tvdac_adj)
1082926deccbSFrançois Tigeot found = 1;
1083926deccbSFrançois Tigeot }
1084926deccbSFrançois Tigeot } else {
1085926deccbSFrançois Tigeot DRM_INFO("No TV DAC info found in BIOS\n");
1086926deccbSFrançois Tigeot }
1087926deccbSFrançois Tigeot }
1088926deccbSFrançois Tigeot
1089926deccbSFrançois Tigeot if (!found) /* fallback to defaults */
1090926deccbSFrançois Tigeot radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac);
1091926deccbSFrançois Tigeot
1092926deccbSFrançois Tigeot return tv_dac;
1093926deccbSFrançois Tigeot }
1094926deccbSFrançois Tigeot
radeon_legacy_get_lvds_info_from_regs(struct radeon_device * rdev)1095926deccbSFrançois Tigeot static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
1096926deccbSFrançois Tigeot radeon_device
1097926deccbSFrançois Tigeot *rdev)
1098926deccbSFrançois Tigeot {
1099926deccbSFrançois Tigeot struct radeon_encoder_lvds *lvds = NULL;
1100926deccbSFrançois Tigeot uint32_t fp_vert_stretch, fp_horz_stretch;
1101926deccbSFrançois Tigeot uint32_t ppll_div_sel, ppll_val;
1102926deccbSFrançois Tigeot uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
1103926deccbSFrançois Tigeot
1104c4ef309bSzrj lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
1105926deccbSFrançois Tigeot
1106926deccbSFrançois Tigeot if (!lvds)
1107926deccbSFrançois Tigeot return NULL;
1108926deccbSFrançois Tigeot
1109926deccbSFrançois Tigeot fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH);
1110926deccbSFrançois Tigeot fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH);
1111926deccbSFrançois Tigeot
1112926deccbSFrançois Tigeot /* These should be fail-safe defaults, fingers crossed */
1113926deccbSFrançois Tigeot lvds->panel_pwr_delay = 200;
1114926deccbSFrançois Tigeot lvds->panel_vcc_delay = 2000;
1115926deccbSFrançois Tigeot
1116926deccbSFrançois Tigeot lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
1117926deccbSFrançois Tigeot lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf;
1118926deccbSFrançois Tigeot lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
1119926deccbSFrançois Tigeot
1120926deccbSFrançois Tigeot if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
1121926deccbSFrançois Tigeot lvds->native_mode.vdisplay =
1122926deccbSFrançois Tigeot ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
1123926deccbSFrançois Tigeot RADEON_VERT_PANEL_SHIFT) + 1;
1124926deccbSFrançois Tigeot else
1125926deccbSFrançois Tigeot lvds->native_mode.vdisplay =
1126926deccbSFrançois Tigeot (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
1127926deccbSFrançois Tigeot
1128926deccbSFrançois Tigeot if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
1129926deccbSFrançois Tigeot lvds->native_mode.hdisplay =
1130926deccbSFrançois Tigeot (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
1131926deccbSFrançois Tigeot RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
1132926deccbSFrançois Tigeot else
1133926deccbSFrançois Tigeot lvds->native_mode.hdisplay =
1134926deccbSFrançois Tigeot ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
1135926deccbSFrançois Tigeot
1136926deccbSFrançois Tigeot if ((lvds->native_mode.hdisplay < 640) ||
1137926deccbSFrançois Tigeot (lvds->native_mode.vdisplay < 480)) {
1138926deccbSFrançois Tigeot lvds->native_mode.hdisplay = 640;
1139926deccbSFrançois Tigeot lvds->native_mode.vdisplay = 480;
1140926deccbSFrançois Tigeot }
1141926deccbSFrançois Tigeot
1142926deccbSFrançois Tigeot ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
1143926deccbSFrançois Tigeot ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel);
1144926deccbSFrançois Tigeot if ((ppll_val & 0x000707ff) == 0x1bb)
1145926deccbSFrançois Tigeot lvds->use_bios_dividers = false;
1146926deccbSFrançois Tigeot else {
1147926deccbSFrançois Tigeot lvds->panel_ref_divider =
1148926deccbSFrançois Tigeot RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
1149926deccbSFrançois Tigeot lvds->panel_post_divider = (ppll_val >> 16) & 0x7;
1150926deccbSFrançois Tigeot lvds->panel_fb_divider = ppll_val & 0x7ff;
1151926deccbSFrançois Tigeot
1152926deccbSFrançois Tigeot if ((lvds->panel_ref_divider != 0) &&
1153926deccbSFrançois Tigeot (lvds->panel_fb_divider > 3))
1154926deccbSFrançois Tigeot lvds->use_bios_dividers = true;
1155926deccbSFrançois Tigeot }
1156926deccbSFrançois Tigeot lvds->panel_vcc_delay = 200;
1157926deccbSFrançois Tigeot
1158926deccbSFrançois Tigeot DRM_INFO("Panel info derived from registers\n");
1159926deccbSFrançois Tigeot DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
1160926deccbSFrançois Tigeot lvds->native_mode.vdisplay);
1161926deccbSFrançois Tigeot
1162926deccbSFrançois Tigeot return lvds;
1163926deccbSFrançois Tigeot }
1164926deccbSFrançois Tigeot
radeon_combios_get_lvds_info(struct radeon_encoder * encoder)1165926deccbSFrançois Tigeot struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
1166926deccbSFrançois Tigeot *encoder)
1167926deccbSFrançois Tigeot {
1168926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1169926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1170926deccbSFrançois Tigeot uint16_t lcd_info;
1171926deccbSFrançois Tigeot uint32_t panel_setup;
1172926deccbSFrançois Tigeot char stmp[30];
1173926deccbSFrançois Tigeot int tmp, i;
1174926deccbSFrançois Tigeot struct radeon_encoder_lvds *lvds = NULL;
1175926deccbSFrançois Tigeot
1176926deccbSFrançois Tigeot lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
1177926deccbSFrançois Tigeot
1178926deccbSFrançois Tigeot if (lcd_info) {
1179c4ef309bSzrj lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
1180926deccbSFrançois Tigeot
1181926deccbSFrançois Tigeot if (!lvds)
1182926deccbSFrançois Tigeot return NULL;
1183926deccbSFrançois Tigeot
1184926deccbSFrançois Tigeot for (i = 0; i < 24; i++)
1185926deccbSFrançois Tigeot stmp[i] = RBIOS8(lcd_info + i + 1);
1186926deccbSFrançois Tigeot stmp[24] = 0;
1187926deccbSFrançois Tigeot
1188926deccbSFrançois Tigeot DRM_INFO("Panel ID String: %s\n", stmp);
1189926deccbSFrançois Tigeot
1190926deccbSFrançois Tigeot lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
1191926deccbSFrançois Tigeot lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
1192926deccbSFrançois Tigeot
1193926deccbSFrançois Tigeot DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
1194926deccbSFrançois Tigeot lvds->native_mode.vdisplay);
1195926deccbSFrançois Tigeot
1196926deccbSFrançois Tigeot lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
1197926deccbSFrançois Tigeot lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000);
1198926deccbSFrançois Tigeot
1199926deccbSFrançois Tigeot lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24);
1200926deccbSFrançois Tigeot lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf;
1201926deccbSFrançois Tigeot lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf;
1202926deccbSFrançois Tigeot
1203926deccbSFrançois Tigeot lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e);
1204926deccbSFrançois Tigeot lvds->panel_post_divider = RBIOS8(lcd_info + 0x30);
1205926deccbSFrançois Tigeot lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31);
1206926deccbSFrançois Tigeot if ((lvds->panel_ref_divider != 0) &&
1207926deccbSFrançois Tigeot (lvds->panel_fb_divider > 3))
1208926deccbSFrançois Tigeot lvds->use_bios_dividers = true;
1209926deccbSFrançois Tigeot
1210926deccbSFrançois Tigeot panel_setup = RBIOS32(lcd_info + 0x39);
1211926deccbSFrançois Tigeot lvds->lvds_gen_cntl = 0xff00;
1212926deccbSFrançois Tigeot if (panel_setup & 0x1)
1213926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT;
1214926deccbSFrançois Tigeot
1215926deccbSFrançois Tigeot if ((panel_setup >> 4) & 0x1)
1216926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE;
1217926deccbSFrançois Tigeot
1218926deccbSFrançois Tigeot switch ((panel_setup >> 8) & 0x7) {
1219926deccbSFrançois Tigeot case 0:
1220926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM;
1221926deccbSFrançois Tigeot break;
1222926deccbSFrançois Tigeot case 1:
1223926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY;
1224926deccbSFrançois Tigeot break;
1225926deccbSFrançois Tigeot case 2:
1226926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY;
1227926deccbSFrançois Tigeot break;
1228926deccbSFrançois Tigeot default:
1229926deccbSFrançois Tigeot break;
1230926deccbSFrançois Tigeot }
1231926deccbSFrançois Tigeot
1232926deccbSFrançois Tigeot if ((panel_setup >> 16) & 0x1)
1233926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW;
1234926deccbSFrançois Tigeot
1235926deccbSFrançois Tigeot if ((panel_setup >> 17) & 0x1)
1236926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW;
1237926deccbSFrançois Tigeot
1238926deccbSFrançois Tigeot if ((panel_setup >> 18) & 0x1)
1239926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW;
1240926deccbSFrançois Tigeot
1241926deccbSFrançois Tigeot if ((panel_setup >> 23) & 0x1)
1242926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL;
1243926deccbSFrançois Tigeot
1244926deccbSFrançois Tigeot lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000);
1245926deccbSFrançois Tigeot
1246926deccbSFrançois Tigeot for (i = 0; i < 32; i++) {
1247926deccbSFrançois Tigeot tmp = RBIOS16(lcd_info + 64 + i * 2);
1248926deccbSFrançois Tigeot if (tmp == 0)
1249926deccbSFrançois Tigeot break;
1250926deccbSFrançois Tigeot
1251926deccbSFrançois Tigeot if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
1252926deccbSFrançois Tigeot (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) {
1253c59a5c48SFrançois Tigeot u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
1254c59a5c48SFrançois Tigeot
1255c59a5c48SFrançois Tigeot if (hss > lvds->native_mode.hdisplay)
1256c59a5c48SFrançois Tigeot hss = (10 - 1) * 8;
1257c59a5c48SFrançois Tigeot
1258926deccbSFrançois Tigeot lvds->native_mode.htotal = lvds->native_mode.hdisplay +
1259926deccbSFrançois Tigeot (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
1260926deccbSFrançois Tigeot lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
1261c59a5c48SFrançois Tigeot hss;
1262926deccbSFrançois Tigeot lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
1263926deccbSFrançois Tigeot (RBIOS8(tmp + 23) * 8);
1264926deccbSFrançois Tigeot
1265926deccbSFrançois Tigeot lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
1266926deccbSFrançois Tigeot (RBIOS16(tmp + 24) - RBIOS16(tmp + 26));
1267926deccbSFrançois Tigeot lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
1268926deccbSFrançois Tigeot ((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26));
1269926deccbSFrançois Tigeot lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
1270926deccbSFrançois Tigeot ((RBIOS16(tmp + 28) & 0xf800) >> 11);
1271926deccbSFrançois Tigeot
1272926deccbSFrançois Tigeot lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
1273926deccbSFrançois Tigeot lvds->native_mode.flags = 0;
1274926deccbSFrançois Tigeot /* set crtc values */
1275926deccbSFrançois Tigeot drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
1276926deccbSFrançois Tigeot
1277926deccbSFrançois Tigeot }
1278926deccbSFrançois Tigeot }
1279926deccbSFrançois Tigeot } else {
1280926deccbSFrançois Tigeot DRM_INFO("No panel info found in BIOS\n");
1281926deccbSFrançois Tigeot lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
1282926deccbSFrançois Tigeot }
1283926deccbSFrançois Tigeot
1284926deccbSFrançois Tigeot if (lvds)
1285926deccbSFrançois Tigeot encoder->native_mode = lvds->native_mode;
1286926deccbSFrançois Tigeot return lvds;
1287926deccbSFrançois Tigeot }
1288926deccbSFrançois Tigeot
1289926deccbSFrançois Tigeot static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
1290926deccbSFrançois Tigeot {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R100 */
1291926deccbSFrançois Tigeot {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV100 */
1292926deccbSFrançois Tigeot {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS100 */
1293926deccbSFrançois Tigeot {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV200 */
1294926deccbSFrançois Tigeot {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RS200 */
1295926deccbSFrançois Tigeot {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R200 */
1296926deccbSFrançois Tigeot {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /* CHIP_RV250 */
1297926deccbSFrançois Tigeot {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS300 */
1298926deccbSFrançois Tigeot {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /* CHIP_RV280 */
1299926deccbSFrançois Tigeot {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R300 */
1300926deccbSFrançois Tigeot {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R350 */
1301926deccbSFrançois Tigeot {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV350 */
1302926deccbSFrançois Tigeot {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV380 */
1303926deccbSFrançois Tigeot {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
1304926deccbSFrançois Tigeot {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
1305926deccbSFrançois Tigeot {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
1306926deccbSFrançois Tigeot { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
1307926deccbSFrançois Tigeot { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
1308926deccbSFrançois Tigeot };
1309926deccbSFrançois Tigeot
radeon_legacy_get_tmds_info_from_table(struct radeon_encoder * encoder,struct radeon_encoder_int_tmds * tmds)1310926deccbSFrançois Tigeot bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
1311926deccbSFrançois Tigeot struct radeon_encoder_int_tmds *tmds)
1312926deccbSFrançois Tigeot {
1313926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1314926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1315926deccbSFrançois Tigeot int i;
1316926deccbSFrançois Tigeot
1317926deccbSFrançois Tigeot for (i = 0; i < 4; i++) {
1318926deccbSFrançois Tigeot tmds->tmds_pll[i].value =
1319926deccbSFrançois Tigeot default_tmds_pll[rdev->family][i].value;
1320926deccbSFrançois Tigeot tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
1321926deccbSFrançois Tigeot }
1322926deccbSFrançois Tigeot
1323926deccbSFrançois Tigeot return true;
1324926deccbSFrançois Tigeot }
1325926deccbSFrançois Tigeot
radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder * encoder,struct radeon_encoder_int_tmds * tmds)1326926deccbSFrançois Tigeot bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1327926deccbSFrançois Tigeot struct radeon_encoder_int_tmds *tmds)
1328926deccbSFrançois Tigeot {
1329926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1330926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1331926deccbSFrançois Tigeot uint16_t tmds_info;
1332926deccbSFrançois Tigeot int i, n;
1333926deccbSFrançois Tigeot uint8_t ver;
1334926deccbSFrançois Tigeot
1335926deccbSFrançois Tigeot tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
1336926deccbSFrançois Tigeot
1337926deccbSFrançois Tigeot if (tmds_info) {
1338926deccbSFrançois Tigeot ver = RBIOS8(tmds_info);
1339926deccbSFrançois Tigeot DRM_DEBUG_KMS("DFP table revision: %d\n", ver);
1340926deccbSFrançois Tigeot if (ver == 3) {
1341926deccbSFrançois Tigeot n = RBIOS8(tmds_info + 5) + 1;
1342926deccbSFrançois Tigeot if (n > 4)
1343926deccbSFrançois Tigeot n = 4;
1344926deccbSFrançois Tigeot for (i = 0; i < n; i++) {
1345926deccbSFrançois Tigeot tmds->tmds_pll[i].value =
1346926deccbSFrançois Tigeot RBIOS32(tmds_info + i * 10 + 0x08);
1347926deccbSFrançois Tigeot tmds->tmds_pll[i].freq =
1348926deccbSFrançois Tigeot RBIOS16(tmds_info + i * 10 + 0x10);
1349926deccbSFrançois Tigeot DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
1350926deccbSFrançois Tigeot tmds->tmds_pll[i].freq,
1351926deccbSFrançois Tigeot tmds->tmds_pll[i].value);
1352926deccbSFrançois Tigeot }
1353926deccbSFrançois Tigeot } else if (ver == 4) {
1354926deccbSFrançois Tigeot int stride = 0;
1355926deccbSFrançois Tigeot n = RBIOS8(tmds_info + 5) + 1;
1356926deccbSFrançois Tigeot if (n > 4)
1357926deccbSFrançois Tigeot n = 4;
1358926deccbSFrançois Tigeot for (i = 0; i < n; i++) {
1359926deccbSFrançois Tigeot tmds->tmds_pll[i].value =
1360926deccbSFrançois Tigeot RBIOS32(tmds_info + stride + 0x08);
1361926deccbSFrançois Tigeot tmds->tmds_pll[i].freq =
1362926deccbSFrançois Tigeot RBIOS16(tmds_info + stride + 0x10);
1363926deccbSFrançois Tigeot if (i == 0)
1364926deccbSFrançois Tigeot stride += 10;
1365926deccbSFrançois Tigeot else
1366926deccbSFrançois Tigeot stride += 6;
1367926deccbSFrançois Tigeot DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
1368926deccbSFrançois Tigeot tmds->tmds_pll[i].freq,
1369926deccbSFrançois Tigeot tmds->tmds_pll[i].value);
1370926deccbSFrançois Tigeot }
1371926deccbSFrançois Tigeot }
1372926deccbSFrançois Tigeot } else {
1373926deccbSFrançois Tigeot DRM_INFO("No TMDS info found in BIOS\n");
1374926deccbSFrançois Tigeot return false;
1375926deccbSFrançois Tigeot }
1376926deccbSFrançois Tigeot return true;
1377926deccbSFrançois Tigeot }
1378926deccbSFrançois Tigeot
radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder * encoder,struct radeon_encoder_ext_tmds * tmds)1379926deccbSFrançois Tigeot bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
1380926deccbSFrançois Tigeot struct radeon_encoder_ext_tmds *tmds)
1381926deccbSFrançois Tigeot {
1382926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1383926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1384926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c_bus;
1385926deccbSFrançois Tigeot
1386926deccbSFrançois Tigeot /* default for macs */
1387926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1388926deccbSFrançois Tigeot tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1389926deccbSFrançois Tigeot
1390926deccbSFrançois Tigeot /* XXX some macs have duallink chips */
1391926deccbSFrançois Tigeot switch (rdev->mode_info.connector_table) {
1392926deccbSFrançois Tigeot case CT_POWERBOOK_EXTERNAL:
1393926deccbSFrançois Tigeot case CT_MINI_EXTERNAL:
1394926deccbSFrançois Tigeot default:
1395926deccbSFrançois Tigeot tmds->dvo_chip = DVO_SIL164;
1396926deccbSFrançois Tigeot tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1397926deccbSFrançois Tigeot break;
1398926deccbSFrançois Tigeot }
1399926deccbSFrançois Tigeot
1400926deccbSFrançois Tigeot return true;
1401926deccbSFrançois Tigeot }
1402926deccbSFrançois Tigeot
radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder * encoder,struct radeon_encoder_ext_tmds * tmds)1403926deccbSFrançois Tigeot bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
1404926deccbSFrançois Tigeot struct radeon_encoder_ext_tmds *tmds)
1405926deccbSFrançois Tigeot {
1406926deccbSFrançois Tigeot struct drm_device *dev = encoder->base.dev;
1407926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1408926deccbSFrançois Tigeot uint16_t offset;
1409926deccbSFrançois Tigeot uint8_t ver;
1410926deccbSFrançois Tigeot enum radeon_combios_ddc gpio;
1411926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c_bus;
1412926deccbSFrançois Tigeot
1413926deccbSFrançois Tigeot tmds->i2c_bus = NULL;
1414926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
1415926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1416926deccbSFrançois Tigeot tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1417926deccbSFrançois Tigeot tmds->dvo_chip = DVO_SIL164;
1418926deccbSFrançois Tigeot tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1419926deccbSFrançois Tigeot } else {
1420926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
1421926deccbSFrançois Tigeot if (offset) {
1422926deccbSFrançois Tigeot ver = RBIOS8(offset);
1423926deccbSFrançois Tigeot DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver);
1424926deccbSFrançois Tigeot tmds->slave_addr = RBIOS8(offset + 4 + 2);
1425926deccbSFrançois Tigeot tmds->slave_addr >>= 1; /* 7 bit addressing */
1426926deccbSFrançois Tigeot gpio = RBIOS8(offset + 4 + 3);
1427926deccbSFrançois Tigeot if (gpio == DDC_LCD) {
1428926deccbSFrançois Tigeot /* MM i2c */
1429926deccbSFrançois Tigeot i2c_bus.valid = true;
1430926deccbSFrançois Tigeot i2c_bus.hw_capable = true;
1431926deccbSFrançois Tigeot i2c_bus.mm_i2c = true;
1432926deccbSFrançois Tigeot i2c_bus.i2c_id = 0xa0;
1433926deccbSFrançois Tigeot } else
1434926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
1435926deccbSFrançois Tigeot tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
1436926deccbSFrançois Tigeot }
1437926deccbSFrançois Tigeot }
1438926deccbSFrançois Tigeot
1439926deccbSFrançois Tigeot if (!tmds->i2c_bus) {
1440926deccbSFrançois Tigeot DRM_INFO("No valid Ext TMDS info found in BIOS\n");
1441926deccbSFrançois Tigeot return false;
1442926deccbSFrançois Tigeot }
1443926deccbSFrançois Tigeot
1444926deccbSFrançois Tigeot return true;
1445926deccbSFrançois Tigeot }
1446926deccbSFrançois Tigeot
radeon_get_legacy_connector_info_from_table(struct drm_device * dev)1447926deccbSFrançois Tigeot bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
1448926deccbSFrançois Tigeot {
1449926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
1450926deccbSFrançois Tigeot struct radeon_i2c_bus_rec ddc_i2c;
1451926deccbSFrançois Tigeot struct radeon_hpd hpd;
1452926deccbSFrançois Tigeot
1453926deccbSFrançois Tigeot rdev->mode_info.connector_table = radeon_connector_table;
1454926deccbSFrançois Tigeot if (rdev->mode_info.connector_table == CT_NONE) {
1455926deccbSFrançois Tigeot #ifdef CONFIG_PPC_PMAC
1456926deccbSFrançois Tigeot if (of_machine_is_compatible("PowerBook3,3")) {
1457926deccbSFrançois Tigeot /* powerbook with VGA */
1458926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_POWERBOOK_VGA;
1459926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerBook3,4") ||
1460926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook3,5")) {
1461926deccbSFrançois Tigeot /* powerbook with internal tmds */
1462926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL;
1463926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerBook5,1") ||
1464926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,2") ||
1465926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,3") ||
1466926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,4") ||
1467926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,5")) {
1468926deccbSFrançois Tigeot /* powerbook with external single link tmds (sil164) */
1469926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
1470926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerBook5,6")) {
1471926deccbSFrançois Tigeot /* powerbook with external dual or single link tmds */
1472926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
1473926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerBook5,7") ||
1474926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,8") ||
1475926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook5,9")) {
1476926deccbSFrançois Tigeot /* PowerBook6,2 ? */
1477926deccbSFrançois Tigeot /* powerbook with external dual link tmds (sil1178?) */
1478926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
1479926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerBook4,1") ||
1480926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook4,2") ||
1481926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook4,3") ||
1482926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook6,3") ||
1483926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook6,5") ||
1484926deccbSFrançois Tigeot of_machine_is_compatible("PowerBook6,7")) {
1485926deccbSFrançois Tigeot /* ibook */
1486926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_IBOOK;
1487926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerMac3,5")) {
1488926deccbSFrançois Tigeot /* PowerMac G4 Silver radeon 7500 */
1489926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
1490926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerMac4,4")) {
1491926deccbSFrançois Tigeot /* emac */
1492926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_EMAC;
1493926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerMac10,1")) {
1494926deccbSFrançois Tigeot /* mini with internal tmds */
1495926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_MINI_INTERNAL;
1496926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerMac10,2")) {
1497926deccbSFrançois Tigeot /* mini with external tmds */
1498926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_MINI_EXTERNAL;
1499926deccbSFrançois Tigeot } else if (of_machine_is_compatible("PowerMac12,1")) {
1500926deccbSFrançois Tigeot /* PowerMac8,1 ? */
1501926deccbSFrançois Tigeot /* imac g5 isight */
1502926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
1503c6f73aabSFrançois Tigeot } else if ((rdev->pdev->device == 0x4a48) &&
1504c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_vendor == 0x1002) &&
1505c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_device == 0x4a48)) {
1506926deccbSFrançois Tigeot /* Mac X800 */
1507926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_MAC_X800;
1508926deccbSFrançois Tigeot } else if ((of_machine_is_compatible("PowerMac7,2") ||
1509926deccbSFrançois Tigeot of_machine_is_compatible("PowerMac7,3")) &&
1510c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x4150) &&
1511c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_vendor == 0x1002) &&
1512c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_device == 0x4150)) {
1513926deccbSFrançois Tigeot /* Mac G5 tower 9600 */
1514926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_MAC_G5_9600;
1515c6f73aabSFrançois Tigeot } else if ((rdev->pdev->device == 0x4c66) &&
1516c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_vendor == 0x1002) &&
1517c6f73aabSFrançois Tigeot (rdev->pdev->subsystem_device == 0x4c66)) {
1518926deccbSFrançois Tigeot /* SAM440ep RV250 embedded board */
1519926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_SAM440EP;
1520926deccbSFrançois Tigeot } else
1521926deccbSFrançois Tigeot #endif /* CONFIG_PPC_PMAC */
1522926deccbSFrançois Tigeot #ifdef CONFIG_PPC64
1523926deccbSFrançois Tigeot if (ASIC_IS_RN50(rdev))
1524926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_RN50_POWER;
1525926deccbSFrançois Tigeot else
1526926deccbSFrançois Tigeot #endif
1527926deccbSFrançois Tigeot rdev->mode_info.connector_table = CT_GENERIC;
1528926deccbSFrançois Tigeot }
1529926deccbSFrançois Tigeot
1530926deccbSFrançois Tigeot switch (rdev->mode_info.connector_table) {
1531926deccbSFrançois Tigeot case CT_GENERIC:
1532926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (generic)\n",
1533926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1534926deccbSFrançois Tigeot /* these are the most common settings */
1535926deccbSFrançois Tigeot if (rdev->flags & RADEON_SINGLE_CRTC) {
1536926deccbSFrançois Tigeot /* VGA - primary dac */
1537926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1538926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1539926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1540926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1541926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1542926deccbSFrançois Tigeot 1),
1543926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1544926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
1545926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1546926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA,
1547926deccbSFrançois Tigeot &ddc_i2c,
1548926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1549926deccbSFrançois Tigeot &hpd);
1550926deccbSFrançois Tigeot } else if (rdev->flags & RADEON_IS_MOBILITY) {
1551926deccbSFrançois Tigeot /* LVDS */
1552926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
1553926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1554926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1555926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1556926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1557926deccbSFrançois Tigeot 0),
1558926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
1559926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
1560926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1561926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS,
1562926deccbSFrançois Tigeot &ddc_i2c,
1563926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
1564926deccbSFrançois Tigeot &hpd);
1565926deccbSFrançois Tigeot
1566926deccbSFrançois Tigeot /* VGA - primary dac */
1567926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1568926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1569926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1570926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1571926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1572926deccbSFrançois Tigeot 1),
1573926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1574926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
1575926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1576926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA,
1577926deccbSFrançois Tigeot &ddc_i2c,
1578926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1579926deccbSFrançois Tigeot &hpd);
1580926deccbSFrançois Tigeot } else {
1581926deccbSFrançois Tigeot /* DVI-I - tv dac, int tmds */
1582926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1583926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1;
1584926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1585926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1586926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
1587926deccbSFrançois Tigeot 0),
1588926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
1589926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1590926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1591926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1592926deccbSFrançois Tigeot 2),
1593926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1594926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
1595926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
1596926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1597926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII,
1598926deccbSFrançois Tigeot &ddc_i2c,
1599926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1600926deccbSFrançois Tigeot &hpd);
1601926deccbSFrançois Tigeot
1602926deccbSFrançois Tigeot /* VGA - primary dac */
1603926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1604926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1605926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1606926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1607926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1608926deccbSFrançois Tigeot 1),
1609926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1610926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
1611926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1612926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA,
1613926deccbSFrançois Tigeot &ddc_i2c,
1614926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1615926deccbSFrançois Tigeot &hpd);
1616926deccbSFrançois Tigeot }
1617926deccbSFrançois Tigeot
1618926deccbSFrançois Tigeot if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
1619926deccbSFrançois Tigeot /* TV - tv dac */
1620926deccbSFrançois Tigeot ddc_i2c.valid = false;
1621926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1622926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1623926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1624926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1625926deccbSFrançois Tigeot 2),
1626926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1627926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2,
1628926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1629926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1630926deccbSFrançois Tigeot &ddc_i2c,
1631926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1632926deccbSFrançois Tigeot &hpd);
1633926deccbSFrançois Tigeot }
1634926deccbSFrançois Tigeot break;
1635926deccbSFrançois Tigeot case CT_IBOOK:
1636926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (ibook)\n",
1637926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1638926deccbSFrançois Tigeot /* LVDS */
1639926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1640926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1641926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1642926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1643926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1644926deccbSFrançois Tigeot 0),
1645926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
1646926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1647926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1648926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
1649926deccbSFrançois Tigeot &hpd);
1650926deccbSFrançois Tigeot /* VGA - TV DAC */
1651926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1652926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1653926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1654926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1655926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1656926deccbSFrançois Tigeot 2),
1657926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1658926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1659926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1660926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1661926deccbSFrançois Tigeot &hpd);
1662926deccbSFrançois Tigeot /* TV - TV DAC */
1663926deccbSFrançois Tigeot ddc_i2c.valid = false;
1664926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1665926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1666926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1667926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1668926deccbSFrançois Tigeot 2),
1669926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1670926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1671926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1672926deccbSFrançois Tigeot &ddc_i2c,
1673926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1674926deccbSFrançois Tigeot &hpd);
1675926deccbSFrançois Tigeot break;
1676926deccbSFrançois Tigeot case CT_POWERBOOK_EXTERNAL:
1677926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
1678926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1679926deccbSFrançois Tigeot /* LVDS */
1680926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1681926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1682926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1683926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1684926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1685926deccbSFrançois Tigeot 0),
1686926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
1687926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1688926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1689926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
1690926deccbSFrançois Tigeot &hpd);
1691926deccbSFrançois Tigeot /* DVI-I - primary dac, ext tmds */
1692926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1693926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_2; /* ??? */
1694926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1695926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1696926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT,
1697926deccbSFrançois Tigeot 0),
1698926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT);
1699926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1700926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1701926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1702926deccbSFrançois Tigeot 1),
1703926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1704926deccbSFrançois Tigeot /* XXX some are SL */
1705926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
1706926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT |
1707926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1708926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1709926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
1710926deccbSFrançois Tigeot &hpd);
1711926deccbSFrançois Tigeot /* TV - TV DAC */
1712926deccbSFrançois Tigeot ddc_i2c.valid = false;
1713926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1714926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1715926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1716926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1717926deccbSFrançois Tigeot 2),
1718926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1719926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1720926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1721926deccbSFrançois Tigeot &ddc_i2c,
1722926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1723926deccbSFrançois Tigeot &hpd);
1724926deccbSFrançois Tigeot break;
1725926deccbSFrançois Tigeot case CT_POWERBOOK_INTERNAL:
1726926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
1727926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1728926deccbSFrançois Tigeot /* LVDS */
1729926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1730926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1731926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1732926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1733926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1734926deccbSFrançois Tigeot 0),
1735926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
1736926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1737926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1738926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
1739926deccbSFrançois Tigeot &hpd);
1740926deccbSFrançois Tigeot /* DVI-I - primary dac, int tmds */
1741926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1742926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
1743926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1744926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1745926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
1746926deccbSFrançois Tigeot 0),
1747926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
1748926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1749926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1750926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1751926deccbSFrançois Tigeot 1),
1752926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1753926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
1754926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
1755926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1756926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1757926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1758926deccbSFrançois Tigeot &hpd);
1759926deccbSFrançois Tigeot /* TV - TV DAC */
1760926deccbSFrançois Tigeot ddc_i2c.valid = false;
1761926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1762926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1763926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1764926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1765926deccbSFrançois Tigeot 2),
1766926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1767926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1768926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1769926deccbSFrançois Tigeot &ddc_i2c,
1770926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1771926deccbSFrançois Tigeot &hpd);
1772926deccbSFrançois Tigeot break;
1773926deccbSFrançois Tigeot case CT_POWERBOOK_VGA:
1774926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (powerbook vga)\n",
1775926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1776926deccbSFrançois Tigeot /* LVDS */
1777926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1778926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1779926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1780926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1781926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
1782926deccbSFrançois Tigeot 0),
1783926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
1784926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
1785926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
1786926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
1787926deccbSFrançois Tigeot &hpd);
1788926deccbSFrançois Tigeot /* VGA - primary dac */
1789926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1790926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1791926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1792926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1793926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1794926deccbSFrançois Tigeot 1),
1795926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1796926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
1797926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1798926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1799926deccbSFrançois Tigeot &hpd);
1800926deccbSFrançois Tigeot /* TV - TV DAC */
1801926deccbSFrançois Tigeot ddc_i2c.valid = false;
1802926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1803926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1804926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1805926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1806926deccbSFrançois Tigeot 2),
1807926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1808926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1809926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1810926deccbSFrançois Tigeot &ddc_i2c,
1811926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1812926deccbSFrançois Tigeot &hpd);
1813926deccbSFrançois Tigeot break;
1814926deccbSFrançois Tigeot case CT_MINI_EXTERNAL:
1815926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (mini external tmds)\n",
1816926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1817926deccbSFrançois Tigeot /* DVI-I - tv dac, ext tmds */
1818926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1819926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_2; /* ??? */
1820926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1821926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1822926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT,
1823926deccbSFrançois Tigeot 0),
1824926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT);
1825926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1826926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1827926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1828926deccbSFrançois Tigeot 2),
1829926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1830926deccbSFrançois Tigeot /* XXX are any DL? */
1831926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
1832926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT |
1833926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1834926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1835926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1836926deccbSFrançois Tigeot &hpd);
1837926deccbSFrançois Tigeot /* TV - TV DAC */
1838926deccbSFrançois Tigeot ddc_i2c.valid = false;
1839926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1840926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1841926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1842926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1843926deccbSFrançois Tigeot 2),
1844926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1845926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
1846926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1847926deccbSFrançois Tigeot &ddc_i2c,
1848926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1849926deccbSFrançois Tigeot &hpd);
1850926deccbSFrançois Tigeot break;
1851926deccbSFrançois Tigeot case CT_MINI_INTERNAL:
1852926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (mini internal tmds)\n",
1853926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1854926deccbSFrançois Tigeot /* DVI-I - tv dac, int tmds */
1855926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1856926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
1857926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1858926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1859926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
1860926deccbSFrançois Tigeot 0),
1861926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
1862926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1863926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1864926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1865926deccbSFrançois Tigeot 2),
1866926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1867926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
1868926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
1869926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1870926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
1871926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
1872926deccbSFrançois Tigeot &hpd);
1873926deccbSFrançois Tigeot /* TV - TV DAC */
1874926deccbSFrançois Tigeot ddc_i2c.valid = false;
1875926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1876926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1877926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1878926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1879926deccbSFrançois Tigeot 2),
1880926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1881926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
1882926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1883926deccbSFrançois Tigeot &ddc_i2c,
1884926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1885926deccbSFrançois Tigeot &hpd);
1886926deccbSFrançois Tigeot break;
1887926deccbSFrançois Tigeot case CT_IMAC_G5_ISIGHT:
1888926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (imac g5 isight)\n",
1889926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1890926deccbSFrançois Tigeot /* DVI-D - int tmds */
1891926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
1892926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
1893926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1894926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1895926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
1896926deccbSFrançois Tigeot 0),
1897926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
1898926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
1899926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
1900926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
1901926deccbSFrançois Tigeot &hpd);
1902926deccbSFrançois Tigeot /* VGA - tv dac */
1903926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
1904926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1905926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1906926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1907926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1908926deccbSFrançois Tigeot 2),
1909926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1910926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1911926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1912926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1913926deccbSFrançois Tigeot &hpd);
1914926deccbSFrançois Tigeot /* TV - TV DAC */
1915926deccbSFrançois Tigeot ddc_i2c.valid = false;
1916926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1917926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1918926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1919926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1920926deccbSFrançois Tigeot 2),
1921926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1922926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1923926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1924926deccbSFrançois Tigeot &ddc_i2c,
1925926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1926926deccbSFrançois Tigeot &hpd);
1927926deccbSFrançois Tigeot break;
1928926deccbSFrançois Tigeot case CT_EMAC:
1929926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (emac)\n",
1930926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1931926deccbSFrançois Tigeot /* VGA - primary dac */
1932926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1933926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1934926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1935926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1936926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1937926deccbSFrançois Tigeot 1),
1938926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1939926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
1940926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1941926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1942926deccbSFrançois Tigeot &hpd);
1943926deccbSFrançois Tigeot /* VGA - tv dac */
1944926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1945926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1946926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1947926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1948926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1949926deccbSFrançois Tigeot 2),
1950926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1951926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1952926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1953926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1954926deccbSFrançois Tigeot &hpd);
1955926deccbSFrançois Tigeot /* TV - TV DAC */
1956926deccbSFrançois Tigeot ddc_i2c.valid = false;
1957926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1958926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1959926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1960926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
1961926deccbSFrançois Tigeot 2),
1962926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
1963926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
1964926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
1965926deccbSFrançois Tigeot &ddc_i2c,
1966926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
1967926deccbSFrançois Tigeot &hpd);
1968926deccbSFrançois Tigeot break;
1969926deccbSFrançois Tigeot case CT_RN50_POWER:
1970926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (rn50-power)\n",
1971926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1972926deccbSFrançois Tigeot /* VGA - primary dac */
1973926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
1974926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1975926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1976926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1977926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
1978926deccbSFrançois Tigeot 1),
1979926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
1980926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
1981926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1982926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1983926deccbSFrançois Tigeot &hpd);
1984926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
1985926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
1986926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
1987926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
1988926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
1989926deccbSFrançois Tigeot 2),
1990926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
1991926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
1992926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
1993926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
1994926deccbSFrançois Tigeot &hpd);
1995926deccbSFrançois Tigeot break;
1996926deccbSFrançois Tigeot case CT_MAC_X800:
1997926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (mac x800)\n",
1998926deccbSFrançois Tigeot rdev->mode_info.connector_table);
1999926deccbSFrançois Tigeot /* DVI - primary dac, internal tmds */
2000926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2001926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
2002926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2003926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2004926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2005926deccbSFrançois Tigeot 0),
2006926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2007926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2008926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2009926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2010926deccbSFrançois Tigeot 1),
2011926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2012926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
2013926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
2014926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2015926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2016926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2017926deccbSFrançois Tigeot &hpd);
2018926deccbSFrançois Tigeot /* DVI - tv dac, dvo */
2019926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
2020926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_2; /* ??? */
2021926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2022926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2023926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT,
2024926deccbSFrançois Tigeot 0),
2025926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT);
2026926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2027926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2028926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2029926deccbSFrançois Tigeot 2),
2030926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2031926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
2032926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT |
2033926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2034926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2035926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
2036926deccbSFrançois Tigeot &hpd);
2037926deccbSFrançois Tigeot break;
2038926deccbSFrançois Tigeot case CT_MAC_G5_9600:
2039926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (mac g5 9600)\n",
2040926deccbSFrançois Tigeot rdev->mode_info.connector_table);
2041926deccbSFrançois Tigeot /* DVI - tv dac, dvo */
2042926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2043926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
2044926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2045926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2046926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT,
2047926deccbSFrançois Tigeot 0),
2048926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT);
2049926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2050926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2051926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2052926deccbSFrançois Tigeot 2),
2053926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2054926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
2055926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT |
2056926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2057926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2058926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2059926deccbSFrançois Tigeot &hpd);
2060926deccbSFrançois Tigeot /* ADC - primary dac, internal tmds */
2061926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2062926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_2; /* ??? */
2063926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2064926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2065926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2066926deccbSFrançois Tigeot 0),
2067926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2068926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2069926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2070926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2071926deccbSFrançois Tigeot 1),
2072926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2073926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
2074926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
2075926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2076926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2077926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2078926deccbSFrançois Tigeot &hpd);
2079926deccbSFrançois Tigeot /* TV - TV DAC */
2080926deccbSFrançois Tigeot ddc_i2c.valid = false;
2081926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2082926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2083926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2084926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2085926deccbSFrançois Tigeot 2),
2086926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
2087926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
2088926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
2089926deccbSFrançois Tigeot &ddc_i2c,
2090926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
2091926deccbSFrançois Tigeot &hpd);
2092926deccbSFrançois Tigeot break;
2093926deccbSFrançois Tigeot case CT_SAM440EP:
2094926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
2095926deccbSFrançois Tigeot rdev->mode_info.connector_table);
2096926deccbSFrançois Tigeot /* LVDS */
2097926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
2098926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2099926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2100926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2101926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
2102926deccbSFrançois Tigeot 0),
2103926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
2104926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
2105926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
2106926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
2107926deccbSFrançois Tigeot &hpd);
2108926deccbSFrançois Tigeot /* DVI-I - secondary dac, int tmds */
2109926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2110926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
2111926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2112926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2113926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2114926deccbSFrançois Tigeot 0),
2115926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2116926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2117926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2118926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2119926deccbSFrançois Tigeot 2),
2120926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2121926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1,
2122926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
2123926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2124926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2125926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2126926deccbSFrançois Tigeot &hpd);
2127926deccbSFrançois Tigeot /* VGA - primary dac */
2128926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2129926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2130926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2131926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2132926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2133926deccbSFrançois Tigeot 1),
2134926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2135926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2,
2136926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2137926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
2138926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
2139926deccbSFrançois Tigeot &hpd);
2140926deccbSFrançois Tigeot /* TV - TV DAC */
2141926deccbSFrançois Tigeot ddc_i2c.valid = false;
2142926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2143926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2144926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2145926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2146926deccbSFrançois Tigeot 2),
2147926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
2148926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT,
2149926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
2150926deccbSFrançois Tigeot &ddc_i2c,
2151926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
2152926deccbSFrançois Tigeot &hpd);
2153926deccbSFrançois Tigeot break;
2154926deccbSFrançois Tigeot case CT_MAC_G4_SILVER:
2155926deccbSFrançois Tigeot DRM_INFO("Connector Table: %d (mac g4 silver)\n",
2156926deccbSFrançois Tigeot rdev->mode_info.connector_table);
2157926deccbSFrançois Tigeot /* DVI-I - tv dac, int tmds */
2158926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2159926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1; /* ??? */
2160926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2161926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2162926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2163926deccbSFrançois Tigeot 0),
2164926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2165926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2166926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2167926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2168926deccbSFrançois Tigeot 2),
2169926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2170926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 0,
2171926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT |
2172926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2173926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
2174926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2175926deccbSFrançois Tigeot &hpd);
2176926deccbSFrançois Tigeot /* VGA - primary dac */
2177926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2178926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2179926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2180926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2181926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2182926deccbSFrançois Tigeot 1),
2183926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2184926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
2185926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
2186926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
2187926deccbSFrançois Tigeot &hpd);
2188926deccbSFrançois Tigeot /* TV - TV DAC */
2189926deccbSFrançois Tigeot ddc_i2c.valid = false;
2190926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2191926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2192926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2193926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2194926deccbSFrançois Tigeot 2),
2195926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
2196926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
2197926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
2198926deccbSFrançois Tigeot &ddc_i2c,
2199926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
2200926deccbSFrançois Tigeot &hpd);
2201926deccbSFrançois Tigeot break;
2202926deccbSFrançois Tigeot default:
2203926deccbSFrançois Tigeot DRM_INFO("Connector table: %d (invalid)\n",
2204926deccbSFrançois Tigeot rdev->mode_info.connector_table);
2205926deccbSFrançois Tigeot return false;
2206926deccbSFrançois Tigeot }
2207926deccbSFrançois Tigeot
2208926deccbSFrançois Tigeot radeon_link_encoder_connector(dev);
2209926deccbSFrançois Tigeot
2210926deccbSFrançois Tigeot return true;
2211926deccbSFrançois Tigeot }
2212926deccbSFrançois Tigeot
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)2213926deccbSFrançois Tigeot static bool radeon_apply_legacy_quirks(struct drm_device *dev,
2214926deccbSFrançois Tigeot int bios_index,
2215926deccbSFrançois Tigeot enum radeon_combios_connector
2216926deccbSFrançois Tigeot *legacy_connector,
2217926deccbSFrançois Tigeot struct radeon_i2c_bus_rec *ddc_i2c,
2218926deccbSFrançois Tigeot struct radeon_hpd *hpd)
2219926deccbSFrançois Tigeot {
2220926deccbSFrançois Tigeot
2221926deccbSFrançois Tigeot /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
2222926deccbSFrançois Tigeot one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
2223c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x515e &&
2224c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x1014) {
2225926deccbSFrançois Tigeot if (*legacy_connector == CONNECTOR_CRT_LEGACY &&
2226926deccbSFrançois Tigeot ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
2227926deccbSFrançois Tigeot return false;
2228926deccbSFrançois Tigeot }
2229926deccbSFrançois Tigeot
2230926deccbSFrançois Tigeot /* X300 card with extra non-existent DVI port */
2231c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x5B60 &&
2232c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x17af &&
2233c6f73aabSFrançois Tigeot dev->pdev->subsystem_device == 0x201e && bios_index == 2) {
2234926deccbSFrançois Tigeot if (*legacy_connector == CONNECTOR_DVI_I_LEGACY)
2235926deccbSFrançois Tigeot return false;
2236926deccbSFrançois Tigeot }
2237926deccbSFrançois Tigeot
2238926deccbSFrançois Tigeot return true;
2239926deccbSFrançois Tigeot }
2240926deccbSFrançois Tigeot
radeon_apply_legacy_tv_quirks(struct drm_device * dev)2241926deccbSFrançois Tigeot static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
2242926deccbSFrançois Tigeot {
2243926deccbSFrançois Tigeot /* Acer 5102 has non-existent TV port */
2244c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x5975 &&
2245c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x1025 &&
2246c6f73aabSFrançois Tigeot dev->pdev->subsystem_device == 0x009f)
2247926deccbSFrançois Tigeot return false;
2248926deccbSFrançois Tigeot
2249926deccbSFrançois Tigeot /* HP dc5750 has non-existent TV port */
2250c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x5974 &&
2251c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x103c &&
2252c6f73aabSFrançois Tigeot dev->pdev->subsystem_device == 0x280a)
2253926deccbSFrançois Tigeot return false;
2254926deccbSFrançois Tigeot
2255926deccbSFrançois Tigeot /* MSI S270 has non-existent TV port */
2256c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x5955 &&
2257c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x1462 &&
2258c6f73aabSFrançois Tigeot dev->pdev->subsystem_device == 0x0131)
2259926deccbSFrançois Tigeot return false;
2260926deccbSFrançois Tigeot
2261926deccbSFrançois Tigeot return true;
2262926deccbSFrançois Tigeot }
2263926deccbSFrançois Tigeot
combios_check_dl_dvi(struct drm_device * dev,int is_dvi_d)2264926deccbSFrançois Tigeot static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
2265926deccbSFrançois Tigeot {
2266926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
2267926deccbSFrançois Tigeot uint32_t ext_tmds_info;
2268926deccbSFrançois Tigeot
2269926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
2270926deccbSFrançois Tigeot if (is_dvi_d)
2271926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
2272926deccbSFrançois Tigeot else
2273926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2274926deccbSFrançois Tigeot }
2275926deccbSFrançois Tigeot ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
2276926deccbSFrançois Tigeot if (ext_tmds_info) {
2277926deccbSFrançois Tigeot uint8_t rev = RBIOS8(ext_tmds_info);
2278926deccbSFrançois Tigeot uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
2279926deccbSFrançois Tigeot if (rev >= 3) {
2280926deccbSFrançois Tigeot if (is_dvi_d)
2281926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
2282926deccbSFrançois Tigeot else
2283926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
2284926deccbSFrançois Tigeot } else {
2285926deccbSFrançois Tigeot if (flags & 1) {
2286926deccbSFrançois Tigeot if (is_dvi_d)
2287926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
2288926deccbSFrançois Tigeot else
2289926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
2290926deccbSFrançois Tigeot }
2291926deccbSFrançois Tigeot }
2292926deccbSFrançois Tigeot }
2293926deccbSFrançois Tigeot if (is_dvi_d)
2294926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
2295926deccbSFrançois Tigeot else
2296926deccbSFrançois Tigeot return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2297926deccbSFrançois Tigeot }
2298926deccbSFrançois Tigeot
radeon_get_legacy_connector_info_from_bios(struct drm_device * dev)2299926deccbSFrançois Tigeot bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
2300926deccbSFrançois Tigeot {
2301926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
2302926deccbSFrançois Tigeot uint32_t conn_info, entry, devices;
2303926deccbSFrançois Tigeot uint16_t tmp, connector_object_id;
2304926deccbSFrançois Tigeot enum radeon_combios_ddc ddc_type;
2305926deccbSFrançois Tigeot enum radeon_combios_connector connector;
2306926deccbSFrançois Tigeot int i = 0;
2307926deccbSFrançois Tigeot struct radeon_i2c_bus_rec ddc_i2c;
2308926deccbSFrançois Tigeot struct radeon_hpd hpd;
2309926deccbSFrançois Tigeot
2310926deccbSFrançois Tigeot conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
2311926deccbSFrançois Tigeot if (conn_info) {
2312926deccbSFrançois Tigeot for (i = 0; i < 4; i++) {
2313926deccbSFrançois Tigeot entry = conn_info + 2 + i * 2;
2314926deccbSFrançois Tigeot
2315926deccbSFrançois Tigeot if (!RBIOS16(entry))
2316926deccbSFrançois Tigeot break;
2317926deccbSFrançois Tigeot
2318926deccbSFrançois Tigeot tmp = RBIOS16(entry);
2319926deccbSFrançois Tigeot
2320926deccbSFrançois Tigeot connector = (tmp >> 12) & 0xf;
2321926deccbSFrançois Tigeot
2322926deccbSFrançois Tigeot ddc_type = (tmp >> 8) & 0xf;
2323926deccbSFrançois Tigeot if (ddc_type == 5)
2324926deccbSFrançois Tigeot ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
2325926deccbSFrançois Tigeot else
2326926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
2327926deccbSFrançois Tigeot
2328926deccbSFrançois Tigeot switch (connector) {
2329926deccbSFrançois Tigeot case CONNECTOR_PROPRIETARY_LEGACY:
2330926deccbSFrançois Tigeot case CONNECTOR_DVI_I_LEGACY:
2331926deccbSFrançois Tigeot case CONNECTOR_DVI_D_LEGACY:
2332926deccbSFrançois Tigeot if ((tmp >> 4) & 0x1)
2333926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_2;
2334926deccbSFrançois Tigeot else
2335926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1;
2336926deccbSFrançois Tigeot break;
2337926deccbSFrançois Tigeot default:
2338926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2339926deccbSFrançois Tigeot break;
2340926deccbSFrançois Tigeot }
2341926deccbSFrançois Tigeot
2342926deccbSFrançois Tigeot if (!radeon_apply_legacy_quirks(dev, i, &connector,
2343926deccbSFrançois Tigeot &ddc_i2c, &hpd))
2344926deccbSFrançois Tigeot continue;
2345926deccbSFrançois Tigeot
2346926deccbSFrançois Tigeot switch (connector) {
2347926deccbSFrançois Tigeot case CONNECTOR_PROPRIETARY_LEGACY:
2348926deccbSFrançois Tigeot if ((tmp >> 4) & 0x1)
2349926deccbSFrançois Tigeot devices = ATOM_DEVICE_DFP2_SUPPORT;
2350926deccbSFrançois Tigeot else
2351926deccbSFrançois Tigeot devices = ATOM_DEVICE_DFP1_SUPPORT;
2352926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2353926deccbSFrançois Tigeot radeon_get_encoder_enum
2354926deccbSFrançois Tigeot (dev, devices, 0),
2355926deccbSFrançois Tigeot devices);
2356926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, i, devices,
2357926deccbSFrançois Tigeot legacy_connector_convert
2358926deccbSFrançois Tigeot [connector],
2359926deccbSFrançois Tigeot &ddc_i2c,
2360926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
2361926deccbSFrançois Tigeot &hpd);
2362926deccbSFrançois Tigeot break;
2363926deccbSFrançois Tigeot case CONNECTOR_CRT_LEGACY:
2364926deccbSFrançois Tigeot if (tmp & 0x1) {
2365926deccbSFrançois Tigeot devices = ATOM_DEVICE_CRT2_SUPPORT;
2366926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2367926deccbSFrançois Tigeot radeon_get_encoder_enum
2368926deccbSFrançois Tigeot (dev,
2369926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2370926deccbSFrançois Tigeot 2),
2371926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2372926deccbSFrançois Tigeot } else {
2373926deccbSFrançois Tigeot devices = ATOM_DEVICE_CRT1_SUPPORT;
2374926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2375926deccbSFrançois Tigeot radeon_get_encoder_enum
2376926deccbSFrançois Tigeot (dev,
2377926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2378926deccbSFrançois Tigeot 1),
2379926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2380926deccbSFrançois Tigeot }
2381926deccbSFrançois Tigeot radeon_add_legacy_connector(dev,
2382926deccbSFrançois Tigeot i,
2383926deccbSFrançois Tigeot devices,
2384926deccbSFrançois Tigeot legacy_connector_convert
2385926deccbSFrançois Tigeot [connector],
2386926deccbSFrançois Tigeot &ddc_i2c,
2387926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
2388926deccbSFrançois Tigeot &hpd);
2389926deccbSFrançois Tigeot break;
2390926deccbSFrançois Tigeot case CONNECTOR_DVI_I_LEGACY:
2391926deccbSFrançois Tigeot devices = 0;
2392926deccbSFrançois Tigeot if (tmp & 0x1) {
2393926deccbSFrançois Tigeot devices |= ATOM_DEVICE_CRT2_SUPPORT;
2394926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2395926deccbSFrançois Tigeot radeon_get_encoder_enum
2396926deccbSFrançois Tigeot (dev,
2397926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT,
2398926deccbSFrançois Tigeot 2),
2399926deccbSFrançois Tigeot ATOM_DEVICE_CRT2_SUPPORT);
2400926deccbSFrançois Tigeot } else {
2401926deccbSFrançois Tigeot devices |= ATOM_DEVICE_CRT1_SUPPORT;
2402926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2403926deccbSFrançois Tigeot radeon_get_encoder_enum
2404926deccbSFrançois Tigeot (dev,
2405926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2406926deccbSFrançois Tigeot 1),
2407926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2408926deccbSFrançois Tigeot }
2409926deccbSFrançois Tigeot /* RV100 board with external TDMS bit mis-set.
2410926deccbSFrançois Tigeot * Actually uses internal TMDS, clear the bit.
2411926deccbSFrançois Tigeot */
2412c6f73aabSFrançois Tigeot if (dev->pdev->device == 0x5159 &&
2413c6f73aabSFrançois Tigeot dev->pdev->subsystem_vendor == 0x1014 &&
2414c6f73aabSFrançois Tigeot dev->pdev->subsystem_device == 0x029A) {
2415926deccbSFrançois Tigeot tmp &= ~(1 << 4);
2416926deccbSFrançois Tigeot }
2417926deccbSFrançois Tigeot if ((tmp >> 4) & 0x1) {
2418926deccbSFrançois Tigeot devices |= ATOM_DEVICE_DFP2_SUPPORT;
2419926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2420926deccbSFrançois Tigeot radeon_get_encoder_enum
2421926deccbSFrançois Tigeot (dev,
2422926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT,
2423926deccbSFrançois Tigeot 0),
2424926deccbSFrançois Tigeot ATOM_DEVICE_DFP2_SUPPORT);
2425926deccbSFrançois Tigeot connector_object_id = combios_check_dl_dvi(dev, 0);
2426926deccbSFrançois Tigeot } else {
2427926deccbSFrançois Tigeot devices |= ATOM_DEVICE_DFP1_SUPPORT;
2428926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2429926deccbSFrançois Tigeot radeon_get_encoder_enum
2430926deccbSFrançois Tigeot (dev,
2431926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2432926deccbSFrançois Tigeot 0),
2433926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2434926deccbSFrançois Tigeot connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2435926deccbSFrançois Tigeot }
2436926deccbSFrançois Tigeot radeon_add_legacy_connector(dev,
2437926deccbSFrançois Tigeot i,
2438926deccbSFrançois Tigeot devices,
2439926deccbSFrançois Tigeot legacy_connector_convert
2440926deccbSFrançois Tigeot [connector],
2441926deccbSFrançois Tigeot &ddc_i2c,
2442926deccbSFrançois Tigeot connector_object_id,
2443926deccbSFrançois Tigeot &hpd);
2444926deccbSFrançois Tigeot break;
2445926deccbSFrançois Tigeot case CONNECTOR_DVI_D_LEGACY:
2446926deccbSFrançois Tigeot if ((tmp >> 4) & 0x1) {
2447926deccbSFrançois Tigeot devices = ATOM_DEVICE_DFP2_SUPPORT;
2448926deccbSFrançois Tigeot connector_object_id = combios_check_dl_dvi(dev, 1);
2449926deccbSFrançois Tigeot } else {
2450926deccbSFrançois Tigeot devices = ATOM_DEVICE_DFP1_SUPPORT;
2451926deccbSFrançois Tigeot connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
2452926deccbSFrançois Tigeot }
2453926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2454926deccbSFrançois Tigeot radeon_get_encoder_enum
2455926deccbSFrançois Tigeot (dev, devices, 0),
2456926deccbSFrançois Tigeot devices);
2457926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, i, devices,
2458926deccbSFrançois Tigeot legacy_connector_convert
2459926deccbSFrançois Tigeot [connector],
2460926deccbSFrançois Tigeot &ddc_i2c,
2461926deccbSFrançois Tigeot connector_object_id,
2462926deccbSFrançois Tigeot &hpd);
2463926deccbSFrançois Tigeot break;
2464926deccbSFrançois Tigeot case CONNECTOR_CTV_LEGACY:
2465926deccbSFrançois Tigeot case CONNECTOR_STV_LEGACY:
2466926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2467926deccbSFrançois Tigeot radeon_get_encoder_enum
2468926deccbSFrançois Tigeot (dev,
2469926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2470926deccbSFrançois Tigeot 2),
2471926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
2472926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, i,
2473926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2474926deccbSFrançois Tigeot legacy_connector_convert
2475926deccbSFrançois Tigeot [connector],
2476926deccbSFrançois Tigeot &ddc_i2c,
2477926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
2478926deccbSFrançois Tigeot &hpd);
2479926deccbSFrançois Tigeot break;
2480926deccbSFrançois Tigeot default:
2481926deccbSFrançois Tigeot DRM_ERROR("Unknown connector type: %d\n",
2482926deccbSFrançois Tigeot connector);
2483926deccbSFrançois Tigeot continue;
2484926deccbSFrançois Tigeot }
2485926deccbSFrançois Tigeot
2486926deccbSFrançois Tigeot }
2487926deccbSFrançois Tigeot } else {
2488926deccbSFrançois Tigeot uint16_t tmds_info =
2489926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
2490926deccbSFrançois Tigeot if (tmds_info) {
2491926deccbSFrançois Tigeot DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
2492926deccbSFrançois Tigeot
2493926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2494926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2495926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2496926deccbSFrançois Tigeot 1),
2497926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2498926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2499926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2500926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2501926deccbSFrançois Tigeot 0),
2502926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT);
2503926deccbSFrançois Tigeot
2504926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
2505926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_1;
2506926deccbSFrançois Tigeot radeon_add_legacy_connector(dev,
2507926deccbSFrançois Tigeot 0,
2508926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT |
2509926deccbSFrançois Tigeot ATOM_DEVICE_DFP1_SUPPORT,
2510926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_DVII,
2511926deccbSFrançois Tigeot &ddc_i2c,
2512926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
2513926deccbSFrançois Tigeot &hpd);
2514926deccbSFrançois Tigeot } else {
2515926deccbSFrançois Tigeot uint16_t crt_info =
2516926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
2517926deccbSFrançois Tigeot DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
2518926deccbSFrançois Tigeot if (crt_info) {
2519926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2520926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2521926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2522926deccbSFrançois Tigeot 1),
2523926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT);
2524926deccbSFrançois Tigeot ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
2525926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2526926deccbSFrançois Tigeot radeon_add_legacy_connector(dev,
2527926deccbSFrançois Tigeot 0,
2528926deccbSFrançois Tigeot ATOM_DEVICE_CRT1_SUPPORT,
2529926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_VGA,
2530926deccbSFrançois Tigeot &ddc_i2c,
2531926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_VGA,
2532926deccbSFrançois Tigeot &hpd);
2533926deccbSFrançois Tigeot } else {
2534926deccbSFrançois Tigeot DRM_DEBUG_KMS("No connector info found\n");
2535926deccbSFrançois Tigeot return false;
2536926deccbSFrançois Tigeot }
2537926deccbSFrançois Tigeot }
2538926deccbSFrançois Tigeot }
2539926deccbSFrançois Tigeot
2540926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) {
2541926deccbSFrançois Tigeot uint16_t lcd_info =
2542926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
2543926deccbSFrançois Tigeot if (lcd_info) {
2544926deccbSFrançois Tigeot uint16_t lcd_ddc_info =
2545926deccbSFrançois Tigeot combios_get_table_offset(dev,
2546926deccbSFrançois Tigeot COMBIOS_LCD_DDC_INFO_TABLE);
2547926deccbSFrançois Tigeot
2548926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2549926deccbSFrançois Tigeot radeon_get_encoder_enum(dev,
2550926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
2551926deccbSFrançois Tigeot 0),
2552926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT);
2553926deccbSFrançois Tigeot
2554926deccbSFrançois Tigeot if (lcd_ddc_info) {
2555926deccbSFrançois Tigeot ddc_type = RBIOS8(lcd_ddc_info + 2);
2556926deccbSFrançois Tigeot switch (ddc_type) {
2557926deccbSFrançois Tigeot case DDC_LCD:
2558926deccbSFrançois Tigeot ddc_i2c =
2559926deccbSFrançois Tigeot combios_setup_i2c_bus(rdev,
2560926deccbSFrançois Tigeot DDC_LCD,
2561926deccbSFrançois Tigeot RBIOS32(lcd_ddc_info + 3),
2562926deccbSFrançois Tigeot RBIOS32(lcd_ddc_info + 7));
2563926deccbSFrançois Tigeot radeon_i2c_add(rdev, &ddc_i2c, "LCD");
2564926deccbSFrançois Tigeot break;
2565926deccbSFrançois Tigeot case DDC_GPIO:
2566926deccbSFrançois Tigeot ddc_i2c =
2567926deccbSFrançois Tigeot combios_setup_i2c_bus(rdev,
2568926deccbSFrançois Tigeot DDC_GPIO,
2569926deccbSFrançois Tigeot RBIOS32(lcd_ddc_info + 3),
2570926deccbSFrançois Tigeot RBIOS32(lcd_ddc_info + 7));
2571926deccbSFrançois Tigeot radeon_i2c_add(rdev, &ddc_i2c, "LCD");
2572926deccbSFrançois Tigeot break;
2573926deccbSFrançois Tigeot default:
2574926deccbSFrançois Tigeot ddc_i2c =
2575926deccbSFrançois Tigeot combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
2576926deccbSFrançois Tigeot break;
2577926deccbSFrançois Tigeot }
2578926deccbSFrançois Tigeot DRM_DEBUG_KMS("LCD DDC Info Table found!\n");
2579926deccbSFrançois Tigeot } else
2580926deccbSFrançois Tigeot ddc_i2c.valid = false;
2581926deccbSFrançois Tigeot
2582926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2583926deccbSFrançois Tigeot radeon_add_legacy_connector(dev,
2584926deccbSFrançois Tigeot 5,
2585926deccbSFrançois Tigeot ATOM_DEVICE_LCD1_SUPPORT,
2586926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_LVDS,
2587926deccbSFrançois Tigeot &ddc_i2c,
2588926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_LVDS,
2589926deccbSFrançois Tigeot &hpd);
2590926deccbSFrançois Tigeot }
2591926deccbSFrançois Tigeot }
2592926deccbSFrançois Tigeot
2593926deccbSFrançois Tigeot /* check TV table */
2594926deccbSFrançois Tigeot if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
2595926deccbSFrançois Tigeot uint32_t tv_info =
2596926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
2597926deccbSFrançois Tigeot if (tv_info) {
2598926deccbSFrançois Tigeot if (RBIOS8(tv_info + 6) == 'T') {
2599926deccbSFrançois Tigeot if (radeon_apply_legacy_tv_quirks(dev)) {
2600926deccbSFrançois Tigeot hpd.hpd = RADEON_HPD_NONE;
2601926deccbSFrançois Tigeot ddc_i2c.valid = false;
2602926deccbSFrançois Tigeot radeon_add_legacy_encoder(dev,
2603926deccbSFrançois Tigeot radeon_get_encoder_enum
2604926deccbSFrançois Tigeot (dev,
2605926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2606926deccbSFrançois Tigeot 2),
2607926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT);
2608926deccbSFrançois Tigeot radeon_add_legacy_connector(dev, 6,
2609926deccbSFrançois Tigeot ATOM_DEVICE_TV1_SUPPORT,
2610926deccbSFrançois Tigeot DRM_MODE_CONNECTOR_SVIDEO,
2611926deccbSFrançois Tigeot &ddc_i2c,
2612926deccbSFrançois Tigeot CONNECTOR_OBJECT_ID_SVIDEO,
2613926deccbSFrançois Tigeot &hpd);
2614926deccbSFrançois Tigeot }
2615926deccbSFrançois Tigeot }
2616926deccbSFrançois Tigeot }
2617926deccbSFrançois Tigeot }
2618926deccbSFrançois Tigeot
2619926deccbSFrançois Tigeot radeon_link_encoder_connector(dev);
2620926deccbSFrançois Tigeot
2621926deccbSFrançois Tigeot return true;
2622926deccbSFrançois Tigeot }
2623926deccbSFrançois Tigeot
2624926deccbSFrançois Tigeot static const char *thermal_controller_names[] = {
2625926deccbSFrançois Tigeot "NONE",
2626926deccbSFrançois Tigeot "lm63",
2627926deccbSFrançois Tigeot "adm1032",
2628926deccbSFrançois Tigeot };
2629926deccbSFrançois Tigeot
radeon_combios_get_power_modes(struct radeon_device * rdev)2630926deccbSFrançois Tigeot void radeon_combios_get_power_modes(struct radeon_device *rdev)
2631926deccbSFrançois Tigeot {
2632926deccbSFrançois Tigeot struct drm_device *dev = rdev->ddev;
2633926deccbSFrançois Tigeot u16 offset, misc, misc2 = 0;
2634926deccbSFrançois Tigeot u8 rev, blocks, tmp;
2635926deccbSFrançois Tigeot int state_index = 0;
2636926deccbSFrançois Tigeot struct radeon_i2c_bus_rec i2c_bus;
2637926deccbSFrançois Tigeot
2638926deccbSFrançois Tigeot rdev->pm.default_power_state_index = -1;
2639926deccbSFrançois Tigeot
2640926deccbSFrançois Tigeot /* allocate 2 power states */
2641c4ef309bSzrj rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL);
2642926deccbSFrançois Tigeot if (rdev->pm.power_state) {
2643926deccbSFrançois Tigeot /* allocate 1 clock mode per state */
2644926deccbSFrançois Tigeot rdev->pm.power_state[0].clock_info =
2645c4ef309bSzrj kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2646926deccbSFrançois Tigeot rdev->pm.power_state[1].clock_info =
2647c4ef309bSzrj kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2648926deccbSFrançois Tigeot if (!rdev->pm.power_state[0].clock_info ||
2649926deccbSFrançois Tigeot !rdev->pm.power_state[1].clock_info)
2650926deccbSFrançois Tigeot goto pm_failed;
2651926deccbSFrançois Tigeot } else
2652926deccbSFrançois Tigeot goto pm_failed;
2653926deccbSFrançois Tigeot
2654926deccbSFrançois Tigeot /* check for a thermal chip */
2655926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
2656926deccbSFrançois Tigeot if (offset) {
2657926deccbSFrançois Tigeot u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
2658926deccbSFrançois Tigeot
2659926deccbSFrançois Tigeot rev = RBIOS8(offset);
2660926deccbSFrançois Tigeot
2661926deccbSFrançois Tigeot if (rev == 0) {
2662926deccbSFrançois Tigeot thermal_controller = RBIOS8(offset + 3);
2663926deccbSFrançois Tigeot gpio = RBIOS8(offset + 4) & 0x3f;
2664926deccbSFrançois Tigeot i2c_addr = RBIOS8(offset + 5);
2665926deccbSFrançois Tigeot } else if (rev == 1) {
2666926deccbSFrançois Tigeot thermal_controller = RBIOS8(offset + 4);
2667926deccbSFrançois Tigeot gpio = RBIOS8(offset + 5) & 0x3f;
2668926deccbSFrançois Tigeot i2c_addr = RBIOS8(offset + 6);
2669926deccbSFrançois Tigeot } else if (rev == 2) {
2670926deccbSFrançois Tigeot thermal_controller = RBIOS8(offset + 4);
2671926deccbSFrançois Tigeot gpio = RBIOS8(offset + 5) & 0x3f;
2672926deccbSFrançois Tigeot i2c_addr = RBIOS8(offset + 6);
2673926deccbSFrançois Tigeot clk_bit = RBIOS8(offset + 0xa);
2674926deccbSFrançois Tigeot data_bit = RBIOS8(offset + 0xb);
2675926deccbSFrançois Tigeot }
2676926deccbSFrançois Tigeot if ((thermal_controller > 0) && (thermal_controller < 3)) {
2677926deccbSFrançois Tigeot DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2678926deccbSFrançois Tigeot thermal_controller_names[thermal_controller],
2679926deccbSFrançois Tigeot i2c_addr >> 1);
2680926deccbSFrançois Tigeot if (gpio == DDC_LCD) {
2681926deccbSFrançois Tigeot /* MM i2c */
2682926deccbSFrançois Tigeot i2c_bus.valid = true;
2683926deccbSFrançois Tigeot i2c_bus.hw_capable = true;
2684926deccbSFrançois Tigeot i2c_bus.mm_i2c = true;
2685926deccbSFrançois Tigeot i2c_bus.i2c_id = 0xa0;
2686926deccbSFrançois Tigeot } else if (gpio == DDC_GPIO)
2687926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
2688926deccbSFrançois Tigeot else
2689926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
2690926deccbSFrançois Tigeot rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2691926deccbSFrançois Tigeot if (rdev->pm.i2c_bus) {
2692926deccbSFrançois Tigeot struct i2c_board_info info = { };
2693926deccbSFrançois Tigeot const char *name = thermal_controller_names[thermal_controller];
2694926deccbSFrançois Tigeot info.addr = i2c_addr >> 1;
2695926deccbSFrançois Tigeot strlcpy(info.type, name, sizeof(info.type));
2696926deccbSFrançois Tigeot i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
2697926deccbSFrançois Tigeot }
2698926deccbSFrançois Tigeot }
2699926deccbSFrançois Tigeot } else {
2700926deccbSFrançois Tigeot /* boards with a thermal chip, but no overdrive table */
2701926deccbSFrançois Tigeot
2702926deccbSFrançois Tigeot /* Asus 9600xt has an f75375 on the monid bus */
2703c6f73aabSFrançois Tigeot if ((dev->pdev->device == 0x4152) &&
2704c6f73aabSFrançois Tigeot (dev->pdev->subsystem_vendor == 0x1043) &&
2705c6f73aabSFrançois Tigeot (dev->pdev->subsystem_device == 0xc002)) {
2706926deccbSFrançois Tigeot i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
2707926deccbSFrançois Tigeot rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2708926deccbSFrançois Tigeot if (rdev->pm.i2c_bus) {
2709926deccbSFrançois Tigeot struct i2c_board_info info = { };
2710926deccbSFrançois Tigeot const char *name = "f75375";
2711926deccbSFrançois Tigeot info.addr = 0x28;
2712926deccbSFrançois Tigeot strlcpy(info.type, name, sizeof(info.type));
2713926deccbSFrançois Tigeot i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
2714926deccbSFrançois Tigeot DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2715926deccbSFrançois Tigeot name, info.addr);
2716926deccbSFrançois Tigeot }
2717926deccbSFrançois Tigeot }
2718926deccbSFrançois Tigeot }
2719926deccbSFrançois Tigeot
2720926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_MOBILITY) {
2721926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
2722926deccbSFrançois Tigeot if (offset) {
2723926deccbSFrançois Tigeot rev = RBIOS8(offset);
2724926deccbSFrançois Tigeot blocks = RBIOS8(offset + 0x2);
2725926deccbSFrançois Tigeot /* power mode 0 tends to be the only valid one */
2726926deccbSFrançois Tigeot rdev->pm.power_state[state_index].num_clock_modes = 1;
2727926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
2728926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
2729926deccbSFrançois Tigeot if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2730926deccbSFrançois Tigeot (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2731926deccbSFrançois Tigeot goto default_mode;
2732926deccbSFrançois Tigeot rdev->pm.power_state[state_index].type =
2733926deccbSFrançois Tigeot POWER_STATE_TYPE_BATTERY;
2734926deccbSFrançois Tigeot misc = RBIOS16(offset + 0x5 + 0x0);
2735926deccbSFrançois Tigeot if (rev > 4)
2736926deccbSFrançois Tigeot misc2 = RBIOS16(offset + 0x5 + 0xe);
2737926deccbSFrançois Tigeot rdev->pm.power_state[state_index].misc = misc;
2738926deccbSFrançois Tigeot rdev->pm.power_state[state_index].misc2 = misc2;
2739926deccbSFrançois Tigeot if (misc & 0x4) {
2740926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
2741926deccbSFrançois Tigeot if (misc & 0x8)
2742926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2743926deccbSFrançois Tigeot true;
2744926deccbSFrançois Tigeot else
2745926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2746926deccbSFrançois Tigeot false;
2747926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
2748926deccbSFrançois Tigeot if (rev < 6) {
2749926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
2750926deccbSFrançois Tigeot RBIOS16(offset + 0x5 + 0xb) * 4;
2751926deccbSFrançois Tigeot tmp = RBIOS8(offset + 0x5 + 0xd);
2752926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
2753926deccbSFrançois Tigeot } else {
2754926deccbSFrançois Tigeot u8 entries = RBIOS8(offset + 0x5 + 0xb);
2755926deccbSFrançois Tigeot u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
2756926deccbSFrançois Tigeot if (entries && voltage_table_offset) {
2757926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
2758926deccbSFrançois Tigeot RBIOS16(voltage_table_offset) * 4;
2759926deccbSFrançois Tigeot tmp = RBIOS8(voltage_table_offset + 0x2);
2760926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
2761926deccbSFrançois Tigeot } else
2762926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
2763926deccbSFrançois Tigeot }
2764926deccbSFrançois Tigeot switch ((misc2 & 0x700) >> 8) {
2765926deccbSFrançois Tigeot case 0:
2766926deccbSFrançois Tigeot default:
2767926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
2768926deccbSFrançois Tigeot break;
2769926deccbSFrançois Tigeot case 1:
2770926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
2771926deccbSFrançois Tigeot break;
2772926deccbSFrançois Tigeot case 2:
2773926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
2774926deccbSFrançois Tigeot break;
2775926deccbSFrançois Tigeot case 3:
2776926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
2777926deccbSFrançois Tigeot break;
2778926deccbSFrançois Tigeot case 4:
2779926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
2780926deccbSFrançois Tigeot break;
2781926deccbSFrançois Tigeot }
2782926deccbSFrançois Tigeot } else
2783926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2784926deccbSFrançois Tigeot if (rev > 6)
2785926deccbSFrançois Tigeot rdev->pm.power_state[state_index].pcie_lanes =
2786926deccbSFrançois Tigeot RBIOS8(offset + 0x5 + 0x10);
2787926deccbSFrançois Tigeot rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2788926deccbSFrançois Tigeot state_index++;
2789926deccbSFrançois Tigeot } else {
2790926deccbSFrançois Tigeot /* XXX figure out some good default low power mode for mobility cards w/out power tables */
2791926deccbSFrançois Tigeot }
2792926deccbSFrançois Tigeot } else {
2793926deccbSFrançois Tigeot /* XXX figure out some good default low power mode for desktop cards */
2794926deccbSFrançois Tigeot }
2795926deccbSFrançois Tigeot
2796926deccbSFrançois Tigeot default_mode:
2797926deccbSFrançois Tigeot /* add the default mode */
2798926deccbSFrançois Tigeot rdev->pm.power_state[state_index].type =
2799926deccbSFrançois Tigeot POWER_STATE_TYPE_DEFAULT;
2800926deccbSFrançois Tigeot rdev->pm.power_state[state_index].num_clock_modes = 1;
2801926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2802926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2803926deccbSFrançois Tigeot rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
2804926deccbSFrançois Tigeot if ((state_index > 0) &&
2805926deccbSFrançois Tigeot (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO))
2806926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage =
2807926deccbSFrançois Tigeot rdev->pm.power_state[0].clock_info[0].voltage;
2808926deccbSFrançois Tigeot else
2809926deccbSFrançois Tigeot rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2810926deccbSFrançois Tigeot rdev->pm.power_state[state_index].pcie_lanes = 16;
2811926deccbSFrançois Tigeot rdev->pm.power_state[state_index].flags = 0;
2812926deccbSFrançois Tigeot rdev->pm.default_power_state_index = state_index;
2813926deccbSFrançois Tigeot rdev->pm.num_power_states = state_index + 1;
2814926deccbSFrançois Tigeot
2815926deccbSFrançois Tigeot rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2816926deccbSFrançois Tigeot rdev->pm.current_clock_mode_index = 0;
2817926deccbSFrançois Tigeot return;
2818926deccbSFrançois Tigeot
2819926deccbSFrançois Tigeot pm_failed:
2820926deccbSFrançois Tigeot rdev->pm.default_power_state_index = state_index;
2821926deccbSFrançois Tigeot rdev->pm.num_power_states = 0;
2822926deccbSFrançois Tigeot
2823926deccbSFrançois Tigeot rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2824926deccbSFrançois Tigeot rdev->pm.current_clock_mode_index = 0;
2825926deccbSFrançois Tigeot }
2826926deccbSFrançois Tigeot
radeon_external_tmds_setup(struct drm_encoder * encoder)2827926deccbSFrançois Tigeot void radeon_external_tmds_setup(struct drm_encoder *encoder)
2828926deccbSFrançois Tigeot {
2829926deccbSFrançois Tigeot struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2830926deccbSFrançois Tigeot struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2831926deccbSFrançois Tigeot
2832926deccbSFrançois Tigeot if (!tmds)
2833926deccbSFrançois Tigeot return;
2834926deccbSFrançois Tigeot
2835926deccbSFrançois Tigeot switch (tmds->dvo_chip) {
2836926deccbSFrançois Tigeot case DVO_SIL164:
2837926deccbSFrançois Tigeot /* sil 164 */
2838926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2839926deccbSFrançois Tigeot tmds->slave_addr,
2840926deccbSFrançois Tigeot 0x08, 0x30);
2841926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2842926deccbSFrançois Tigeot tmds->slave_addr,
2843926deccbSFrançois Tigeot 0x09, 0x00);
2844926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2845926deccbSFrançois Tigeot tmds->slave_addr,
2846926deccbSFrançois Tigeot 0x0a, 0x90);
2847926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2848926deccbSFrançois Tigeot tmds->slave_addr,
2849926deccbSFrançois Tigeot 0x0c, 0x89);
2850926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2851926deccbSFrançois Tigeot tmds->slave_addr,
2852926deccbSFrançois Tigeot 0x08, 0x3b);
2853926deccbSFrançois Tigeot break;
2854926deccbSFrançois Tigeot case DVO_SIL1178:
2855926deccbSFrançois Tigeot /* sil 1178 - untested */
2856926deccbSFrançois Tigeot /*
2857926deccbSFrançois Tigeot * 0x0f, 0x44
2858926deccbSFrançois Tigeot * 0x0f, 0x4c
2859926deccbSFrançois Tigeot * 0x0e, 0x01
2860926deccbSFrançois Tigeot * 0x0a, 0x80
2861926deccbSFrançois Tigeot * 0x09, 0x30
2862926deccbSFrançois Tigeot * 0x0c, 0xc9
2863926deccbSFrançois Tigeot * 0x0d, 0x70
2864926deccbSFrançois Tigeot * 0x08, 0x32
2865926deccbSFrançois Tigeot * 0x08, 0x33
2866926deccbSFrançois Tigeot */
2867926deccbSFrançois Tigeot break;
2868926deccbSFrançois Tigeot default:
2869926deccbSFrançois Tigeot break;
2870926deccbSFrançois Tigeot }
2871926deccbSFrançois Tigeot
2872926deccbSFrançois Tigeot }
2873926deccbSFrançois Tigeot
radeon_combios_external_tmds_setup(struct drm_encoder * encoder)2874926deccbSFrançois Tigeot bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
2875926deccbSFrançois Tigeot {
2876926deccbSFrançois Tigeot struct drm_device *dev = encoder->dev;
2877926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
2878926deccbSFrançois Tigeot struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2879926deccbSFrançois Tigeot uint16_t offset;
2880926deccbSFrançois Tigeot uint8_t blocks, slave_addr, rev;
2881926deccbSFrançois Tigeot uint32_t index, id;
2882926deccbSFrançois Tigeot uint32_t reg, val, and_mask, or_mask;
2883926deccbSFrançois Tigeot struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2884926deccbSFrançois Tigeot
2885926deccbSFrançois Tigeot if (!tmds)
2886926deccbSFrançois Tigeot return false;
2887926deccbSFrançois Tigeot
2888926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
2889926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
2890926deccbSFrançois Tigeot rev = RBIOS8(offset);
2891926deccbSFrançois Tigeot if (offset) {
2892926deccbSFrançois Tigeot rev = RBIOS8(offset);
2893926deccbSFrançois Tigeot if (rev > 1) {
2894926deccbSFrançois Tigeot blocks = RBIOS8(offset + 3);
2895926deccbSFrançois Tigeot index = offset + 4;
2896926deccbSFrançois Tigeot while (blocks > 0) {
2897926deccbSFrançois Tigeot id = RBIOS16(index);
2898926deccbSFrançois Tigeot index += 2;
2899926deccbSFrançois Tigeot switch (id >> 13) {
2900926deccbSFrançois Tigeot case 0:
2901926deccbSFrançois Tigeot reg = (id & 0x1fff) * 4;
2902926deccbSFrançois Tigeot val = RBIOS32(index);
2903926deccbSFrançois Tigeot index += 4;
2904926deccbSFrançois Tigeot WREG32(reg, val);
2905926deccbSFrançois Tigeot break;
2906926deccbSFrançois Tigeot case 2:
2907926deccbSFrançois Tigeot reg = (id & 0x1fff) * 4;
2908926deccbSFrançois Tigeot and_mask = RBIOS32(index);
2909926deccbSFrançois Tigeot index += 4;
2910926deccbSFrançois Tigeot or_mask = RBIOS32(index);
2911926deccbSFrançois Tigeot index += 4;
2912926deccbSFrançois Tigeot val = RREG32(reg);
2913926deccbSFrançois Tigeot val = (val & and_mask) | or_mask;
2914926deccbSFrançois Tigeot WREG32(reg, val);
2915926deccbSFrançois Tigeot break;
2916926deccbSFrançois Tigeot case 3:
2917926deccbSFrançois Tigeot val = RBIOS16(index);
2918926deccbSFrançois Tigeot index += 2;
2919c4ef309bSzrj udelay(val);
2920926deccbSFrançois Tigeot break;
2921926deccbSFrançois Tigeot case 4:
2922926deccbSFrançois Tigeot val = RBIOS16(index);
2923926deccbSFrançois Tigeot index += 2;
2924c4ef309bSzrj mdelay(val);
2925926deccbSFrançois Tigeot break;
2926926deccbSFrançois Tigeot case 6:
2927926deccbSFrançois Tigeot slave_addr = id & 0xff;
2928926deccbSFrançois Tigeot slave_addr >>= 1; /* 7 bit addressing */
2929926deccbSFrançois Tigeot index++;
2930926deccbSFrançois Tigeot reg = RBIOS8(index);
2931926deccbSFrançois Tigeot index++;
2932926deccbSFrançois Tigeot val = RBIOS8(index);
2933926deccbSFrançois Tigeot index++;
2934926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2935926deccbSFrançois Tigeot slave_addr,
2936926deccbSFrançois Tigeot reg, val);
2937926deccbSFrançois Tigeot break;
2938926deccbSFrançois Tigeot default:
2939926deccbSFrançois Tigeot DRM_ERROR("Unknown id %d\n", id >> 13);
2940926deccbSFrançois Tigeot break;
2941926deccbSFrançois Tigeot }
2942926deccbSFrançois Tigeot blocks--;
2943926deccbSFrançois Tigeot }
2944926deccbSFrançois Tigeot return true;
2945926deccbSFrançois Tigeot }
2946926deccbSFrançois Tigeot }
2947926deccbSFrançois Tigeot } else {
2948926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
2949926deccbSFrançois Tigeot if (offset) {
2950926deccbSFrançois Tigeot index = offset + 10;
2951926deccbSFrançois Tigeot id = RBIOS16(index);
2952926deccbSFrançois Tigeot while (id != 0xffff) {
2953926deccbSFrançois Tigeot index += 2;
2954926deccbSFrançois Tigeot switch (id >> 13) {
2955926deccbSFrançois Tigeot case 0:
2956926deccbSFrançois Tigeot reg = (id & 0x1fff) * 4;
2957926deccbSFrançois Tigeot val = RBIOS32(index);
2958926deccbSFrançois Tigeot WREG32(reg, val);
2959926deccbSFrançois Tigeot break;
2960926deccbSFrançois Tigeot case 2:
2961926deccbSFrançois Tigeot reg = (id & 0x1fff) * 4;
2962926deccbSFrançois Tigeot and_mask = RBIOS32(index);
2963926deccbSFrançois Tigeot index += 4;
2964926deccbSFrançois Tigeot or_mask = RBIOS32(index);
2965926deccbSFrançois Tigeot index += 4;
2966926deccbSFrançois Tigeot val = RREG32(reg);
2967926deccbSFrançois Tigeot val = (val & and_mask) | or_mask;
2968926deccbSFrançois Tigeot WREG32(reg, val);
2969926deccbSFrançois Tigeot break;
2970926deccbSFrançois Tigeot case 4:
2971926deccbSFrançois Tigeot val = RBIOS16(index);
2972926deccbSFrançois Tigeot index += 2;
2973c4ef309bSzrj udelay(val);
2974926deccbSFrançois Tigeot break;
2975926deccbSFrançois Tigeot case 5:
2976926deccbSFrançois Tigeot reg = id & 0x1fff;
2977926deccbSFrançois Tigeot and_mask = RBIOS32(index);
2978926deccbSFrançois Tigeot index += 4;
2979926deccbSFrançois Tigeot or_mask = RBIOS32(index);
2980926deccbSFrançois Tigeot index += 4;
2981926deccbSFrançois Tigeot val = RREG32_PLL(reg);
2982926deccbSFrançois Tigeot val = (val & and_mask) | or_mask;
2983926deccbSFrançois Tigeot WREG32_PLL(reg, val);
2984926deccbSFrançois Tigeot break;
2985926deccbSFrançois Tigeot case 6:
2986926deccbSFrançois Tigeot reg = id & 0x1fff;
2987926deccbSFrançois Tigeot val = RBIOS8(index);
2988926deccbSFrançois Tigeot index += 1;
2989926deccbSFrançois Tigeot radeon_i2c_put_byte(tmds->i2c_bus,
2990926deccbSFrançois Tigeot tmds->slave_addr,
2991926deccbSFrançois Tigeot reg, val);
2992926deccbSFrançois Tigeot break;
2993926deccbSFrançois Tigeot default:
2994926deccbSFrançois Tigeot DRM_ERROR("Unknown id %d\n", id >> 13);
2995926deccbSFrançois Tigeot break;
2996926deccbSFrançois Tigeot }
2997926deccbSFrançois Tigeot id = RBIOS16(index);
2998926deccbSFrançois Tigeot }
2999926deccbSFrançois Tigeot return true;
3000926deccbSFrançois Tigeot }
3001926deccbSFrançois Tigeot }
3002926deccbSFrançois Tigeot return false;
3003926deccbSFrançois Tigeot }
3004926deccbSFrançois Tigeot
combios_parse_mmio_table(struct drm_device * dev,uint16_t offset)3005926deccbSFrançois Tigeot static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
3006926deccbSFrançois Tigeot {
3007926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3008926deccbSFrançois Tigeot
3009926deccbSFrançois Tigeot if (offset) {
3010926deccbSFrançois Tigeot while (RBIOS16(offset)) {
3011926deccbSFrançois Tigeot uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13);
3012926deccbSFrançois Tigeot uint32_t addr = (RBIOS16(offset) & 0x1fff);
3013926deccbSFrançois Tigeot uint32_t val, and_mask, or_mask;
3014926deccbSFrançois Tigeot uint32_t tmp;
3015926deccbSFrançois Tigeot
3016926deccbSFrançois Tigeot offset += 2;
3017926deccbSFrançois Tigeot switch (cmd) {
3018926deccbSFrançois Tigeot case 0:
3019926deccbSFrançois Tigeot val = RBIOS32(offset);
3020926deccbSFrançois Tigeot offset += 4;
3021926deccbSFrançois Tigeot WREG32(addr, val);
3022926deccbSFrançois Tigeot break;
3023926deccbSFrançois Tigeot case 1:
3024926deccbSFrançois Tigeot val = RBIOS32(offset);
3025926deccbSFrançois Tigeot offset += 4;
3026926deccbSFrançois Tigeot WREG32(addr, val);
3027926deccbSFrançois Tigeot break;
3028926deccbSFrançois Tigeot case 2:
3029926deccbSFrançois Tigeot and_mask = RBIOS32(offset);
3030926deccbSFrançois Tigeot offset += 4;
3031926deccbSFrançois Tigeot or_mask = RBIOS32(offset);
3032926deccbSFrançois Tigeot offset += 4;
3033926deccbSFrançois Tigeot tmp = RREG32(addr);
3034926deccbSFrançois Tigeot tmp &= and_mask;
3035926deccbSFrançois Tigeot tmp |= or_mask;
3036926deccbSFrançois Tigeot WREG32(addr, tmp);
3037926deccbSFrançois Tigeot break;
3038926deccbSFrançois Tigeot case 3:
3039926deccbSFrançois Tigeot and_mask = RBIOS32(offset);
3040926deccbSFrançois Tigeot offset += 4;
3041926deccbSFrançois Tigeot or_mask = RBIOS32(offset);
3042926deccbSFrançois Tigeot offset += 4;
3043926deccbSFrançois Tigeot tmp = RREG32(addr);
3044926deccbSFrançois Tigeot tmp &= and_mask;
3045926deccbSFrançois Tigeot tmp |= or_mask;
3046926deccbSFrançois Tigeot WREG32(addr, tmp);
3047926deccbSFrançois Tigeot break;
3048926deccbSFrançois Tigeot case 4:
3049926deccbSFrançois Tigeot val = RBIOS16(offset);
3050926deccbSFrançois Tigeot offset += 2;
3051c4ef309bSzrj udelay(val);
3052926deccbSFrançois Tigeot break;
3053926deccbSFrançois Tigeot case 5:
3054926deccbSFrançois Tigeot val = RBIOS16(offset);
3055926deccbSFrançois Tigeot offset += 2;
3056926deccbSFrançois Tigeot switch (addr) {
3057926deccbSFrançois Tigeot case 8:
3058926deccbSFrançois Tigeot while (val--) {
3059926deccbSFrançois Tigeot if (!
3060926deccbSFrançois Tigeot (RREG32_PLL
3061926deccbSFrançois Tigeot (RADEON_CLK_PWRMGT_CNTL) &
3062926deccbSFrançois Tigeot RADEON_MC_BUSY))
3063926deccbSFrançois Tigeot break;
3064926deccbSFrançois Tigeot }
3065926deccbSFrançois Tigeot break;
3066926deccbSFrançois Tigeot case 9:
3067926deccbSFrançois Tigeot while (val--) {
3068926deccbSFrançois Tigeot if ((RREG32(RADEON_MC_STATUS) &
3069926deccbSFrançois Tigeot RADEON_MC_IDLE))
3070926deccbSFrançois Tigeot break;
3071926deccbSFrançois Tigeot }
3072926deccbSFrançois Tigeot break;
3073926deccbSFrançois Tigeot default:
3074926deccbSFrançois Tigeot break;
3075926deccbSFrançois Tigeot }
3076926deccbSFrançois Tigeot break;
3077926deccbSFrançois Tigeot default:
3078926deccbSFrançois Tigeot break;
3079926deccbSFrançois Tigeot }
3080926deccbSFrançois Tigeot }
3081926deccbSFrançois Tigeot }
3082926deccbSFrançois Tigeot }
3083926deccbSFrançois Tigeot
combios_parse_pll_table(struct drm_device * dev,uint16_t offset)3084926deccbSFrançois Tigeot static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
3085926deccbSFrançois Tigeot {
3086926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3087926deccbSFrançois Tigeot
3088926deccbSFrançois Tigeot if (offset) {
3089926deccbSFrançois Tigeot while (RBIOS8(offset)) {
3090926deccbSFrançois Tigeot uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6);
3091926deccbSFrançois Tigeot uint8_t addr = (RBIOS8(offset) & 0x3f);
3092926deccbSFrançois Tigeot uint32_t val, shift, tmp;
3093926deccbSFrançois Tigeot uint32_t and_mask, or_mask;
3094926deccbSFrançois Tigeot
3095926deccbSFrançois Tigeot offset++;
3096926deccbSFrançois Tigeot switch (cmd) {
3097926deccbSFrançois Tigeot case 0:
3098926deccbSFrançois Tigeot val = RBIOS32(offset);
3099926deccbSFrançois Tigeot offset += 4;
3100926deccbSFrançois Tigeot WREG32_PLL(addr, val);
3101926deccbSFrançois Tigeot break;
3102926deccbSFrançois Tigeot case 1:
3103926deccbSFrançois Tigeot shift = RBIOS8(offset) * 8;
3104926deccbSFrançois Tigeot offset++;
3105926deccbSFrançois Tigeot and_mask = RBIOS8(offset) << shift;
3106926deccbSFrançois Tigeot and_mask |= ~(0xff << shift);
3107926deccbSFrançois Tigeot offset++;
3108926deccbSFrançois Tigeot or_mask = RBIOS8(offset) << shift;
3109926deccbSFrançois Tigeot offset++;
3110926deccbSFrançois Tigeot tmp = RREG32_PLL(addr);
3111926deccbSFrançois Tigeot tmp &= and_mask;
3112926deccbSFrançois Tigeot tmp |= or_mask;
3113926deccbSFrançois Tigeot WREG32_PLL(addr, tmp);
3114926deccbSFrançois Tigeot break;
3115926deccbSFrançois Tigeot case 2:
3116926deccbSFrançois Tigeot case 3:
3117926deccbSFrançois Tigeot tmp = 1000;
3118926deccbSFrançois Tigeot switch (addr) {
3119926deccbSFrançois Tigeot case 1:
3120c4ef309bSzrj udelay(150);
3121926deccbSFrançois Tigeot break;
3122926deccbSFrançois Tigeot case 2:
3123c4ef309bSzrj mdelay(1);
3124926deccbSFrançois Tigeot break;
3125926deccbSFrançois Tigeot case 3:
3126926deccbSFrançois Tigeot while (tmp--) {
3127926deccbSFrançois Tigeot if (!
3128926deccbSFrançois Tigeot (RREG32_PLL
3129926deccbSFrançois Tigeot (RADEON_CLK_PWRMGT_CNTL) &
3130926deccbSFrançois Tigeot RADEON_MC_BUSY))
3131926deccbSFrançois Tigeot break;
3132926deccbSFrançois Tigeot }
3133926deccbSFrançois Tigeot break;
3134926deccbSFrançois Tigeot case 4:
3135926deccbSFrançois Tigeot while (tmp--) {
3136926deccbSFrançois Tigeot if (RREG32_PLL
3137926deccbSFrançois Tigeot (RADEON_CLK_PWRMGT_CNTL) &
3138926deccbSFrançois Tigeot RADEON_DLL_READY)
3139926deccbSFrançois Tigeot break;
3140926deccbSFrançois Tigeot }
3141926deccbSFrançois Tigeot break;
3142926deccbSFrançois Tigeot case 5:
3143926deccbSFrançois Tigeot tmp =
3144926deccbSFrançois Tigeot RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
3145926deccbSFrançois Tigeot if (tmp & RADEON_CG_NO1_DEBUG_0) {
3146926deccbSFrançois Tigeot #if 0
3147926deccbSFrançois Tigeot uint32_t mclk_cntl =
3148926deccbSFrançois Tigeot RREG32_PLL
3149926deccbSFrançois Tigeot (RADEON_MCLK_CNTL);
3150926deccbSFrançois Tigeot mclk_cntl &= 0xffff0000;
3151926deccbSFrançois Tigeot /*mclk_cntl |= 0x00001111;*//* ??? */
3152926deccbSFrançois Tigeot WREG32_PLL(RADEON_MCLK_CNTL,
3153926deccbSFrançois Tigeot mclk_cntl);
3154c4ef309bSzrj mdelay(10);
3155926deccbSFrançois Tigeot #endif
3156926deccbSFrançois Tigeot WREG32_PLL
3157926deccbSFrançois Tigeot (RADEON_CLK_PWRMGT_CNTL,
3158926deccbSFrançois Tigeot tmp &
3159926deccbSFrançois Tigeot ~RADEON_CG_NO1_DEBUG_0);
3160c4ef309bSzrj mdelay(10);
3161926deccbSFrançois Tigeot }
3162926deccbSFrançois Tigeot break;
3163926deccbSFrançois Tigeot default:
3164926deccbSFrançois Tigeot break;
3165926deccbSFrançois Tigeot }
3166926deccbSFrançois Tigeot break;
3167926deccbSFrançois Tigeot default:
3168926deccbSFrançois Tigeot break;
3169926deccbSFrançois Tigeot }
3170926deccbSFrançois Tigeot }
3171926deccbSFrançois Tigeot }
3172926deccbSFrançois Tigeot }
3173926deccbSFrançois Tigeot
combios_parse_ram_reset_table(struct drm_device * dev,uint16_t offset)3174926deccbSFrançois Tigeot static void combios_parse_ram_reset_table(struct drm_device *dev,
3175926deccbSFrançois Tigeot uint16_t offset)
3176926deccbSFrançois Tigeot {
3177926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3178926deccbSFrançois Tigeot uint32_t tmp;
3179926deccbSFrançois Tigeot
3180926deccbSFrançois Tigeot if (offset) {
3181926deccbSFrançois Tigeot uint8_t val = RBIOS8(offset);
3182926deccbSFrançois Tigeot while (val != 0xff) {
3183926deccbSFrançois Tigeot offset++;
3184926deccbSFrançois Tigeot
3185926deccbSFrançois Tigeot if (val == 0x0f) {
3186926deccbSFrançois Tigeot uint32_t channel_complete_mask;
3187926deccbSFrançois Tigeot
3188926deccbSFrançois Tigeot if (ASIC_IS_R300(rdev))
3189926deccbSFrançois Tigeot channel_complete_mask =
3190926deccbSFrançois Tigeot R300_MEM_PWRUP_COMPLETE;
3191926deccbSFrançois Tigeot else
3192926deccbSFrançois Tigeot channel_complete_mask =
3193926deccbSFrançois Tigeot RADEON_MEM_PWRUP_COMPLETE;
3194926deccbSFrançois Tigeot tmp = 20000;
3195926deccbSFrançois Tigeot while (tmp--) {
3196926deccbSFrançois Tigeot if ((RREG32(RADEON_MEM_STR_CNTL) &
3197926deccbSFrançois Tigeot channel_complete_mask) ==
3198926deccbSFrançois Tigeot channel_complete_mask)
3199926deccbSFrançois Tigeot break;
3200926deccbSFrançois Tigeot }
3201926deccbSFrançois Tigeot } else {
3202926deccbSFrançois Tigeot uint32_t or_mask = RBIOS16(offset);
3203926deccbSFrançois Tigeot offset += 2;
3204926deccbSFrançois Tigeot
3205926deccbSFrançois Tigeot tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
3206926deccbSFrançois Tigeot tmp &= RADEON_SDRAM_MODE_MASK;
3207926deccbSFrançois Tigeot tmp |= or_mask;
3208926deccbSFrançois Tigeot WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
3209926deccbSFrançois Tigeot
3210926deccbSFrançois Tigeot or_mask = val << 24;
3211926deccbSFrançois Tigeot tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
3212926deccbSFrançois Tigeot tmp &= RADEON_B3MEM_RESET_MASK;
3213926deccbSFrançois Tigeot tmp |= or_mask;
3214926deccbSFrançois Tigeot WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
3215926deccbSFrançois Tigeot }
3216926deccbSFrançois Tigeot val = RBIOS8(offset);
3217926deccbSFrançois Tigeot }
3218926deccbSFrançois Tigeot }
3219926deccbSFrançois Tigeot }
3220926deccbSFrançois Tigeot
combios_detect_ram(struct drm_device * dev,int ram,int mem_addr_mapping)3221926deccbSFrançois Tigeot static uint32_t combios_detect_ram(struct drm_device *dev, int ram,
3222926deccbSFrançois Tigeot int mem_addr_mapping)
3223926deccbSFrançois Tigeot {
3224926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3225926deccbSFrançois Tigeot uint32_t mem_cntl;
3226926deccbSFrançois Tigeot uint32_t mem_size;
3227926deccbSFrançois Tigeot uint32_t addr = 0;
3228926deccbSFrançois Tigeot
3229926deccbSFrançois Tigeot mem_cntl = RREG32(RADEON_MEM_CNTL);
3230926deccbSFrançois Tigeot if (mem_cntl & RV100_HALF_MODE)
3231926deccbSFrançois Tigeot ram /= 2;
3232926deccbSFrançois Tigeot mem_size = ram;
3233926deccbSFrançois Tigeot mem_cntl &= ~(0xff << 8);
3234926deccbSFrançois Tigeot mem_cntl |= (mem_addr_mapping & 0xff) << 8;
3235926deccbSFrançois Tigeot WREG32(RADEON_MEM_CNTL, mem_cntl);
3236926deccbSFrançois Tigeot RREG32(RADEON_MEM_CNTL);
3237926deccbSFrançois Tigeot
3238926deccbSFrançois Tigeot /* sdram reset ? */
3239926deccbSFrançois Tigeot
3240926deccbSFrançois Tigeot /* something like this???? */
3241926deccbSFrançois Tigeot while (ram--) {
3242926deccbSFrançois Tigeot addr = ram * 1024 * 1024;
3243926deccbSFrançois Tigeot /* write to each page */
3244926deccbSFrançois Tigeot WREG32_IDX((addr) | RADEON_MM_APER, 0xdeadbeef);
3245926deccbSFrançois Tigeot /* read back and verify */
3246926deccbSFrançois Tigeot if (RREG32_IDX((addr) | RADEON_MM_APER) != 0xdeadbeef)
3247926deccbSFrançois Tigeot return 0;
3248926deccbSFrançois Tigeot }
3249926deccbSFrançois Tigeot
3250926deccbSFrançois Tigeot return mem_size;
3251926deccbSFrançois Tigeot }
3252926deccbSFrançois Tigeot
combios_write_ram_size(struct drm_device * dev)3253926deccbSFrançois Tigeot static void combios_write_ram_size(struct drm_device *dev)
3254926deccbSFrançois Tigeot {
3255926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3256926deccbSFrançois Tigeot uint8_t rev;
3257926deccbSFrançois Tigeot uint16_t offset;
3258926deccbSFrançois Tigeot uint32_t mem_size = 0;
3259926deccbSFrançois Tigeot uint32_t mem_cntl = 0;
3260926deccbSFrançois Tigeot
3261926deccbSFrançois Tigeot /* should do something smarter here I guess... */
3262926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP)
3263926deccbSFrançois Tigeot return;
3264926deccbSFrançois Tigeot
3265926deccbSFrançois Tigeot /* first check detected mem table */
3266926deccbSFrançois Tigeot offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE);
3267926deccbSFrançois Tigeot if (offset) {
3268926deccbSFrançois Tigeot rev = RBIOS8(offset);
3269926deccbSFrançois Tigeot if (rev < 3) {
3270926deccbSFrançois Tigeot mem_cntl = RBIOS32(offset + 1);
3271926deccbSFrançois Tigeot mem_size = RBIOS16(offset + 5);
3272926deccbSFrançois Tigeot if ((rdev->family < CHIP_R200) &&
3273926deccbSFrançois Tigeot !ASIC_IS_RN50(rdev))
3274926deccbSFrançois Tigeot WREG32(RADEON_MEM_CNTL, mem_cntl);
3275926deccbSFrançois Tigeot }
3276926deccbSFrançois Tigeot }
3277926deccbSFrançois Tigeot
3278926deccbSFrançois Tigeot if (!mem_size) {
3279926deccbSFrançois Tigeot offset =
3280926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
3281926deccbSFrançois Tigeot if (offset) {
3282926deccbSFrançois Tigeot rev = RBIOS8(offset - 1);
3283926deccbSFrançois Tigeot if (rev < 1) {
3284926deccbSFrançois Tigeot if ((rdev->family < CHIP_R200)
3285926deccbSFrançois Tigeot && !ASIC_IS_RN50(rdev)) {
3286926deccbSFrançois Tigeot int ram = 0;
3287926deccbSFrançois Tigeot int mem_addr_mapping = 0;
3288926deccbSFrançois Tigeot
3289926deccbSFrançois Tigeot while (RBIOS8(offset)) {
3290926deccbSFrançois Tigeot ram = RBIOS8(offset);
3291926deccbSFrançois Tigeot mem_addr_mapping =
3292926deccbSFrançois Tigeot RBIOS8(offset + 1);
3293926deccbSFrançois Tigeot if (mem_addr_mapping != 0x25)
3294926deccbSFrançois Tigeot ram *= 2;
3295926deccbSFrançois Tigeot mem_size =
3296926deccbSFrançois Tigeot combios_detect_ram(dev, ram,
3297926deccbSFrançois Tigeot mem_addr_mapping);
3298926deccbSFrançois Tigeot if (mem_size)
3299926deccbSFrançois Tigeot break;
3300926deccbSFrançois Tigeot offset += 2;
3301926deccbSFrançois Tigeot }
3302926deccbSFrançois Tigeot } else
3303926deccbSFrançois Tigeot mem_size = RBIOS8(offset);
3304926deccbSFrançois Tigeot } else {
3305926deccbSFrançois Tigeot mem_size = RBIOS8(offset);
3306926deccbSFrançois Tigeot mem_size *= 2; /* convert to MB */
3307926deccbSFrançois Tigeot }
3308926deccbSFrançois Tigeot }
3309926deccbSFrançois Tigeot }
3310926deccbSFrançois Tigeot
3311926deccbSFrançois Tigeot mem_size *= (1024 * 1024); /* convert to bytes */
3312926deccbSFrançois Tigeot WREG32(RADEON_CONFIG_MEMSIZE, mem_size);
3313926deccbSFrançois Tigeot }
3314926deccbSFrançois Tigeot
radeon_combios_asic_init(struct drm_device * dev)3315926deccbSFrançois Tigeot void radeon_combios_asic_init(struct drm_device *dev)
3316926deccbSFrançois Tigeot {
3317926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3318926deccbSFrançois Tigeot uint16_t table;
3319926deccbSFrançois Tigeot
3320926deccbSFrançois Tigeot /* port hardcoded mac stuff from radeonfb */
3321926deccbSFrançois Tigeot if (rdev->bios == NULL)
3322926deccbSFrançois Tigeot return;
3323926deccbSFrançois Tigeot
3324926deccbSFrançois Tigeot /* ASIC INIT 1 */
3325926deccbSFrançois Tigeot table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE);
3326926deccbSFrançois Tigeot if (table)
3327926deccbSFrançois Tigeot combios_parse_mmio_table(dev, table);
3328926deccbSFrançois Tigeot
3329926deccbSFrançois Tigeot /* PLL INIT */
3330926deccbSFrançois Tigeot table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE);
3331926deccbSFrançois Tigeot if (table)
3332926deccbSFrançois Tigeot combios_parse_pll_table(dev, table);
3333926deccbSFrançois Tigeot
3334926deccbSFrançois Tigeot /* ASIC INIT 2 */
3335926deccbSFrançois Tigeot table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE);
3336926deccbSFrançois Tigeot if (table)
3337926deccbSFrançois Tigeot combios_parse_mmio_table(dev, table);
3338926deccbSFrançois Tigeot
3339926deccbSFrançois Tigeot if (!(rdev->flags & RADEON_IS_IGP)) {
3340926deccbSFrançois Tigeot /* ASIC INIT 4 */
3341926deccbSFrançois Tigeot table =
3342926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE);
3343926deccbSFrançois Tigeot if (table)
3344926deccbSFrançois Tigeot combios_parse_mmio_table(dev, table);
3345926deccbSFrançois Tigeot
3346926deccbSFrançois Tigeot /* RAM RESET */
3347926deccbSFrançois Tigeot table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE);
3348926deccbSFrançois Tigeot if (table)
3349926deccbSFrançois Tigeot combios_parse_ram_reset_table(dev, table);
3350926deccbSFrançois Tigeot
3351926deccbSFrançois Tigeot /* ASIC INIT 3 */
3352926deccbSFrançois Tigeot table =
3353926deccbSFrançois Tigeot combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE);
3354926deccbSFrançois Tigeot if (table)
3355926deccbSFrançois Tigeot combios_parse_mmio_table(dev, table);
3356926deccbSFrançois Tigeot
3357926deccbSFrançois Tigeot /* write CONFIG_MEMSIZE */
3358926deccbSFrançois Tigeot combios_write_ram_size(dev);
3359926deccbSFrançois Tigeot }
3360926deccbSFrançois Tigeot
3361926deccbSFrançois Tigeot /* quirk for rs4xx HP nx6125 laptop to make it resume
3362926deccbSFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3363926deccbSFrançois Tigeot */
3364926deccbSFrançois Tigeot if (rdev->family == CHIP_RS480 &&
3365c6f73aabSFrançois Tigeot rdev->pdev->subsystem_vendor == 0x103c &&
3366c6f73aabSFrançois Tigeot rdev->pdev->subsystem_device == 0x308b)
3367926deccbSFrançois Tigeot return;
3368926deccbSFrançois Tigeot
3369926deccbSFrançois Tigeot /* quirk for rs4xx HP dv5000 laptop to make it resume
3370926deccbSFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3371926deccbSFrançois Tigeot */
3372926deccbSFrançois Tigeot if (rdev->family == CHIP_RS480 &&
3373c6f73aabSFrançois Tigeot rdev->pdev->subsystem_vendor == 0x103c &&
3374c6f73aabSFrançois Tigeot rdev->pdev->subsystem_device == 0x30a4)
3375926deccbSFrançois Tigeot return;
3376926deccbSFrançois Tigeot
3377926deccbSFrançois Tigeot /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume
3378926deccbSFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3379926deccbSFrançois Tigeot */
3380926deccbSFrançois Tigeot if (rdev->family == CHIP_RS480 &&
3381c6f73aabSFrançois Tigeot rdev->pdev->subsystem_vendor == 0x103c &&
3382c6f73aabSFrançois Tigeot rdev->pdev->subsystem_device == 0x30ae)
3383926deccbSFrançois Tigeot return;
3384*a85cb24fSFrançois Tigeot /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
3385*a85cb24fSFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3386*a85cb24fSFrançois Tigeot */
3387*a85cb24fSFrançois Tigeot if (rdev->family == CHIP_RS400 &&
3388*a85cb24fSFrançois Tigeot rdev->pdev->subsystem_vendor == 0x1179 &&
3389*a85cb24fSFrançois Tigeot rdev->pdev->subsystem_device == 0xff31)
3390*a85cb24fSFrançois Tigeot return;
3391926deccbSFrançois Tigeot
3392c59a5c48SFrançois Tigeot /* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume
3393c59a5c48SFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3394c59a5c48SFrançois Tigeot */
3395c59a5c48SFrançois Tigeot if (rdev->family == CHIP_RS480 &&
3396c59a5c48SFrançois Tigeot rdev->pdev->subsystem_vendor == 0x103c &&
3397c59a5c48SFrançois Tigeot rdev->pdev->subsystem_device == 0x280a)
3398c59a5c48SFrançois Tigeot return;
3399c59a5c48SFrançois Tigeot /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
3400c59a5c48SFrançois Tigeot * - it hangs on resume inside the dynclk 1 table.
3401c59a5c48SFrançois Tigeot */
3402c59a5c48SFrançois Tigeot if (rdev->family == CHIP_RS400 &&
3403c59a5c48SFrançois Tigeot rdev->pdev->subsystem_vendor == 0x1179 &&
3404c59a5c48SFrançois Tigeot rdev->pdev->subsystem_device == 0xff31)
3405c59a5c48SFrançois Tigeot return;
3406c59a5c48SFrançois Tigeot
3407926deccbSFrançois Tigeot /* DYN CLK 1 */
3408926deccbSFrançois Tigeot table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
3409926deccbSFrançois Tigeot if (table)
3410926deccbSFrançois Tigeot combios_parse_pll_table(dev, table);
3411926deccbSFrançois Tigeot
3412926deccbSFrançois Tigeot }
3413926deccbSFrançois Tigeot
radeon_combios_initialize_bios_scratch_regs(struct drm_device * dev)3414926deccbSFrançois Tigeot void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev)
3415926deccbSFrançois Tigeot {
3416926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3417926deccbSFrançois Tigeot uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch;
3418926deccbSFrançois Tigeot
3419926deccbSFrançois Tigeot bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
3420926deccbSFrançois Tigeot bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3421926deccbSFrançois Tigeot bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH);
3422926deccbSFrançois Tigeot
3423926deccbSFrançois Tigeot /* let the bios control the backlight */
3424926deccbSFrançois Tigeot bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
3425926deccbSFrançois Tigeot
3426926deccbSFrançois Tigeot /* tell the bios not to handle mode switching */
3427926deccbSFrançois Tigeot bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
3428926deccbSFrançois Tigeot RADEON_ACC_MODE_CHANGE);
3429926deccbSFrançois Tigeot
3430926deccbSFrançois Tigeot /* tell the bios a driver is loaded */
3431926deccbSFrançois Tigeot bios_7_scratch |= RADEON_DRV_LOADED;
3432926deccbSFrançois Tigeot
3433926deccbSFrançois Tigeot WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
3434926deccbSFrançois Tigeot WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3435926deccbSFrançois Tigeot WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch);
3436926deccbSFrançois Tigeot }
3437926deccbSFrançois Tigeot
radeon_combios_output_lock(struct drm_encoder * encoder,bool lock)3438926deccbSFrançois Tigeot void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock)
3439926deccbSFrançois Tigeot {
3440926deccbSFrançois Tigeot struct drm_device *dev = encoder->dev;
3441926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3442926deccbSFrançois Tigeot uint32_t bios_6_scratch;
3443926deccbSFrançois Tigeot
3444926deccbSFrançois Tigeot bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3445926deccbSFrançois Tigeot
3446926deccbSFrançois Tigeot if (lock)
3447926deccbSFrançois Tigeot bios_6_scratch |= RADEON_DRIVER_CRITICAL;
3448926deccbSFrançois Tigeot else
3449926deccbSFrançois Tigeot bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
3450926deccbSFrançois Tigeot
3451926deccbSFrançois Tigeot WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3452926deccbSFrançois Tigeot }
3453926deccbSFrançois Tigeot
3454926deccbSFrançois Tigeot void
radeon_combios_connected_scratch_regs(struct drm_connector * connector,struct drm_encoder * encoder,bool connected)3455926deccbSFrançois Tigeot radeon_combios_connected_scratch_regs(struct drm_connector *connector,
3456926deccbSFrançois Tigeot struct drm_encoder *encoder,
3457926deccbSFrançois Tigeot bool connected)
3458926deccbSFrançois Tigeot {
3459926deccbSFrançois Tigeot struct drm_device *dev = connector->dev;
3460926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3461926deccbSFrançois Tigeot struct radeon_connector *radeon_connector =
3462926deccbSFrançois Tigeot to_radeon_connector(connector);
3463926deccbSFrançois Tigeot struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3464926deccbSFrançois Tigeot uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH);
3465926deccbSFrançois Tigeot uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
3466926deccbSFrançois Tigeot
3467926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
3468926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
3469926deccbSFrançois Tigeot if (connected) {
3470926deccbSFrançois Tigeot DRM_DEBUG_KMS("TV1 connected\n");
3471926deccbSFrançois Tigeot /* fix me */
3472926deccbSFrançois Tigeot bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
3473926deccbSFrançois Tigeot /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */
3474926deccbSFrançois Tigeot bios_5_scratch |= RADEON_TV1_ON;
3475926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_TV1;
3476926deccbSFrançois Tigeot } else {
3477926deccbSFrançois Tigeot DRM_DEBUG_KMS("TV1 disconnected\n");
3478926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
3479926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_TV1_ON;
3480926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_TV1;
3481926deccbSFrançois Tigeot }
3482926deccbSFrançois Tigeot }
3483926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
3484926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
3485926deccbSFrançois Tigeot if (connected) {
3486926deccbSFrançois Tigeot DRM_DEBUG_KMS("LCD1 connected\n");
3487926deccbSFrançois Tigeot bios_4_scratch |= RADEON_LCD1_ATTACHED;
3488926deccbSFrançois Tigeot bios_5_scratch |= RADEON_LCD1_ON;
3489926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_LCD1;
3490926deccbSFrançois Tigeot } else {
3491926deccbSFrançois Tigeot DRM_DEBUG_KMS("LCD1 disconnected\n");
3492926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
3493926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_LCD1_ON;
3494926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_LCD1;
3495926deccbSFrançois Tigeot }
3496926deccbSFrançois Tigeot }
3497926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
3498926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
3499926deccbSFrançois Tigeot if (connected) {
3500926deccbSFrançois Tigeot DRM_DEBUG_KMS("CRT1 connected\n");
3501926deccbSFrançois Tigeot bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
3502926deccbSFrançois Tigeot bios_5_scratch |= RADEON_CRT1_ON;
3503926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_CRT1;
3504926deccbSFrançois Tigeot } else {
3505926deccbSFrançois Tigeot DRM_DEBUG_KMS("CRT1 disconnected\n");
3506926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
3507926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_CRT1_ON;
3508926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_CRT1;
3509926deccbSFrançois Tigeot }
3510926deccbSFrançois Tigeot }
3511926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
3512926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
3513926deccbSFrançois Tigeot if (connected) {
3514926deccbSFrançois Tigeot DRM_DEBUG_KMS("CRT2 connected\n");
3515926deccbSFrançois Tigeot bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
3516926deccbSFrançois Tigeot bios_5_scratch |= RADEON_CRT2_ON;
3517926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_CRT2;
3518926deccbSFrançois Tigeot } else {
3519926deccbSFrançois Tigeot DRM_DEBUG_KMS("CRT2 disconnected\n");
3520926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
3521926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_CRT2_ON;
3522926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_CRT2;
3523926deccbSFrançois Tigeot }
3524926deccbSFrançois Tigeot }
3525926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
3526926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
3527926deccbSFrançois Tigeot if (connected) {
3528926deccbSFrançois Tigeot DRM_DEBUG_KMS("DFP1 connected\n");
3529926deccbSFrançois Tigeot bios_4_scratch |= RADEON_DFP1_ATTACHED;
3530926deccbSFrançois Tigeot bios_5_scratch |= RADEON_DFP1_ON;
3531926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_DFP1;
3532926deccbSFrançois Tigeot } else {
3533926deccbSFrançois Tigeot DRM_DEBUG_KMS("DFP1 disconnected\n");
3534926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
3535926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_DFP1_ON;
3536926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_DFP1;
3537926deccbSFrançois Tigeot }
3538926deccbSFrançois Tigeot }
3539926deccbSFrançois Tigeot if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
3540926deccbSFrançois Tigeot (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
3541926deccbSFrançois Tigeot if (connected) {
3542926deccbSFrançois Tigeot DRM_DEBUG_KMS("DFP2 connected\n");
3543926deccbSFrançois Tigeot bios_4_scratch |= RADEON_DFP2_ATTACHED;
3544926deccbSFrançois Tigeot bios_5_scratch |= RADEON_DFP2_ON;
3545926deccbSFrançois Tigeot bios_5_scratch |= RADEON_ACC_REQ_DFP2;
3546926deccbSFrançois Tigeot } else {
3547926deccbSFrançois Tigeot DRM_DEBUG_KMS("DFP2 disconnected\n");
3548926deccbSFrançois Tigeot bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
3549926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_DFP2_ON;
3550926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_ACC_REQ_DFP2;
3551926deccbSFrançois Tigeot }
3552926deccbSFrançois Tigeot }
3553926deccbSFrançois Tigeot WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch);
3554926deccbSFrançois Tigeot WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
3555926deccbSFrançois Tigeot }
3556926deccbSFrançois Tigeot
3557926deccbSFrançois Tigeot void
radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder * encoder,int crtc)3558926deccbSFrançois Tigeot radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
3559926deccbSFrançois Tigeot {
3560926deccbSFrançois Tigeot struct drm_device *dev = encoder->dev;
3561926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3562926deccbSFrançois Tigeot struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3563926deccbSFrançois Tigeot uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
3564926deccbSFrançois Tigeot
3565926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
3566926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
3567926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT);
3568926deccbSFrançois Tigeot }
3569926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
3570926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
3571926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT);
3572926deccbSFrançois Tigeot }
3573926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
3574926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
3575926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT);
3576926deccbSFrançois Tigeot }
3577926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
3578926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
3579926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT);
3580926deccbSFrançois Tigeot }
3581926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
3582926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
3583926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT);
3584926deccbSFrançois Tigeot }
3585926deccbSFrançois Tigeot if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
3586926deccbSFrançois Tigeot bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
3587926deccbSFrançois Tigeot bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT);
3588926deccbSFrançois Tigeot }
3589926deccbSFrançois Tigeot WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
3590926deccbSFrançois Tigeot }
3591926deccbSFrançois Tigeot
3592926deccbSFrançois Tigeot void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder * encoder,bool on)3593926deccbSFrançois Tigeot radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
3594926deccbSFrançois Tigeot {
3595926deccbSFrançois Tigeot struct drm_device *dev = encoder->dev;
3596926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private;
3597926deccbSFrançois Tigeot struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3598926deccbSFrançois Tigeot uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3599926deccbSFrançois Tigeot
3600926deccbSFrançois Tigeot if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
3601926deccbSFrançois Tigeot if (on)
3602926deccbSFrançois Tigeot bios_6_scratch |= RADEON_TV_DPMS_ON;
3603926deccbSFrançois Tigeot else
3604926deccbSFrançois Tigeot bios_6_scratch &= ~RADEON_TV_DPMS_ON;
3605926deccbSFrançois Tigeot }
3606926deccbSFrançois Tigeot if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
3607926deccbSFrançois Tigeot if (on)
3608926deccbSFrançois Tigeot bios_6_scratch |= RADEON_CRT_DPMS_ON;
3609926deccbSFrançois Tigeot else
3610926deccbSFrançois Tigeot bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
3611926deccbSFrançois Tigeot }
3612926deccbSFrançois Tigeot if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
3613926deccbSFrançois Tigeot if (on)
3614926deccbSFrançois Tigeot bios_6_scratch |= RADEON_LCD_DPMS_ON;
3615926deccbSFrançois Tigeot else
3616926deccbSFrançois Tigeot bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
3617926deccbSFrançois Tigeot }
3618926deccbSFrançois Tigeot if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
3619926deccbSFrançois Tigeot if (on)
3620926deccbSFrançois Tigeot bios_6_scratch |= RADEON_DFP_DPMS_ON;
3621926deccbSFrançois Tigeot else
3622926deccbSFrançois Tigeot bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
3623926deccbSFrançois Tigeot }
3624926deccbSFrançois Tigeot WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3625926deccbSFrançois Tigeot }
3626