OSDN Git Service

Add additional quirks from ddx
[android-x86/external-libdrm.git] / linux-core / radeon_combios.c
1 /*
2  * Copyright 2004 ATI Technologies Inc., Markham, Ontario
3  * Copyright 2007-8 Advanced Micro Devices, Inc.
4  * Copyright 2008 Red Hat Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  */
27 #include "drmP.h"
28 #include "radeon_drm.h"
29 #include "radeon_drv.h"
30
31 /* old legacy ATI BIOS routines */
32
33 /* COMBIOS table offsets */
34 enum radeon_combios_table_offset
35 {
36         /* absolute offset tables */
37         COMBIOS_ASIC_INIT_1_TABLE,
38         COMBIOS_BIOS_SUPPORT_TABLE,
39         COMBIOS_DAC_PROGRAMMING_TABLE,
40         COMBIOS_MAX_COLOR_DEPTH_TABLE,
41         COMBIOS_CRTC_INFO_TABLE,
42         COMBIOS_PLL_INFO_TABLE,
43         COMBIOS_TV_INFO_TABLE,
44         COMBIOS_DFP_INFO_TABLE,
45         COMBIOS_HW_CONFIG_INFO_TABLE,
46         COMBIOS_MULTIMEDIA_INFO_TABLE,
47         COMBIOS_TV_STD_PATCH_TABLE,
48         COMBIOS_LCD_INFO_TABLE,
49         COMBIOS_MOBILE_INFO_TABLE,
50         COMBIOS_PLL_INIT_TABLE,
51         COMBIOS_MEM_CONFIG_TABLE,
52         COMBIOS_SAVE_MASK_TABLE,
53         COMBIOS_HARDCODED_EDID_TABLE,
54         COMBIOS_ASIC_INIT_2_TABLE,
55         COMBIOS_CONNECTOR_INFO_TABLE,
56         COMBIOS_DYN_CLK_1_TABLE,
57         COMBIOS_RESERVED_MEM_TABLE,
58         COMBIOS_EXT_TDMS_INFO_TABLE,
59         COMBIOS_MEM_CLK_INFO_TABLE,
60         COMBIOS_EXT_DAC_INFO_TABLE,
61         COMBIOS_MISC_INFO_TABLE,
62         COMBIOS_CRT_INFO_TABLE,
63         COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
64         COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
65         COMBIOS_FAN_SPEED_INFO_TABLE,
66         COMBIOS_OVERDRIVE_INFO_TABLE,
67         COMBIOS_OEM_INFO_TABLE,
68         COMBIOS_DYN_CLK_2_TABLE,
69         COMBIOS_POWER_CONNECTOR_INFO_TABLE,
70         COMBIOS_I2C_INFO_TABLE,
71         /* relative offset tables */
72         COMBIOS_ASIC_INIT_3_TABLE,      /* offset from misc info */
73         COMBIOS_ASIC_INIT_4_TABLE,      /* offset from misc info */
74         COMBIOS_ASIC_INIT_5_TABLE,      /* offset from misc info */
75         COMBIOS_RAM_RESET_TABLE,        /* offset from mem config */
76         COMBIOS_POWERPLAY_TABLE,        /* offset from mobile info */
77         COMBIOS_GPIO_INFO_TABLE,        /* offset from mobile info */
78         COMBIOS_LCD_DDC_INFO_TABLE,     /* offset from mobile info */
79         COMBIOS_TMDS_POWER_TABLE,       /* offset from mobile info */
80         COMBIOS_TMDS_POWER_ON_TABLE,    /* offset from tmds power */
81         COMBIOS_TMDS_POWER_OFF_TABLE,   /* offset from tmds power */
82 };
83
84 enum radeon_combios_ddc
85 {
86     DDC_NONE_DETECTED,
87     DDC_MONID,
88     DDC_DVI,
89     DDC_VGA,
90     DDC_CRT2,
91     DDC_LCD,
92     DDC_GPIO,
93 };
94
95 enum radeon_combios_connector
96 {
97     CONNECTOR_NONE_LEGACY,
98     CONNECTOR_PROPRIETARY_LEGACY,
99     CONNECTOR_CRT_LEGACY,
100     CONNECTOR_DVI_I_LEGACY,
101     CONNECTOR_DVI_D_LEGACY,
102     CONNECTOR_CTV_LEGACY,
103     CONNECTOR_STV_LEGACY,
104     CONNECTOR_UNSUPPORTED_LEGACY
105 };
106
107 static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_combios_table_offset table)
108 {
109         struct drm_radeon_private *dev_priv = dev->dev_private;
110         int rev;
111         uint16_t offset = 0, check_offset;
112
113         switch (table) {
114         /* absolute offset tables */
115         case COMBIOS_ASIC_INIT_1_TABLE:
116                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0xc);
117                 if (check_offset)
118                         offset = check_offset;
119                 break;
120         case COMBIOS_BIOS_SUPPORT_TABLE:
121                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x14);
122                 if (check_offset)
123                         offset = check_offset;
124                 break;
125         case COMBIOS_DAC_PROGRAMMING_TABLE:
126                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2a);
127                 if (check_offset)
128                         offset = check_offset;
129                 break;
130         case COMBIOS_MAX_COLOR_DEPTH_TABLE:
131                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2c);
132                 if (check_offset)
133                         offset = check_offset;
134                 break;
135         case COMBIOS_CRTC_INFO_TABLE:
136                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2e);
137                 if (check_offset)
138                         offset = check_offset;
139                 break;
140         case COMBIOS_PLL_INFO_TABLE:
141                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x30);
142                 if (check_offset)
143                         offset = check_offset;
144                 break;
145         case COMBIOS_TV_INFO_TABLE:
146                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x32);
147                 if (check_offset)
148                         offset = check_offset;
149                 break;
150         case COMBIOS_DFP_INFO_TABLE:
151                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34);
152                 if (check_offset)
153                         offset = check_offset;
154                 break;
155         case COMBIOS_HW_CONFIG_INFO_TABLE:
156                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x36);
157                 if (check_offset)
158                         offset = check_offset;
159                 break;
160         case COMBIOS_MULTIMEDIA_INFO_TABLE:
161                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x38);
162                 if (check_offset)
163                         offset = check_offset;
164                 break;
165         case COMBIOS_TV_STD_PATCH_TABLE:
166                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x3e);
167                 if (check_offset)
168                         offset = check_offset;
169                 break;
170         case COMBIOS_LCD_INFO_TABLE:
171                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
172                 if (check_offset)
173                         offset = check_offset;
174                 break;
175         case COMBIOS_MOBILE_INFO_TABLE:
176                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x42);
177                 if (check_offset)
178                         offset = check_offset;
179                 break;
180         case COMBIOS_PLL_INIT_TABLE:
181                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x46);
182                 if (check_offset)
183                         offset = check_offset;
184                 break;
185         case COMBIOS_MEM_CONFIG_TABLE:
186                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x48);
187                 if (check_offset)
188                         offset = check_offset;
189                 break;
190         case COMBIOS_SAVE_MASK_TABLE:
191                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4a);
192                 if (check_offset)
193                         offset = check_offset;
194                 break;
195         case COMBIOS_HARDCODED_EDID_TABLE:
196                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4c);
197                 if (check_offset)
198                         offset = check_offset;
199                 break;
200         case COMBIOS_ASIC_INIT_2_TABLE:
201                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4e);
202                 if (check_offset)
203                         offset = check_offset;
204                 break;
205         case COMBIOS_CONNECTOR_INFO_TABLE:
206                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x50);
207                 if (check_offset)
208                         offset = check_offset;
209                 break;
210         case COMBIOS_DYN_CLK_1_TABLE:
211                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x52);
212                 if (check_offset)
213                         offset = check_offset;
214                 break;
215         case COMBIOS_RESERVED_MEM_TABLE:
216                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x54);
217                 if (check_offset)
218                         offset = check_offset;
219                 break;
220         case COMBIOS_EXT_TDMS_INFO_TABLE:
221                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x58);
222                 if (check_offset)
223                         offset = check_offset;
224                 break;
225         case COMBIOS_MEM_CLK_INFO_TABLE:
226                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5a);
227                 if (check_offset)
228                         offset = check_offset;
229                 break;
230         case COMBIOS_EXT_DAC_INFO_TABLE:
231                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5c);
232                 if (check_offset)
233                         offset = check_offset;
234                 break;
235         case COMBIOS_MISC_INFO_TABLE:
236                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5e);
237                 if (check_offset)
238                         offset = check_offset;
239                 break;
240         case COMBIOS_CRT_INFO_TABLE:
241                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x60);
242                 if (check_offset)
243                         offset = check_offset;
244                 break;
245         case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
246                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x62);
247                 if (check_offset)
248                         offset = check_offset;
249                 break;
250         case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
251                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x64);
252                 if (check_offset)
253                         offset = check_offset;
254                 break;
255         case COMBIOS_FAN_SPEED_INFO_TABLE:
256                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x66);
257                 if (check_offset)
258                         offset = check_offset;
259                 break;
260         case COMBIOS_OVERDRIVE_INFO_TABLE:
261                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x68);
262                 if (check_offset)
263                         offset = check_offset;
264                 break;
265         case COMBIOS_OEM_INFO_TABLE:
266                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6a);
267                 if (check_offset)
268                         offset = check_offset;
269                 break;
270         case COMBIOS_DYN_CLK_2_TABLE:
271                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6c);
272                 if (check_offset)
273                         offset = check_offset;
274                 break;
275         case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
276                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6e);
277                 if (check_offset)
278                         offset = check_offset;
279                 break;
280         case COMBIOS_I2C_INFO_TABLE:
281                 check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x70);
282                 if (check_offset)
283                         offset = check_offset;
284                 break;
285         /* relative offset tables */
286         case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */
287                 check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
288                 if (check_offset) {
289                         rev = radeon_bios8(dev_priv, check_offset);
290                         if (rev > 0) {
291                                 check_offset = radeon_bios16(dev_priv, check_offset + 0x3);
292                                 if (check_offset)
293                                         offset = check_offset;
294                         }
295                 }
296                 break;
297         case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */
298                 check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
299                 if (check_offset) {
300                         rev = radeon_bios8(dev_priv, check_offset);
301                         if (rev > 0) {
302                                 check_offset = radeon_bios16(dev_priv, check_offset + 0x5);
303                                 if (check_offset)
304                                         offset = check_offset;
305                         }
306                 }
307                 break;
308         case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */
309                 check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
310                 if (check_offset) {
311                         rev = radeon_bios8(dev_priv, check_offset);
312                         if (rev == 2) {
313                                 check_offset = radeon_bios16(dev_priv, check_offset + 0x9);
314                                 if (check_offset)
315                                         offset = check_offset;
316                         }
317                 }
318                 break;
319         case COMBIOS_RAM_RESET_TABLE:   /* offset from mem config */
320                 check_offset = combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
321                 if (check_offset) {
322                         while (radeon_bios8(dev_priv, check_offset++));
323                         check_offset += 2;
324                         if (check_offset)
325                                 offset = check_offset;
326                 }
327                 break;
328         case COMBIOS_POWERPLAY_TABLE:   /* offset from mobile info */
329                 check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
330                 if (check_offset) {
331                         check_offset = radeon_bios16(dev_priv, check_offset + 0x11);
332                         if (check_offset)
333                                 offset = check_offset;
334                 }
335                 break;
336         case COMBIOS_GPIO_INFO_TABLE:   /* offset from mobile info */
337                 check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
338                 if (check_offset) {
339                         check_offset = radeon_bios16(dev_priv, check_offset + 0x13);
340                         if (check_offset)
341                                 offset = check_offset;
342                 }
343                 break;
344         case COMBIOS_LCD_DDC_INFO_TABLE:        /* offset from mobile info */
345                 check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
346                 if (check_offset) {
347                         check_offset = radeon_bios16(dev_priv, check_offset + 0x15);
348                         if (check_offset)
349                                 offset = check_offset;
350                 }
351                 break;
352         case COMBIOS_TMDS_POWER_TABLE:          /* offset from mobile info */
353                 check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
354                 if (check_offset) {
355                         check_offset = radeon_bios16(dev_priv, check_offset + 0x17);
356                         if (check_offset)
357                                 offset = check_offset;
358                 }
359                 break;
360         case COMBIOS_TMDS_POWER_ON_TABLE:       /* offset from tmds power */
361                 check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
362                 if (check_offset) {
363                         check_offset = radeon_bios16(dev_priv, check_offset + 0x2);
364                         if (check_offset)
365                                 offset = check_offset;
366                 }
367                 break;
368         case COMBIOS_TMDS_POWER_OFF_TABLE:      /* offset from tmds power */
369                 check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
370                 if (check_offset) {
371                         check_offset = radeon_bios16(dev_priv, check_offset + 0x4);
372                         if (check_offset)
373                                 offset = check_offset;
374                 }
375                 break;
376         default:
377                 break;
378         }
379
380         return offset;
381
382 }
383
384 struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
385 {
386         struct radeon_i2c_bus_rec i2c;
387
388         i2c.mask_clk_mask = RADEON_GPIO_EN_1;
389         i2c.mask_data_mask = RADEON_GPIO_EN_0;
390         i2c.a_clk_mask = RADEON_GPIO_A_1;
391         i2c.a_data_mask = RADEON_GPIO_A_0;
392         i2c.put_clk_mask = RADEON_GPIO_EN_1;
393         i2c.put_data_mask = RADEON_GPIO_EN_0;
394         i2c.get_clk_mask = RADEON_GPIO_Y_1;
395         i2c.get_data_mask = RADEON_GPIO_Y_0;
396         if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
397             (ddc_line == RADEON_MDGPIO_EN_REG)) {
398                 i2c.mask_clk_reg = ddc_line;
399                 i2c.mask_data_reg = ddc_line;
400                 i2c.a_clk_reg = ddc_line;
401                 i2c.a_data_reg = ddc_line;
402                 i2c.put_clk_reg = ddc_line;
403                 i2c.put_data_reg = ddc_line;
404                 i2c.get_clk_reg = ddc_line + 4;
405                 i2c.get_data_reg = ddc_line + 4;
406         } else {
407                 i2c.mask_clk_reg = ddc_line;
408                 i2c.mask_data_reg = ddc_line;
409                 i2c.a_clk_reg = ddc_line;
410                 i2c.a_data_reg = ddc_line;
411                 i2c.put_clk_reg = ddc_line;
412                 i2c.put_data_reg = ddc_line;
413                 i2c.get_clk_reg = ddc_line;
414                 i2c.get_data_reg = ddc_line;
415         }
416
417         if (ddc_line)
418                 i2c.valid = true;
419         else
420                 i2c.valid = false;
421
422         return i2c;
423 }
424
425 bool radeon_combios_get_clock_info(struct drm_device *dev)
426 {
427         struct drm_radeon_private *dev_priv = dev->dev_private;
428         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
429         uint16_t pll_info;
430         struct radeon_pll *pll = &mode_info->pll;
431         int rev;
432
433         pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
434         if (pll_info) {
435                 rev = radeon_bios8(dev_priv, pll_info);
436
437                 pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe);
438                 pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10);
439                 pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12);
440                 pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16);
441
442                 if (rev > 9) {
443                         pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36);
444                         pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a);
445                 } else {
446                         pll->pll_in_min = 40;
447                         pll->pll_in_max = 500;
448                 }
449
450                 pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08);
451
452                 // sclk/mclk use fixed point
453
454                 return true;
455         }
456         return false;
457 }
458
459 bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder)
460 {
461         struct drm_device *dev = encoder->base.dev;
462         struct drm_radeon_private *dev_priv = dev->dev_private;
463         uint16_t lcd_info;
464         char stmp[30];
465         int tmp, i;
466
467         lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
468
469         if (lcd_info) {
470                 for (i = 0; i < 24; i++)
471                         stmp[i] = radeon_bios8(dev_priv, lcd_info + i + 1);
472                 stmp[24] = 0;
473
474                 DRM_INFO("Panel ID String: %s\n", stmp);
475
476                 encoder->panel_xres = radeon_bios16(dev_priv, lcd_info + 25);
477                 encoder->panel_yres = radeon_bios16(dev_priv, lcd_info + 27);
478
479                 DRM_INFO("Panel Size %dx%d\n", encoder->panel_xres, encoder->panel_yres);
480
481                 encoder->panel_pwr_delay = radeon_bios16(dev_priv, lcd_info + 44);
482                 if (encoder->panel_pwr_delay > 2000 || encoder->panel_pwr_delay < 0)
483                         encoder->panel_pwr_delay = 2000;
484
485                 for (i = 0; i < 32; i++) {
486                         tmp = radeon_bios16(dev_priv, lcd_info + 64 + i * 2);
487                         if (tmp == 0) break;
488
489                         if ((radeon_bios16(dev_priv, tmp) == encoder->panel_xres) &&
490                             (radeon_bios16(dev_priv, tmp + 2) == encoder->panel_yres)) {
491                                 encoder->hblank = (radeon_bios16(dev_priv, tmp + 17) -
492                                                    radeon_bios16(dev_priv, tmp + 19)) * 8;
493                                 encoder->hoverplus = (radeon_bios16(dev_priv, tmp + 21) -
494                                                       radeon_bios16(dev_priv, tmp + 19) - 1) * 8;
495                                 encoder->hsync_width = radeon_bios8(dev_priv, tmp + 23) * 8;
496
497                                 encoder->vblank = (radeon_bios16(dev_priv, tmp + 24) -
498                                                    radeon_bios16(dev_priv, tmp + 26));
499                                 encoder->voverplus = ((radeon_bios16(dev_priv, tmp + 28) & 0x7fff) -
500                                                       radeon_bios16(dev_priv, tmp + 26));
501                                 encoder->vsync_width = ((radeon_bios16(dev_priv, tmp + 28) & 0xf800) >> 11);
502                                 encoder->dotclock = radeon_bios16(dev_priv, tmp + 9) * 10;
503                                 encoder->flags = 0;
504                         }
505                 }
506                 return true;
507         }
508         DRM_INFO("No panel info found in BIOS\n");
509         return false;
510
511 }
512
513 bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
514 {
515         struct drm_device *dev = encoder->base.dev;
516         struct drm_radeon_private *dev_priv = dev->dev_private;
517         uint16_t tmds_info;
518         int i, n;
519         uint8_t ver;
520
521         tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
522
523         if (tmds_info) {
524                 ver = radeon_bios8(dev_priv, tmds_info);
525                 DRM_INFO("DFP table revision: %d\n", ver);
526                 if (ver == 3) {
527                         n = radeon_bios8(dev_priv, tmds_info + 5) + 1;
528                         if (n > 4)
529                                 n = 4;
530                         for (i = 0; i < n; i++) {
531                                 encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + i * 10 + 0x08);
532                                 encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + i * 10 + 0x10);
533                         }
534                         return true;
535                 } else if (ver == 4) {
536                         int stride = 0;
537                         n = radeon_bios8(dev_priv, tmds_info + 5) + 1;
538                         if (n > 4)
539                                 n = 4;
540                         for (i = 0; i < n; i++) {
541                                 encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + stride + 0x08);
542                                 encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + stride + 0x10);
543                                 if (i == 0)
544                                         stride += 10;
545                                 else
546                                         stride += 6;
547                         }
548                         return true;
549                 }
550         }
551
552         DRM_INFO("No TMDS info found in BIOS\n");
553         return false;
554 }
555
556 static void radeon_apply_legacy_quirks(struct drm_device *dev, int bios_index)
557 {
558         struct drm_radeon_private *dev_priv = dev->dev_private;
559         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
560
561         /* XPRESS DDC quirks */
562         if ((dev_priv->chip_family == CHIP_RS400 ||
563              dev_priv->chip_family == CHIP_RS480) &&
564             mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
565                 mode_info->bios_connector[bios_index].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
566         } else if ((dev_priv->chip_family == CHIP_RS400 ||
567                     dev_priv->chip_family == CHIP_RS480) &&
568                    mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg == RADEON_GPIO_MONID) {
569                 mode_info->bios_connector[bios_index].ddc_i2c.valid = true;
570                 mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_mask = (0x20 << 8);
571                 mode_info->bios_connector[bios_index].ddc_i2c.mask_data_mask = 0x80;
572                 mode_info->bios_connector[bios_index].ddc_i2c.a_clk_mask = (0x20 << 8);
573                 mode_info->bios_connector[bios_index].ddc_i2c.a_data_mask = 0x80;
574                 mode_info->bios_connector[bios_index].ddc_i2c.put_clk_mask = (0x20 << 8);
575                 mode_info->bios_connector[bios_index].ddc_i2c.put_data_mask = 0x80;
576                 mode_info->bios_connector[bios_index].ddc_i2c.get_clk_mask = (0x20 << 8);
577                 mode_info->bios_connector[bios_index].ddc_i2c.get_data_mask = 0x80;
578                 mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
579                 mode_info->bios_connector[bios_index].ddc_i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
580                 mode_info->bios_connector[bios_index].ddc_i2c.a_clk_reg = RADEON_GPIOPAD_A;
581                 mode_info->bios_connector[bios_index].ddc_i2c.a_data_reg = RADEON_GPIOPAD_A;
582                 mode_info->bios_connector[bios_index].ddc_i2c.put_clk_reg = RADEON_GPIOPAD_EN;
583                 mode_info->bios_connector[bios_index].ddc_i2c.put_data_reg = RADEON_GPIOPAD_EN;
584                 mode_info->bios_connector[bios_index].ddc_i2c.get_clk_reg = RADEON_LCD_GPIO_Y_REG;
585                 mode_info->bios_connector[bios_index].ddc_i2c.get_data_reg = RADEON_LCD_GPIO_Y_REG;
586         }
587
588         /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
589            one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
590         if (dev->pdev->device == 0x515e &&
591             dev->pdev->subsystem_vendor == 0x1014) {
592                 if (mode_info->bios_connector[bios_index].connector_type == CONNECTOR_VGA &&
593                     mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
594                         mode_info->bios_connector[bios_index].valid = false;
595                 }
596         }
597
598         /* Some RV100 cards with 2 VGA ports show up with DVI+VGA */
599         if (dev->pdev->device == 0x5159 &&
600             dev->pdev->subsystem_vendor == 0x1002 &&
601             dev->pdev->subsystem_device == 0x013a) {
602                 if (mode_info->bios_connector[bios_index].connector_type == CONNECTOR_DVI_I)
603                         mode_info->bios_connector[bios_index].connector_type = CONNECTOR_VGA;
604
605         }
606
607         /* X300 card with extra non-existent DVI port */
608         if (dev->pdev->device == 0x5B60 &&
609             dev->pdev->subsystem_vendor == 0x17af &&
610             dev->pdev->subsystem_device == 0x201e &&
611             bios_index == 2) {
612                 if (mode_info->bios_connector[bios_index].connector_type == CONNECTOR_DVI_I)
613                         mode_info->bios_connector[bios_index].valid = false;
614         }
615
616 }
617
618 bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
619 {
620         struct drm_radeon_private *dev_priv = dev->dev_private;
621         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
622         uint32_t conn_info, entry;
623         uint16_t tmp;
624         enum radeon_combios_ddc ddc_type;
625         enum radeon_combios_connector connector_type;
626         int i;
627
628         DRM_DEBUG("\n");
629         conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
630         if (conn_info) {
631                 for (i = 0; i < 4; i++) {
632                         entry = conn_info + 2 + i * 2;
633
634                         if (!radeon_bios16(dev_priv, entry))
635                                     break;
636
637                         mode_info->bios_connector[i].valid = true;
638
639                         tmp = radeon_bios16(dev_priv, entry);
640
641                         connector_type = (tmp >> 12) & 0xf;
642                         mode_info->bios_connector[i].connector_type = connector_type;
643
644                         switch(connector_type) {
645                         case CONNECTOR_PROPRIETARY_LEGACY:
646                                 mode_info->bios_connector[i].connector_type = CONNECTOR_DVI_D;
647                                 break;
648                         case CONNECTOR_CRT_LEGACY:
649                                 mode_info->bios_connector[i].connector_type = CONNECTOR_VGA;
650                                 break;
651                         case CONNECTOR_DVI_I_LEGACY:
652                                 mode_info->bios_connector[i].connector_type = CONNECTOR_DVI_I;
653                                 break;
654                         case CONNECTOR_DVI_D_LEGACY:
655                                 mode_info->bios_connector[i].connector_type = CONNECTOR_DVI_D;
656                                 break;
657                         case CONNECTOR_CTV_LEGACY:
658                                 mode_info->bios_connector[i].connector_type = CONNECTOR_CTV;
659                                 break;
660                         case CONNECTOR_STV_LEGACY:
661                                 mode_info->bios_connector[i].connector_type = CONNECTOR_STV;
662                                 break;
663                         default:
664                                 DRM_ERROR("Unknown connector type: %d\n", connector_type);
665                                 mode_info->bios_connector[i].valid = false;
666                                 break;
667                         }
668
669                         mode_info->bios_connector[i].ddc_i2c.valid = false;
670
671                         ddc_type = (tmp >> 8) & 0xf;
672                         switch (ddc_type) {
673                         case DDC_MONID:
674                                 mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
675                                 break;
676                         case DDC_DVI:
677                                 mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
678                                 break;
679                         case DDC_VGA:
680                                 mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
681                                 break;
682                         case DDC_CRT2:
683                                 mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
684                                 break;
685                         default:
686                                 break;
687                         }
688
689                         if (tmp & 0x1)
690                                 mode_info->bios_connector[i].dac_type = DAC_TVDAC;
691                         else
692                                 mode_info->bios_connector[i].dac_type = DAC_PRIMARY;
693
694                         if ((dev_priv->chip_family == CHIP_RS300) ||
695                             (dev_priv->chip_family == CHIP_RS400) ||
696                             (dev_priv->chip_family == CHIP_RS480))
697                                 mode_info->bios_connector[i].dac_type = DAC_TVDAC;
698
699                         if ((tmp >> 4) & 0x1)
700                                 mode_info->bios_connector[i].tmds_type = TMDS_EXT;
701                         else
702                                 mode_info->bios_connector[i].tmds_type = TMDS_INT;
703
704                         radeon_apply_legacy_quirks(dev, i);
705                 }
706         } else {
707                 uint16_t tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
708                 if (tmds_info) {
709                         DRM_DEBUG("Found DFP table, assuming DVI connector\n");
710
711                         mode_info->bios_connector[0].valid = true;
712                         mode_info->bios_connector[0].connector_type = CONNECTOR_DVI_I;
713                         mode_info->bios_connector[0].dac_type = DAC_PRIMARY;
714                         mode_info->bios_connector[0].tmds_type = TMDS_INT;
715                         mode_info->bios_connector[0].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
716                 } else {
717                         DRM_DEBUG("No connector info found\n");
718                         return false;
719                 }
720         }
721
722         if (dev_priv->flags & RADEON_IS_MOBILITY ||
723             dev_priv->chip_family == CHIP_RS400 ||
724             dev_priv->chip_family == CHIP_RS480) {
725                 uint16_t lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
726                 if (lcd_info) {
727                         uint16_t lcd_ddc_info = lcd_ddc_info = combios_get_table_offset(dev, COMBIOS_LCD_DDC_INFO_TABLE);
728
729                         mode_info->bios_connector[4].valid = true;
730                         mode_info->bios_connector[4].connector_type = CONNECTOR_LVDS;
731                         mode_info->bios_connector[4].dac_type = DAC_NONE;
732                         mode_info->bios_connector[4].tmds_type = TMDS_NONE;
733                         mode_info->bios_connector[4].ddc_i2c.valid = false;
734
735                         if (lcd_ddc_info) {
736                                 ddc_type = radeon_bios8(dev_priv, lcd_ddc_info + 2);
737                                 switch(ddc_type) {
738                                 case DDC_MONID:
739                                         mode_info->bios_connector[4].ddc_i2c =
740                                                 combios_setup_i2c_bus(RADEON_GPIO_MONID);
741                                         break;
742                                 case DDC_DVI:
743                                         mode_info->bios_connector[4].ddc_i2c =
744                                                 combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
745                                         break;
746                                 case DDC_VGA:
747                                         mode_info->bios_connector[4].ddc_i2c =
748                                                 combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
749                                         break;
750                                 case DDC_CRT2:
751                                         mode_info->bios_connector[4].ddc_i2c =
752                                                 combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
753                                         break;
754                                 case DDC_LCD:
755                                         mode_info->bios_connector[4].ddc_i2c =
756                                                 combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
757                                         mode_info->bios_connector[4].ddc_i2c.mask_clk_mask =
758                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
759                                         mode_info->bios_connector[4].ddc_i2c.mask_data_mask =
760                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
761                                         mode_info->bios_connector[4].ddc_i2c.a_clk_mask =
762                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
763                                         mode_info->bios_connector[4].ddc_i2c.a_data_mask =
764                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
765                                         mode_info->bios_connector[4].ddc_i2c.put_clk_mask =
766                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
767                                         mode_info->bios_connector[4].ddc_i2c.put_data_mask =
768                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
769                                         mode_info->bios_connector[4].ddc_i2c.get_clk_mask =
770                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
771                                         mode_info->bios_connector[4].ddc_i2c.get_data_mask =
772                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
773                                         break;
774                                 case DDC_GPIO:
775                                         mode_info->bios_connector[4].ddc_i2c =
776                                                 combios_setup_i2c_bus(RADEON_MDGPIO_EN_REG);
777                                         mode_info->bios_connector[4].ddc_i2c.mask_clk_mask =
778                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
779                                         mode_info->bios_connector[4].ddc_i2c.mask_data_mask =
780                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
781                                         mode_info->bios_connector[4].ddc_i2c.a_clk_mask =
782                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
783                                         mode_info->bios_connector[4].ddc_i2c.a_data_mask =
784                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
785                                         mode_info->bios_connector[4].ddc_i2c.put_clk_mask =
786                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
787                                         mode_info->bios_connector[4].ddc_i2c.put_data_mask =
788                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
789                                         mode_info->bios_connector[4].ddc_i2c.get_clk_mask =
790                                                 radeon_bios32(dev_priv, lcd_ddc_info + 3);
791                                         mode_info->bios_connector[4].ddc_i2c.get_data_mask =
792                                                 radeon_bios32(dev_priv, lcd_ddc_info + 7);
793                                         break;
794                                 default:
795                                         break;
796                                 }
797                                 DRM_DEBUG("LCD DDC Info Table found!\n");
798                         }
799                 } else
800                         mode_info->bios_connector[4].ddc_i2c.valid = false;
801         }
802
803         /* check TV table */
804         if (dev_priv->chip_family != CHIP_R100 &&
805             dev_priv->chip_family != CHIP_R200) {
806                 uint32_t tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
807                 if (tv_info) {
808                         if (radeon_bios8(dev_priv, tv_info + 6) == 'T') {
809                                 mode_info->bios_connector[5].valid = true;
810                                 mode_info->bios_connector[5].connector_type = CONNECTOR_DIN;
811                                 mode_info->bios_connector[5].dac_type = DAC_TVDAC;
812                                 mode_info->bios_connector[5].tmds_type = TMDS_NONE;
813                                 mode_info->bios_connector[5].ddc_i2c.valid = false;
814                         }
815                 }
816         }
817
818
819         DRM_DEBUG("BIOS Connector table\n");
820         for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
821                 if (!mode_info->bios_connector[i].valid)
822                         continue;
823
824                 DRM_DEBUG("Port %d: ddc_type 0x%x, dac_type %d, tmds_type %d, connector type %d, hpd_mask %d\n",
825                           i, mode_info->bios_connector[i].ddc_i2c.mask_clk_reg,
826                           mode_info->bios_connector[i].dac_type,
827                           mode_info->bios_connector[i].tmds_type,
828                           mode_info->bios_connector[i].connector_type,
829                           mode_info->bios_connector[i].hpd_mask);
830         }
831
832         return true;
833 }
834