Merge tag 'drm-intel-fixes-2014-06-26' of git://anongit.freedesktop.org/drm-intel...
[deliverable/linux.git] / drivers / gpu / drm / radeon / radeon_atombios.c
CommitLineData
771fe6b9
JG
1/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 */
760285e7
DH
26#include <drm/drmP.h>
27#include <drm/radeon_drm.h>
771fe6b9
JG
28#include "radeon.h"
29
30#include "atom.h"
31#include "atom-bits.h"
32
771fe6b9 33extern void
5137ee94 34radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
36868bda 35 uint32_t supported_device, u16 caps);
771fe6b9 36
771fe6b9
JG
37/* from radeon_legacy_encoder.c */
38extern void
5137ee94 39radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
771fe6b9
JG
40 uint32_t supported_device);
41
42union atom_supported_devices {
43 struct _ATOM_SUPPORTED_DEVICES_INFO info;
44 struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
45 struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
46};
47
21240f9b
AD
48static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev,
49 ATOM_GPIO_I2C_ASSIGMENT *gpio,
50 u8 index)
51{
52 /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */
53 if ((rdev->family == CHIP_R420) ||
54 (rdev->family == CHIP_R423) ||
55 (rdev->family == CHIP_RV410)) {
56 if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) ||
57 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) ||
58 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) {
59 gpio->ucClkMaskShift = 0x19;
60 gpio->ucDataMaskShift = 0x18;
61 }
62 }
63
64 /* some evergreen boards have bad data for this entry */
65 if (ASIC_IS_DCE4(rdev)) {
66 if ((index == 7) &&
67 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
68 (gpio->sucI2cId.ucAccess == 0)) {
69 gpio->sucI2cId.ucAccess = 0x97;
70 gpio->ucDataMaskShift = 8;
71 gpio->ucDataEnShift = 8;
72 gpio->ucDataY_Shift = 8;
73 gpio->ucDataA_Shift = 8;
74 }
75 }
76
77 /* some DCE3 boards have bad data for this entry */
78 if (ASIC_IS_DCE3(rdev)) {
79 if ((index == 4) &&
80 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
81 (gpio->sucI2cId.ucAccess == 0x94))
82 gpio->sucI2cId.ucAccess = 0x14;
83 }
84}
85
86static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
87{
88 struct radeon_i2c_bus_rec i2c;
89
90 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
91
92 i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
93 i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
94 i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
95 i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
96 i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
97 i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
98 i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
99 i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
100 i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
101 i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
102 i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
103 i2c.en_data_mask = (1 << gpio->ucDataEnShift);
104 i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
105 i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
106 i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
107 i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
108
109 if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
110 i2c.hw_capable = true;
111 else
112 i2c.hw_capable = false;
113
114 if (gpio->sucI2cId.ucAccess == 0xa0)
115 i2c.mm_i2c = true;
116 else
117 i2c.mm_i2c = false;
118
119 i2c.i2c_id = gpio->sucI2cId.ucAccess;
120
121 if (i2c.mask_clk_reg)
122 i2c.valid = true;
123 else
124 i2c.valid = false;
125
126 return i2c;
127}
128
ce580fab 129static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
eed45b30 130 uint8_t id)
771fe6b9 131{
771fe6b9 132 struct atom_context *ctx = rdev->mode_info.atom_context;
6a93cb25 133 ATOM_GPIO_I2C_ASSIGMENT *gpio;
771fe6b9
JG
134 struct radeon_i2c_bus_rec i2c;
135 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
136 struct _ATOM_GPIO_I2C_INFO *i2c_info;
95beb690
AD
137 uint16_t data_offset, size;
138 int i, num_indices;
771fe6b9
JG
139
140 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
141 i2c.valid = false;
142
95beb690 143 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
a084e6ee
AD
144 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
145
95beb690
AD
146 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
147 sizeof(ATOM_GPIO_I2C_ASSIGMENT);
148
607f2c27 149 gpio = &i2c_info->asGPIO_Info[0];
95beb690 150 for (i = 0; i < num_indices; i++) {
a084e6ee 151
21240f9b 152 radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
3074adc8 153
a084e6ee 154 if (gpio->sucI2cId.ucAccess == id) {
21240f9b 155 i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
a084e6ee
AD
156 break;
157 }
607f2c27
AD
158 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
159 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
d3f420d1
AD
160 }
161 }
771fe6b9
JG
162
163 return i2c;
164}
165
f376b94f
AD
166void radeon_atombios_i2c_init(struct radeon_device *rdev)
167{
168 struct atom_context *ctx = rdev->mode_info.atom_context;
169 ATOM_GPIO_I2C_ASSIGMENT *gpio;
170 struct radeon_i2c_bus_rec i2c;
171 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
172 struct _ATOM_GPIO_I2C_INFO *i2c_info;
173 uint16_t data_offset, size;
174 int i, num_indices;
175 char stmp[32];
176
f376b94f
AD
177 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
178 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
179
180 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
181 sizeof(ATOM_GPIO_I2C_ASSIGMENT);
182
607f2c27 183 gpio = &i2c_info->asGPIO_Info[0];
f376b94f 184 for (i = 0; i < num_indices; i++) {
21240f9b 185 radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
ea39302b 186
21240f9b 187 i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
3074adc8 188
21240f9b 189 if (i2c.valid) {
f376b94f
AD
190 sprintf(stmp, "0x%x", i2c.i2c_id);
191 rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
192 }
607f2c27
AD
193 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
194 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
f376b94f
AD
195 }
196 }
197}
198
ce580fab 199static struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
cc8dbbb4 200 u8 id)
eed45b30
AD
201{
202 struct atom_context *ctx = rdev->mode_info.atom_context;
203 struct radeon_gpio_rec gpio;
204 int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
205 struct _ATOM_GPIO_PIN_LUT *gpio_info;
206 ATOM_GPIO_PIN_ASSIGNMENT *pin;
207 u16 data_offset, size;
208 int i, num_indices;
209
210 memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
211 gpio.valid = false;
212
a084e6ee
AD
213 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
214 gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
eed45b30 215
a084e6ee
AD
216 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
217 sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
eed45b30 218
607f2c27 219 pin = gpio_info->asGPIO_Pin;
a084e6ee 220 for (i = 0; i < num_indices; i++) {
a084e6ee
AD
221 if (id == pin->ucGPIO_ID) {
222 gpio.id = pin->ucGPIO_ID;
4589433c 223 gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4;
a084e6ee
AD
224 gpio.mask = (1 << pin->ucGpioPinBitShift);
225 gpio.valid = true;
226 break;
227 }
607f2c27
AD
228 pin = (ATOM_GPIO_PIN_ASSIGNMENT *)
229 ((u8 *)pin + sizeof(ATOM_GPIO_PIN_ASSIGNMENT));
eed45b30
AD
230 }
231 }
232
233 return gpio;
234}
235
236static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
237 struct radeon_gpio_rec *gpio)
238{
239 struct radeon_hpd hpd;
bcc1c2a1
AD
240 u32 reg;
241
1d978dac
JD
242 memset(&hpd, 0, sizeof(struct radeon_hpd));
243
82d118ef
AD
244 if (ASIC_IS_DCE6(rdev))
245 reg = SI_DC_GPIO_HPD_A;
246 else if (ASIC_IS_DCE4(rdev))
bcc1c2a1
AD
247 reg = EVERGREEN_DC_GPIO_HPD_A;
248 else
249 reg = AVIVO_DC_GPIO_HPD_A;
250
eed45b30 251 hpd.gpio = *gpio;
bcc1c2a1 252 if (gpio->reg == reg) {
eed45b30
AD
253 switch(gpio->mask) {
254 case (1 << 0):
255 hpd.hpd = RADEON_HPD_1;
256 break;
257 case (1 << 8):
258 hpd.hpd = RADEON_HPD_2;
259 break;
260 case (1 << 16):
261 hpd.hpd = RADEON_HPD_3;
262 break;
263 case (1 << 24):
264 hpd.hpd = RADEON_HPD_4;
265 break;
266 case (1 << 26):
267 hpd.hpd = RADEON_HPD_5;
268 break;
269 case (1 << 28):
270 hpd.hpd = RADEON_HPD_6;
271 break;
272 default:
273 hpd.hpd = RADEON_HPD_NONE;
274 break;
275 }
276 } else
277 hpd.hpd = RADEON_HPD_NONE;
278 return hpd;
279}
280
771fe6b9
JG
281static bool radeon_atom_apply_quirks(struct drm_device *dev,
282 uint32_t supported_device,
283 int *connector_type,
848577ee 284 struct radeon_i2c_bus_rec *i2c_bus,
eed45b30
AD
285 uint16_t *line_mux,
286 struct radeon_hpd *hpd)
771fe6b9
JG
287{
288
289 /* Asus M2A-VM HDMI board lists the DVI port as HDMI */
290 if ((dev->pdev->device == 0x791e) &&
291 (dev->pdev->subsystem_vendor == 0x1043) &&
292 (dev->pdev->subsystem_device == 0x826d)) {
293 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
294 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
295 *connector_type = DRM_MODE_CONNECTOR_DVID;
296 }
297
c86a9038
AD
298 /* Asrock RS600 board lists the DVI port as HDMI */
299 if ((dev->pdev->device == 0x7941) &&
300 (dev->pdev->subsystem_vendor == 0x1849) &&
301 (dev->pdev->subsystem_device == 0x7941)) {
302 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
303 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
304 *connector_type = DRM_MODE_CONNECTOR_DVID;
305 }
306
f36fce0f
AD
307 /* MSI K9A2GM V2/V3 board has no HDMI or DVI */
308 if ((dev->pdev->device == 0x796e) &&
309 (dev->pdev->subsystem_vendor == 0x1462) &&
310 (dev->pdev->subsystem_device == 0x7302)) {
311 if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) ||
312 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
313 return false;
314 }
315
771fe6b9
JG
316 /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
317 if ((dev->pdev->device == 0x7941) &&
318 (dev->pdev->subsystem_vendor == 0x147b) &&
319 (dev->pdev->subsystem_device == 0x2412)) {
320 if (*connector_type == DRM_MODE_CONNECTOR_DVII)
321 return false;
322 }
323
324 /* Falcon NW laptop lists vga ddc line for LVDS */
325 if ((dev->pdev->device == 0x5653) &&
326 (dev->pdev->subsystem_vendor == 0x1462) &&
327 (dev->pdev->subsystem_device == 0x0291)) {
848577ee 328 if (*connector_type == DRM_MODE_CONNECTOR_LVDS) {
771fe6b9 329 i2c_bus->valid = false;
848577ee
AD
330 *line_mux = 53;
331 }
771fe6b9
JG
332 }
333
4e3f9b78
AD
334 /* HIS X1300 is DVI+VGA, not DVI+DVI */
335 if ((dev->pdev->device == 0x7146) &&
336 (dev->pdev->subsystem_vendor == 0x17af) &&
337 (dev->pdev->subsystem_device == 0x2058)) {
338 if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
339 return false;
340 }
341
aa1a750e
DA
342 /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
343 if ((dev->pdev->device == 0x7142) &&
344 (dev->pdev->subsystem_vendor == 0x1458) &&
345 (dev->pdev->subsystem_device == 0x2134)) {
346 if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
347 return false;
348 }
349
350
771fe6b9
JG
351 /* Funky macbooks */
352 if ((dev->pdev->device == 0x71C5) &&
353 (dev->pdev->subsystem_vendor == 0x106b) &&
354 (dev->pdev->subsystem_device == 0x0080)) {
355 if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||
356 (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
357 return false;
e1e8a5dd
AD
358 if (supported_device == ATOM_DEVICE_CRT2_SUPPORT)
359 *line_mux = 0x90;
771fe6b9
JG
360 }
361
be23da8a
AD
362 /* mac rv630, rv730, others */
363 if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
364 (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
365 *connector_type = DRM_MODE_CONNECTOR_9PinDIN;
366 *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
f598aa75
AD
367 }
368
771fe6b9
JG
369 /* ASUS HD 3600 XT board lists the DVI port as HDMI */
370 if ((dev->pdev->device == 0x9598) &&
371 (dev->pdev->subsystem_vendor == 0x1043) &&
372 (dev->pdev->subsystem_device == 0x01da)) {
705af9c7 373 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
d42571ef 374 *connector_type = DRM_MODE_CONNECTOR_DVII;
705af9c7
AD
375 }
376 }
377
e153b70b
AD
378 /* ASUS HD 3600 board lists the DVI port as HDMI */
379 if ((dev->pdev->device == 0x9598) &&
380 (dev->pdev->subsystem_vendor == 0x1043) &&
381 (dev->pdev->subsystem_device == 0x01e4)) {
382 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
383 *connector_type = DRM_MODE_CONNECTOR_DVII;
384 }
385 }
386
705af9c7
AD
387 /* ASUS HD 3450 board lists the DVI port as HDMI */
388 if ((dev->pdev->device == 0x95C5) &&
389 (dev->pdev->subsystem_vendor == 0x1043) &&
390 (dev->pdev->subsystem_device == 0x01e2)) {
391 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
d42571ef 392 *connector_type = DRM_MODE_CONNECTOR_DVII;
771fe6b9
JG
393 }
394 }
395
705af9c7
AD
396 /* some BIOSes seem to report DAC on HDMI - usually this is a board with
397 * HDMI + VGA reporting as HDMI
398 */
399 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
400 if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {
401 *connector_type = DRM_MODE_CONNECTOR_VGA;
402 *line_mux = 0;
403 }
404 }
405
4f87af46 406 /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port
2f299d5d
AD
407 * on the laptop and a DVI port on the docking station and
408 * both share the same encoder, hpd pin, and ddc line.
409 * So while the bios table is technically correct,
410 * we drop the DVI port here since xrandr has no concept of
411 * encoders and will try and drive both connectors
412 * with different crtcs which isn't possible on the hardware
413 * side and leaves no crtcs for LVDS or VGA.
414 */
4f87af46 415 if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) &&
3e5f8ff3
AD
416 (dev->pdev->subsystem_vendor == 0x1025) &&
417 (dev->pdev->subsystem_device == 0x013c)) {
418 if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
9ea2c4be 419 (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) {
2f299d5d 420 /* actually it's a DVI-D port not DVI-I */
3e5f8ff3 421 *connector_type = DRM_MODE_CONNECTOR_DVID;
2f299d5d 422 return false;
9ea2c4be 423 }
3e5f8ff3
AD
424 }
425
efa8450f
DA
426 /* XFX Pine Group device rv730 reports no VGA DDC lines
427 * even though they are wired up to record 0x93
428 */
429 if ((dev->pdev->device == 0x9498) &&
430 (dev->pdev->subsystem_vendor == 0x1682) &&
1ebf169a
AD
431 (dev->pdev->subsystem_device == 0x2452) &&
432 (i2c_bus->valid == false) &&
433 !(supported_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))) {
efa8450f
DA
434 struct radeon_device *rdev = dev->dev_private;
435 *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93);
436 }
4c1b2d2d
AD
437
438 /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
52e9b39d 439 if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&
4c1b2d2d
AD
440 (dev->pdev->subsystem_vendor == 0x1734) &&
441 (dev->pdev->subsystem_device == 0x11bd)) {
442 if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
443 *connector_type = DRM_MODE_CONNECTOR_DVII;
444 *line_mux = 0x3103;
445 } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) {
446 *connector_type = DRM_MODE_CONNECTOR_DVII;
447 }
448 }
449
450
771fe6b9
JG
451 return true;
452}
453
454const int supported_devices_connector_convert[] = {
455 DRM_MODE_CONNECTOR_Unknown,
456 DRM_MODE_CONNECTOR_VGA,
457 DRM_MODE_CONNECTOR_DVII,
458 DRM_MODE_CONNECTOR_DVID,
459 DRM_MODE_CONNECTOR_DVIA,
460 DRM_MODE_CONNECTOR_SVIDEO,
461 DRM_MODE_CONNECTOR_Composite,
462 DRM_MODE_CONNECTOR_LVDS,
463 DRM_MODE_CONNECTOR_Unknown,
464 DRM_MODE_CONNECTOR_Unknown,
465 DRM_MODE_CONNECTOR_HDMIA,
466 DRM_MODE_CONNECTOR_HDMIB,
467 DRM_MODE_CONNECTOR_Unknown,
468 DRM_MODE_CONNECTOR_Unknown,
469 DRM_MODE_CONNECTOR_9PinDIN,
470 DRM_MODE_CONNECTOR_DisplayPort
471};
472
b75fad06
AD
473const uint16_t supported_devices_connector_object_id_convert[] = {
474 CONNECTOR_OBJECT_ID_NONE,
475 CONNECTOR_OBJECT_ID_VGA,
476 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */
477 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */
478 CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */
479 CONNECTOR_OBJECT_ID_COMPOSITE,
480 CONNECTOR_OBJECT_ID_SVIDEO,
481 CONNECTOR_OBJECT_ID_LVDS,
482 CONNECTOR_OBJECT_ID_9PIN_DIN,
483 CONNECTOR_OBJECT_ID_9PIN_DIN,
484 CONNECTOR_OBJECT_ID_DISPLAYPORT,
485 CONNECTOR_OBJECT_ID_HDMI_TYPE_A,
486 CONNECTOR_OBJECT_ID_HDMI_TYPE_B,
487 CONNECTOR_OBJECT_ID_SVIDEO
488};
489
771fe6b9
JG
490const int object_connector_convert[] = {
491 DRM_MODE_CONNECTOR_Unknown,
492 DRM_MODE_CONNECTOR_DVII,
493 DRM_MODE_CONNECTOR_DVII,
494 DRM_MODE_CONNECTOR_DVID,
495 DRM_MODE_CONNECTOR_DVID,
496 DRM_MODE_CONNECTOR_VGA,
497 DRM_MODE_CONNECTOR_Composite,
498 DRM_MODE_CONNECTOR_SVIDEO,
499 DRM_MODE_CONNECTOR_Unknown,
705af9c7 500 DRM_MODE_CONNECTOR_Unknown,
771fe6b9
JG
501 DRM_MODE_CONNECTOR_9PinDIN,
502 DRM_MODE_CONNECTOR_Unknown,
503 DRM_MODE_CONNECTOR_HDMIA,
504 DRM_MODE_CONNECTOR_HDMIB,
771fe6b9
JG
505 DRM_MODE_CONNECTOR_LVDS,
506 DRM_MODE_CONNECTOR_9PinDIN,
507 DRM_MODE_CONNECTOR_Unknown,
508 DRM_MODE_CONNECTOR_Unknown,
509 DRM_MODE_CONNECTOR_Unknown,
196c58d2
AD
510 DRM_MODE_CONNECTOR_DisplayPort,
511 DRM_MODE_CONNECTOR_eDP,
512 DRM_MODE_CONNECTOR_Unknown
771fe6b9
JG
513};
514
515bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
516{
517 struct radeon_device *rdev = dev->dev_private;
518 struct radeon_mode_info *mode_info = &rdev->mode_info;
519 struct atom_context *ctx = mode_info->atom_context;
520 int index = GetIndexIntoMasterTable(DATA, Object_Header);
eed45b30
AD
521 u16 size, data_offset;
522 u8 frev, crev;
771fe6b9 523 ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
36868bda 524 ATOM_ENCODER_OBJECT_TABLE *enc_obj;
26b5bc98 525 ATOM_OBJECT_TABLE *router_obj;
771fe6b9
JG
526 ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
527 ATOM_OBJECT_HEADER *obj_header;
26b5bc98 528 int i, j, k, path_size, device_support;
771fe6b9 529 int connector_type;
eed45b30 530 u16 igp_lane_info, conn_id, connector_object_id;
771fe6b9 531 struct radeon_i2c_bus_rec ddc_bus;
26b5bc98 532 struct radeon_router router;
eed45b30
AD
533 struct radeon_gpio_rec gpio;
534 struct radeon_hpd hpd;
535
a084e6ee 536 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
771fe6b9
JG
537 return false;
538
539 if (crev < 2)
540 return false;
541
542 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
543 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
544 (ctx->bios + data_offset +
545 le16_to_cpu(obj_header->usDisplayPathTableOffset));
546 con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
547 (ctx->bios + data_offset +
548 le16_to_cpu(obj_header->usConnectorObjectTableOffset));
36868bda
AD
549 enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
550 (ctx->bios + data_offset +
551 le16_to_cpu(obj_header->usEncoderObjectTableOffset));
26b5bc98
AD
552 router_obj = (ATOM_OBJECT_TABLE *)
553 (ctx->bios + data_offset +
554 le16_to_cpu(obj_header->usRouterObjectTableOffset));
771fe6b9
JG
555 device_support = le16_to_cpu(obj_header->usDeviceSupport);
556
557 path_size = 0;
558 for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
559 uint8_t *addr = (uint8_t *) path_obj->asDispPath;
560 ATOM_DISPLAY_OBJECT_PATH *path;
561 addr += path_size;
562 path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
563 path_size += le16_to_cpu(path->usSize);
5137ee94 564
771fe6b9
JG
565 if (device_support & le16_to_cpu(path->usDeviceTag)) {
566 uint8_t con_obj_id, con_obj_num, con_obj_type;
567
568 con_obj_id =
569 (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)
570 >> OBJECT_ID_SHIFT;
571 con_obj_num =
572 (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK)
573 >> ENUM_ID_SHIFT;
574 con_obj_type =
575 (le16_to_cpu(path->usConnObjectId) &
576 OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
577
4bbd4973
DA
578 /* TODO CV support */
579 if (le16_to_cpu(path->usDeviceTag) ==
580 ATOM_DEVICE_CV_SUPPORT)
771fe6b9
JG
581 continue;
582
ee59f2b4
AD
583 /* IGP chips */
584 if ((rdev->flags & RADEON_IS_IGP) &&
771fe6b9
JG
585 (con_obj_id ==
586 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
587 uint16_t igp_offset = 0;
588 ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj;
589
590 index =
591 GetIndexIntoMasterTable(DATA,
592 IntegratedSystemInfo);
593
a084e6ee
AD
594 if (atom_parse_data_header(ctx, index, &size, &frev,
595 &crev, &igp_offset)) {
596
597 if (crev >= 2) {
598 igp_obj =
599 (ATOM_INTEGRATED_SYSTEM_INFO_V2
600 *) (ctx->bios + igp_offset);
601
602 if (igp_obj) {
603 uint32_t slot_config, ct;
604
605 if (con_obj_num == 1)
606 slot_config =
607 igp_obj->
608 ulDDISlot1Config;
609 else
610 slot_config =
611 igp_obj->
612 ulDDISlot2Config;
613
614 ct = (slot_config >> 16) & 0xff;
615 connector_type =
616 object_connector_convert
617 [ct];
618 connector_object_id = ct;
619 igp_lane_info =
620 slot_config & 0xffff;
621 } else
622 continue;
771fe6b9
JG
623 } else
624 continue;
a084e6ee
AD
625 } else {
626 igp_lane_info = 0;
627 connector_type =
628 object_connector_convert[con_obj_id];
629 connector_object_id = con_obj_id;
630 }
771fe6b9
JG
631 } else {
632 igp_lane_info = 0;
633 connector_type =
634 object_connector_convert[con_obj_id];
b75fad06 635 connector_object_id = con_obj_id;
771fe6b9
JG
636 }
637
638 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
639 continue;
640
bdd91b2b
TW
641 router.ddc_valid = false;
642 router.cd_valid = false;
26b5bc98
AD
643 for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
644 uint8_t grph_obj_id, grph_obj_num, grph_obj_type;
771fe6b9 645
26b5bc98 646 grph_obj_id =
771fe6b9
JG
647 (le16_to_cpu(path->usGraphicObjIds[j]) &
648 OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
26b5bc98 649 grph_obj_num =
771fe6b9
JG
650 (le16_to_cpu(path->usGraphicObjIds[j]) &
651 ENUM_ID_MASK) >> ENUM_ID_SHIFT;
26b5bc98 652 grph_obj_type =
771fe6b9
JG
653 (le16_to_cpu(path->usGraphicObjIds[j]) &
654 OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
655
26b5bc98 656 if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
36868bda
AD
657 for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
658 u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);
659 if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {
660 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
661 (ctx->bios + data_offset +
662 le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));
663 ATOM_ENCODER_CAP_RECORD *cap_record;
664 u16 caps = 0;
771fe6b9 665
97ea530f
JL
666 while (record->ucRecordSize > 0 &&
667 record->ucRecordType > 0 &&
36868bda
AD
668 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
669 switch (record->ucRecordType) {
670 case ATOM_ENCODER_CAP_RECORD_TYPE:
671 cap_record =(ATOM_ENCODER_CAP_RECORD *)
672 record;
673 caps = le16_to_cpu(cap_record->usEncoderCap);
674 break;
675 }
676 record = (ATOM_COMMON_RECORD_HEADER *)
677 ((char *)record + record->ucRecordSize);
678 }
679 radeon_add_atom_encoder(dev,
680 encoder_obj,
681 le16_to_cpu
682 (path->
683 usDeviceTag),
684 caps);
685 }
686 }
26b5bc98 687 } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
26b5bc98 688 for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
bdd91b2b 689 u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
26b5bc98
AD
690 if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {
691 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
692 (ctx->bios + data_offset +
693 le16_to_cpu(router_obj->asObjects[k].usRecordOffset));
694 ATOM_I2C_RECORD *i2c_record;
695 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
696 ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;
fb939dfc 697 ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;
26b5bc98
AD
698 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =
699 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
700 (ctx->bios + data_offset +
701 le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));
fb93df1c
AD
702 u8 *num_dst_objs = (u8 *)
703 ((u8 *)router_src_dst_table + 1 +
704 (router_src_dst_table->ucNumberOfSrc * 2));
705 u16 *dst_objs = (u16 *)(num_dst_objs + 1);
26b5bc98
AD
706 int enum_id;
707
708 router.router_id = router_obj_id;
fb93df1c 709 for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) {
26b5bc98 710 if (le16_to_cpu(path->usConnObjectId) ==
fb93df1c 711 le16_to_cpu(dst_objs[enum_id]))
26b5bc98
AD
712 break;
713 }
714
97ea530f
JL
715 while (record->ucRecordSize > 0 &&
716 record->ucRecordType > 0 &&
26b5bc98
AD
717 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
718 switch (record->ucRecordType) {
719 case ATOM_I2C_RECORD_TYPE:
720 i2c_record =
721 (ATOM_I2C_RECORD *)
722 record;
723 i2c_config =
724 (ATOM_I2C_ID_CONFIG_ACCESS *)
725 &i2c_record->sucI2cId;
726 router.i2c_info =
727 radeon_lookup_i2c_gpio(rdev,
728 i2c_config->
729 ucAccess);
730 router.i2c_addr = i2c_record->ucI2CAddr >> 1;
731 break;
732 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
733 ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)
734 record;
fb939dfc
AD
735 router.ddc_valid = true;
736 router.ddc_mux_type = ddc_path->ucMuxType;
737 router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;
738 router.ddc_mux_state = ddc_path->ucMuxState[enum_id];
739 break;
740 case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
741 cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)
742 record;
743 router.cd_valid = true;
744 router.cd_mux_type = cd_path->ucMuxType;
745 router.cd_mux_control_pin = cd_path->ucMuxControlPin;
746 router.cd_mux_state = cd_path->ucMuxState[enum_id];
26b5bc98
AD
747 break;
748 }
749 record = (ATOM_COMMON_RECORD_HEADER *)
750 ((char *)record + record->ucRecordSize);
751 }
752 }
753 }
771fe6b9
JG
754 }
755 }
756
eed45b30 757 /* look up gpio for ddc, hpd */
2bfcc0fc
AD
758 ddc_bus.valid = false;
759 hpd.hpd = RADEON_HPD_NONE;
771fe6b9 760 if ((le16_to_cpu(path->usDeviceTag) &
eed45b30 761 (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
771fe6b9
JG
762 for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
763 if (le16_to_cpu(path->usConnObjectId) ==
764 le16_to_cpu(con_obj->asObjects[j].
765 usObjectID)) {
766 ATOM_COMMON_RECORD_HEADER
767 *record =
768 (ATOM_COMMON_RECORD_HEADER
769 *)
770 (ctx->bios + data_offset +
771 le16_to_cpu(con_obj->
772 asObjects[j].
773 usRecordOffset));
774 ATOM_I2C_RECORD *i2c_record;
eed45b30 775 ATOM_HPD_INT_RECORD *hpd_record;
d3f420d1 776 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
6a93cb25 777
97ea530f
JL
778 while (record->ucRecordSize > 0 &&
779 record->ucRecordType > 0 &&
780 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
eed45b30 781 switch (record->ucRecordType) {
771fe6b9
JG
782 case ATOM_I2C_RECORD_TYPE:
783 i2c_record =
eed45b30
AD
784 (ATOM_I2C_RECORD *)
785 record;
d3f420d1
AD
786 i2c_config =
787 (ATOM_I2C_ID_CONFIG_ACCESS *)
788 &i2c_record->sucI2cId;
eed45b30 789 ddc_bus = radeon_lookup_i2c_gpio(rdev,
d3f420d1
AD
790 i2c_config->
791 ucAccess);
eed45b30
AD
792 break;
793 case ATOM_HPD_INT_RECORD_TYPE:
794 hpd_record =
795 (ATOM_HPD_INT_RECORD *)
796 record;
797 gpio = radeon_lookup_gpio(rdev,
798 hpd_record->ucHPDIntGPIOID);
799 hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
800 hpd.plugged_state = hpd_record->ucPlugged_PinState;
771fe6b9
JG
801 break;
802 }
803 record =
804 (ATOM_COMMON_RECORD_HEADER
805 *) ((char *)record
806 +
807 record->
808 ucRecordSize);
809 }
810 break;
811 }
812 }
eed45b30 813 }
771fe6b9 814
bcc1c2a1 815 /* needed for aux chan transactions */
8e36ed00 816 ddc_bus.hpd = hpd.hpd;
bcc1c2a1 817
705af9c7
AD
818 conn_id = le16_to_cpu(path->usConnObjectId);
819
820 if (!radeon_atom_apply_quirks
821 (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
eed45b30 822 &ddc_bus, &conn_id, &hpd))
705af9c7
AD
823 continue;
824
771fe6b9 825 radeon_add_atom_connector(dev,
705af9c7 826 conn_id,
771fe6b9
JG
827 le16_to_cpu(path->
828 usDeviceTag),
829 connector_type, &ddc_bus,
5137ee94 830 igp_lane_info,
eed45b30 831 connector_object_id,
26b5bc98
AD
832 &hpd,
833 &router);
771fe6b9
JG
834
835 }
836 }
837
838 radeon_link_encoder_connector(dev);
839
840 return true;
841}
842
b75fad06
AD
843static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
844 int connector_type,
845 uint16_t devices)
846{
847 struct radeon_device *rdev = dev->dev_private;
848
849 if (rdev->flags & RADEON_IS_IGP) {
850 return supported_devices_connector_object_id_convert
851 [connector_type];
852 } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) ||
853 (connector_type == DRM_MODE_CONNECTOR_DVID)) &&
854 (devices & ATOM_DEVICE_DFP2_SUPPORT)) {
855 struct radeon_mode_info *mode_info = &rdev->mode_info;
856 struct atom_context *ctx = mode_info->atom_context;
857 int index = GetIndexIntoMasterTable(DATA, XTMDS_Info);
858 uint16_t size, data_offset;
859 uint8_t frev, crev;
860 ATOM_XTMDS_INFO *xtmds;
861
a084e6ee
AD
862 if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {
863 xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
b75fad06 864
a084e6ee
AD
865 if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
866 if (connector_type == DRM_MODE_CONNECTOR_DVII)
867 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
868 else
869 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
870 } else {
871 if (connector_type == DRM_MODE_CONNECTOR_DVII)
872 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
873 else
874 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
875 }
876 } else
877 return supported_devices_connector_object_id_convert
878 [connector_type];
b75fad06
AD
879 } else {
880 return supported_devices_connector_object_id_convert
881 [connector_type];
882 }
883}
884
771fe6b9
JG
885struct bios_connector {
886 bool valid;
705af9c7 887 uint16_t line_mux;
771fe6b9
JG
888 uint16_t devices;
889 int connector_type;
890 struct radeon_i2c_bus_rec ddc_bus;
eed45b30 891 struct radeon_hpd hpd;
771fe6b9
JG
892};
893
894bool radeon_get_atom_connector_info_from_supported_devices_table(struct
895 drm_device
896 *dev)
897{
898 struct radeon_device *rdev = dev->dev_private;
899 struct radeon_mode_info *mode_info = &rdev->mode_info;
900 struct atom_context *ctx = mode_info->atom_context;
901 int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);
902 uint16_t size, data_offset;
903 uint8_t frev, crev;
904 uint16_t device_support;
905 uint8_t dac;
906 union atom_supported_devices *supported_devices;
eed45b30 907 int i, j, max_device;
f49d273d
PB
908 struct bios_connector *bios_connectors;
909 size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE;
26b5bc98
AD
910 struct radeon_router router;
911
fb939dfc
AD
912 router.ddc_valid = false;
913 router.cd_valid = false;
771fe6b9 914
f49d273d
PB
915 bios_connectors = kzalloc(bc_size, GFP_KERNEL);
916 if (!bios_connectors)
917 return false;
918
919 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev,
920 &data_offset)) {
921 kfree(bios_connectors);
a084e6ee 922 return false;
f49d273d 923 }
771fe6b9
JG
924
925 supported_devices =
926 (union atom_supported_devices *)(ctx->bios + data_offset);
927
928 device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
929
eed45b30
AD
930 if (frev > 1)
931 max_device = ATOM_MAX_SUPPORTED_DEVICE;
932 else
933 max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
934
935 for (i = 0; i < max_device; i++) {
771fe6b9
JG
936 ATOM_CONNECTOR_INFO_I2C ci =
937 supported_devices->info.asConnInfo[i];
938
939 bios_connectors[i].valid = false;
940
941 if (!(device_support & (1 << i))) {
942 continue;
943 }
944
945 if (i == ATOM_DEVICE_CV_INDEX) {
d9fdaafb 946 DRM_DEBUG_KMS("Skipping Component Video\n");
771fe6b9
JG
947 continue;
948 }
949
771fe6b9
JG
950 bios_connectors[i].connector_type =
951 supported_devices_connector_convert[ci.sucConnectorInfo.
952 sbfAccess.
953 bfConnectorType];
954
955 if (bios_connectors[i].connector_type ==
956 DRM_MODE_CONNECTOR_Unknown)
957 continue;
958
959 dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
960
d3f420d1
AD
961 bios_connectors[i].line_mux =
962 ci.sucI2cId.ucAccess;
771fe6b9
JG
963
964 /* give tv unique connector ids */
965 if (i == ATOM_DEVICE_TV1_INDEX) {
966 bios_connectors[i].ddc_bus.valid = false;
967 bios_connectors[i].line_mux = 50;
968 } else if (i == ATOM_DEVICE_TV2_INDEX) {
969 bios_connectors[i].ddc_bus.valid = false;
970 bios_connectors[i].line_mux = 51;
971 } else if (i == ATOM_DEVICE_CV_INDEX) {
972 bios_connectors[i].ddc_bus.valid = false;
973 bios_connectors[i].line_mux = 52;
974 } else
975 bios_connectors[i].ddc_bus =
eed45b30
AD
976 radeon_lookup_i2c_gpio(rdev,
977 bios_connectors[i].line_mux);
978
979 if ((crev > 1) && (frev > 1)) {
980 u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
981 switch (isb) {
982 case 0x4:
983 bios_connectors[i].hpd.hpd = RADEON_HPD_1;
984 break;
985 case 0xa:
986 bios_connectors[i].hpd.hpd = RADEON_HPD_2;
987 break;
988 default:
989 bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
990 break;
991 }
992 } else {
993 if (i == ATOM_DEVICE_DFP1_INDEX)
994 bios_connectors[i].hpd.hpd = RADEON_HPD_1;
995 else if (i == ATOM_DEVICE_DFP2_INDEX)
996 bios_connectors[i].hpd.hpd = RADEON_HPD_2;
997 else
998 bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
999 }
771fe6b9
JG
1000
1001 /* Always set the connector type to VGA for CRT1/CRT2. if they are
1002 * shared with a DVI port, we'll pick up the DVI connector when we
1003 * merge the outputs. Some bioses incorrectly list VGA ports as DVI.
1004 */
1005 if (i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX)
1006 bios_connectors[i].connector_type =
1007 DRM_MODE_CONNECTOR_VGA;
1008
1009 if (!radeon_atom_apply_quirks
1010 (dev, (1 << i), &bios_connectors[i].connector_type,
eed45b30
AD
1011 &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
1012 &bios_connectors[i].hpd))
771fe6b9
JG
1013 continue;
1014
1015 bios_connectors[i].valid = true;
1016 bios_connectors[i].devices = (1 << i);
1017
1018 if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)
1019 radeon_add_atom_encoder(dev,
5137ee94 1020 radeon_get_encoder_enum(dev,
771fe6b9
JG
1021 (1 << i),
1022 dac),
36868bda
AD
1023 (1 << i),
1024 0);
771fe6b9
JG
1025 else
1026 radeon_add_legacy_encoder(dev,
5137ee94 1027 radeon_get_encoder_enum(dev,
f56cd64f 1028 (1 << i),
771fe6b9
JG
1029 dac),
1030 (1 << i));
1031 }
1032
1033 /* combine shared connectors */
eed45b30 1034 for (i = 0; i < max_device; i++) {
771fe6b9 1035 if (bios_connectors[i].valid) {
eed45b30 1036 for (j = 0; j < max_device; j++) {
771fe6b9
JG
1037 if (bios_connectors[j].valid && (i != j)) {
1038 if (bios_connectors[i].line_mux ==
1039 bios_connectors[j].line_mux) {
f56cd64f
AD
1040 /* make sure not to combine LVDS */
1041 if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
1042 bios_connectors[i].line_mux = 53;
1043 bios_connectors[i].ddc_bus.valid = false;
1044 continue;
1045 }
1046 if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
1047 bios_connectors[j].line_mux = 53;
1048 bios_connectors[j].ddc_bus.valid = false;
1049 continue;
1050 }
1051 /* combine analog and digital for DVI-I */
1052 if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
1053 (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) ||
1054 ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
1055 (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) {
1056 bios_connectors[i].devices |=
1057 bios_connectors[j].devices;
1058 bios_connectors[i].connector_type =
1059 DRM_MODE_CONNECTOR_DVII;
1060 if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT))
eed45b30
AD
1061 bios_connectors[i].hpd =
1062 bios_connectors[j].hpd;
f56cd64f 1063 bios_connectors[j].valid = false;
771fe6b9
JG
1064 }
1065 }
1066 }
1067 }
1068 }
1069 }
1070
1071 /* add the connectors */
eed45b30 1072 for (i = 0; i < max_device; i++) {
b75fad06
AD
1073 if (bios_connectors[i].valid) {
1074 uint16_t connector_object_id =
1075 atombios_get_connector_object_id(dev,
1076 bios_connectors[i].connector_type,
1077 bios_connectors[i].devices);
771fe6b9
JG
1078 radeon_add_atom_connector(dev,
1079 bios_connectors[i].line_mux,
1080 bios_connectors[i].devices,
1081 bios_connectors[i].
1082 connector_type,
1083 &bios_connectors[i].ddc_bus,
5137ee94 1084 0,
eed45b30 1085 connector_object_id,
26b5bc98
AD
1086 &bios_connectors[i].hpd,
1087 &router);
b75fad06 1088 }
771fe6b9
JG
1089 }
1090
1091 radeon_link_encoder_connector(dev);
1092
f49d273d 1093 kfree(bios_connectors);
771fe6b9
JG
1094 return true;
1095}
1096
1097union firmware_info {
1098 ATOM_FIRMWARE_INFO info;
1099 ATOM_FIRMWARE_INFO_V1_2 info_12;
1100 ATOM_FIRMWARE_INFO_V1_3 info_13;
1101 ATOM_FIRMWARE_INFO_V1_4 info_14;
bcc1c2a1 1102 ATOM_FIRMWARE_INFO_V2_1 info_21;
f82b3ddc 1103 ATOM_FIRMWARE_INFO_V2_2 info_22;
771fe6b9
JG
1104};
1105
1106bool radeon_atom_get_clock_info(struct drm_device *dev)
1107{
1108 struct radeon_device *rdev = dev->dev_private;
1109 struct radeon_mode_info *mode_info = &rdev->mode_info;
1110 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
1111 union firmware_info *firmware_info;
1112 uint8_t frev, crev;
1113 struct radeon_pll *p1pll = &rdev->clock.p1pll;
1114 struct radeon_pll *p2pll = &rdev->clock.p2pll;
bcc1c2a1 1115 struct radeon_pll *dcpll = &rdev->clock.dcpll;
771fe6b9
JG
1116 struct radeon_pll *spll = &rdev->clock.spll;
1117 struct radeon_pll *mpll = &rdev->clock.mpll;
1118 uint16_t data_offset;
1119
a084e6ee
AD
1120 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1121 &frev, &crev, &data_offset)) {
1122 firmware_info =
1123 (union firmware_info *)(mode_info->atom_context->bios +
1124 data_offset);
771fe6b9
JG
1125 /* pixel clocks */
1126 p1pll->reference_freq =
1127 le16_to_cpu(firmware_info->info.usReferenceClock);
1128 p1pll->reference_div = 0;
1129
bc293e58
MF
1130 if (crev < 2)
1131 p1pll->pll_out_min =
1132 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
1133 else
1134 p1pll->pll_out_min =
1135 le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
771fe6b9
JG
1136 p1pll->pll_out_max =
1137 le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
1138
86cb2bbf
AD
1139 if (crev >= 4) {
1140 p1pll->lcd_pll_out_min =
1141 le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
1142 if (p1pll->lcd_pll_out_min == 0)
1143 p1pll->lcd_pll_out_min = p1pll->pll_out_min;
1144 p1pll->lcd_pll_out_max =
1145 le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
1146 if (p1pll->lcd_pll_out_max == 0)
1147 p1pll->lcd_pll_out_max = p1pll->pll_out_max;
1148 } else {
1149 p1pll->lcd_pll_out_min = p1pll->pll_out_min;
1150 p1pll->lcd_pll_out_max = p1pll->pll_out_max;
1151 }
1152
771fe6b9
JG
1153 if (p1pll->pll_out_min == 0) {
1154 if (ASIC_IS_AVIVO(rdev))
1155 p1pll->pll_out_min = 64800;
1156 else
1157 p1pll->pll_out_min = 20000;
1158 }
1159
1160 p1pll->pll_in_min =
1161 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
1162 p1pll->pll_in_max =
1163 le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
1164
1165 *p2pll = *p1pll;
1166
1167 /* system clock */
f82b3ddc
AD
1168 if (ASIC_IS_DCE4(rdev))
1169 spll->reference_freq =
1170 le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
1171 else
1172 spll->reference_freq =
1173 le16_to_cpu(firmware_info->info.usReferenceClock);
771fe6b9
JG
1174 spll->reference_div = 0;
1175
1176 spll->pll_out_min =
1177 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output);
1178 spll->pll_out_max =
1179 le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output);
1180
1181 /* ??? */
1182 if (spll->pll_out_min == 0) {
1183 if (ASIC_IS_AVIVO(rdev))
1184 spll->pll_out_min = 64800;
1185 else
1186 spll->pll_out_min = 20000;
1187 }
1188
1189 spll->pll_in_min =
1190 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input);
1191 spll->pll_in_max =
1192 le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
1193
1194 /* memory clock */
f82b3ddc
AD
1195 if (ASIC_IS_DCE4(rdev))
1196 mpll->reference_freq =
1197 le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
1198 else
1199 mpll->reference_freq =
1200 le16_to_cpu(firmware_info->info.usReferenceClock);
771fe6b9
JG
1201 mpll->reference_div = 0;
1202
1203 mpll->pll_out_min =
1204 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output);
1205 mpll->pll_out_max =
1206 le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output);
1207
1208 /* ??? */
1209 if (mpll->pll_out_min == 0) {
1210 if (ASIC_IS_AVIVO(rdev))
1211 mpll->pll_out_min = 64800;
1212 else
1213 mpll->pll_out_min = 20000;
1214 }
1215
1216 mpll->pll_in_min =
1217 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input);
1218 mpll->pll_in_max =
1219 le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input);
1220
1221 rdev->clock.default_sclk =
1222 le32_to_cpu(firmware_info->info.ulDefaultEngineClock);
1223 rdev->clock.default_mclk =
1224 le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);
1225
bcc1c2a1
AD
1226 if (ASIC_IS_DCE4(rdev)) {
1227 rdev->clock.default_dispclk =
1228 le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
f82b3ddc
AD
1229 if (rdev->clock.default_dispclk == 0) {
1230 if (ASIC_IS_DCE5(rdev))
1231 rdev->clock.default_dispclk = 54000; /* 540 Mhz */
1232 else
1233 rdev->clock.default_dispclk = 60000; /* 600 Mhz */
1234 }
bcc1c2a1
AD
1235 rdev->clock.dp_extclk =
1236 le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
4489cd62 1237 rdev->clock.current_dispclk = rdev->clock.default_dispclk;
bcc1c2a1
AD
1238 }
1239 *dcpll = *p1pll;
1240
b20f9bef
AD
1241 rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);
1242 if (rdev->clock.max_pixel_clock == 0)
1243 rdev->clock.max_pixel_clock = 40000;
1244
af7912e5
AD
1245 /* not technically a clock, but... */
1246 rdev->mode_info.firmware_flags =
1247 le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
1248
771fe6b9
JG
1249 return true;
1250 }
bcc1c2a1 1251
771fe6b9
JG
1252 return false;
1253}
1254
06b6476d
AD
1255union igp_info {
1256 struct _ATOM_INTEGRATED_SYSTEM_INFO info;
1257 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
3838f46e
AD
1258 struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
1259 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
c2037ad1 1260 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
06b6476d
AD
1261};
1262
1263bool radeon_atombios_sideport_present(struct radeon_device *rdev)
1264{
1265 struct radeon_mode_info *mode_info = &rdev->mode_info;
1266 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1267 union igp_info *igp_info;
1268 u8 frev, crev;
1269 u16 data_offset;
1270
4c70b2ea
AD
1271 /* sideport is AMD only */
1272 if (rdev->family == CHIP_RS600)
1273 return false;
1274
a084e6ee
AD
1275 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1276 &frev, &crev, &data_offset)) {
1277 igp_info = (union igp_info *)(mode_info->atom_context->bios +
06b6476d 1278 data_offset);
06b6476d
AD
1279 switch (crev) {
1280 case 1:
4589433c 1281 if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock))
4c70b2ea 1282 return true;
06b6476d
AD
1283 break;
1284 case 2:
4589433c 1285 if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock))
06b6476d
AD
1286 return true;
1287 break;
1288 default:
1289 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
1290 break;
1291 }
1292 }
1293 return false;
1294}
1295
445282db
DA
1296bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
1297 struct radeon_encoder_int_tmds *tmds)
771fe6b9
JG
1298{
1299 struct drm_device *dev = encoder->base.dev;
1300 struct radeon_device *rdev = dev->dev_private;
1301 struct radeon_mode_info *mode_info = &rdev->mode_info;
1302 int index = GetIndexIntoMasterTable(DATA, TMDS_Info);
1303 uint16_t data_offset;
1304 struct _ATOM_TMDS_INFO *tmds_info;
1305 uint8_t frev, crev;
1306 uint16_t maxfreq;
1307 int i;
771fe6b9 1308
a084e6ee
AD
1309 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1310 &frev, &crev, &data_offset)) {
1311 tmds_info =
1312 (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
1313 data_offset);
771fe6b9 1314
771fe6b9
JG
1315 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
1316 for (i = 0; i < 4; i++) {
1317 tmds->tmds_pll[i].freq =
1318 le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency);
1319 tmds->tmds_pll[i].value =
1320 tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f;
1321 tmds->tmds_pll[i].value |=
1322 (tmds_info->asMiscInfo[i].
1323 ucPLL_VCO_Gain & 0x3f) << 6;
1324 tmds->tmds_pll[i].value |=
1325 (tmds_info->asMiscInfo[i].
1326 ucPLL_DutyCycle & 0xf) << 12;
1327 tmds->tmds_pll[i].value |=
1328 (tmds_info->asMiscInfo[i].
1329 ucPLL_VoltageSwing & 0xf) << 16;
1330
d9fdaafb 1331 DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n",
771fe6b9
JG
1332 tmds->tmds_pll[i].freq,
1333 tmds->tmds_pll[i].value);
1334
1335 if (maxfreq == tmds->tmds_pll[i].freq) {
1336 tmds->tmds_pll[i].freq = 0xffffffff;
1337 break;
1338 }
1339 }
445282db 1340 return true;
771fe6b9 1341 }
445282db 1342 return false;
771fe6b9
JG
1343}
1344
ba032a58
AD
1345bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
1346 struct radeon_atom_ss *ss,
1347 int id)
ebbe1cb9 1348{
ebbe1cb9
AD
1349 struct radeon_mode_info *mode_info = &rdev->mode_info;
1350 int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info);
ba032a58 1351 uint16_t data_offset, size;
ebbe1cb9 1352 struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
a7ee824a 1353 struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign;
ebbe1cb9 1354 uint8_t frev, crev;
ba032a58 1355 int i, num_indices;
ebbe1cb9 1356
ba032a58
AD
1357 memset(ss, 0, sizeof(struct radeon_atom_ss));
1358 if (atom_parse_data_header(mode_info->atom_context, index, &size,
a084e6ee
AD
1359 &frev, &crev, &data_offset)) {
1360 ss_info =
1361 (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
ebbe1cb9 1362
ba032a58
AD
1363 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1364 sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT);
a7ee824a
AD
1365 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*)
1366 ((u8 *)&ss_info->asSS_Info[0]);
ba032a58 1367 for (i = 0; i < num_indices; i++) {
a7ee824a 1368 if (ss_assign->ucSS_Id == id) {
279b215e 1369 ss->percentage =
a7ee824a
AD
1370 le16_to_cpu(ss_assign->usSpreadSpectrumPercentage);
1371 ss->type = ss_assign->ucSpreadSpectrumType;
1372 ss->step = ss_assign->ucSS_Step;
1373 ss->delay = ss_assign->ucSS_Delay;
1374 ss->range = ss_assign->ucSS_Range;
1375 ss->refdiv = ss_assign->ucRecommendedRef_Div;
ba032a58
AD
1376 return true;
1377 }
a7ee824a
AD
1378 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*)
1379 ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT));
ba032a58
AD
1380 }
1381 }
1382 return false;
1383}
1384
4339c442
AD
1385static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev,
1386 struct radeon_atom_ss *ss,
1387 int id)
1388{
1389 struct radeon_mode_info *mode_info = &rdev->mode_info;
1390 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1391 u16 data_offset, size;
3838f46e 1392 union igp_info *igp_info;
4339c442
AD
1393 u8 frev, crev;
1394 u16 percentage = 0, rate = 0;
1395
1396 /* get any igp specific overrides */
1397 if (atom_parse_data_header(mode_info->atom_context, index, &size,
1398 &frev, &crev, &data_offset)) {
3838f46e 1399 igp_info = (union igp_info *)
4339c442 1400 (mode_info->atom_context->bios + data_offset);
3838f46e
AD
1401 switch (crev) {
1402 case 6:
1403 switch (id) {
1404 case ASIC_INTERNAL_SS_ON_TMDS:
1405 percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
1406 rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
1407 break;
1408 case ASIC_INTERNAL_SS_ON_HDMI:
1409 percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
1410 rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
1411 break;
1412 case ASIC_INTERNAL_SS_ON_LVDS:
1413 percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
1414 rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
1415 break;
1416 }
4339c442 1417 break;
3838f46e
AD
1418 case 7:
1419 switch (id) {
1420 case ASIC_INTERNAL_SS_ON_TMDS:
1421 percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
1422 rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
1423 break;
1424 case ASIC_INTERNAL_SS_ON_HDMI:
1425 percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
1426 rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
1427 break;
1428 case ASIC_INTERNAL_SS_ON_LVDS:
1429 percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
1430 rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
1431 break;
1432 }
4339c442 1433 break;
c2037ad1
AD
1434 case 8:
1435 switch (id) {
1436 case ASIC_INTERNAL_SS_ON_TMDS:
1437 percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);
1438 rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
1439 break;
1440 case ASIC_INTERNAL_SS_ON_HDMI:
1441 percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
1442 rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
1443 break;
1444 case ASIC_INTERNAL_SS_ON_LVDS:
1445 percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
1446 rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
1447 break;
1448 }
1449 break;
3838f46e
AD
1450 default:
1451 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
4339c442
AD
1452 break;
1453 }
1454 if (percentage)
1455 ss->percentage = percentage;
1456 if (rate)
1457 ss->rate = rate;
1458 }
1459}
1460
ba032a58
AD
1461union asic_ss_info {
1462 struct _ATOM_ASIC_INTERNAL_SS_INFO info;
1463 struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;
1464 struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3;
1465};
1466
a7ee824a
AD
1467union asic_ss_assignment {
1468 struct _ATOM_ASIC_SS_ASSIGNMENT v1;
1469 struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2;
1470 struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3;
1471};
1472
ba032a58
AD
1473bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
1474 struct radeon_atom_ss *ss,
1475 int id, u32 clock)
1476{
1477 struct radeon_mode_info *mode_info = &rdev->mode_info;
1478 int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
1479 uint16_t data_offset, size;
1480 union asic_ss_info *ss_info;
a7ee824a 1481 union asic_ss_assignment *ss_assign;
ba032a58
AD
1482 uint8_t frev, crev;
1483 int i, num_indices;
1484
9cb84ab0
AD
1485 if (id == ASIC_INTERNAL_MEMORY_SS) {
1486 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT))
1487 return false;
1488 }
1489 if (id == ASIC_INTERNAL_ENGINE_SS) {
1490 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT))
1491 return false;
1492 }
1493
ba032a58
AD
1494 memset(ss, 0, sizeof(struct radeon_atom_ss));
1495 if (atom_parse_data_header(mode_info->atom_context, index, &size,
1496 &frev, &crev, &data_offset)) {
1497
1498 ss_info =
1499 (union asic_ss_info *)(mode_info->atom_context->bios + data_offset);
1500
1501 switch (frev) {
1502 case 1:
1503 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1504 sizeof(ATOM_ASIC_SS_ASSIGNMENT);
1505
a7ee824a 1506 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]);
ba032a58 1507 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1508 if ((ss_assign->v1.ucClockIndication == id) &&
1509 (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) {
ba032a58 1510 ss->percentage =
a7ee824a
AD
1511 le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
1512 ss->type = ss_assign->v1.ucSpreadSpectrumMode;
1513 ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
18f8f52b 1514 ss->percentage_divider = 100;
ba032a58
AD
1515 return true;
1516 }
a7ee824a
AD
1517 ss_assign = (union asic_ss_assignment *)
1518 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT));
279b215e 1519 }
ba032a58
AD
1520 break;
1521 case 2:
1522 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1523 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
a7ee824a 1524 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]);
ba032a58 1525 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1526 if ((ss_assign->v2.ucClockIndication == id) &&
1527 (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) {
ba032a58 1528 ss->percentage =
a7ee824a
AD
1529 le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
1530 ss->type = ss_assign->v2.ucSpreadSpectrumMode;
1531 ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
18f8f52b 1532 ss->percentage_divider = 100;
ae5b0abb
AD
1533 if ((crev == 2) &&
1534 ((id == ASIC_INTERNAL_ENGINE_SS) ||
1535 (id == ASIC_INTERNAL_MEMORY_SS)))
1536 ss->rate /= 100;
ba032a58
AD
1537 return true;
1538 }
a7ee824a
AD
1539 ss_assign = (union asic_ss_assignment *)
1540 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2));
ba032a58
AD
1541 }
1542 break;
1543 case 3:
1544 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1545 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
a7ee824a 1546 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]);
ba032a58 1547 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1548 if ((ss_assign->v3.ucClockIndication == id) &&
1549 (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) {
ba032a58 1550 ss->percentage =
a7ee824a
AD
1551 le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
1552 ss->type = ss_assign->v3.ucSpreadSpectrumMode;
1553 ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
18f8f52b
AD
1554 if (ss_assign->v3.ucSpreadSpectrumMode &
1555 SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)
1556 ss->percentage_divider = 1000;
1557 else
1558 ss->percentage_divider = 100;
ae5b0abb
AD
1559 if ((id == ASIC_INTERNAL_ENGINE_SS) ||
1560 (id == ASIC_INTERNAL_MEMORY_SS))
1561 ss->rate /= 100;
4339c442
AD
1562 if (rdev->flags & RADEON_IS_IGP)
1563 radeon_atombios_get_igp_ss_overrides(rdev, ss, id);
ba032a58
AD
1564 return true;
1565 }
a7ee824a
AD
1566 ss_assign = (union asic_ss_assignment *)
1567 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3));
ba032a58
AD
1568 }
1569 break;
1570 default:
1571 DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev);
1572 break;
279b215e 1573 }
ba032a58 1574
ebbe1cb9 1575 }
ba032a58 1576 return false;
ebbe1cb9
AD
1577}
1578
771fe6b9
JG
1579union lvds_info {
1580 struct _ATOM_LVDS_INFO info;
1581 struct _ATOM_LVDS_INFO_V12 info_12;
1582};
1583
1584struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
1585 radeon_encoder
1586 *encoder)
1587{
1588 struct drm_device *dev = encoder->base.dev;
1589 struct radeon_device *rdev = dev->dev_private;
1590 struct radeon_mode_info *mode_info = &rdev->mode_info;
1591 int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
7dde8a19 1592 uint16_t data_offset, misc;
771fe6b9
JG
1593 union lvds_info *lvds_info;
1594 uint8_t frev, crev;
1595 struct radeon_encoder_atom_dig *lvds = NULL;
5137ee94 1596 int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
771fe6b9 1597
a084e6ee
AD
1598 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1599 &frev, &crev, &data_offset)) {
1600 lvds_info =
1601 (union lvds_info *)(mode_info->atom_context->bios + data_offset);
771fe6b9
JG
1602 lvds =
1603 kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
1604
1605 if (!lvds)
1606 return NULL;
1607
de2103e4 1608 lvds->native_mode.clock =
771fe6b9 1609 le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
de2103e4 1610 lvds->native_mode.hdisplay =
771fe6b9 1611 le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
de2103e4 1612 lvds->native_mode.vdisplay =
771fe6b9 1613 le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
de2103e4
AD
1614 lvds->native_mode.htotal = lvds->native_mode.hdisplay +
1615 le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
1616 lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
1617 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
1618 lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
1619 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
1620 lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
1621 le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
1622 lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
1ff26a36 1623 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
de2103e4
AD
1624 lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
1625 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
771fe6b9
JG
1626 lvds->panel_pwr_delay =
1627 le16_to_cpu(lvds_info->info.usOffDelayInMs);
ba032a58 1628 lvds->lcd_misc = lvds_info->info.ucLVDS_Misc;
7dde8a19
AD
1629
1630 misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
1631 if (misc & ATOM_VSYNC_POLARITY)
1632 lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
1633 if (misc & ATOM_HSYNC_POLARITY)
1634 lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
1635 if (misc & ATOM_COMPOSITESYNC)
1636 lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
1637 if (misc & ATOM_INTERLACE)
1638 lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
1639 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1640 lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
1641
4589433c
CC
1642 lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize);
1643 lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize);
7a868e18 1644
de2103e4
AD
1645 /* set crtc values */
1646 drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
771fe6b9 1647
ba032a58 1648 lvds->lcd_ss_id = lvds_info->info.ucSS_Id;
ebbe1cb9 1649
771fe6b9 1650 encoder->native_mode = lvds->native_mode;
5137ee94
AD
1651
1652 if (encoder_enum == 2)
1653 lvds->linkb = true;
1654 else
1655 lvds->linkb = false;
1656
c324acd5 1657 /* parse the lcd record table */
4589433c 1658 if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) {
c324acd5
AD
1659 ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;
1660 ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;
1661 bool bad_record = false;
05fa7ea7
AD
1662 u8 *record;
1663
1664 if ((frev == 1) && (crev < 2))
1665 /* absolute */
1666 record = (u8 *)(mode_info->atom_context->bios +
1667 le16_to_cpu(lvds_info->info.usModePatchTableOffset));
1668 else
1669 /* relative */
1670 record = (u8 *)(mode_info->atom_context->bios +
1671 data_offset +
1672 le16_to_cpu(lvds_info->info.usModePatchTableOffset));
c324acd5
AD
1673 while (*record != ATOM_RECORD_END_TYPE) {
1674 switch (*record) {
1675 case LCD_MODE_PATCH_RECORD_MODE_TYPE:
1676 record += sizeof(ATOM_PATCH_RECORD_MODE);
1677 break;
1678 case LCD_RTS_RECORD_TYPE:
1679 record += sizeof(ATOM_LCD_RTS_RECORD);
1680 break;
1681 case LCD_CAP_RECORD_TYPE:
1682 record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);
1683 break;
1684 case LCD_FAKE_EDID_PATCH_RECORD_TYPE:
1685 fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
1686 if (fake_edid_record->ucFakeEDIDLength) {
1687 struct edid *edid;
1688 int edid_size =
1689 max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
1690 edid = kmalloc(edid_size, GFP_KERNEL);
1691 if (edid) {
1692 memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
1693 fake_edid_record->ucFakeEDIDLength);
1694
eaa4f5e1 1695 if (drm_edid_is_valid(edid)) {
c324acd5 1696 rdev->mode_info.bios_hardcoded_edid = edid;
eaa4f5e1
DA
1697 rdev->mode_info.bios_hardcoded_edid_size = edid_size;
1698 } else
c324acd5
AD
1699 kfree(edid);
1700 }
1701 }
95663948
AD
1702 record += fake_edid_record->ucFakeEDIDLength ?
1703 fake_edid_record->ucFakeEDIDLength + 2 :
1704 sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
c324acd5
AD
1705 break;
1706 case LCD_PANEL_RESOLUTION_RECORD_TYPE:
1707 panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
1708 lvds->native_mode.width_mm = panel_res_record->usHSize;
1709 lvds->native_mode.height_mm = panel_res_record->usVSize;
1710 record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
1711 break;
1712 default:
1713 DRM_ERROR("Bad LCD record %d\n", *record);
1714 bad_record = true;
1715 break;
1716 }
1717 if (bad_record)
1718 break;
1719 }
1720 }
771fe6b9
JG
1721 }
1722 return lvds;
1723}
1724
6fe7ac3f
AD
1725struct radeon_encoder_primary_dac *
1726radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
1727{
1728 struct drm_device *dev = encoder->base.dev;
1729 struct radeon_device *rdev = dev->dev_private;
1730 struct radeon_mode_info *mode_info = &rdev->mode_info;
1731 int index = GetIndexIntoMasterTable(DATA, CompassionateData);
1732 uint16_t data_offset;
1733 struct _COMPASSIONATE_DATA *dac_info;
1734 uint8_t frev, crev;
1735 uint8_t bg, dac;
6fe7ac3f
AD
1736 struct radeon_encoder_primary_dac *p_dac = NULL;
1737
a084e6ee
AD
1738 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1739 &frev, &crev, &data_offset)) {
1740 dac_info = (struct _COMPASSIONATE_DATA *)
1741 (mode_info->atom_context->bios + data_offset);
6fe7ac3f 1742
6fe7ac3f
AD
1743 p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
1744
1745 if (!p_dac)
1746 return NULL;
1747
1748 bg = dac_info->ucDAC1_BG_Adjustment;
1749 dac = dac_info->ucDAC1_DAC_Adjustment;
1750 p_dac->ps2_pdac_adj = (bg << 8) | (dac);
1751
1752 }
1753 return p_dac;
1754}
1755
4ce001ab 1756bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
5a9bcacc 1757 struct drm_display_mode *mode)
4ce001ab
DA
1758{
1759 struct radeon_mode_info *mode_info = &rdev->mode_info;
1760 ATOM_ANALOG_TV_INFO *tv_info;
1761 ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;
1762 ATOM_DTD_FORMAT *dtd_timings;
1763 int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
1764 u8 frev, crev;
5a9bcacc 1765 u16 data_offset, misc;
4ce001ab 1766
a084e6ee
AD
1767 if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
1768 &frev, &crev, &data_offset))
1769 return false;
4ce001ab
DA
1770
1771 switch (crev) {
1772 case 1:
1773 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
0031c41b 1774 if (index >= MAX_SUPPORTED_TV_TIMING)
4ce001ab
DA
1775 return false;
1776
5a9bcacc
AD
1777 mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
1778 mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
1779 mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
1780 mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
1781 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
1782
1783 mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
1784 mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
1785 mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
1786 mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
1787 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
1788
1789 mode->flags = 0;
1790 misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
1791 if (misc & ATOM_VSYNC_POLARITY)
1792 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1793 if (misc & ATOM_HSYNC_POLARITY)
1794 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1795 if (misc & ATOM_COMPOSITESYNC)
1796 mode->flags |= DRM_MODE_FLAG_CSYNC;
1797 if (misc & ATOM_INTERLACE)
1798 mode->flags |= DRM_MODE_FLAG_INTERLACE;
1799 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1800 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1801
265d09aa
VS
1802 mode->crtc_clock = mode->clock =
1803 le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
4ce001ab
DA
1804
1805 if (index == 1) {
1806 /* PAL timings appear to have wrong values for totals */
5a9bcacc
AD
1807 mode->crtc_htotal -= 1;
1808 mode->crtc_vtotal -= 1;
4ce001ab
DA
1809 }
1810 break;
1811 case 2:
1812 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
0031c41b 1813 if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
4ce001ab
DA
1814 return false;
1815
1816 dtd_timings = &tv_info_v1_2->aModeTimings[index];
5a9bcacc
AD
1817 mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) +
1818 le16_to_cpu(dtd_timings->usHBlanking_Time);
1819 mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive);
1820 mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) +
1821 le16_to_cpu(dtd_timings->usHSyncOffset);
1822 mode->crtc_hsync_end = mode->crtc_hsync_start +
1823 le16_to_cpu(dtd_timings->usHSyncWidth);
1824
1825 mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) +
1826 le16_to_cpu(dtd_timings->usVBlanking_Time);
1827 mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive);
1828 mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) +
1829 le16_to_cpu(dtd_timings->usVSyncOffset);
1830 mode->crtc_vsync_end = mode->crtc_vsync_start +
1831 le16_to_cpu(dtd_timings->usVSyncWidth);
1832
1833 mode->flags = 0;
1834 misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
1835 if (misc & ATOM_VSYNC_POLARITY)
1836 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1837 if (misc & ATOM_HSYNC_POLARITY)
1838 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1839 if (misc & ATOM_COMPOSITESYNC)
1840 mode->flags |= DRM_MODE_FLAG_CSYNC;
1841 if (misc & ATOM_INTERLACE)
1842 mode->flags |= DRM_MODE_FLAG_INTERLACE;
1843 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1844 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1845
265d09aa
VS
1846 mode->crtc_clock = mode->clock =
1847 le16_to_cpu(dtd_timings->usPixClk) * 10;
4ce001ab
DA
1848 break;
1849 }
1850 return true;
1851}
1852
d79766fa
AD
1853enum radeon_tv_std
1854radeon_atombios_get_tv_info(struct radeon_device *rdev)
1855{
1856 struct radeon_mode_info *mode_info = &rdev->mode_info;
1857 int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
1858 uint16_t data_offset;
1859 uint8_t frev, crev;
1860 struct _ATOM_ANALOG_TV_INFO *tv_info;
1861 enum radeon_tv_std tv_std = TV_STD_NTSC;
1862
a084e6ee
AD
1863 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1864 &frev, &crev, &data_offset)) {
d79766fa 1865
a084e6ee
AD
1866 tv_info = (struct _ATOM_ANALOG_TV_INFO *)
1867 (mode_info->atom_context->bios + data_offset);
d79766fa 1868
a084e6ee
AD
1869 switch (tv_info->ucTV_BootUpDefaultStandard) {
1870 case ATOM_TV_NTSC:
1871 tv_std = TV_STD_NTSC;
40f76d81 1872 DRM_DEBUG_KMS("Default TV standard: NTSC\n");
a084e6ee
AD
1873 break;
1874 case ATOM_TV_NTSCJ:
1875 tv_std = TV_STD_NTSC_J;
40f76d81 1876 DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
a084e6ee
AD
1877 break;
1878 case ATOM_TV_PAL:
1879 tv_std = TV_STD_PAL;
40f76d81 1880 DRM_DEBUG_KMS("Default TV standard: PAL\n");
a084e6ee
AD
1881 break;
1882 case ATOM_TV_PALM:
1883 tv_std = TV_STD_PAL_M;
40f76d81 1884 DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
a084e6ee
AD
1885 break;
1886 case ATOM_TV_PALN:
1887 tv_std = TV_STD_PAL_N;
40f76d81 1888 DRM_DEBUG_KMS("Default TV standard: PAL-N\n");
a084e6ee
AD
1889 break;
1890 case ATOM_TV_PALCN:
1891 tv_std = TV_STD_PAL_CN;
40f76d81 1892 DRM_DEBUG_KMS("Default TV standard: PAL-CN\n");
a084e6ee
AD
1893 break;
1894 case ATOM_TV_PAL60:
1895 tv_std = TV_STD_PAL_60;
40f76d81 1896 DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
a084e6ee
AD
1897 break;
1898 case ATOM_TV_SECAM:
1899 tv_std = TV_STD_SECAM;
40f76d81 1900 DRM_DEBUG_KMS("Default TV standard: SECAM\n");
a084e6ee
AD
1901 break;
1902 default:
1903 tv_std = TV_STD_NTSC;
40f76d81 1904 DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n");
a084e6ee
AD
1905 break;
1906 }
d79766fa
AD
1907 }
1908 return tv_std;
1909}
1910
6fe7ac3f
AD
1911struct radeon_encoder_tv_dac *
1912radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
1913{
1914 struct drm_device *dev = encoder->base.dev;
1915 struct radeon_device *rdev = dev->dev_private;
1916 struct radeon_mode_info *mode_info = &rdev->mode_info;
1917 int index = GetIndexIntoMasterTable(DATA, CompassionateData);
1918 uint16_t data_offset;
1919 struct _COMPASSIONATE_DATA *dac_info;
1920 uint8_t frev, crev;
1921 uint8_t bg, dac;
6fe7ac3f
AD
1922 struct radeon_encoder_tv_dac *tv_dac = NULL;
1923
a084e6ee
AD
1924 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1925 &frev, &crev, &data_offset)) {
6fe7ac3f 1926
a084e6ee
AD
1927 dac_info = (struct _COMPASSIONATE_DATA *)
1928 (mode_info->atom_context->bios + data_offset);
6fe7ac3f 1929
6fe7ac3f
AD
1930 tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
1931
1932 if (!tv_dac)
1933 return NULL;
1934
1935 bg = dac_info->ucDAC2_CRT2_BG_Adjustment;
1936 dac = dac_info->ucDAC2_CRT2_DAC_Adjustment;
1937 tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1938
1939 bg = dac_info->ucDAC2_PAL_BG_Adjustment;
1940 dac = dac_info->ucDAC2_PAL_DAC_Adjustment;
1941 tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1942
1943 bg = dac_info->ucDAC2_NTSC_BG_Adjustment;
1944 dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;
1945 tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
1946
d79766fa 1947 tv_dac->tv_std = radeon_atombios_get_tv_info(rdev);
6fe7ac3f
AD
1948 }
1949 return tv_dac;
1950}
1951
29fb52ca
AD
1952static const char *thermal_controller_names[] = {
1953 "NONE",
678e7dfa
AD
1954 "lm63",
1955 "adm1032",
1956 "adm1030",
1957 "max6649",
1958 "lm64",
1959 "f75375",
1960 "asc7xxx",
29fb52ca
AD
1961};
1962
1963static const char *pp_lib_thermal_controller_names[] = {
1964 "NONE",
678e7dfa
AD
1965 "lm63",
1966 "adm1032",
1967 "adm1030",
1968 "max6649",
1969 "lm64",
1970 "f75375",
29fb52ca
AD
1971 "RV6xx",
1972 "RV770",
678e7dfa 1973 "adt7473",
560154e9 1974 "NONE",
49f65982
AD
1975 "External GPIO",
1976 "Evergreen",
b0e66414
AD
1977 "emc2103",
1978 "Sumo",
4fddba1f 1979 "Northern Islands",
14607d08
AD
1980 "Southern Islands",
1981 "lm96163",
51150207 1982 "Sea Islands",
29fb52ca
AD
1983};
1984
56278a8e
AD
1985union power_info {
1986 struct _ATOM_POWERPLAY_INFO info;
1987 struct _ATOM_POWERPLAY_INFO_V2 info_2;
1988 struct _ATOM_POWERPLAY_INFO_V3 info_3;
560154e9 1989 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
b0e66414
AD
1990 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
1991 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
56278a8e
AD
1992};
1993
560154e9
AD
1994union pplib_clock_info {
1995 struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
1996 struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
1997 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
b0e66414 1998 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
14607d08 1999 struct _ATOM_PPLIB_SI_CLOCK_INFO si;
bc19f597 2000 struct _ATOM_PPLIB_CI_CLOCK_INFO ci;
560154e9
AD
2001};
2002
2003union pplib_power_state {
2004 struct _ATOM_PPLIB_STATE v1;
2005 struct _ATOM_PPLIB_STATE_V2 v2;
2006};
2007
2008static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev,
2009 int state_index,
2010 u32 misc, u32 misc2)
2011{
2012 rdev->pm.power_state[state_index].misc = misc;
2013 rdev->pm.power_state[state_index].misc2 = misc2;
2014 /* order matters! */
2015 if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
2016 rdev->pm.power_state[state_index].type =
2017 POWER_STATE_TYPE_POWERSAVE;
2018 if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
2019 rdev->pm.power_state[state_index].type =
2020 POWER_STATE_TYPE_BATTERY;
2021 if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
2022 rdev->pm.power_state[state_index].type =
2023 POWER_STATE_TYPE_BATTERY;
2024 if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
2025 rdev->pm.power_state[state_index].type =
2026 POWER_STATE_TYPE_BALANCED;
2027 if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
2028 rdev->pm.power_state[state_index].type =
2029 POWER_STATE_TYPE_PERFORMANCE;
2030 rdev->pm.power_state[state_index].flags &=
2031 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2032 }
2033 if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
2034 rdev->pm.power_state[state_index].type =
2035 POWER_STATE_TYPE_BALANCED;
2036 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
2037 rdev->pm.power_state[state_index].type =
2038 POWER_STATE_TYPE_DEFAULT;
2039 rdev->pm.default_power_state_index = state_index;
2040 rdev->pm.power_state[state_index].default_clock_mode =
2041 &rdev->pm.power_state[state_index].clock_info[0];
2042 } else if (state_index == 0) {
2043 rdev->pm.power_state[state_index].clock_info[0].flags |=
2044 RADEON_PM_MODE_NO_DISPLAY;
2045 }
2046}
2047
2048static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
771fe6b9 2049{
56278a8e 2050 struct radeon_mode_info *mode_info = &rdev->mode_info;
560154e9
AD
2051 u32 misc, misc2 = 0;
2052 int num_modes = 0, i;
2053 int state_index = 0;
2054 struct radeon_i2c_bus_rec i2c_bus;
2055 union power_info *power_info;
56278a8e 2056 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
560154e9 2057 u16 data_offset;
56278a8e 2058 u8 frev, crev;
771fe6b9 2059
560154e9
AD
2060 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2061 &frev, &crev, &data_offset))
2062 return state_index;
2063 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2064
2065 /* add the i2c bus for thermal/fan chip */
4755fab5
AD
2066 if ((power_info->info.ucOverdriveThermalController > 0) &&
2067 (power_info->info.ucOverdriveThermalController < ARRAY_SIZE(thermal_controller_names))) {
560154e9
AD
2068 DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2069 thermal_controller_names[power_info->info.ucOverdriveThermalController],
2070 power_info->info.ucOverdriveControllerAddress >> 1);
2071 i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
2072 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2073 if (rdev->pm.i2c_bus) {
2074 struct i2c_board_info info = { };
2075 const char *name = thermal_controller_names[power_info->info.
2076 ucOverdriveThermalController];
2077 info.addr = power_info->info.ucOverdriveControllerAddress >> 1;
2078 strlcpy(info.type, name, sizeof(info.type));
2079 i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
2080 }
2081 }
2082 num_modes = power_info->info.ucNumOfPowerModeEntries;
2083 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
2084 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
f8e6bfc2
AD
2085 if (num_modes == 0)
2086 return state_index;
0975b162
AD
2087 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
2088 if (!rdev->pm.power_state)
2089 return state_index;
560154e9
AD
2090 /* last mode is usually default, array is low to high */
2091 for (i = 0; i < num_modes; i++) {
6991b8f2
AD
2092 rdev->pm.power_state[state_index].clock_info =
2093 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2094 if (!rdev->pm.power_state[state_index].clock_info)
2095 return state_index;
2096 rdev->pm.power_state[state_index].num_clock_modes = 1;
560154e9
AD
2097 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2098 switch (frev) {
2099 case 1:
560154e9
AD
2100 rdev->pm.power_state[state_index].clock_info[0].mclk =
2101 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
2102 rdev->pm.power_state[state_index].clock_info[0].sclk =
2103 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock);
2104 /* skip invalid modes */
2105 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2106 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2107 continue;
2108 rdev->pm.power_state[state_index].pcie_lanes =
2109 power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
2110 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
2111 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2112 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2113 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2114 VOLTAGE_GPIO;
2115 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
2116 radeon_lookup_gpio(rdev,
2117 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);
2118 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2119 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2120 true;
2121 else
2122 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2123 false;
2124 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2125 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2126 VOLTAGE_VDDC;
2127 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2128 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
29fb52ca 2129 }
560154e9
AD
2130 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2131 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0);
2132 state_index++;
2133 break;
2134 case 2:
560154e9
AD
2135 rdev->pm.power_state[state_index].clock_info[0].mclk =
2136 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
2137 rdev->pm.power_state[state_index].clock_info[0].sclk =
2138 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock);
2139 /* skip invalid modes */
2140 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2141 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2142 continue;
2143 rdev->pm.power_state[state_index].pcie_lanes =
2144 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
2145 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
2146 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
2147 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2148 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2149 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2150 VOLTAGE_GPIO;
2151 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
2152 radeon_lookup_gpio(rdev,
2153 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);
2154 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2155 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2156 true;
2157 else
2158 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2159 false;
2160 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2161 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2162 VOLTAGE_VDDC;
2163 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2164 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
56278a8e 2165 }
560154e9
AD
2166 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2167 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
2168 state_index++;
2169 break;
2170 case 3:
560154e9
AD
2171 rdev->pm.power_state[state_index].clock_info[0].mclk =
2172 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
2173 rdev->pm.power_state[state_index].clock_info[0].sclk =
2174 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock);
2175 /* skip invalid modes */
2176 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2177 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2178 continue;
2179 rdev->pm.power_state[state_index].pcie_lanes =
2180 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
2181 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
2182 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
2183 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2184 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2185 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2186 VOLTAGE_GPIO;
2187 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
2188 radeon_lookup_gpio(rdev,
2189 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);
2190 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2191 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2192 true;
2193 else
2194 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2195 false;
2196 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2197 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2198 VOLTAGE_VDDC;
2199 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2200 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex;
2201 if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) {
2202 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled =
2203 true;
2204 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id =
2205 power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;
2206 }
02b17cc0 2207 }
560154e9
AD
2208 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2209 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
2210 state_index++;
2211 break;
2212 }
2213 }
2214 /* last mode is usually default */
2215 if (rdev->pm.default_power_state_index == -1) {
2216 rdev->pm.power_state[state_index - 1].type =
2217 POWER_STATE_TYPE_DEFAULT;
2218 rdev->pm.default_power_state_index = state_index - 1;
2219 rdev->pm.power_state[state_index - 1].default_clock_mode =
2220 &rdev->pm.power_state[state_index - 1].clock_info[0];
2221 rdev->pm.power_state[state_index].flags &=
2222 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2223 rdev->pm.power_state[state_index].misc = 0;
2224 rdev->pm.power_state[state_index].misc2 = 0;
2225 }
2226 return state_index;
2227}
2228
2229static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev,
2230 ATOM_PPLIB_THERMALCONTROLLER *controller)
2231{
2232 struct radeon_i2c_bus_rec i2c_bus;
2233
2234 /* add the i2c bus for thermal/fan chip */
2235 if (controller->ucType > 0) {
2236 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
2237 DRM_INFO("Internal thermal controller %s fan control\n",
2238 (controller->ucFanParameters &
2239 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2240 rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
2241 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
2242 DRM_INFO("Internal thermal controller %s fan control\n",
2243 (controller->ucFanParameters &
2244 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2245 rdev->pm.int_thermal_type = THERMAL_TYPE_RV770;
2246 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
2247 DRM_INFO("Internal thermal controller %s fan control\n",
2248 (controller->ucFanParameters &
2249 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2250 rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
b0e66414
AD
2251 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
2252 DRM_INFO("Internal thermal controller %s fan control\n",
2253 (controller->ucFanParameters &
2254 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2255 rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
4fddba1f
AD
2256 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
2257 DRM_INFO("Internal thermal controller %s fan control\n",
2258 (controller->ucFanParameters &
2259 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2260 rdev->pm.int_thermal_type = THERMAL_TYPE_NI;
14607d08
AD
2261 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
2262 DRM_INFO("Internal thermal controller %s fan control\n",
2263 (controller->ucFanParameters &
2264 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2265 rdev->pm.int_thermal_type = THERMAL_TYPE_SI;
51150207
AD
2266 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
2267 DRM_INFO("Internal thermal controller %s fan control\n",
2268 (controller->ucFanParameters &
2269 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2270 rdev->pm.int_thermal_type = THERMAL_TYPE_CI;
16fbe00d
AD
2271 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
2272 DRM_INFO("Internal thermal controller %s fan control\n",
2273 (controller->ucFanParameters &
2274 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2275 rdev->pm.int_thermal_type = THERMAL_TYPE_KV;
560154e9
AD
2276 } else if ((controller->ucType ==
2277 ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
2278 (controller->ucType ==
b0e66414
AD
2279 ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) ||
2280 (controller->ucType ==
2281 ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) {
560154e9 2282 DRM_INFO("Special thermal controller config\n");
4755fab5 2283 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
560154e9
AD
2284 DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
2285 pp_lib_thermal_controller_names[controller->ucType],
2286 controller->ucI2cAddress >> 1,
2287 (controller->ucFanParameters &
2288 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2289 i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine);
2290 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2291 if (rdev->pm.i2c_bus) {
2292 struct i2c_board_info info = { };
2293 const char *name = pp_lib_thermal_controller_names[controller->ucType];
2294 info.addr = controller->ucI2cAddress >> 1;
2295 strlcpy(info.type, name, sizeof(info.type));
2296 i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
c5e8ce61 2297 }
4755fab5
AD
2298 } else {
2299 DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
2300 controller->ucType,
2301 controller->ucI2cAddress >> 1,
2302 (controller->ucFanParameters &
2303 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
560154e9
AD
2304 }
2305 }
2306}
c5e8ce61 2307
4a6369e9 2308void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
2abba66e 2309 u16 *vddc, u16 *vddci, u16 *mvdd)
560154e9
AD
2310{
2311 struct radeon_mode_info *mode_info = &rdev->mode_info;
2312 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
2313 u8 frev, crev;
2314 u16 data_offset;
2315 union firmware_info *firmware_info;
2feea49a
AD
2316
2317 *vddc = 0;
2318 *vddci = 0;
2abba66e 2319 *mvdd = 0;
678e7dfa 2320
560154e9
AD
2321 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2322 &frev, &crev, &data_offset)) {
2323 firmware_info =
2324 (union firmware_info *)(mode_info->atom_context->bios +
2325 data_offset);
2feea49a 2326 *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
2abba66e 2327 if ((frev == 2) && (crev >= 2)) {
2feea49a 2328 *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
2abba66e
AD
2329 *mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
2330 }
560154e9 2331 }
560154e9
AD
2332}
2333
2334static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
2335 int state_index, int mode_index,
2336 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info)
2337{
2338 int j;
2339 u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
2340 u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
2abba66e 2341 u16 vddc, vddci, mvdd;
2feea49a 2342
2abba66e 2343 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
560154e9
AD
2344
2345 rdev->pm.power_state[state_index].misc = misc;
2346 rdev->pm.power_state[state_index].misc2 = misc2;
2347 rdev->pm.power_state[state_index].pcie_lanes =
2348 ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>
2349 ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
2350 switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
2351 case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
2352 rdev->pm.power_state[state_index].type =
2353 POWER_STATE_TYPE_BATTERY;
2354 break;
2355 case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
2356 rdev->pm.power_state[state_index].type =
2357 POWER_STATE_TYPE_BALANCED;
2358 break;
2359 case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
2360 rdev->pm.power_state[state_index].type =
2361 POWER_STATE_TYPE_PERFORMANCE;
2362 break;
2363 case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
2364 if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
2365 rdev->pm.power_state[state_index].type =
2366 POWER_STATE_TYPE_PERFORMANCE;
2367 break;
2368 }
2369 rdev->pm.power_state[state_index].flags = 0;
2370 if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
2371 rdev->pm.power_state[state_index].flags |=
2372 RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2373 if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {
2374 rdev->pm.power_state[state_index].type =
2375 POWER_STATE_TYPE_DEFAULT;
2376 rdev->pm.default_power_state_index = state_index;
2377 rdev->pm.power_state[state_index].default_clock_mode =
2378 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
982cb329 2379 if ((rdev->family >= CHIP_BARTS) && !(rdev->flags & RADEON_IS_IGP)) {
9ace9f7b
AD
2380 /* NI chips post without MC ucode, so default clocks are strobe mode only */
2381 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2382 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
2383 rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
2feea49a 2384 rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
9ace9f7b 2385 } else {
ae5b0abb
AD
2386 u16 max_vddci = 0;
2387
2388 if (ASIC_IS_DCE4(rdev))
2389 radeon_atom_get_max_voltage(rdev,
2390 SET_VOLTAGE_TYPE_ASIC_VDDCI,
2391 &max_vddci);
2392 /* patch the table values with the default sclk/mclk from firmware info */
9ace9f7b
AD
2393 for (j = 0; j < mode_index; j++) {
2394 rdev->pm.power_state[state_index].clock_info[j].mclk =
2395 rdev->clock.default_mclk;
2396 rdev->pm.power_state[state_index].clock_info[j].sclk =
2397 rdev->clock.default_sclk;
2398 if (vddc)
2399 rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
2400 vddc;
ae5b0abb
AD
2401 if (max_vddci)
2402 rdev->pm.power_state[state_index].clock_info[j].voltage.vddci =
2403 max_vddci;
9ace9f7b 2404 }
560154e9
AD
2405 }
2406 }
2407}
2408
2409static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
2410 int state_index, int mode_index,
2411 union pplib_clock_info *clock_info)
2412{
2413 u32 sclk, mclk;
e83753bb 2414 u16 vddc;
560154e9
AD
2415
2416 if (rdev->flags & RADEON_IS_IGP) {
b0e66414
AD
2417 if (rdev->family >= CHIP_PALM) {
2418 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
2419 sclk |= clock_info->sumo.ucEngineClockHigh << 16;
2420 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2421 } else {
2422 sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
2423 sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
2424 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2425 }
bc19f597
AD
2426 } else if (rdev->family >= CHIP_BONAIRE) {
2427 sclk = le16_to_cpu(clock_info->ci.usEngineClockLow);
2428 sclk |= clock_info->ci.ucEngineClockHigh << 16;
2429 mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow);
2430 mclk |= clock_info->ci.ucMemoryClockHigh << 16;
2431 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2432 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2433 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2434 VOLTAGE_NONE;
982cb329 2435 } else if (rdev->family >= CHIP_TAHITI) {
14607d08
AD
2436 sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
2437 sclk |= clock_info->si.ucEngineClockHigh << 16;
2438 mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
2439 mclk |= clock_info->si.ucMemoryClockHigh << 16;
2440 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2441 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2442 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2443 VOLTAGE_SW;
2444 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
2445 le16_to_cpu(clock_info->si.usVDDC);
2446 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2447 le16_to_cpu(clock_info->si.usVDDCI);
982cb329 2448 } else if (rdev->family >= CHIP_CEDAR) {
560154e9
AD
2449 sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
2450 sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
2451 mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
2452 mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
2453 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2454 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2455 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2456 VOLTAGE_SW;
2457 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
4589433c 2458 le16_to_cpu(clock_info->evergreen.usVDDC);
2feea49a
AD
2459 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2460 le16_to_cpu(clock_info->evergreen.usVDDCI);
560154e9
AD
2461 } else {
2462 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
2463 sclk |= clock_info->r600.ucEngineClockHigh << 16;
2464 mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
2465 mclk |= clock_info->r600.ucMemoryClockHigh << 16;
2466 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2467 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2468 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2469 VOLTAGE_SW;
2470 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
4589433c 2471 le16_to_cpu(clock_info->r600.usVDDC);
560154e9
AD
2472 }
2473
ee4017f4 2474 /* patch up vddc if necessary */
e83753bb
AD
2475 switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) {
2476 case ATOM_VIRTUAL_VOLTAGE_ID0:
2477 case ATOM_VIRTUAL_VOLTAGE_ID1:
2478 case ATOM_VIRTUAL_VOLTAGE_ID2:
2479 case ATOM_VIRTUAL_VOLTAGE_ID3:
c6cf7777
AD
2480 case ATOM_VIRTUAL_VOLTAGE_ID4:
2481 case ATOM_VIRTUAL_VOLTAGE_ID5:
2482 case ATOM_VIRTUAL_VOLTAGE_ID6:
2483 case ATOM_VIRTUAL_VOLTAGE_ID7:
e83753bb
AD
2484 if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC,
2485 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage,
2486 &vddc) == 0)
ee4017f4 2487 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc;
e83753bb
AD
2488 break;
2489 default:
2490 break;
ee4017f4
AD
2491 }
2492
560154e9
AD
2493 if (rdev->flags & RADEON_IS_IGP) {
2494 /* skip invalid modes */
2495 if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
2496 return false;
2497 } else {
2498 /* skip invalid modes */
2499 if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
2500 (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
2501 return false;
2502 }
2503 return true;
2504}
2505
2506static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
2507{
2508 struct radeon_mode_info *mode_info = &rdev->mode_info;
2509 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2510 union pplib_power_state *power_state;
2511 int i, j;
2512 int state_index = 0, mode_index = 0;
2513 union pplib_clock_info *clock_info;
2514 bool valid;
2515 union power_info *power_info;
2516 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2517 u16 data_offset;
2518 u8 frev, crev;
2519
2520 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2521 &frev, &crev, &data_offset))
2522 return state_index;
2523 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2524
2525 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
f8e6bfc2
AD
2526 if (power_info->pplib.ucNumStates == 0)
2527 return state_index;
0975b162
AD
2528 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2529 power_info->pplib.ucNumStates, GFP_KERNEL);
2530 if (!rdev->pm.power_state)
2531 return state_index;
560154e9
AD
2532 /* first mode is usually default, followed by low to high */
2533 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
2534 mode_index = 0;
2535 power_state = (union pplib_power_state *)
2536 (mode_info->atom_context->bios + data_offset +
2537 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
2538 i * power_info->pplib.ucStateEntrySize);
2539 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2540 (mode_info->atom_context->bios + data_offset +
2541 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
2542 (power_state->v1.ucNonClockStateIndex *
2543 power_info->pplib.ucNonClockSize));
8f3f1c9a
AD
2544 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2545 ((power_info->pplib.ucStateEntrySize - 1) ?
2546 (power_info->pplib.ucStateEntrySize - 1) : 1),
2547 GFP_KERNEL);
2548 if (!rdev->pm.power_state[i].clock_info)
2549 return state_index;
2550 if (power_info->pplib.ucStateEntrySize - 1) {
2551 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
2552 clock_info = (union pplib_clock_info *)
2553 (mode_info->atom_context->bios + data_offset +
2554 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
2555 (power_state->v1.ucClockStateIndices[j] *
2556 power_info->pplib.ucClockInfoSize));
2557 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2558 state_index, mode_index,
2559 clock_info);
2560 if (valid)
2561 mode_index++;
2562 }
2563 } else {
2564 rdev->pm.power_state[state_index].clock_info[0].mclk =
2565 rdev->clock.default_mclk;
2566 rdev->pm.power_state[state_index].clock_info[0].sclk =
2567 rdev->clock.default_sclk;
2568 mode_index++;
560154e9
AD
2569 }
2570 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2571 if (mode_index) {
2572 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2573 non_clock_info);
2574 state_index++;
2575 }
2576 }
2577 /* if multiple clock modes, mark the lowest as no display */
2578 for (i = 0; i < state_index; i++) {
2579 if (rdev->pm.power_state[i].num_clock_modes > 1)
2580 rdev->pm.power_state[i].clock_info[0].flags |=
2581 RADEON_PM_MODE_NO_DISPLAY;
2582 }
2583 /* first mode is usually default */
2584 if (rdev->pm.default_power_state_index == -1) {
2585 rdev->pm.power_state[0].type =
2586 POWER_STATE_TYPE_DEFAULT;
2587 rdev->pm.default_power_state_index = 0;
2588 rdev->pm.power_state[0].default_clock_mode =
2589 &rdev->pm.power_state[0].clock_info[0];
2590 }
2591 return state_index;
2592}
2593
b0e66414
AD
2594static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2595{
2596 struct radeon_mode_info *mode_info = &rdev->mode_info;
2597 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2598 union pplib_power_state *power_state;
2599 int i, j, non_clock_array_index, clock_array_index;
2600 int state_index = 0, mode_index = 0;
2601 union pplib_clock_info *clock_info;
f7346881
AD
2602 struct _StateArray *state_array;
2603 struct _ClockInfoArray *clock_info_array;
2604 struct _NonClockInfoArray *non_clock_info_array;
b0e66414
AD
2605 bool valid;
2606 union power_info *power_info;
2607 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2608 u16 data_offset;
2609 u8 frev, crev;
441e76ca 2610 u8 *power_state_offset;
b0e66414
AD
2611
2612 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2613 &frev, &crev, &data_offset))
2614 return state_index;
2615 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2616
2617 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
f7346881 2618 state_array = (struct _StateArray *)
b0e66414 2619 (mode_info->atom_context->bios + data_offset +
4589433c 2620 le16_to_cpu(power_info->pplib.usStateArrayOffset));
f7346881 2621 clock_info_array = (struct _ClockInfoArray *)
b0e66414 2622 (mode_info->atom_context->bios + data_offset +
4589433c 2623 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
f7346881 2624 non_clock_info_array = (struct _NonClockInfoArray *)
b0e66414 2625 (mode_info->atom_context->bios + data_offset +
4589433c 2626 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
f8e6bfc2
AD
2627 if (state_array->ucNumEntries == 0)
2628 return state_index;
0975b162
AD
2629 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2630 state_array->ucNumEntries, GFP_KERNEL);
2631 if (!rdev->pm.power_state)
2632 return state_index;
441e76ca 2633 power_state_offset = (u8 *)state_array->states;
b0e66414
AD
2634 for (i = 0; i < state_array->ucNumEntries; i++) {
2635 mode_index = 0;
441e76ca
AD
2636 power_state = (union pplib_power_state *)power_state_offset;
2637 non_clock_array_index = power_state->v2.nonClockInfoIndex;
b0e66414
AD
2638 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2639 &non_clock_info_array->nonClockInfo[non_clock_array_index];
8f3f1c9a
AD
2640 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2641 (power_state->v2.ucNumDPMLevels ?
2642 power_state->v2.ucNumDPMLevels : 1),
2643 GFP_KERNEL);
2644 if (!rdev->pm.power_state[i].clock_info)
2645 return state_index;
2646 if (power_state->v2.ucNumDPMLevels) {
2647 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2648 clock_array_index = power_state->v2.clockInfoIndex[j];
8f3f1c9a 2649 clock_info = (union pplib_clock_info *)
f7346881 2650 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
8f3f1c9a
AD
2651 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2652 state_index, mode_index,
2653 clock_info);
2654 if (valid)
2655 mode_index++;
2656 }
2657 } else {
2658 rdev->pm.power_state[state_index].clock_info[0].mclk =
2659 rdev->clock.default_mclk;
2660 rdev->pm.power_state[state_index].clock_info[0].sclk =
2661 rdev->clock.default_sclk;
2662 mode_index++;
b0e66414
AD
2663 }
2664 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2665 if (mode_index) {
2666 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2667 non_clock_info);
2668 state_index++;
2669 }
441e76ca 2670 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
b0e66414
AD
2671 }
2672 /* if multiple clock modes, mark the lowest as no display */
2673 for (i = 0; i < state_index; i++) {
2674 if (rdev->pm.power_state[i].num_clock_modes > 1)
2675 rdev->pm.power_state[i].clock_info[0].flags |=
2676 RADEON_PM_MODE_NO_DISPLAY;
2677 }
2678 /* first mode is usually default */
2679 if (rdev->pm.default_power_state_index == -1) {
2680 rdev->pm.power_state[0].type =
2681 POWER_STATE_TYPE_DEFAULT;
2682 rdev->pm.default_power_state_index = 0;
2683 rdev->pm.power_state[0].default_clock_mode =
2684 &rdev->pm.power_state[0].clock_info[0];
2685 }
2686 return state_index;
2687}
2688
560154e9
AD
2689void radeon_atombios_get_power_modes(struct radeon_device *rdev)
2690{
2691 struct radeon_mode_info *mode_info = &rdev->mode_info;
2692 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2693 u16 data_offset;
2694 u8 frev, crev;
2695 int state_index = 0;
2696
2697 rdev->pm.default_power_state_index = -1;
2698
2699 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2700 &frev, &crev, &data_offset)) {
2701 switch (frev) {
2702 case 1:
2703 case 2:
2704 case 3:
2705 state_index = radeon_atombios_parse_power_table_1_3(rdev);
2706 break;
2707 case 4:
2708 case 5:
2709 state_index = radeon_atombios_parse_power_table_4_5(rdev);
2710 break;
b0e66414
AD
2711 case 6:
2712 state_index = radeon_atombios_parse_power_table_6(rdev);
2713 break;
560154e9
AD
2714 default:
2715 break;
56278a8e 2716 }
f8e6bfc2
AD
2717 }
2718
2719 if (state_index == 0) {
0975b162
AD
2720 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2721 if (rdev->pm.power_state) {
8f3f1c9a
AD
2722 rdev->pm.power_state[0].clock_info =
2723 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2724 if (rdev->pm.power_state[0].clock_info) {
2725 /* add the default mode */
2726 rdev->pm.power_state[state_index].type =
2727 POWER_STATE_TYPE_DEFAULT;
2728 rdev->pm.power_state[state_index].num_clock_modes = 1;
2729 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2730 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2731 rdev->pm.power_state[state_index].default_clock_mode =
2732 &rdev->pm.power_state[state_index].clock_info[0];
2733 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2734 rdev->pm.power_state[state_index].pcie_lanes = 16;
2735 rdev->pm.default_power_state_index = state_index;
2736 rdev->pm.power_state[state_index].flags = 0;
2737 state_index++;
2738 }
0975b162 2739 }
56278a8e 2740 }
02b17cc0 2741
56278a8e 2742 rdev->pm.num_power_states = state_index;
9038dfdf 2743
a48b9b4e
AD
2744 rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2745 rdev->pm.current_clock_mode_index = 0;
4376eee9
AM
2746 if (rdev->pm.default_power_state_index >= 0)
2747 rdev->pm.current_vddc =
2748 rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
2749 else
2750 rdev->pm.current_vddc = 0;
771fe6b9
JG
2751}
2752
7062ab67
CK
2753union get_clock_dividers {
2754 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
2755 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
2756 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
2757 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
2758 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
9219ed65
AD
2759 struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
2760 struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
7062ab67
CK
2761};
2762
2763int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
2764 u8 clock_type,
2765 u32 clock,
2766 bool strobe_mode,
2767 struct atom_clock_dividers *dividers)
2768{
2769 union get_clock_dividers args;
2770 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
2771 u8 frev, crev;
2772
2773 memset(&args, 0, sizeof(args));
2774 memset(dividers, 0, sizeof(struct atom_clock_dividers));
2775
2776 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2777 return -EINVAL;
2778
2779 switch (crev) {
2780 case 1:
2781 /* r4xx, r5xx */
2782 args.v1.ucAction = clock_type;
2783 args.v1.ulClock = cpu_to_le32(clock); /* 10 khz */
2784
2785 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2786
2787 dividers->post_div = args.v1.ucPostDiv;
2788 dividers->fb_div = args.v1.ucFbDiv;
2789 dividers->enable_post_div = true;
2790 break;
2791 case 2:
2792 case 3:
360b1f5e
AD
2793 case 5:
2794 /* r6xx, r7xx, evergreen, ni, si */
7062ab67
CK
2795 if (rdev->family <= CHIP_RV770) {
2796 args.v2.ucAction = clock_type;
2797 args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */
2798
2799 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2800
2801 dividers->post_div = args.v2.ucPostDiv;
2802 dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);
2803 dividers->ref_div = args.v2.ucAction;
2804 if (rdev->family == CHIP_RV770) {
2805 dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?
2806 true : false;
2807 dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;
2808 } else
2809 dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;
2810 } else {
2811 if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
f4a2596c 2812 args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
7062ab67
CK
2813
2814 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2815
2816 dividers->post_div = args.v3.ucPostDiv;
2817 dividers->enable_post_div = (args.v3.ucCntlFlag &
2818 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2819 dividers->enable_dithen = (args.v3.ucCntlFlag &
2820 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
20fab641 2821 dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
7062ab67
CK
2822 dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
2823 dividers->ref_div = args.v3.ucRefDiv;
2824 dividers->vco_mode = (args.v3.ucCntlFlag &
2825 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2826 } else {
360b1f5e
AD
2827 /* for SI we use ComputeMemoryClockParam for memory plls */
2828 if (rdev->family >= CHIP_TAHITI)
2829 return -EINVAL;
f4a2596c 2830 args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
7062ab67
CK
2831 if (strobe_mode)
2832 args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
2833
2834 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2835
2836 dividers->post_div = args.v5.ucPostDiv;
2837 dividers->enable_post_div = (args.v5.ucCntlFlag &
2838 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2839 dividers->enable_dithen = (args.v5.ucCntlFlag &
2840 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
2841 dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
2842 dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
2843 dividers->ref_div = args.v5.ucRefDiv;
2844 dividers->vco_mode = (args.v5.ucCntlFlag &
2845 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2846 }
2847 }
2848 break;
2849 case 4:
2850 /* fusion */
2851 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
2852
2853 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2854
9219ed65 2855 dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
7062ab67
CK
2856 dividers->real_clock = le32_to_cpu(args.v4.ulClock);
2857 break;
9219ed65
AD
2858 case 6:
2859 /* CI */
2860 /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
2861 args.v6_in.ulClock.ulComputeClockFlag = clock_type;
2862 args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */
2863
2864 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2865
2866 dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
2867 dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
2868 dividers->ref_div = args.v6_out.ucPllRefDiv;
2869 dividers->post_div = args.v6_out.ucPllPostDiv;
2870 dividers->flags = args.v6_out.ucPllCntlFlag;
2871 dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
2872 dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
2873 break;
7062ab67
CK
2874 default:
2875 return -EINVAL;
2876 }
2877 return 0;
2878}
2879
eaa778af
AD
2880int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
2881 u32 clock,
2882 bool strobe_mode,
2883 struct atom_mpll_param *mpll_param)
2884{
2885 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
2886 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
2887 u8 frev, crev;
2888
2889 memset(&args, 0, sizeof(args));
2890 memset(mpll_param, 0, sizeof(struct atom_mpll_param));
2891
2892 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2893 return -EINVAL;
2894
2895 switch (frev) {
2896 case 2:
2897 switch (crev) {
2898 case 1:
2899 /* SI */
2900 args.ulClock = cpu_to_le32(clock); /* 10 khz */
2901 args.ucInputFlag = 0;
2902 if (strobe_mode)
2903 args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
2904
2905 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2906
2907 mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
2908 mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
2909 mpll_param->post_div = args.ucPostDiv;
2910 mpll_param->dll_speed = args.ucDllSpeed;
2911 mpll_param->bwcntl = args.ucBWCntl;
2912 mpll_param->vco_mode =
180f805f 2913 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);
eaa778af
AD
2914 mpll_param->yclk_sel =
2915 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
2916 mpll_param->qdr =
2917 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
2918 mpll_param->half_rate =
2919 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
2920 break;
2921 default:
2922 return -EINVAL;
2923 }
2924 break;
2925 default:
2926 return -EINVAL;
2927 }
2928 return 0;
2929}
2930
771fe6b9 2931void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
771fe6b9 2932{
771fe6b9
JG
2933 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
2934 int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
771fe6b9
JG
2935
2936 args.ucEnable = enable;
2937
2938 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2939}
2940
7433874e
RM
2941uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)
2942{
2943 GET_ENGINE_CLOCK_PS_ALLOCATION args;
2944 int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
2945
2946 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
4589433c 2947 return le32_to_cpu(args.ulReturnEngineClock);
7433874e
RM
2948}
2949
2950uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
2951{
2952 GET_MEMORY_CLOCK_PS_ALLOCATION args;
2953 int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
2954
2955 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
4589433c 2956 return le32_to_cpu(args.ulReturnMemoryClock);
7433874e
RM
2957}
2958
771fe6b9
JG
2959void radeon_atom_set_engine_clock(struct radeon_device *rdev,
2960 uint32_t eng_clock)
2961{
2962 SET_ENGINE_CLOCK_PS_ALLOCATION args;
2963 int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);
2964
4589433c 2965 args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */
771fe6b9
JG
2966
2967 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2968}
2969
2970void radeon_atom_set_memory_clock(struct radeon_device *rdev,
2971 uint32_t mem_clock)
2972{
2973 SET_MEMORY_CLOCK_PS_ALLOCATION args;
2974 int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock);
2975
2976 if (rdev->flags & RADEON_IS_IGP)
2977 return;
2978
4589433c 2979 args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */
771fe6b9
JG
2980
2981 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2982}
2983
ae5b0abb
AD
2984void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
2985 u32 eng_clock, u32 mem_clock)
2986{
2987 SET_ENGINE_CLOCK_PS_ALLOCATION args;
2988 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
2989 u32 tmp;
2990
2991 memset(&args, 0, sizeof(args));
2992
2993 tmp = eng_clock & SET_CLOCK_FREQ_MASK;
2994 tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);
2995
2996 args.ulTargetEngineClock = cpu_to_le32(tmp);
2997 if (mem_clock)
2998 args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
2999
3000 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3001}
3002
3003void radeon_atom_update_memory_dll(struct radeon_device *rdev,
3004 u32 mem_clock)
3005{
3006 u32 args;
3007 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
3008
3009 args = cpu_to_le32(mem_clock); /* 10 khz */
3010
3011 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3012}
3013
3014void radeon_atom_set_ac_timing(struct radeon_device *rdev,
3015 u32 mem_clock)
3016{
3017 SET_MEMORY_CLOCK_PS_ALLOCATION args;
3018 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
3019 u32 tmp = mem_clock | (COMPUTE_MEMORY_PLL_PARAM << 24);
3020
3021 args.ulTargetMemoryClock = cpu_to_le32(tmp); /* 10 khz */
3022
3023 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3024}
3025
7ac9aa5a
AD
3026union set_voltage {
3027 struct _SET_VOLTAGE_PS_ALLOCATION alloc;
3028 struct _SET_VOLTAGE_PARAMETERS v1;
3029 struct _SET_VOLTAGE_PARAMETERS_V2 v2;
e83753bb 3030 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
7ac9aa5a
AD
3031};
3032
8a83ec5e 3033void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)
7ac9aa5a
AD
3034{
3035 union set_voltage args;
3036 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
8a83ec5e 3037 u8 frev, crev, volt_index = voltage_level;
7ac9aa5a
AD
3038
3039 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3040 return;
3041
a377e187
AD
3042 /* 0xff01 is a flag rather then an actual voltage */
3043 if (voltage_level == 0xff01)
3044 return;
3045
7ac9aa5a
AD
3046 switch (crev) {
3047 case 1:
8a83ec5e 3048 args.v1.ucVoltageType = voltage_type;
7ac9aa5a
AD
3049 args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
3050 args.v1.ucVoltageIndex = volt_index;
3051 break;
3052 case 2:
8a83ec5e 3053 args.v2.ucVoltageType = voltage_type;
7ac9aa5a 3054 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
8a83ec5e 3055 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
7ac9aa5a 3056 break;
e83753bb
AD
3057 case 3:
3058 args.v3.ucVoltageType = voltage_type;
3059 args.v3.ucVoltageMode = ATOM_SET_VOLTAGE;
3060 args.v3.usVoltageLevel = cpu_to_le16(voltage_level);
3061 break;
7ac9aa5a
AD
3062 default:
3063 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3064 return;
3065 }
3066
3067 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3068}
3069
ae5b0abb
AD
3070int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
3071 u16 voltage_id, u16 *voltage)
ee4017f4
AD
3072{
3073 union set_voltage args;
3074 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3075 u8 frev, crev;
3076
3077 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3078 return -EINVAL;
3079
3080 switch (crev) {
3081 case 1:
3082 return -EINVAL;
3083 case 2:
3084 args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
3085 args.v2.ucVoltageMode = 0;
3086 args.v2.usVoltageLevel = 0;
3087
3088 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3089
3090 *voltage = le16_to_cpu(args.v2.usVoltageLevel);
3091 break;
e83753bb
AD
3092 case 3:
3093 args.v3.ucVoltageType = voltage_type;
3094 args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
3095 args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
3096
3097 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3098
3099 *voltage = le16_to_cpu(args.v3.usVoltageLevel);
3100 break;
ee4017f4
AD
3101 default:
3102 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3103 return -EINVAL;
3104 }
7ac9aa5a 3105
ee4017f4
AD
3106 return 0;
3107}
7ac9aa5a 3108
beb79f40
AD
3109int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,
3110 u16 *voltage,
3111 u16 leakage_idx)
3112{
3113 return radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
3114}
3115
62c35fd7
AD
3116int radeon_atom_get_leakage_id_from_vbios(struct radeon_device *rdev,
3117 u16 *leakage_id)
3118{
3119 union set_voltage args;
3120 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3121 u8 frev, crev;
3122
3123 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3124 return -EINVAL;
3125
3126 switch (crev) {
3127 case 3:
3128 case 4:
3129 args.v3.ucVoltageType = 0;
3130 args.v3.ucVoltageMode = ATOM_GET_LEAKAGE_ID;
3131 args.v3.usVoltageLevel = 0;
3132
3133 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3134
3135 *leakage_id = le16_to_cpu(args.v3.usVoltageLevel);
3136 break;
3137 default:
3138 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3139 return -EINVAL;
3140 }
3141
3142 return 0;
3143}
3144
3145int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *rdev,
3146 u16 *vddc, u16 *vddci,
3147 u16 virtual_voltage_id,
3148 u16 vbios_voltage_id)
3149{
3150 int index = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);
3151 u8 frev, crev;
3152 u16 data_offset, size;
3153 int i, j;
3154 ATOM_ASIC_PROFILING_INFO_V2_1 *profile;
3155 u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf;
3156
3157 *vddc = 0;
3158 *vddci = 0;
3159
3160 if (!atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3161 &frev, &crev, &data_offset))
3162 return -EINVAL;
3163
3164 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)
3165 (rdev->mode_info.atom_context->bios + data_offset);
3166
3167 switch (frev) {
3168 case 1:
3169 return -EINVAL;
3170 case 2:
3171 switch (crev) {
3172 case 1:
3173 if (size < sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))
3174 return -EINVAL;
3175 leakage_bin = (u16 *)
3176 (rdev->mode_info.atom_context->bios + data_offset +
3177 le16_to_cpu(profile->usLeakageBinArrayOffset));
3178 vddc_id_buf = (u16 *)
3179 (rdev->mode_info.atom_context->bios + data_offset +
3180 le16_to_cpu(profile->usElbVDDC_IdArrayOffset));
3181 vddc_buf = (u16 *)
3182 (rdev->mode_info.atom_context->bios + data_offset +
3183 le16_to_cpu(profile->usElbVDDC_LevelArrayOffset));
3184 vddci_id_buf = (u16 *)
3185 (rdev->mode_info.atom_context->bios + data_offset +
3186 le16_to_cpu(profile->usElbVDDCI_IdArrayOffset));
3187 vddci_buf = (u16 *)
3188 (rdev->mode_info.atom_context->bios + data_offset +
3189 le16_to_cpu(profile->usElbVDDCI_LevelArrayOffset));
3190
3191 if (profile->ucElbVDDC_Num > 0) {
3192 for (i = 0; i < profile->ucElbVDDC_Num; i++) {
3193 if (vddc_id_buf[i] == virtual_voltage_id) {
3194 for (j = 0; j < profile->ucLeakageBinNum; j++) {
3195 if (vbios_voltage_id <= leakage_bin[j]) {
3196 *vddc = vddc_buf[j * profile->ucElbVDDC_Num + i];
3197 break;
3198 }
3199 }
3200 break;
3201 }
3202 }
3203 }
3204 if (profile->ucElbVDDCI_Num > 0) {
3205 for (i = 0; i < profile->ucElbVDDCI_Num; i++) {
3206 if (vddci_id_buf[i] == virtual_voltage_id) {
3207 for (j = 0; j < profile->ucLeakageBinNum; j++) {
3208 if (vbios_voltage_id <= leakage_bin[j]) {
3209 *vddci = vddci_buf[j * profile->ucElbVDDCI_Num + i];
3210 break;
3211 }
3212 }
3213 break;
3214 }
3215 }
3216 }
3217 break;
3218 default:
3219 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3220 return -EINVAL;
3221 }
3222 break;
3223 default:
3224 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3225 return -EINVAL;
3226 }
3227
3228 return 0;
3229}
3230
ae5b0abb
AD
3231int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
3232 u16 voltage_level, u8 voltage_type,
3233 u32 *gpio_value, u32 *gpio_mask)
3234{
3235 union set_voltage args;
3236 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3237 u8 frev, crev;
3238
3239 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3240 return -EINVAL;
3241
3242 switch (crev) {
3243 case 1:
3244 return -EINVAL;
3245 case 2:
3246 args.v2.ucVoltageType = voltage_type;
3247 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK;
3248 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
3249
3250 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3251
3252 *gpio_mask = le32_to_cpu(*(u32 *)&args.v2);
3253
3254 args.v2.ucVoltageType = voltage_type;
3255 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL;
3256 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
3257
3258 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3259
3260 *gpio_value = le32_to_cpu(*(u32 *)&args.v2);
3261 break;
3262 default:
3263 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3264 return -EINVAL;
3265 }
3266
3267 return 0;
3268}
3269
3270union voltage_object_info {
58653abd
AD
3271 struct _ATOM_VOLTAGE_OBJECT_INFO v1;
3272 struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
3273 struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
ae5b0abb
AD
3274};
3275
779187f2
AD
3276union voltage_object {
3277 struct _ATOM_VOLTAGE_OBJECT v1;
3278 struct _ATOM_VOLTAGE_OBJECT_V2 v2;
3279 union _ATOM_VOLTAGE_OBJECT_V3 v3;
3280};
3281
3282static ATOM_VOLTAGE_OBJECT *atom_lookup_voltage_object_v1(ATOM_VOLTAGE_OBJECT_INFO *v1,
3283 u8 voltage_type)
3284{
6e764764 3285 u32 size = le16_to_cpu(v1->sHeader.usStructureSize);
779187f2
AD
3286 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO, asVoltageObj[0]);
3287 u8 *start = (u8 *)v1;
3288
3289 while (offset < size) {
3290 ATOM_VOLTAGE_OBJECT *vo = (ATOM_VOLTAGE_OBJECT *)(start + offset);
3291 if (vo->ucVoltageType == voltage_type)
3292 return vo;
3293 offset += offsetof(ATOM_VOLTAGE_OBJECT, asFormula.ucVIDAdjustEntries) +
3294 vo->asFormula.ucNumOfVoltageEntries;
3295 }
3296 return NULL;
3297}
3298
3299static ATOM_VOLTAGE_OBJECT_V2 *atom_lookup_voltage_object_v2(ATOM_VOLTAGE_OBJECT_INFO_V2 *v2,
3300 u8 voltage_type)
3301{
6e764764 3302 u32 size = le16_to_cpu(v2->sHeader.usStructureSize);
779187f2
AD
3303 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V2, asVoltageObj[0]);
3304 u8 *start = (u8*)v2;
3305
3306 while (offset < size) {
3307 ATOM_VOLTAGE_OBJECT_V2 *vo = (ATOM_VOLTAGE_OBJECT_V2 *)(start + offset);
3308 if (vo->ucVoltageType == voltage_type)
3309 return vo;
3310 offset += offsetof(ATOM_VOLTAGE_OBJECT_V2, asFormula.asVIDAdjustEntries) +
3311 (vo->asFormula.ucNumOfVoltageEntries * sizeof(VOLTAGE_LUT_ENTRY));
3312 }
3313 return NULL;
3314}
3315
3316static ATOM_VOLTAGE_OBJECT_V3 *atom_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,
3317 u8 voltage_type, u8 voltage_mode)
3318{
6e764764 3319 u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
779187f2
AD
3320 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
3321 u8 *start = (u8*)v3;
3322
3323 while (offset < size) {
3324 ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
3325 if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
3326 (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
3327 return vo;
6e764764 3328 offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
779187f2
AD
3329 }
3330 return NULL;
3331}
3332
ae5b0abb 3333bool
58653abd
AD
3334radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
3335 u8 voltage_type, u8 voltage_mode)
ae5b0abb
AD
3336{
3337 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3338 u8 frev, crev;
3339 u16 data_offset, size;
ae5b0abb 3340 union voltage_object_info *voltage_info;
779187f2 3341 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3342
3343 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3344 &frev, &crev, &data_offset)) {
3345 voltage_info = (union voltage_object_info *)
3346 (rdev->mode_info.atom_context->bios + data_offset);
3347
58653abd 3348 switch (frev) {
ae5b0abb 3349 case 1:
58653abd
AD
3350 case 2:
3351 switch (crev) {
3352 case 1:
779187f2
AD
3353 voltage_object = (union voltage_object *)
3354 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3355 if (voltage_object &&
3356 (voltage_object->v1.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
3357 return true;
58653abd
AD
3358 break;
3359 case 2:
779187f2
AD
3360 voltage_object = (union voltage_object *)
3361 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3362 if (voltage_object &&
3363 (voltage_object->v2.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
3364 return true;
58653abd
AD
3365 break;
3366 default:
3367 DRM_ERROR("unknown voltage object table\n");
3368 return false;
ae5b0abb
AD
3369 }
3370 break;
58653abd
AD
3371 case 3:
3372 switch (crev) {
3373 case 1:
779187f2
AD
3374 if (atom_lookup_voltage_object_v3(&voltage_info->v3,
3375 voltage_type, voltage_mode))
3376 return true;
58653abd
AD
3377 break;
3378 default:
3379 DRM_ERROR("unknown voltage object table\n");
3380 return false;
ae5b0abb
AD
3381 }
3382 break;
3383 default:
3384 DRM_ERROR("unknown voltage object table\n");
3385 return false;
3386 }
3387
3388 }
3389 return false;
3390}
3391
3392int radeon_atom_get_max_voltage(struct radeon_device *rdev,
3393 u8 voltage_type, u16 *max_voltage)
3394{
3395 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3396 u8 frev, crev;
3397 u16 data_offset, size;
ae5b0abb 3398 union voltage_object_info *voltage_info;
779187f2 3399 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3400
3401 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3402 &frev, &crev, &data_offset)) {
3403 voltage_info = (union voltage_object_info *)
3404 (rdev->mode_info.atom_context->bios + data_offset);
3405
3406 switch (crev) {
3407 case 1:
779187f2
AD
3408 voltage_object = (union voltage_object *)
3409 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3410 if (voltage_object) {
3411 ATOM_VOLTAGE_FORMULA *formula =
3412 &voltage_object->v1.asFormula;
3413 if (formula->ucFlag & 1)
3414 *max_voltage =
3415 le16_to_cpu(formula->usVoltageBaseLevel) +
3416 formula->ucNumOfVoltageEntries / 2 *
3417 le16_to_cpu(formula->usVoltageStep);
3418 else
3419 *max_voltage =
3420 le16_to_cpu(formula->usVoltageBaseLevel) +
3421 (formula->ucNumOfVoltageEntries - 1) *
3422 le16_to_cpu(formula->usVoltageStep);
3423 return 0;
ae5b0abb
AD
3424 }
3425 break;
3426 case 2:
779187f2
AD
3427 voltage_object = (union voltage_object *)
3428 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3429 if (voltage_object) {
3430 ATOM_VOLTAGE_FORMULA_V2 *formula =
3431 &voltage_object->v2.asFormula;
3432 if (formula->ucNumOfVoltageEntries) {
607f2c27
AD
3433 VOLTAGE_LUT_ENTRY *lut = (VOLTAGE_LUT_ENTRY *)
3434 ((u8 *)&formula->asVIDAdjustEntries[0] +
3435 (sizeof(VOLTAGE_LUT_ENTRY) * (formula->ucNumOfVoltageEntries - 1)));
779187f2 3436 *max_voltage =
607f2c27 3437 le16_to_cpu(lut->usVoltageValue);
779187f2 3438 return 0;
ae5b0abb
AD
3439 }
3440 }
3441 break;
3442 default:
3443 DRM_ERROR("unknown voltage object table\n");
3444 return -EINVAL;
3445 }
3446
3447 }
3448 return -EINVAL;
3449}
3450
3451int radeon_atom_get_min_voltage(struct radeon_device *rdev,
3452 u8 voltage_type, u16 *min_voltage)
3453{
3454 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3455 u8 frev, crev;
3456 u16 data_offset, size;
ae5b0abb 3457 union voltage_object_info *voltage_info;
779187f2 3458 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3459
3460 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3461 &frev, &crev, &data_offset)) {
3462 voltage_info = (union voltage_object_info *)
3463 (rdev->mode_info.atom_context->bios + data_offset);
3464
3465 switch (crev) {
3466 case 1:
779187f2
AD
3467 voltage_object = (union voltage_object *)
3468 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3469 if (voltage_object) {
3470 ATOM_VOLTAGE_FORMULA *formula =
3471 &voltage_object->v1.asFormula;
3472 *min_voltage =
3473 le16_to_cpu(formula->usVoltageBaseLevel);
3474 return 0;
ae5b0abb
AD
3475 }
3476 break;
3477 case 2:
779187f2
AD
3478 voltage_object = (union voltage_object *)
3479 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3480 if (voltage_object) {
3481 ATOM_VOLTAGE_FORMULA_V2 *formula =
3482 &voltage_object->v2.asFormula;
3483 if (formula->ucNumOfVoltageEntries) {
3484 *min_voltage =
3485 le16_to_cpu(formula->asVIDAdjustEntries[
3486 0
3487 ].usVoltageValue);
3488 return 0;
ae5b0abb
AD
3489 }
3490 }
3491 break;
3492 default:
3493 DRM_ERROR("unknown voltage object table\n");
3494 return -EINVAL;
3495 }
3496
3497 }
3498 return -EINVAL;
3499}
3500
3501int radeon_atom_get_voltage_step(struct radeon_device *rdev,
3502 u8 voltage_type, u16 *voltage_step)
3503{
3504 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3505 u8 frev, crev;
3506 u16 data_offset, size;
ae5b0abb 3507 union voltage_object_info *voltage_info;
779187f2 3508 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3509
3510 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3511 &frev, &crev, &data_offset)) {
3512 voltage_info = (union voltage_object_info *)
3513 (rdev->mode_info.atom_context->bios + data_offset);
3514
3515 switch (crev) {
3516 case 1:
779187f2
AD
3517 voltage_object = (union voltage_object *)
3518 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3519 if (voltage_object) {
3520 ATOM_VOLTAGE_FORMULA *formula =
3521 &voltage_object->v1.asFormula;
3522 if (formula->ucFlag & 1)
3523 *voltage_step =
3524 (le16_to_cpu(formula->usVoltageStep) + 1) / 2;
3525 else
3526 *voltage_step =
3527 le16_to_cpu(formula->usVoltageStep);
3528 return 0;
ae5b0abb
AD
3529 }
3530 break;
3531 case 2:
3532 return -EINVAL;
3533 default:
3534 DRM_ERROR("unknown voltage object table\n");
3535 return -EINVAL;
3536 }
3537
3538 }
3539 return -EINVAL;
3540}
3541
3542int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
3543 u8 voltage_type,
3544 u16 nominal_voltage,
3545 u16 *true_voltage)
3546{
3547 u16 min_voltage, max_voltage, voltage_step;
3548
3549 if (radeon_atom_get_max_voltage(rdev, voltage_type, &max_voltage))
3550 return -EINVAL;
3551 if (radeon_atom_get_min_voltage(rdev, voltage_type, &min_voltage))
3552 return -EINVAL;
3553 if (radeon_atom_get_voltage_step(rdev, voltage_type, &voltage_step))
3554 return -EINVAL;
3555
3556 if (nominal_voltage <= min_voltage)
3557 *true_voltage = min_voltage;
3558 else if (nominal_voltage >= max_voltage)
3559 *true_voltage = max_voltage;
3560 else
3561 *true_voltage = min_voltage +
3562 ((nominal_voltage - min_voltage) / voltage_step) *
3563 voltage_step;
3564
3565 return 0;
3566}
3567
3568int radeon_atom_get_voltage_table(struct radeon_device *rdev,
65171944 3569 u8 voltage_type, u8 voltage_mode,
ae5b0abb
AD
3570 struct atom_voltage_table *voltage_table)
3571{
3572 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3573 u8 frev, crev;
3574 u16 data_offset, size;
779187f2 3575 int i, ret;
ae5b0abb 3576 union voltage_object_info *voltage_info;
779187f2 3577 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3578
3579 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3580 &frev, &crev, &data_offset)) {
3581 voltage_info = (union voltage_object_info *)
3582 (rdev->mode_info.atom_context->bios + data_offset);
3583
65171944 3584 switch (frev) {
ae5b0abb 3585 case 1:
ae5b0abb 3586 case 2:
65171944
AD
3587 switch (crev) {
3588 case 1:
3589 DRM_ERROR("old table version %d, %d\n", frev, crev);
3590 return -EINVAL;
3591 case 2:
779187f2
AD
3592 voltage_object = (union voltage_object *)
3593 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3594 if (voltage_object) {
3595 ATOM_VOLTAGE_FORMULA_V2 *formula =
3596 &voltage_object->v2.asFormula;
607f2c27 3597 VOLTAGE_LUT_ENTRY *lut;
779187f2
AD
3598 if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)
3599 return -EINVAL;
607f2c27 3600 lut = &formula->asVIDAdjustEntries[0];
779187f2
AD
3601 for (i = 0; i < formula->ucNumOfVoltageEntries; i++) {
3602 voltage_table->entries[i].value =
607f2c27 3603 le16_to_cpu(lut->usVoltageValue);
779187f2
AD
3604 ret = radeon_atom_get_voltage_gpio_settings(rdev,
3605 voltage_table->entries[i].value,
3606 voltage_type,
3607 &voltage_table->entries[i].smio_low,
3608 &voltage_table->mask_low);
3609 if (ret)
3610 return ret;
607f2c27
AD
3611 lut = (VOLTAGE_LUT_ENTRY *)
3612 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY));
ae5b0abb 3613 }
779187f2
AD
3614 voltage_table->count = formula->ucNumOfVoltageEntries;
3615 return 0;
ae5b0abb 3616 }
65171944
AD
3617 break;
3618 default:
3619 DRM_ERROR("unknown voltage object table\n");
3620 return -EINVAL;
3621 }
3622 break;
3623 case 3:
3624 switch (crev) {
3625 case 1:
779187f2
AD
3626 voltage_object = (union voltage_object *)
3627 atom_lookup_voltage_object_v3(&voltage_info->v3,
3628 voltage_type, voltage_mode);
3629 if (voltage_object) {
3630 ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
3631 &voltage_object->v3.asGpioVoltageObj;
607f2c27 3632 VOLTAGE_LUT_ENTRY_V2 *lut;
779187f2
AD
3633 if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
3634 return -EINVAL;
607f2c27 3635 lut = &gpio->asVolGpioLut[0];
779187f2
AD
3636 for (i = 0; i < gpio->ucGpioEntryNum; i++) {
3637 voltage_table->entries[i].value =
607f2c27 3638 le16_to_cpu(lut->usVoltageValue);
779187f2 3639 voltage_table->entries[i].smio_low =
607f2c27
AD
3640 le32_to_cpu(lut->ulVoltageId);
3641 lut = (VOLTAGE_LUT_ENTRY_V2 *)
3642 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2));
65171944 3643 }
779187f2
AD
3644 voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
3645 voltage_table->count = gpio->ucGpioEntryNum;
3646 voltage_table->phase_delay = gpio->ucPhaseDelay;
3647 return 0;
65171944
AD
3648 }
3649 break;
3650 default:
3651 DRM_ERROR("unknown voltage object table\n");
3652 return -EINVAL;
ae5b0abb
AD
3653 }
3654 break;
3655 default:
3656 DRM_ERROR("unknown voltage object table\n");
3657 return -EINVAL;
3658 }
ae5b0abb
AD
3659 }
3660 return -EINVAL;
3661}
3662
3663union vram_info {
3664 struct _ATOM_VRAM_INFO_V3 v1_3;
3665 struct _ATOM_VRAM_INFO_V4 v1_4;
3666 struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;
3667};
3668
3669int radeon_atom_get_memory_info(struct radeon_device *rdev,
3670 u8 module_index, struct atom_memory_info *mem_info)
3671{
3672 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3673 u8 frev, crev, i;
3674 u16 data_offset, size;
3675 union vram_info *vram_info;
ae5b0abb
AD
3676
3677 memset(mem_info, 0, sizeof(struct atom_memory_info));
3678
3679 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3680 &frev, &crev, &data_offset)) {
3681 vram_info = (union vram_info *)
3682 (rdev->mode_info.atom_context->bios + data_offset);
3683 switch (frev) {
3684 case 1:
3685 switch (crev) {
3686 case 3:
3687 /* r6xx */
3688 if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {
3689 ATOM_VRAM_MODULE_V3 *vram_module =
3690 (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;
ae5b0abb
AD
3691
3692 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3693 if (le16_to_cpu(vram_module->usSize) == 0)
3694 return -EINVAL;
77c7d50a
AD
3695 vram_module = (ATOM_VRAM_MODULE_V3 *)
3696 ((u8 *)vram_module + le16_to_cpu(vram_module->usSize));
ae5b0abb
AD
3697 }
3698 mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;
3699 mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;
3700 } else
3701 return -EINVAL;
3702 break;
3703 case 4:
3704 /* r7xx, evergreen */
3705 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
3706 ATOM_VRAM_MODULE_V4 *vram_module =
3707 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
ae5b0abb
AD
3708
3709 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3710 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3711 return -EINVAL;
77c7d50a
AD
3712 vram_module = (ATOM_VRAM_MODULE_V4 *)
3713 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3714 }
3715 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
3716 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
3717 } else
3718 return -EINVAL;
3719 break;
3720 default:
3721 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3722 return -EINVAL;
3723 }
3724 break;
3725 case 2:
3726 switch (crev) {
3727 case 1:
3728 /* ni */
3729 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
3730 ATOM_VRAM_MODULE_V7 *vram_module =
3731 (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;
ae5b0abb
AD
3732
3733 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3734 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3735 return -EINVAL;
77c7d50a
AD
3736 vram_module = (ATOM_VRAM_MODULE_V7 *)
3737 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3738 }
3739 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
3740 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
3741 } else
3742 return -EINVAL;
3743 break;
3744 default:
3745 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3746 return -EINVAL;
3747 }
3748 break;
3749 default:
3750 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3751 return -EINVAL;
3752 }
3753 return 0;
3754 }
3755 return -EINVAL;
3756}
3757
3758int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
3759 bool gddr5, u8 module_index,
3760 struct atom_memory_clock_range_table *mclk_range_table)
3761{
3762 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3763 u8 frev, crev, i;
3764 u16 data_offset, size;
3765 union vram_info *vram_info;
3766 u32 mem_timing_size = gddr5 ?
3767 sizeof(ATOM_MEMORY_TIMING_FORMAT_V2) : sizeof(ATOM_MEMORY_TIMING_FORMAT);
ae5b0abb
AD
3768
3769 memset(mclk_range_table, 0, sizeof(struct atom_memory_clock_range_table));
3770
3771 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3772 &frev, &crev, &data_offset)) {
3773 vram_info = (union vram_info *)
3774 (rdev->mode_info.atom_context->bios + data_offset);
3775 switch (frev) {
3776 case 1:
3777 switch (crev) {
3778 case 3:
3779 DRM_ERROR("old table version %d, %d\n", frev, crev);
3780 return -EINVAL;
3781 case 4:
3782 /* r7xx, evergreen */
3783 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
3784 ATOM_VRAM_MODULE_V4 *vram_module =
3785 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
607f2c27 3786 ATOM_MEMORY_TIMING_FORMAT *format;
ae5b0abb
AD
3787
3788 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3789 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3790 return -EINVAL;
77c7d50a
AD
3791 vram_module = (ATOM_VRAM_MODULE_V4 *)
3792 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3793 }
3794 mclk_range_table->num_entries = (u8)
1fa4252a 3795 ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /
ae5b0abb 3796 mem_timing_size);
607f2c27 3797 format = &vram_module->asMemTiming[0];
ae5b0abb 3798 for (i = 0; i < mclk_range_table->num_entries; i++) {
e631227f 3799 mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
607f2c27
AD
3800 format = (ATOM_MEMORY_TIMING_FORMAT *)
3801 ((u8 *)format + mem_timing_size);
ae5b0abb
AD
3802 }
3803 } else
3804 return -EINVAL;
3805 break;
3806 default:
3807 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3808 return -EINVAL;
3809 }
3810 break;
3811 case 2:
3812 DRM_ERROR("new table version %d, %d\n", frev, crev);
3813 return -EINVAL;
3814 default:
3815 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3816 return -EINVAL;
3817 }
3818 return 0;
3819 }
3820 return -EINVAL;
3821}
3822
3823#define MEM_ID_MASK 0xff000000
3824#define MEM_ID_SHIFT 24
3825#define CLOCK_RANGE_MASK 0x00ffffff
3826#define CLOCK_RANGE_SHIFT 0
3827#define LOW_NIBBLE_MASK 0xf
3828#define DATA_EQU_PREV 0
3829#define DATA_FROM_TABLE 4
3830
3831int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
3832 u8 module_index,
3833 struct atom_mc_reg_table *reg_table)
3834{
3835 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3836 u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;
3837 u32 i = 0, j;
3838 u16 data_offset, size;
3839 union vram_info *vram_info;
3840
3841 memset(reg_table, 0, sizeof(struct atom_mc_reg_table));
3842
3843 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3844 &frev, &crev, &data_offset)) {
3845 vram_info = (union vram_info *)
3846 (rdev->mode_info.atom_context->bios + data_offset);
3847 switch (frev) {
3848 case 1:
3849 DRM_ERROR("old table version %d, %d\n", frev, crev);
3850 return -EINVAL;
3851 case 2:
3852 switch (crev) {
3853 case 1:
3854 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
3855 ATOM_INIT_REG_BLOCK *reg_block =
3856 (ATOM_INIT_REG_BLOCK *)
3857 ((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));
3858 ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =
3859 (ATOM_MEMORY_SETTING_DATA_BLOCK *)
3860 ((u8 *)reg_block + (2 * sizeof(u16)) +
3861 le16_to_cpu(reg_block->usRegIndexTblSize));
f90555cb 3862 ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
ae5b0abb
AD
3863 num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
3864 sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
3865 if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
3866 return -EINVAL;
48fa04c3 3867 while (i < num_entries) {
f90555cb 3868 if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
48fa04c3 3869 break;
ae5b0abb 3870 reg_table->mc_reg_address[i].s1 =
f90555cb 3871 (u16)(le16_to_cpu(format->usRegIndex));
ae5b0abb 3872 reg_table->mc_reg_address[i].pre_reg_data =
f90555cb 3873 (u8)(format->ucPreRegDataLength);
ae5b0abb 3874 i++;
f90555cb
AD
3875 format = (ATOM_INIT_REG_INDEX_FORMAT *)
3876 ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
ae5b0abb
AD
3877 }
3878 reg_table->last = i;
d526fbdd 3879 while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) &&
ae5b0abb 3880 (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {
d526fbdd
AD
3881 t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK)
3882 >> MEM_ID_SHIFT);
ae5b0abb
AD
3883 if (module_index == t_mem_id) {
3884 reg_table->mc_reg_table_entry[num_ranges].mclk_max =
d526fbdd
AD
3885 (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK)
3886 >> CLOCK_RANGE_SHIFT);
ae5b0abb
AD
3887 for (i = 0, j = 1; i < reg_table->last; i++) {
3888 if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
3889 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
d526fbdd 3890 (u32)le32_to_cpu(*((u32 *)reg_data + j));
ae5b0abb
AD
3891 j++;
3892 } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
3893 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
3894 reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
3895 }
3896 }
3897 num_ranges++;
3898 }
4da18e26
AD
3899 reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
3900 ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
ae5b0abb 3901 }
d526fbdd 3902 if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK)
ae5b0abb
AD
3903 return -EINVAL;
3904 reg_table->num_entries = num_ranges;
3905 } else
3906 return -EINVAL;
3907 break;
3908 default:
3909 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3910 return -EINVAL;
3911 }
3912 break;
3913 default:
3914 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3915 return -EINVAL;
3916 }
3917 return 0;
3918 }
3919 return -EINVAL;
3920}
3921
771fe6b9
JG
3922void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
3923{
3924 struct radeon_device *rdev = dev->dev_private;
3925 uint32_t bios_2_scratch, bios_6_scratch;
3926
3927 if (rdev->family >= CHIP_R600) {
4ce001ab 3928 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
771fe6b9
JG
3929 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
3930 } else {
4ce001ab 3931 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
771fe6b9
JG
3932 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3933 }
3934
3935 /* let the bios control the backlight */
3936 bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
3937
3938 /* tell the bios not to handle mode switching */
87364760 3939 bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
771fe6b9 3940
6802d4ba
AD
3941 /* clear the vbios dpms state */
3942 if (ASIC_IS_DCE4(rdev))
3943 bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
3944
771fe6b9
JG
3945 if (rdev->family >= CHIP_R600) {
3946 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
3947 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
3948 } else {
3949 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
3950 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
3951 }
3952
3953}
3954
f657c2a7
YZ
3955void radeon_save_bios_scratch_regs(struct radeon_device *rdev)
3956{
3957 uint32_t scratch_reg;
3958 int i;
3959
3960 if (rdev->family >= CHIP_R600)
3961 scratch_reg = R600_BIOS_0_SCRATCH;
3962 else
3963 scratch_reg = RADEON_BIOS_0_SCRATCH;
3964
3965 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
3966 rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));
3967}
3968
3969void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)
3970{
3971 uint32_t scratch_reg;
3972 int i;
3973
3974 if (rdev->family >= CHIP_R600)
3975 scratch_reg = R600_BIOS_0_SCRATCH;
3976 else
3977 scratch_reg = RADEON_BIOS_0_SCRATCH;
3978
3979 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
3980 WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);
3981}
3982
771fe6b9
JG
3983void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
3984{
3985 struct drm_device *dev = encoder->dev;
3986 struct radeon_device *rdev = dev->dev_private;
3987 uint32_t bios_6_scratch;
3988
3989 if (rdev->family >= CHIP_R600)
3990 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
3991 else
3992 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
3993
87364760 3994 if (lock) {
771fe6b9 3995 bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
87364760
AD
3996 bios_6_scratch &= ~ATOM_S6_ACC_MODE;
3997 } else {
771fe6b9 3998 bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
87364760
AD
3999 bios_6_scratch |= ATOM_S6_ACC_MODE;
4000 }
771fe6b9
JG
4001
4002 if (rdev->family >= CHIP_R600)
4003 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
4004 else
4005 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
4006}
4007
4008/* at some point we may want to break this out into individual functions */
4009void
4010radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
4011 struct drm_encoder *encoder,
4012 bool connected)
4013{
4014 struct drm_device *dev = connector->dev;
4015 struct radeon_device *rdev = dev->dev_private;
4016 struct radeon_connector *radeon_connector =
4017 to_radeon_connector(connector);
4018 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4019 uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch;
4020
4021 if (rdev->family >= CHIP_R600) {
4022 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
4023 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
4024 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
4025 } else {
4026 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
4027 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);
4028 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
4029 }
4030
4031 if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
4032 (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
4033 if (connected) {
d9fdaafb 4034 DRM_DEBUG_KMS("TV1 connected\n");
771fe6b9
JG
4035 bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
4036 bios_6_scratch |= ATOM_S6_ACC_REQ_TV1;
4037 } else {
d9fdaafb 4038 DRM_DEBUG_KMS("TV1 disconnected\n");
771fe6b9
JG
4039 bios_0_scratch &= ~ATOM_S0_TV1_MASK;
4040 bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
4041 bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1;
4042 }
4043 }
4044 if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) &&
4045 (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) {
4046 if (connected) {
d9fdaafb 4047 DRM_DEBUG_KMS("CV connected\n");
771fe6b9
JG
4048 bios_3_scratch |= ATOM_S3_CV_ACTIVE;
4049 bios_6_scratch |= ATOM_S6_ACC_REQ_CV;
4050 } else {
d9fdaafb 4051 DRM_DEBUG_KMS("CV disconnected\n");
771fe6b9
JG
4052 bios_0_scratch &= ~ATOM_S0_CV_MASK;
4053 bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
4054 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV;
4055 }
4056 }
4057 if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
4058 (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
4059 if (connected) {
d9fdaafb 4060 DRM_DEBUG_KMS("LCD1 connected\n");
771fe6b9
JG
4061 bios_0_scratch |= ATOM_S0_LCD1;
4062 bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
4063 bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1;
4064 } else {
d9fdaafb 4065 DRM_DEBUG_KMS("LCD1 disconnected\n");
771fe6b9
JG
4066 bios_0_scratch &= ~ATOM_S0_LCD1;
4067 bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
4068 bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1;
4069 }
4070 }
4071 if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
4072 (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
4073 if (connected) {
d9fdaafb 4074 DRM_DEBUG_KMS("CRT1 connected\n");
771fe6b9
JG
4075 bios_0_scratch |= ATOM_S0_CRT1_COLOR;
4076 bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
4077 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1;
4078 } else {
d9fdaafb 4079 DRM_DEBUG_KMS("CRT1 disconnected\n");
771fe6b9
JG
4080 bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
4081 bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
4082 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1;
4083 }
4084 }
4085 if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
4086 (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
4087 if (connected) {
d9fdaafb 4088 DRM_DEBUG_KMS("CRT2 connected\n");
771fe6b9
JG
4089 bios_0_scratch |= ATOM_S0_CRT2_COLOR;
4090 bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
4091 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2;
4092 } else {
d9fdaafb 4093 DRM_DEBUG_KMS("CRT2 disconnected\n");
771fe6b9
JG
4094 bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
4095 bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
4096 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2;
4097 }
4098 }
4099 if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
4100 (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
4101 if (connected) {
d9fdaafb 4102 DRM_DEBUG_KMS("DFP1 connected\n");
771fe6b9
JG
4103 bios_0_scratch |= ATOM_S0_DFP1;
4104 bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
4105 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1;
4106 } else {
d9fdaafb 4107 DRM_DEBUG_KMS("DFP1 disconnected\n");
771fe6b9
JG
4108 bios_0_scratch &= ~ATOM_S0_DFP1;
4109 bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
4110 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1;
4111 }
4112 }
4113 if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
4114 (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
4115 if (connected) {
d9fdaafb 4116 DRM_DEBUG_KMS("DFP2 connected\n");
771fe6b9
JG
4117 bios_0_scratch |= ATOM_S0_DFP2;
4118 bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
4119 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2;
4120 } else {
d9fdaafb 4121 DRM_DEBUG_KMS("DFP2 disconnected\n");
771fe6b9
JG
4122 bios_0_scratch &= ~ATOM_S0_DFP2;
4123 bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
4124 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2;
4125 }
4126 }
4127 if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) &&
4128 (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) {
4129 if (connected) {
d9fdaafb 4130 DRM_DEBUG_KMS("DFP3 connected\n");
771fe6b9
JG
4131 bios_0_scratch |= ATOM_S0_DFP3;
4132 bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
4133 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3;
4134 } else {
d9fdaafb 4135 DRM_DEBUG_KMS("DFP3 disconnected\n");
771fe6b9
JG
4136 bios_0_scratch &= ~ATOM_S0_DFP3;
4137 bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
4138 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3;
4139 }
4140 }
4141 if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) &&
4142 (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) {
4143 if (connected) {
d9fdaafb 4144 DRM_DEBUG_KMS("DFP4 connected\n");
771fe6b9
JG
4145 bios_0_scratch |= ATOM_S0_DFP4;
4146 bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;
4147 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4;
4148 } else {
d9fdaafb 4149 DRM_DEBUG_KMS("DFP4 disconnected\n");
771fe6b9
JG
4150 bios_0_scratch &= ~ATOM_S0_DFP4;
4151 bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;
4152 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4;
4153 }
4154 }
4155 if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) &&
4156 (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) {
4157 if (connected) {
d9fdaafb 4158 DRM_DEBUG_KMS("DFP5 connected\n");
771fe6b9
JG
4159 bios_0_scratch |= ATOM_S0_DFP5;
4160 bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;
4161 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5;
4162 } else {
d9fdaafb 4163 DRM_DEBUG_KMS("DFP5 disconnected\n");
771fe6b9
JG
4164 bios_0_scratch &= ~ATOM_S0_DFP5;
4165 bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;
4166 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;
4167 }
4168 }
6f9f8a61
AD
4169 if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&
4170 (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {
4171 if (connected) {
4172 DRM_DEBUG_KMS("DFP6 connected\n");
4173 bios_0_scratch |= ATOM_S0_DFP6;
4174 bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;
4175 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;
4176 } else {
4177 DRM_DEBUG_KMS("DFP6 disconnected\n");
4178 bios_0_scratch &= ~ATOM_S0_DFP6;
4179 bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;
4180 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;
4181 }
4182 }
771fe6b9
JG
4183
4184 if (rdev->family >= CHIP_R600) {
4185 WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch);
4186 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);
4187 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
4188 } else {
4189 WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
4190 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
4191 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
4192 }
4193}
4194
4195void
4196radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
4197{
4198 struct drm_device *dev = encoder->dev;
4199 struct radeon_device *rdev = dev->dev_private;
4200 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4201 uint32_t bios_3_scratch;
4202
6f9f8a61
AD
4203 if (ASIC_IS_DCE4(rdev))
4204 return;
4205
771fe6b9
JG
4206 if (rdev->family >= CHIP_R600)
4207 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
4208 else
4209 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);
4210
4211 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
4212 bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
4213 bios_3_scratch |= (crtc << 18);
4214 }
4215 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
4216 bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
4217 bios_3_scratch |= (crtc << 24);
4218 }
4219 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
4220 bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
4221 bios_3_scratch |= (crtc << 16);
4222 }
4223 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
4224 bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
4225 bios_3_scratch |= (crtc << 20);
4226 }
4227 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
4228 bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
4229 bios_3_scratch |= (crtc << 17);
4230 }
4231 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
4232 bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
4233 bios_3_scratch |= (crtc << 19);
4234 }
4235 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
4236 bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
4237 bios_3_scratch |= (crtc << 23);
4238 }
4239 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {
4240 bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
4241 bios_3_scratch |= (crtc << 25);
4242 }
4243
4244 if (rdev->family >= CHIP_R600)
4245 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);
4246 else
4247 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
4248}
4249
4250void
4251radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
4252{
4253 struct drm_device *dev = encoder->dev;
4254 struct radeon_device *rdev = dev->dev_private;
4255 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4256 uint32_t bios_2_scratch;
4257
3ac0eb6d
AD
4258 if (ASIC_IS_DCE4(rdev))
4259 return;
4260
771fe6b9
JG
4261 if (rdev->family >= CHIP_R600)
4262 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
4263 else
4264 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
4265
4266 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
4267 if (on)
4268 bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
4269 else
4270 bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
4271 }
4272 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
4273 if (on)
4274 bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
4275 else
4276 bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
4277 }
4278 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
4279 if (on)
4280 bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
4281 else
4282 bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
4283 }
4284 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
4285 if (on)
4286 bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
4287 else
4288 bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
4289 }
4290 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
4291 if (on)
4292 bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
4293 else
4294 bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
4295 }
4296 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
4297 if (on)
4298 bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
4299 else
4300 bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
4301 }
4302 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
4303 if (on)
4304 bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
4305 else
4306 bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
4307 }
4308 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {
4309 if (on)
4310 bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
4311 else
4312 bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
4313 }
4314 if (radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) {
4315 if (on)
4316 bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;
4317 else
4318 bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;
4319 }
4320 if (radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) {
4321 if (on)
4322 bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;
4323 else
4324 bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;
4325 }
4326
4327 if (rdev->family >= CHIP_R600)
4328 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
4329 else
4330 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
4331}
This page took 0.517733 seconds and 5 git commands to generate.