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