drm/radeon: clean up fujitsu quirks
[linux-2.6-block.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
ac4a9350
SG
1260 if (ASIC_IS_DCE8(rdev)) {
1261 rdev->clock.gpupll_outputfreq =
1262 le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq);
1263 if (rdev->clock.gpupll_outputfreq == 0)
1264 rdev->clock.gpupll_outputfreq = 360000; /* 3.6 GHz */
1265 }
1266
771fe6b9
JG
1267 return true;
1268 }
bcc1c2a1 1269
771fe6b9
JG
1270 return false;
1271}
1272
06b6476d
AD
1273union igp_info {
1274 struct _ATOM_INTEGRATED_SYSTEM_INFO info;
1275 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
3838f46e
AD
1276 struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
1277 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
c2037ad1 1278 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
06b6476d
AD
1279};
1280
1281bool radeon_atombios_sideport_present(struct radeon_device *rdev)
1282{
1283 struct radeon_mode_info *mode_info = &rdev->mode_info;
1284 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1285 union igp_info *igp_info;
1286 u8 frev, crev;
1287 u16 data_offset;
1288
4c70b2ea
AD
1289 /* sideport is AMD only */
1290 if (rdev->family == CHIP_RS600)
1291 return false;
1292
a084e6ee
AD
1293 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1294 &frev, &crev, &data_offset)) {
1295 igp_info = (union igp_info *)(mode_info->atom_context->bios +
06b6476d 1296 data_offset);
06b6476d
AD
1297 switch (crev) {
1298 case 1:
4589433c 1299 if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock))
4c70b2ea 1300 return true;
06b6476d
AD
1301 break;
1302 case 2:
4589433c 1303 if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock))
06b6476d
AD
1304 return true;
1305 break;
1306 default:
1307 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
1308 break;
1309 }
1310 }
1311 return false;
1312}
1313
445282db
DA
1314bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
1315 struct radeon_encoder_int_tmds *tmds)
771fe6b9
JG
1316{
1317 struct drm_device *dev = encoder->base.dev;
1318 struct radeon_device *rdev = dev->dev_private;
1319 struct radeon_mode_info *mode_info = &rdev->mode_info;
1320 int index = GetIndexIntoMasterTable(DATA, TMDS_Info);
1321 uint16_t data_offset;
1322 struct _ATOM_TMDS_INFO *tmds_info;
1323 uint8_t frev, crev;
1324 uint16_t maxfreq;
1325 int i;
771fe6b9 1326
a084e6ee
AD
1327 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1328 &frev, &crev, &data_offset)) {
1329 tmds_info =
1330 (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
1331 data_offset);
771fe6b9 1332
771fe6b9
JG
1333 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
1334 for (i = 0; i < 4; i++) {
1335 tmds->tmds_pll[i].freq =
1336 le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency);
1337 tmds->tmds_pll[i].value =
1338 tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f;
1339 tmds->tmds_pll[i].value |=
1340 (tmds_info->asMiscInfo[i].
1341 ucPLL_VCO_Gain & 0x3f) << 6;
1342 tmds->tmds_pll[i].value |=
1343 (tmds_info->asMiscInfo[i].
1344 ucPLL_DutyCycle & 0xf) << 12;
1345 tmds->tmds_pll[i].value |=
1346 (tmds_info->asMiscInfo[i].
1347 ucPLL_VoltageSwing & 0xf) << 16;
1348
d9fdaafb 1349 DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n",
771fe6b9
JG
1350 tmds->tmds_pll[i].freq,
1351 tmds->tmds_pll[i].value);
1352
1353 if (maxfreq == tmds->tmds_pll[i].freq) {
1354 tmds->tmds_pll[i].freq = 0xffffffff;
1355 break;
1356 }
1357 }
445282db 1358 return true;
771fe6b9 1359 }
445282db 1360 return false;
771fe6b9
JG
1361}
1362
ba032a58
AD
1363bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
1364 struct radeon_atom_ss *ss,
1365 int id)
ebbe1cb9 1366{
ebbe1cb9
AD
1367 struct radeon_mode_info *mode_info = &rdev->mode_info;
1368 int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info);
ba032a58 1369 uint16_t data_offset, size;
ebbe1cb9 1370 struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
a7ee824a 1371 struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign;
ebbe1cb9 1372 uint8_t frev, crev;
ba032a58 1373 int i, num_indices;
ebbe1cb9 1374
ba032a58
AD
1375 memset(ss, 0, sizeof(struct radeon_atom_ss));
1376 if (atom_parse_data_header(mode_info->atom_context, index, &size,
a084e6ee
AD
1377 &frev, &crev, &data_offset)) {
1378 ss_info =
1379 (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
ebbe1cb9 1380
ba032a58
AD
1381 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1382 sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT);
a7ee824a
AD
1383 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*)
1384 ((u8 *)&ss_info->asSS_Info[0]);
ba032a58 1385 for (i = 0; i < num_indices; i++) {
a7ee824a 1386 if (ss_assign->ucSS_Id == id) {
279b215e 1387 ss->percentage =
a7ee824a
AD
1388 le16_to_cpu(ss_assign->usSpreadSpectrumPercentage);
1389 ss->type = ss_assign->ucSpreadSpectrumType;
1390 ss->step = ss_assign->ucSS_Step;
1391 ss->delay = ss_assign->ucSS_Delay;
1392 ss->range = ss_assign->ucSS_Range;
1393 ss->refdiv = ss_assign->ucRecommendedRef_Div;
ba032a58
AD
1394 return true;
1395 }
a7ee824a
AD
1396 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*)
1397 ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT));
ba032a58
AD
1398 }
1399 }
1400 return false;
1401}
1402
4339c442
AD
1403static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev,
1404 struct radeon_atom_ss *ss,
1405 int id)
1406{
1407 struct radeon_mode_info *mode_info = &rdev->mode_info;
1408 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1409 u16 data_offset, size;
3838f46e 1410 union igp_info *igp_info;
4339c442
AD
1411 u8 frev, crev;
1412 u16 percentage = 0, rate = 0;
1413
1414 /* get any igp specific overrides */
1415 if (atom_parse_data_header(mode_info->atom_context, index, &size,
1416 &frev, &crev, &data_offset)) {
3838f46e 1417 igp_info = (union igp_info *)
4339c442 1418 (mode_info->atom_context->bios + data_offset);
3838f46e
AD
1419 switch (crev) {
1420 case 6:
1421 switch (id) {
1422 case ASIC_INTERNAL_SS_ON_TMDS:
1423 percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
1424 rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
1425 break;
1426 case ASIC_INTERNAL_SS_ON_HDMI:
1427 percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
1428 rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
1429 break;
1430 case ASIC_INTERNAL_SS_ON_LVDS:
1431 percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
1432 rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
1433 break;
1434 }
4339c442 1435 break;
3838f46e
AD
1436 case 7:
1437 switch (id) {
1438 case ASIC_INTERNAL_SS_ON_TMDS:
1439 percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
1440 rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
1441 break;
1442 case ASIC_INTERNAL_SS_ON_HDMI:
1443 percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
1444 rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
1445 break;
1446 case ASIC_INTERNAL_SS_ON_LVDS:
1447 percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
1448 rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
1449 break;
1450 }
4339c442 1451 break;
c2037ad1
AD
1452 case 8:
1453 switch (id) {
1454 case ASIC_INTERNAL_SS_ON_TMDS:
1455 percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);
1456 rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
1457 break;
1458 case ASIC_INTERNAL_SS_ON_HDMI:
1459 percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
1460 rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
1461 break;
1462 case ASIC_INTERNAL_SS_ON_LVDS:
1463 percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
1464 rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
1465 break;
1466 }
1467 break;
3838f46e
AD
1468 default:
1469 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
4339c442
AD
1470 break;
1471 }
1472 if (percentage)
1473 ss->percentage = percentage;
1474 if (rate)
1475 ss->rate = rate;
1476 }
1477}
1478
ba032a58
AD
1479union asic_ss_info {
1480 struct _ATOM_ASIC_INTERNAL_SS_INFO info;
1481 struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;
1482 struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3;
1483};
1484
a7ee824a
AD
1485union asic_ss_assignment {
1486 struct _ATOM_ASIC_SS_ASSIGNMENT v1;
1487 struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2;
1488 struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3;
1489};
1490
ba032a58
AD
1491bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
1492 struct radeon_atom_ss *ss,
1493 int id, u32 clock)
1494{
1495 struct radeon_mode_info *mode_info = &rdev->mode_info;
1496 int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
1497 uint16_t data_offset, size;
1498 union asic_ss_info *ss_info;
a7ee824a 1499 union asic_ss_assignment *ss_assign;
ba032a58
AD
1500 uint8_t frev, crev;
1501 int i, num_indices;
1502
9cb84ab0
AD
1503 if (id == ASIC_INTERNAL_MEMORY_SS) {
1504 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT))
1505 return false;
1506 }
1507 if (id == ASIC_INTERNAL_ENGINE_SS) {
1508 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT))
1509 return false;
1510 }
1511
ba032a58
AD
1512 memset(ss, 0, sizeof(struct radeon_atom_ss));
1513 if (atom_parse_data_header(mode_info->atom_context, index, &size,
1514 &frev, &crev, &data_offset)) {
1515
1516 ss_info =
1517 (union asic_ss_info *)(mode_info->atom_context->bios + data_offset);
1518
1519 switch (frev) {
1520 case 1:
1521 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1522 sizeof(ATOM_ASIC_SS_ASSIGNMENT);
1523
a7ee824a 1524 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]);
ba032a58 1525 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1526 if ((ss_assign->v1.ucClockIndication == id) &&
1527 (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) {
ba032a58 1528 ss->percentage =
a7ee824a
AD
1529 le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
1530 ss->type = ss_assign->v1.ucSpreadSpectrumMode;
1531 ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
18f8f52b 1532 ss->percentage_divider = 100;
ba032a58
AD
1533 return true;
1534 }
a7ee824a
AD
1535 ss_assign = (union asic_ss_assignment *)
1536 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT));
279b215e 1537 }
ba032a58
AD
1538 break;
1539 case 2:
1540 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1541 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
a7ee824a 1542 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]);
ba032a58 1543 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1544 if ((ss_assign->v2.ucClockIndication == id) &&
1545 (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) {
ba032a58 1546 ss->percentage =
a7ee824a
AD
1547 le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
1548 ss->type = ss_assign->v2.ucSpreadSpectrumMode;
1549 ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
18f8f52b 1550 ss->percentage_divider = 100;
ae5b0abb
AD
1551 if ((crev == 2) &&
1552 ((id == ASIC_INTERNAL_ENGINE_SS) ||
1553 (id == ASIC_INTERNAL_MEMORY_SS)))
1554 ss->rate /= 100;
ba032a58
AD
1555 return true;
1556 }
a7ee824a
AD
1557 ss_assign = (union asic_ss_assignment *)
1558 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2));
ba032a58
AD
1559 }
1560 break;
1561 case 3:
1562 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
1563 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
a7ee824a 1564 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]);
ba032a58 1565 for (i = 0; i < num_indices; i++) {
a7ee824a
AD
1566 if ((ss_assign->v3.ucClockIndication == id) &&
1567 (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) {
ba032a58 1568 ss->percentage =
a7ee824a
AD
1569 le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
1570 ss->type = ss_assign->v3.ucSpreadSpectrumMode;
1571 ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
18f8f52b
AD
1572 if (ss_assign->v3.ucSpreadSpectrumMode &
1573 SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)
1574 ss->percentage_divider = 1000;
1575 else
1576 ss->percentage_divider = 100;
ae5b0abb
AD
1577 if ((id == ASIC_INTERNAL_ENGINE_SS) ||
1578 (id == ASIC_INTERNAL_MEMORY_SS))
1579 ss->rate /= 100;
4339c442
AD
1580 if (rdev->flags & RADEON_IS_IGP)
1581 radeon_atombios_get_igp_ss_overrides(rdev, ss, id);
ba032a58
AD
1582 return true;
1583 }
a7ee824a
AD
1584 ss_assign = (union asic_ss_assignment *)
1585 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3));
ba032a58
AD
1586 }
1587 break;
1588 default:
1589 DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev);
1590 break;
279b215e 1591 }
ba032a58 1592
ebbe1cb9 1593 }
ba032a58 1594 return false;
ebbe1cb9
AD
1595}
1596
771fe6b9
JG
1597union lvds_info {
1598 struct _ATOM_LVDS_INFO info;
1599 struct _ATOM_LVDS_INFO_V12 info_12;
1600};
1601
1602struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
1603 radeon_encoder
1604 *encoder)
1605{
1606 struct drm_device *dev = encoder->base.dev;
1607 struct radeon_device *rdev = dev->dev_private;
1608 struct radeon_mode_info *mode_info = &rdev->mode_info;
1609 int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
7dde8a19 1610 uint16_t data_offset, misc;
771fe6b9
JG
1611 union lvds_info *lvds_info;
1612 uint8_t frev, crev;
1613 struct radeon_encoder_atom_dig *lvds = NULL;
5137ee94 1614 int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
771fe6b9 1615
a084e6ee
AD
1616 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1617 &frev, &crev, &data_offset)) {
1618 lvds_info =
1619 (union lvds_info *)(mode_info->atom_context->bios + data_offset);
771fe6b9
JG
1620 lvds =
1621 kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
1622
1623 if (!lvds)
1624 return NULL;
1625
de2103e4 1626 lvds->native_mode.clock =
771fe6b9 1627 le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
de2103e4 1628 lvds->native_mode.hdisplay =
771fe6b9 1629 le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
de2103e4 1630 lvds->native_mode.vdisplay =
771fe6b9 1631 le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
de2103e4
AD
1632 lvds->native_mode.htotal = lvds->native_mode.hdisplay +
1633 le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
1634 lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
1635 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
1636 lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
1637 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
1638 lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
1639 le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
1640 lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
1ff26a36 1641 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
de2103e4
AD
1642 lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
1643 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
771fe6b9
JG
1644 lvds->panel_pwr_delay =
1645 le16_to_cpu(lvds_info->info.usOffDelayInMs);
ba032a58 1646 lvds->lcd_misc = lvds_info->info.ucLVDS_Misc;
7dde8a19
AD
1647
1648 misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
1649 if (misc & ATOM_VSYNC_POLARITY)
1650 lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
1651 if (misc & ATOM_HSYNC_POLARITY)
1652 lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
1653 if (misc & ATOM_COMPOSITESYNC)
1654 lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
1655 if (misc & ATOM_INTERLACE)
1656 lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
1657 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1658 lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
1659
4589433c
CC
1660 lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize);
1661 lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize);
7a868e18 1662
de2103e4
AD
1663 /* set crtc values */
1664 drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
771fe6b9 1665
ba032a58 1666 lvds->lcd_ss_id = lvds_info->info.ucSS_Id;
ebbe1cb9 1667
771fe6b9 1668 encoder->native_mode = lvds->native_mode;
5137ee94
AD
1669
1670 if (encoder_enum == 2)
1671 lvds->linkb = true;
1672 else
1673 lvds->linkb = false;
1674
c324acd5 1675 /* parse the lcd record table */
4589433c 1676 if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) {
c324acd5
AD
1677 ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;
1678 ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;
1679 bool bad_record = false;
05fa7ea7
AD
1680 u8 *record;
1681
1682 if ((frev == 1) && (crev < 2))
1683 /* absolute */
1684 record = (u8 *)(mode_info->atom_context->bios +
1685 le16_to_cpu(lvds_info->info.usModePatchTableOffset));
1686 else
1687 /* relative */
1688 record = (u8 *)(mode_info->atom_context->bios +
1689 data_offset +
1690 le16_to_cpu(lvds_info->info.usModePatchTableOffset));
c324acd5
AD
1691 while (*record != ATOM_RECORD_END_TYPE) {
1692 switch (*record) {
1693 case LCD_MODE_PATCH_RECORD_MODE_TYPE:
1694 record += sizeof(ATOM_PATCH_RECORD_MODE);
1695 break;
1696 case LCD_RTS_RECORD_TYPE:
1697 record += sizeof(ATOM_LCD_RTS_RECORD);
1698 break;
1699 case LCD_CAP_RECORD_TYPE:
1700 record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);
1701 break;
1702 case LCD_FAKE_EDID_PATCH_RECORD_TYPE:
1703 fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
1704 if (fake_edid_record->ucFakeEDIDLength) {
1705 struct edid *edid;
1706 int edid_size =
1707 max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
1708 edid = kmalloc(edid_size, GFP_KERNEL);
1709 if (edid) {
1710 memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
1711 fake_edid_record->ucFakeEDIDLength);
1712
eaa4f5e1 1713 if (drm_edid_is_valid(edid)) {
c324acd5 1714 rdev->mode_info.bios_hardcoded_edid = edid;
eaa4f5e1
DA
1715 rdev->mode_info.bios_hardcoded_edid_size = edid_size;
1716 } else
c324acd5
AD
1717 kfree(edid);
1718 }
1719 }
95663948
AD
1720 record += fake_edid_record->ucFakeEDIDLength ?
1721 fake_edid_record->ucFakeEDIDLength + 2 :
1722 sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
c324acd5
AD
1723 break;
1724 case LCD_PANEL_RESOLUTION_RECORD_TYPE:
1725 panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
1726 lvds->native_mode.width_mm = panel_res_record->usHSize;
1727 lvds->native_mode.height_mm = panel_res_record->usVSize;
1728 record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
1729 break;
1730 default:
1731 DRM_ERROR("Bad LCD record %d\n", *record);
1732 bad_record = true;
1733 break;
1734 }
1735 if (bad_record)
1736 break;
1737 }
1738 }
771fe6b9
JG
1739 }
1740 return lvds;
1741}
1742
6fe7ac3f
AD
1743struct radeon_encoder_primary_dac *
1744radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
1745{
1746 struct drm_device *dev = encoder->base.dev;
1747 struct radeon_device *rdev = dev->dev_private;
1748 struct radeon_mode_info *mode_info = &rdev->mode_info;
1749 int index = GetIndexIntoMasterTable(DATA, CompassionateData);
1750 uint16_t data_offset;
1751 struct _COMPASSIONATE_DATA *dac_info;
1752 uint8_t frev, crev;
1753 uint8_t bg, dac;
6fe7ac3f
AD
1754 struct radeon_encoder_primary_dac *p_dac = NULL;
1755
a084e6ee
AD
1756 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1757 &frev, &crev, &data_offset)) {
1758 dac_info = (struct _COMPASSIONATE_DATA *)
1759 (mode_info->atom_context->bios + data_offset);
6fe7ac3f 1760
6fe7ac3f
AD
1761 p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
1762
1763 if (!p_dac)
1764 return NULL;
1765
1766 bg = dac_info->ucDAC1_BG_Adjustment;
1767 dac = dac_info->ucDAC1_DAC_Adjustment;
1768 p_dac->ps2_pdac_adj = (bg << 8) | (dac);
1769
1770 }
1771 return p_dac;
1772}
1773
4ce001ab 1774bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
5a9bcacc 1775 struct drm_display_mode *mode)
4ce001ab
DA
1776{
1777 struct radeon_mode_info *mode_info = &rdev->mode_info;
1778 ATOM_ANALOG_TV_INFO *tv_info;
1779 ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;
1780 ATOM_DTD_FORMAT *dtd_timings;
1781 int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
1782 u8 frev, crev;
5a9bcacc 1783 u16 data_offset, misc;
4ce001ab 1784
a084e6ee
AD
1785 if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
1786 &frev, &crev, &data_offset))
1787 return false;
4ce001ab
DA
1788
1789 switch (crev) {
1790 case 1:
1791 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
0031c41b 1792 if (index >= MAX_SUPPORTED_TV_TIMING)
4ce001ab
DA
1793 return false;
1794
5a9bcacc
AD
1795 mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
1796 mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
1797 mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
1798 mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
1799 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
1800
1801 mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
1802 mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
1803 mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
1804 mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
1805 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
1806
1807 mode->flags = 0;
1808 misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
1809 if (misc & ATOM_VSYNC_POLARITY)
1810 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1811 if (misc & ATOM_HSYNC_POLARITY)
1812 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1813 if (misc & ATOM_COMPOSITESYNC)
1814 mode->flags |= DRM_MODE_FLAG_CSYNC;
1815 if (misc & ATOM_INTERLACE)
1816 mode->flags |= DRM_MODE_FLAG_INTERLACE;
1817 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1818 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1819
265d09aa
VS
1820 mode->crtc_clock = mode->clock =
1821 le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
4ce001ab
DA
1822
1823 if (index == 1) {
1824 /* PAL timings appear to have wrong values for totals */
5a9bcacc
AD
1825 mode->crtc_htotal -= 1;
1826 mode->crtc_vtotal -= 1;
4ce001ab
DA
1827 }
1828 break;
1829 case 2:
1830 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
0031c41b 1831 if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
4ce001ab
DA
1832 return false;
1833
1834 dtd_timings = &tv_info_v1_2->aModeTimings[index];
5a9bcacc
AD
1835 mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) +
1836 le16_to_cpu(dtd_timings->usHBlanking_Time);
1837 mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive);
1838 mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) +
1839 le16_to_cpu(dtd_timings->usHSyncOffset);
1840 mode->crtc_hsync_end = mode->crtc_hsync_start +
1841 le16_to_cpu(dtd_timings->usHSyncWidth);
1842
1843 mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) +
1844 le16_to_cpu(dtd_timings->usVBlanking_Time);
1845 mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive);
1846 mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) +
1847 le16_to_cpu(dtd_timings->usVSyncOffset);
1848 mode->crtc_vsync_end = mode->crtc_vsync_start +
1849 le16_to_cpu(dtd_timings->usVSyncWidth);
1850
1851 mode->flags = 0;
1852 misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
1853 if (misc & ATOM_VSYNC_POLARITY)
1854 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1855 if (misc & ATOM_HSYNC_POLARITY)
1856 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1857 if (misc & ATOM_COMPOSITESYNC)
1858 mode->flags |= DRM_MODE_FLAG_CSYNC;
1859 if (misc & ATOM_INTERLACE)
1860 mode->flags |= DRM_MODE_FLAG_INTERLACE;
1861 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1862 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1863
265d09aa
VS
1864 mode->crtc_clock = mode->clock =
1865 le16_to_cpu(dtd_timings->usPixClk) * 10;
4ce001ab
DA
1866 break;
1867 }
1868 return true;
1869}
1870
d79766fa
AD
1871enum radeon_tv_std
1872radeon_atombios_get_tv_info(struct radeon_device *rdev)
1873{
1874 struct radeon_mode_info *mode_info = &rdev->mode_info;
1875 int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
1876 uint16_t data_offset;
1877 uint8_t frev, crev;
1878 struct _ATOM_ANALOG_TV_INFO *tv_info;
1879 enum radeon_tv_std tv_std = TV_STD_NTSC;
1880
a084e6ee
AD
1881 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1882 &frev, &crev, &data_offset)) {
d79766fa 1883
a084e6ee
AD
1884 tv_info = (struct _ATOM_ANALOG_TV_INFO *)
1885 (mode_info->atom_context->bios + data_offset);
d79766fa 1886
a084e6ee
AD
1887 switch (tv_info->ucTV_BootUpDefaultStandard) {
1888 case ATOM_TV_NTSC:
1889 tv_std = TV_STD_NTSC;
40f76d81 1890 DRM_DEBUG_KMS("Default TV standard: NTSC\n");
a084e6ee
AD
1891 break;
1892 case ATOM_TV_NTSCJ:
1893 tv_std = TV_STD_NTSC_J;
40f76d81 1894 DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
a084e6ee
AD
1895 break;
1896 case ATOM_TV_PAL:
1897 tv_std = TV_STD_PAL;
40f76d81 1898 DRM_DEBUG_KMS("Default TV standard: PAL\n");
a084e6ee
AD
1899 break;
1900 case ATOM_TV_PALM:
1901 tv_std = TV_STD_PAL_M;
40f76d81 1902 DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
a084e6ee
AD
1903 break;
1904 case ATOM_TV_PALN:
1905 tv_std = TV_STD_PAL_N;
40f76d81 1906 DRM_DEBUG_KMS("Default TV standard: PAL-N\n");
a084e6ee
AD
1907 break;
1908 case ATOM_TV_PALCN:
1909 tv_std = TV_STD_PAL_CN;
40f76d81 1910 DRM_DEBUG_KMS("Default TV standard: PAL-CN\n");
a084e6ee
AD
1911 break;
1912 case ATOM_TV_PAL60:
1913 tv_std = TV_STD_PAL_60;
40f76d81 1914 DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
a084e6ee
AD
1915 break;
1916 case ATOM_TV_SECAM:
1917 tv_std = TV_STD_SECAM;
40f76d81 1918 DRM_DEBUG_KMS("Default TV standard: SECAM\n");
a084e6ee
AD
1919 break;
1920 default:
1921 tv_std = TV_STD_NTSC;
40f76d81 1922 DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n");
a084e6ee
AD
1923 break;
1924 }
d79766fa
AD
1925 }
1926 return tv_std;
1927}
1928
6fe7ac3f
AD
1929struct radeon_encoder_tv_dac *
1930radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
1931{
1932 struct drm_device *dev = encoder->base.dev;
1933 struct radeon_device *rdev = dev->dev_private;
1934 struct radeon_mode_info *mode_info = &rdev->mode_info;
1935 int index = GetIndexIntoMasterTable(DATA, CompassionateData);
1936 uint16_t data_offset;
1937 struct _COMPASSIONATE_DATA *dac_info;
1938 uint8_t frev, crev;
1939 uint8_t bg, dac;
6fe7ac3f
AD
1940 struct radeon_encoder_tv_dac *tv_dac = NULL;
1941
a084e6ee
AD
1942 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1943 &frev, &crev, &data_offset)) {
6fe7ac3f 1944
a084e6ee
AD
1945 dac_info = (struct _COMPASSIONATE_DATA *)
1946 (mode_info->atom_context->bios + data_offset);
6fe7ac3f 1947
6fe7ac3f
AD
1948 tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
1949
1950 if (!tv_dac)
1951 return NULL;
1952
1953 bg = dac_info->ucDAC2_CRT2_BG_Adjustment;
1954 dac = dac_info->ucDAC2_CRT2_DAC_Adjustment;
1955 tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
1956
1957 bg = dac_info->ucDAC2_PAL_BG_Adjustment;
1958 dac = dac_info->ucDAC2_PAL_DAC_Adjustment;
1959 tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
1960
1961 bg = dac_info->ucDAC2_NTSC_BG_Adjustment;
1962 dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;
1963 tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
1964
d79766fa 1965 tv_dac->tv_std = radeon_atombios_get_tv_info(rdev);
6fe7ac3f
AD
1966 }
1967 return tv_dac;
1968}
1969
29fb52ca
AD
1970static const char *thermal_controller_names[] = {
1971 "NONE",
678e7dfa
AD
1972 "lm63",
1973 "adm1032",
1974 "adm1030",
1975 "max6649",
5dc35532 1976 "lm63", /* lm64 */
678e7dfa
AD
1977 "f75375",
1978 "asc7xxx",
29fb52ca
AD
1979};
1980
1981static const char *pp_lib_thermal_controller_names[] = {
1982 "NONE",
678e7dfa
AD
1983 "lm63",
1984 "adm1032",
1985 "adm1030",
1986 "max6649",
5dc35532 1987 "lm63", /* lm64 */
678e7dfa 1988 "f75375",
29fb52ca
AD
1989 "RV6xx",
1990 "RV770",
678e7dfa 1991 "adt7473",
560154e9 1992 "NONE",
49f65982
AD
1993 "External GPIO",
1994 "Evergreen",
b0e66414
AD
1995 "emc2103",
1996 "Sumo",
4fddba1f 1997 "Northern Islands",
14607d08
AD
1998 "Southern Islands",
1999 "lm96163",
51150207 2000 "Sea Islands",
29fb52ca
AD
2001};
2002
56278a8e
AD
2003union power_info {
2004 struct _ATOM_POWERPLAY_INFO info;
2005 struct _ATOM_POWERPLAY_INFO_V2 info_2;
2006 struct _ATOM_POWERPLAY_INFO_V3 info_3;
560154e9 2007 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
b0e66414
AD
2008 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
2009 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
56278a8e
AD
2010};
2011
560154e9
AD
2012union pplib_clock_info {
2013 struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
2014 struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
2015 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
b0e66414 2016 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
14607d08 2017 struct _ATOM_PPLIB_SI_CLOCK_INFO si;
bc19f597 2018 struct _ATOM_PPLIB_CI_CLOCK_INFO ci;
560154e9
AD
2019};
2020
2021union pplib_power_state {
2022 struct _ATOM_PPLIB_STATE v1;
2023 struct _ATOM_PPLIB_STATE_V2 v2;
2024};
2025
2026static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev,
2027 int state_index,
2028 u32 misc, u32 misc2)
2029{
2030 rdev->pm.power_state[state_index].misc = misc;
2031 rdev->pm.power_state[state_index].misc2 = misc2;
2032 /* order matters! */
2033 if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
2034 rdev->pm.power_state[state_index].type =
2035 POWER_STATE_TYPE_POWERSAVE;
2036 if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
2037 rdev->pm.power_state[state_index].type =
2038 POWER_STATE_TYPE_BATTERY;
2039 if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
2040 rdev->pm.power_state[state_index].type =
2041 POWER_STATE_TYPE_BATTERY;
2042 if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
2043 rdev->pm.power_state[state_index].type =
2044 POWER_STATE_TYPE_BALANCED;
2045 if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
2046 rdev->pm.power_state[state_index].type =
2047 POWER_STATE_TYPE_PERFORMANCE;
2048 rdev->pm.power_state[state_index].flags &=
2049 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2050 }
2051 if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
2052 rdev->pm.power_state[state_index].type =
2053 POWER_STATE_TYPE_BALANCED;
2054 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
2055 rdev->pm.power_state[state_index].type =
2056 POWER_STATE_TYPE_DEFAULT;
2057 rdev->pm.default_power_state_index = state_index;
2058 rdev->pm.power_state[state_index].default_clock_mode =
2059 &rdev->pm.power_state[state_index].clock_info[0];
2060 } else if (state_index == 0) {
2061 rdev->pm.power_state[state_index].clock_info[0].flags |=
2062 RADEON_PM_MODE_NO_DISPLAY;
2063 }
2064}
2065
2066static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
771fe6b9 2067{
56278a8e 2068 struct radeon_mode_info *mode_info = &rdev->mode_info;
560154e9
AD
2069 u32 misc, misc2 = 0;
2070 int num_modes = 0, i;
2071 int state_index = 0;
2072 struct radeon_i2c_bus_rec i2c_bus;
2073 union power_info *power_info;
56278a8e 2074 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
560154e9 2075 u16 data_offset;
56278a8e 2076 u8 frev, crev;
771fe6b9 2077
560154e9
AD
2078 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2079 &frev, &crev, &data_offset))
2080 return state_index;
2081 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2082
2083 /* add the i2c bus for thermal/fan chip */
4755fab5
AD
2084 if ((power_info->info.ucOverdriveThermalController > 0) &&
2085 (power_info->info.ucOverdriveThermalController < ARRAY_SIZE(thermal_controller_names))) {
560154e9
AD
2086 DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2087 thermal_controller_names[power_info->info.ucOverdriveThermalController],
2088 power_info->info.ucOverdriveControllerAddress >> 1);
2089 i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
2090 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2091 if (rdev->pm.i2c_bus) {
2092 struct i2c_board_info info = { };
2093 const char *name = thermal_controller_names[power_info->info.
2094 ucOverdriveThermalController];
2095 info.addr = power_info->info.ucOverdriveControllerAddress >> 1;
2096 strlcpy(info.type, name, sizeof(info.type));
2097 i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
2098 }
2099 }
2100 num_modes = power_info->info.ucNumOfPowerModeEntries;
2101 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
2102 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
f8e6bfc2
AD
2103 if (num_modes == 0)
2104 return state_index;
0975b162
AD
2105 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
2106 if (!rdev->pm.power_state)
2107 return state_index;
560154e9
AD
2108 /* last mode is usually default, array is low to high */
2109 for (i = 0; i < num_modes; i++) {
6991b8f2
AD
2110 rdev->pm.power_state[state_index].clock_info =
2111 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2112 if (!rdev->pm.power_state[state_index].clock_info)
2113 return state_index;
2114 rdev->pm.power_state[state_index].num_clock_modes = 1;
560154e9
AD
2115 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2116 switch (frev) {
2117 case 1:
560154e9
AD
2118 rdev->pm.power_state[state_index].clock_info[0].mclk =
2119 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
2120 rdev->pm.power_state[state_index].clock_info[0].sclk =
2121 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock);
2122 /* skip invalid modes */
2123 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2124 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2125 continue;
2126 rdev->pm.power_state[state_index].pcie_lanes =
2127 power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
2128 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
2129 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2130 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2131 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2132 VOLTAGE_GPIO;
2133 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
09e619c0 2134 radeon_atombios_lookup_gpio(rdev,
560154e9
AD
2135 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);
2136 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2137 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2138 true;
2139 else
2140 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2141 false;
2142 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2143 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2144 VOLTAGE_VDDC;
2145 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2146 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
29fb52ca 2147 }
560154e9
AD
2148 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2149 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0);
2150 state_index++;
2151 break;
2152 case 2:
560154e9
AD
2153 rdev->pm.power_state[state_index].clock_info[0].mclk =
2154 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
2155 rdev->pm.power_state[state_index].clock_info[0].sclk =
2156 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock);
2157 /* skip invalid modes */
2158 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2159 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2160 continue;
2161 rdev->pm.power_state[state_index].pcie_lanes =
2162 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
2163 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
2164 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
2165 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2166 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2167 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2168 VOLTAGE_GPIO;
2169 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
09e619c0 2170 radeon_atombios_lookup_gpio(rdev,
560154e9
AD
2171 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);
2172 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2173 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2174 true;
2175 else
2176 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2177 false;
2178 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2179 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2180 VOLTAGE_VDDC;
2181 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2182 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
56278a8e 2183 }
560154e9
AD
2184 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2185 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
2186 state_index++;
2187 break;
2188 case 3:
560154e9
AD
2189 rdev->pm.power_state[state_index].clock_info[0].mclk =
2190 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
2191 rdev->pm.power_state[state_index].clock_info[0].sclk =
2192 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock);
2193 /* skip invalid modes */
2194 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2195 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2196 continue;
2197 rdev->pm.power_state[state_index].pcie_lanes =
2198 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
2199 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
2200 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
2201 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
2202 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
2203 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2204 VOLTAGE_GPIO;
2205 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
09e619c0 2206 radeon_atombios_lookup_gpio(rdev,
560154e9
AD
2207 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);
2208 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
2209 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2210 true;
2211 else
2212 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2213 false;
2214 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
2215 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
2216 VOLTAGE_VDDC;
2217 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
2218 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex;
2219 if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) {
2220 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled =
2221 true;
2222 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id =
2223 power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;
2224 }
02b17cc0 2225 }
560154e9
AD
2226 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2227 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
2228 state_index++;
2229 break;
2230 }
2231 }
2232 /* last mode is usually default */
2233 if (rdev->pm.default_power_state_index == -1) {
2234 rdev->pm.power_state[state_index - 1].type =
2235 POWER_STATE_TYPE_DEFAULT;
2236 rdev->pm.default_power_state_index = state_index - 1;
2237 rdev->pm.power_state[state_index - 1].default_clock_mode =
2238 &rdev->pm.power_state[state_index - 1].clock_info[0];
2239 rdev->pm.power_state[state_index].flags &=
2240 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2241 rdev->pm.power_state[state_index].misc = 0;
2242 rdev->pm.power_state[state_index].misc2 = 0;
2243 }
2244 return state_index;
2245}
2246
2247static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev,
2248 ATOM_PPLIB_THERMALCONTROLLER *controller)
2249{
2250 struct radeon_i2c_bus_rec i2c_bus;
2251
2252 /* add the i2c bus for thermal/fan chip */
2253 if (controller->ucType > 0) {
9b92d1ec
AD
2254 if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
2255 rdev->pm.no_fan = true;
2256 rdev->pm.fan_pulses_per_revolution =
2257 controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
2258 if (rdev->pm.fan_pulses_per_revolution) {
2259 rdev->pm.fan_min_rpm = controller->ucFanMinRPM;
2260 rdev->pm.fan_max_rpm = controller->ucFanMaxRPM;
2261 }
560154e9
AD
2262 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
2263 DRM_INFO("Internal thermal controller %s fan control\n",
2264 (controller->ucFanParameters &
2265 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2266 rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
2267 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
2268 DRM_INFO("Internal thermal controller %s fan control\n",
2269 (controller->ucFanParameters &
2270 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2271 rdev->pm.int_thermal_type = THERMAL_TYPE_RV770;
2272 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
2273 DRM_INFO("Internal thermal controller %s fan control\n",
2274 (controller->ucFanParameters &
2275 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2276 rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
b0e66414
AD
2277 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
2278 DRM_INFO("Internal thermal controller %s fan control\n",
2279 (controller->ucFanParameters &
2280 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2281 rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
4fddba1f
AD
2282 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
2283 DRM_INFO("Internal thermal controller %s fan control\n",
2284 (controller->ucFanParameters &
2285 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2286 rdev->pm.int_thermal_type = THERMAL_TYPE_NI;
14607d08
AD
2287 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
2288 DRM_INFO("Internal thermal controller %s fan control\n",
2289 (controller->ucFanParameters &
2290 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2291 rdev->pm.int_thermal_type = THERMAL_TYPE_SI;
51150207
AD
2292 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
2293 DRM_INFO("Internal thermal controller %s fan control\n",
2294 (controller->ucFanParameters &
2295 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2296 rdev->pm.int_thermal_type = THERMAL_TYPE_CI;
16fbe00d
AD
2297 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
2298 DRM_INFO("Internal thermal controller %s fan control\n",
2299 (controller->ucFanParameters &
2300 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2301 rdev->pm.int_thermal_type = THERMAL_TYPE_KV;
ff437792
AD
2302 } else if (controller->ucType ==
2303 ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {
2304 DRM_INFO("External GPIO thermal controller %s fan control\n",
2305 (controller->ucFanParameters &
2306 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2307 rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;
2308 } else if (controller->ucType ==
2309 ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {
2310 DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",
2311 (controller->ucFanParameters &
2312 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2313 rdev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;
2314 } else if (controller->ucType ==
2315 ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
2316 DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",
2317 (controller->ucFanParameters &
2318 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
2319 rdev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;
4755fab5 2320 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
560154e9
AD
2321 DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
2322 pp_lib_thermal_controller_names[controller->ucType],
2323 controller->ucI2cAddress >> 1,
2324 (controller->ucFanParameters &
2325 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
ff437792 2326 rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;
560154e9
AD
2327 i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine);
2328 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2329 if (rdev->pm.i2c_bus) {
2330 struct i2c_board_info info = { };
2331 const char *name = pp_lib_thermal_controller_names[controller->ucType];
2332 info.addr = controller->ucI2cAddress >> 1;
2333 strlcpy(info.type, name, sizeof(info.type));
2334 i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
c5e8ce61 2335 }
4755fab5
AD
2336 } else {
2337 DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
2338 controller->ucType,
2339 controller->ucI2cAddress >> 1,
2340 (controller->ucFanParameters &
2341 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
560154e9
AD
2342 }
2343 }
2344}
c5e8ce61 2345
4a6369e9 2346void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
2abba66e 2347 u16 *vddc, u16 *vddci, u16 *mvdd)
560154e9
AD
2348{
2349 struct radeon_mode_info *mode_info = &rdev->mode_info;
2350 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
2351 u8 frev, crev;
2352 u16 data_offset;
2353 union firmware_info *firmware_info;
2feea49a
AD
2354
2355 *vddc = 0;
2356 *vddci = 0;
2abba66e 2357 *mvdd = 0;
678e7dfa 2358
560154e9
AD
2359 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2360 &frev, &crev, &data_offset)) {
2361 firmware_info =
2362 (union firmware_info *)(mode_info->atom_context->bios +
2363 data_offset);
2feea49a 2364 *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
2abba66e 2365 if ((frev == 2) && (crev >= 2)) {
2feea49a 2366 *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
2abba66e
AD
2367 *mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
2368 }
560154e9 2369 }
560154e9
AD
2370}
2371
2372static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
2373 int state_index, int mode_index,
2374 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info)
2375{
2376 int j;
2377 u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
2378 u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
2abba66e 2379 u16 vddc, vddci, mvdd;
2feea49a 2380
2abba66e 2381 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
560154e9
AD
2382
2383 rdev->pm.power_state[state_index].misc = misc;
2384 rdev->pm.power_state[state_index].misc2 = misc2;
2385 rdev->pm.power_state[state_index].pcie_lanes =
2386 ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>
2387 ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
2388 switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
2389 case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
2390 rdev->pm.power_state[state_index].type =
2391 POWER_STATE_TYPE_BATTERY;
2392 break;
2393 case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
2394 rdev->pm.power_state[state_index].type =
2395 POWER_STATE_TYPE_BALANCED;
2396 break;
2397 case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
2398 rdev->pm.power_state[state_index].type =
2399 POWER_STATE_TYPE_PERFORMANCE;
2400 break;
2401 case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
2402 if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
2403 rdev->pm.power_state[state_index].type =
2404 POWER_STATE_TYPE_PERFORMANCE;
2405 break;
2406 }
2407 rdev->pm.power_state[state_index].flags = 0;
2408 if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
2409 rdev->pm.power_state[state_index].flags |=
2410 RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
2411 if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {
2412 rdev->pm.power_state[state_index].type =
2413 POWER_STATE_TYPE_DEFAULT;
2414 rdev->pm.default_power_state_index = state_index;
2415 rdev->pm.power_state[state_index].default_clock_mode =
2416 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
982cb329 2417 if ((rdev->family >= CHIP_BARTS) && !(rdev->flags & RADEON_IS_IGP)) {
9ace9f7b
AD
2418 /* NI chips post without MC ucode, so default clocks are strobe mode only */
2419 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2420 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
2421 rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
2feea49a 2422 rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
9ace9f7b 2423 } else {
ae5b0abb
AD
2424 u16 max_vddci = 0;
2425
2426 if (ASIC_IS_DCE4(rdev))
2427 radeon_atom_get_max_voltage(rdev,
2428 SET_VOLTAGE_TYPE_ASIC_VDDCI,
2429 &max_vddci);
2430 /* patch the table values with the default sclk/mclk from firmware info */
9ace9f7b
AD
2431 for (j = 0; j < mode_index; j++) {
2432 rdev->pm.power_state[state_index].clock_info[j].mclk =
2433 rdev->clock.default_mclk;
2434 rdev->pm.power_state[state_index].clock_info[j].sclk =
2435 rdev->clock.default_sclk;
2436 if (vddc)
2437 rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
2438 vddc;
ae5b0abb
AD
2439 if (max_vddci)
2440 rdev->pm.power_state[state_index].clock_info[j].voltage.vddci =
2441 max_vddci;
9ace9f7b 2442 }
560154e9
AD
2443 }
2444 }
2445}
2446
2447static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
2448 int state_index, int mode_index,
2449 union pplib_clock_info *clock_info)
2450{
2451 u32 sclk, mclk;
e83753bb 2452 u16 vddc;
560154e9
AD
2453
2454 if (rdev->flags & RADEON_IS_IGP) {
b0e66414
AD
2455 if (rdev->family >= CHIP_PALM) {
2456 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
2457 sclk |= clock_info->sumo.ucEngineClockHigh << 16;
2458 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2459 } else {
2460 sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
2461 sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
2462 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2463 }
bc19f597
AD
2464 } else if (rdev->family >= CHIP_BONAIRE) {
2465 sclk = le16_to_cpu(clock_info->ci.usEngineClockLow);
2466 sclk |= clock_info->ci.ucEngineClockHigh << 16;
2467 mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow);
2468 mclk |= clock_info->ci.ucMemoryClockHigh << 16;
2469 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2470 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2471 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2472 VOLTAGE_NONE;
982cb329 2473 } else if (rdev->family >= CHIP_TAHITI) {
14607d08
AD
2474 sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
2475 sclk |= clock_info->si.ucEngineClockHigh << 16;
2476 mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
2477 mclk |= clock_info->si.ucMemoryClockHigh << 16;
2478 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2479 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2480 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2481 VOLTAGE_SW;
2482 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
2483 le16_to_cpu(clock_info->si.usVDDC);
2484 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2485 le16_to_cpu(clock_info->si.usVDDCI);
982cb329 2486 } else if (rdev->family >= CHIP_CEDAR) {
560154e9
AD
2487 sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
2488 sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
2489 mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
2490 mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
2491 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2492 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2493 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2494 VOLTAGE_SW;
2495 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
4589433c 2496 le16_to_cpu(clock_info->evergreen.usVDDC);
2feea49a
AD
2497 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2498 le16_to_cpu(clock_info->evergreen.usVDDCI);
560154e9
AD
2499 } else {
2500 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
2501 sclk |= clock_info->r600.ucEngineClockHigh << 16;
2502 mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
2503 mclk |= clock_info->r600.ucMemoryClockHigh << 16;
2504 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
2505 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
2506 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
2507 VOLTAGE_SW;
2508 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
4589433c 2509 le16_to_cpu(clock_info->r600.usVDDC);
560154e9
AD
2510 }
2511
ee4017f4 2512 /* patch up vddc if necessary */
e83753bb
AD
2513 switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) {
2514 case ATOM_VIRTUAL_VOLTAGE_ID0:
2515 case ATOM_VIRTUAL_VOLTAGE_ID1:
2516 case ATOM_VIRTUAL_VOLTAGE_ID2:
2517 case ATOM_VIRTUAL_VOLTAGE_ID3:
c6cf7777
AD
2518 case ATOM_VIRTUAL_VOLTAGE_ID4:
2519 case ATOM_VIRTUAL_VOLTAGE_ID5:
2520 case ATOM_VIRTUAL_VOLTAGE_ID6:
2521 case ATOM_VIRTUAL_VOLTAGE_ID7:
e83753bb
AD
2522 if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC,
2523 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage,
2524 &vddc) == 0)
ee4017f4 2525 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc;
e83753bb
AD
2526 break;
2527 default:
2528 break;
ee4017f4
AD
2529 }
2530
560154e9
AD
2531 if (rdev->flags & RADEON_IS_IGP) {
2532 /* skip invalid modes */
2533 if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
2534 return false;
2535 } else {
2536 /* skip invalid modes */
2537 if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
2538 (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
2539 return false;
2540 }
2541 return true;
2542}
2543
2544static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
2545{
2546 struct radeon_mode_info *mode_info = &rdev->mode_info;
2547 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2548 union pplib_power_state *power_state;
2549 int i, j;
2550 int state_index = 0, mode_index = 0;
2551 union pplib_clock_info *clock_info;
2552 bool valid;
2553 union power_info *power_info;
2554 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2555 u16 data_offset;
2556 u8 frev, crev;
2557
2558 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2559 &frev, &crev, &data_offset))
2560 return state_index;
2561 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2562
2563 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
f8e6bfc2
AD
2564 if (power_info->pplib.ucNumStates == 0)
2565 return state_index;
0975b162
AD
2566 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2567 power_info->pplib.ucNumStates, GFP_KERNEL);
2568 if (!rdev->pm.power_state)
2569 return state_index;
560154e9
AD
2570 /* first mode is usually default, followed by low to high */
2571 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
2572 mode_index = 0;
2573 power_state = (union pplib_power_state *)
2574 (mode_info->atom_context->bios + data_offset +
2575 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
2576 i * power_info->pplib.ucStateEntrySize);
2577 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2578 (mode_info->atom_context->bios + data_offset +
2579 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
2580 (power_state->v1.ucNonClockStateIndex *
2581 power_info->pplib.ucNonClockSize));
8f3f1c9a
AD
2582 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2583 ((power_info->pplib.ucStateEntrySize - 1) ?
2584 (power_info->pplib.ucStateEntrySize - 1) : 1),
2585 GFP_KERNEL);
2586 if (!rdev->pm.power_state[i].clock_info)
2587 return state_index;
2588 if (power_info->pplib.ucStateEntrySize - 1) {
2589 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
2590 clock_info = (union pplib_clock_info *)
2591 (mode_info->atom_context->bios + data_offset +
2592 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
2593 (power_state->v1.ucClockStateIndices[j] *
2594 power_info->pplib.ucClockInfoSize));
2595 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2596 state_index, mode_index,
2597 clock_info);
2598 if (valid)
2599 mode_index++;
2600 }
2601 } else {
2602 rdev->pm.power_state[state_index].clock_info[0].mclk =
2603 rdev->clock.default_mclk;
2604 rdev->pm.power_state[state_index].clock_info[0].sclk =
2605 rdev->clock.default_sclk;
2606 mode_index++;
560154e9
AD
2607 }
2608 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2609 if (mode_index) {
2610 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2611 non_clock_info);
2612 state_index++;
2613 }
2614 }
2615 /* if multiple clock modes, mark the lowest as no display */
2616 for (i = 0; i < state_index; i++) {
2617 if (rdev->pm.power_state[i].num_clock_modes > 1)
2618 rdev->pm.power_state[i].clock_info[0].flags |=
2619 RADEON_PM_MODE_NO_DISPLAY;
2620 }
2621 /* first mode is usually default */
2622 if (rdev->pm.default_power_state_index == -1) {
2623 rdev->pm.power_state[0].type =
2624 POWER_STATE_TYPE_DEFAULT;
2625 rdev->pm.default_power_state_index = 0;
2626 rdev->pm.power_state[0].default_clock_mode =
2627 &rdev->pm.power_state[0].clock_info[0];
2628 }
2629 return state_index;
2630}
2631
b0e66414
AD
2632static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2633{
2634 struct radeon_mode_info *mode_info = &rdev->mode_info;
2635 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2636 union pplib_power_state *power_state;
2637 int i, j, non_clock_array_index, clock_array_index;
2638 int state_index = 0, mode_index = 0;
2639 union pplib_clock_info *clock_info;
f7346881
AD
2640 struct _StateArray *state_array;
2641 struct _ClockInfoArray *clock_info_array;
2642 struct _NonClockInfoArray *non_clock_info_array;
b0e66414
AD
2643 bool valid;
2644 union power_info *power_info;
2645 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2646 u16 data_offset;
2647 u8 frev, crev;
441e76ca 2648 u8 *power_state_offset;
b0e66414
AD
2649
2650 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2651 &frev, &crev, &data_offset))
2652 return state_index;
2653 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2654
2655 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
f7346881 2656 state_array = (struct _StateArray *)
b0e66414 2657 (mode_info->atom_context->bios + data_offset +
4589433c 2658 le16_to_cpu(power_info->pplib.usStateArrayOffset));
f7346881 2659 clock_info_array = (struct _ClockInfoArray *)
b0e66414 2660 (mode_info->atom_context->bios + data_offset +
4589433c 2661 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
f7346881 2662 non_clock_info_array = (struct _NonClockInfoArray *)
b0e66414 2663 (mode_info->atom_context->bios + data_offset +
4589433c 2664 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
f8e6bfc2
AD
2665 if (state_array->ucNumEntries == 0)
2666 return state_index;
0975b162
AD
2667 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2668 state_array->ucNumEntries, GFP_KERNEL);
2669 if (!rdev->pm.power_state)
2670 return state_index;
441e76ca 2671 power_state_offset = (u8 *)state_array->states;
b0e66414
AD
2672 for (i = 0; i < state_array->ucNumEntries; i++) {
2673 mode_index = 0;
441e76ca
AD
2674 power_state = (union pplib_power_state *)power_state_offset;
2675 non_clock_array_index = power_state->v2.nonClockInfoIndex;
b0e66414
AD
2676 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2677 &non_clock_info_array->nonClockInfo[non_clock_array_index];
8f3f1c9a
AD
2678 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2679 (power_state->v2.ucNumDPMLevels ?
2680 power_state->v2.ucNumDPMLevels : 1),
2681 GFP_KERNEL);
2682 if (!rdev->pm.power_state[i].clock_info)
2683 return state_index;
2684 if (power_state->v2.ucNumDPMLevels) {
2685 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2686 clock_array_index = power_state->v2.clockInfoIndex[j];
8f3f1c9a 2687 clock_info = (union pplib_clock_info *)
f7346881 2688 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
8f3f1c9a
AD
2689 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2690 state_index, mode_index,
2691 clock_info);
2692 if (valid)
2693 mode_index++;
2694 }
2695 } else {
2696 rdev->pm.power_state[state_index].clock_info[0].mclk =
2697 rdev->clock.default_mclk;
2698 rdev->pm.power_state[state_index].clock_info[0].sclk =
2699 rdev->clock.default_sclk;
2700 mode_index++;
b0e66414
AD
2701 }
2702 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2703 if (mode_index) {
2704 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
2705 non_clock_info);
2706 state_index++;
2707 }
441e76ca 2708 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
b0e66414
AD
2709 }
2710 /* if multiple clock modes, mark the lowest as no display */
2711 for (i = 0; i < state_index; i++) {
2712 if (rdev->pm.power_state[i].num_clock_modes > 1)
2713 rdev->pm.power_state[i].clock_info[0].flags |=
2714 RADEON_PM_MODE_NO_DISPLAY;
2715 }
2716 /* first mode is usually default */
2717 if (rdev->pm.default_power_state_index == -1) {
2718 rdev->pm.power_state[0].type =
2719 POWER_STATE_TYPE_DEFAULT;
2720 rdev->pm.default_power_state_index = 0;
2721 rdev->pm.power_state[0].default_clock_mode =
2722 &rdev->pm.power_state[0].clock_info[0];
2723 }
2724 return state_index;
2725}
2726
560154e9
AD
2727void radeon_atombios_get_power_modes(struct radeon_device *rdev)
2728{
2729 struct radeon_mode_info *mode_info = &rdev->mode_info;
2730 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2731 u16 data_offset;
2732 u8 frev, crev;
2733 int state_index = 0;
2734
2735 rdev->pm.default_power_state_index = -1;
2736
2737 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2738 &frev, &crev, &data_offset)) {
2739 switch (frev) {
2740 case 1:
2741 case 2:
2742 case 3:
2743 state_index = radeon_atombios_parse_power_table_1_3(rdev);
2744 break;
2745 case 4:
2746 case 5:
2747 state_index = radeon_atombios_parse_power_table_4_5(rdev);
2748 break;
b0e66414
AD
2749 case 6:
2750 state_index = radeon_atombios_parse_power_table_6(rdev);
2751 break;
560154e9
AD
2752 default:
2753 break;
56278a8e 2754 }
f8e6bfc2
AD
2755 }
2756
2757 if (state_index == 0) {
0975b162
AD
2758 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2759 if (rdev->pm.power_state) {
8f3f1c9a
AD
2760 rdev->pm.power_state[0].clock_info =
2761 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2762 if (rdev->pm.power_state[0].clock_info) {
2763 /* add the default mode */
2764 rdev->pm.power_state[state_index].type =
2765 POWER_STATE_TYPE_DEFAULT;
2766 rdev->pm.power_state[state_index].num_clock_modes = 1;
2767 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2768 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2769 rdev->pm.power_state[state_index].default_clock_mode =
2770 &rdev->pm.power_state[state_index].clock_info[0];
2771 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2772 rdev->pm.power_state[state_index].pcie_lanes = 16;
2773 rdev->pm.default_power_state_index = state_index;
2774 rdev->pm.power_state[state_index].flags = 0;
2775 state_index++;
2776 }
0975b162 2777 }
56278a8e 2778 }
02b17cc0 2779
56278a8e 2780 rdev->pm.num_power_states = state_index;
9038dfdf 2781
a48b9b4e
AD
2782 rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2783 rdev->pm.current_clock_mode_index = 0;
4376eee9
AM
2784 if (rdev->pm.default_power_state_index >= 0)
2785 rdev->pm.current_vddc =
2786 rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
2787 else
2788 rdev->pm.current_vddc = 0;
771fe6b9
JG
2789}
2790
7062ab67
CK
2791union get_clock_dividers {
2792 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
2793 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
2794 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
2795 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
2796 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
9219ed65
AD
2797 struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
2798 struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
7062ab67
CK
2799};
2800
2801int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
2802 u8 clock_type,
2803 u32 clock,
2804 bool strobe_mode,
2805 struct atom_clock_dividers *dividers)
2806{
2807 union get_clock_dividers args;
2808 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
2809 u8 frev, crev;
2810
2811 memset(&args, 0, sizeof(args));
2812 memset(dividers, 0, sizeof(struct atom_clock_dividers));
2813
2814 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2815 return -EINVAL;
2816
2817 switch (crev) {
2818 case 1:
2819 /* r4xx, r5xx */
2820 args.v1.ucAction = clock_type;
2821 args.v1.ulClock = cpu_to_le32(clock); /* 10 khz */
2822
2823 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2824
2825 dividers->post_div = args.v1.ucPostDiv;
2826 dividers->fb_div = args.v1.ucFbDiv;
2827 dividers->enable_post_div = true;
2828 break;
2829 case 2:
2830 case 3:
360b1f5e
AD
2831 case 5:
2832 /* r6xx, r7xx, evergreen, ni, si */
7062ab67
CK
2833 if (rdev->family <= CHIP_RV770) {
2834 args.v2.ucAction = clock_type;
2835 args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */
2836
2837 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2838
2839 dividers->post_div = args.v2.ucPostDiv;
2840 dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);
2841 dividers->ref_div = args.v2.ucAction;
2842 if (rdev->family == CHIP_RV770) {
2843 dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?
2844 true : false;
2845 dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;
2846 } else
2847 dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;
2848 } else {
2849 if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
f4a2596c 2850 args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
7062ab67
CK
2851
2852 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2853
2854 dividers->post_div = args.v3.ucPostDiv;
2855 dividers->enable_post_div = (args.v3.ucCntlFlag &
2856 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2857 dividers->enable_dithen = (args.v3.ucCntlFlag &
2858 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
20fab641 2859 dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
7062ab67
CK
2860 dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
2861 dividers->ref_div = args.v3.ucRefDiv;
2862 dividers->vco_mode = (args.v3.ucCntlFlag &
2863 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2864 } else {
360b1f5e
AD
2865 /* for SI we use ComputeMemoryClockParam for memory plls */
2866 if (rdev->family >= CHIP_TAHITI)
2867 return -EINVAL;
f4a2596c 2868 args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
7062ab67
CK
2869 if (strobe_mode)
2870 args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
2871
2872 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2873
2874 dividers->post_div = args.v5.ucPostDiv;
2875 dividers->enable_post_div = (args.v5.ucCntlFlag &
2876 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2877 dividers->enable_dithen = (args.v5.ucCntlFlag &
2878 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
2879 dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
2880 dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
2881 dividers->ref_div = args.v5.ucRefDiv;
2882 dividers->vco_mode = (args.v5.ucCntlFlag &
2883 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2884 }
2885 }
2886 break;
2887 case 4:
2888 /* fusion */
2889 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
2890
2891 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2892
9219ed65 2893 dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
7062ab67
CK
2894 dividers->real_clock = le32_to_cpu(args.v4.ulClock);
2895 break;
9219ed65
AD
2896 case 6:
2897 /* CI */
2898 /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
2899 args.v6_in.ulClock.ulComputeClockFlag = clock_type;
2900 args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */
2901
2902 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2903
2904 dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
2905 dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
2906 dividers->ref_div = args.v6_out.ucPllRefDiv;
2907 dividers->post_div = args.v6_out.ucPllPostDiv;
2908 dividers->flags = args.v6_out.ucPllCntlFlag;
2909 dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
2910 dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
2911 break;
7062ab67
CK
2912 default:
2913 return -EINVAL;
2914 }
2915 return 0;
2916}
2917
eaa778af
AD
2918int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
2919 u32 clock,
2920 bool strobe_mode,
2921 struct atom_mpll_param *mpll_param)
2922{
2923 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
2924 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
2925 u8 frev, crev;
2926
2927 memset(&args, 0, sizeof(args));
2928 memset(mpll_param, 0, sizeof(struct atom_mpll_param));
2929
2930 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2931 return -EINVAL;
2932
2933 switch (frev) {
2934 case 2:
2935 switch (crev) {
2936 case 1:
2937 /* SI */
2938 args.ulClock = cpu_to_le32(clock); /* 10 khz */
2939 args.ucInputFlag = 0;
2940 if (strobe_mode)
2941 args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
2942
2943 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2944
2945 mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
2946 mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
2947 mpll_param->post_div = args.ucPostDiv;
2948 mpll_param->dll_speed = args.ucDllSpeed;
2949 mpll_param->bwcntl = args.ucBWCntl;
2950 mpll_param->vco_mode =
180f805f 2951 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);
eaa778af
AD
2952 mpll_param->yclk_sel =
2953 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
2954 mpll_param->qdr =
2955 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
2956 mpll_param->half_rate =
2957 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
2958 break;
2959 default:
2960 return -EINVAL;
2961 }
2962 break;
2963 default:
2964 return -EINVAL;
2965 }
2966 return 0;
2967}
2968
771fe6b9 2969void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
771fe6b9 2970{
771fe6b9
JG
2971 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
2972 int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
771fe6b9
JG
2973
2974 args.ucEnable = enable;
2975
2976 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2977}
2978
7433874e
RM
2979uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)
2980{
2981 GET_ENGINE_CLOCK_PS_ALLOCATION args;
2982 int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
2983
2984 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
4589433c 2985 return le32_to_cpu(args.ulReturnEngineClock);
7433874e
RM
2986}
2987
2988uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
2989{
2990 GET_MEMORY_CLOCK_PS_ALLOCATION args;
2991 int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
2992
2993 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
4589433c 2994 return le32_to_cpu(args.ulReturnMemoryClock);
7433874e
RM
2995}
2996
771fe6b9
JG
2997void radeon_atom_set_engine_clock(struct radeon_device *rdev,
2998 uint32_t eng_clock)
2999{
3000 SET_ENGINE_CLOCK_PS_ALLOCATION args;
3001 int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);
3002
4589433c 3003 args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */
771fe6b9
JG
3004
3005 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3006}
3007
3008void radeon_atom_set_memory_clock(struct radeon_device *rdev,
3009 uint32_t mem_clock)
3010{
3011 SET_MEMORY_CLOCK_PS_ALLOCATION args;
3012 int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock);
3013
3014 if (rdev->flags & RADEON_IS_IGP)
3015 return;
3016
4589433c 3017 args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */
771fe6b9
JG
3018
3019 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3020}
3021
ae5b0abb
AD
3022void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
3023 u32 eng_clock, u32 mem_clock)
3024{
3025 SET_ENGINE_CLOCK_PS_ALLOCATION args;
3026 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
3027 u32 tmp;
3028
3029 memset(&args, 0, sizeof(args));
3030
3031 tmp = eng_clock & SET_CLOCK_FREQ_MASK;
3032 tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);
3033
3034 args.ulTargetEngineClock = cpu_to_le32(tmp);
3035 if (mem_clock)
3036 args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
3037
3038 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3039}
3040
3041void radeon_atom_update_memory_dll(struct radeon_device *rdev,
3042 u32 mem_clock)
3043{
3044 u32 args;
3045 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
3046
3047 args = cpu_to_le32(mem_clock); /* 10 khz */
3048
3049 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3050}
3051
3052void radeon_atom_set_ac_timing(struct radeon_device *rdev,
3053 u32 mem_clock)
3054{
3055 SET_MEMORY_CLOCK_PS_ALLOCATION args;
3056 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
3057 u32 tmp = mem_clock | (COMPUTE_MEMORY_PLL_PARAM << 24);
3058
3059 args.ulTargetMemoryClock = cpu_to_le32(tmp); /* 10 khz */
3060
3061 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3062}
3063
7ac9aa5a
AD
3064union set_voltage {
3065 struct _SET_VOLTAGE_PS_ALLOCATION alloc;
3066 struct _SET_VOLTAGE_PARAMETERS v1;
3067 struct _SET_VOLTAGE_PARAMETERS_V2 v2;
e83753bb 3068 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
7ac9aa5a
AD
3069};
3070
8a83ec5e 3071void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)
7ac9aa5a
AD
3072{
3073 union set_voltage args;
3074 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
8a83ec5e 3075 u8 frev, crev, volt_index = voltage_level;
7ac9aa5a
AD
3076
3077 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3078 return;
3079
a377e187
AD
3080 /* 0xff01 is a flag rather then an actual voltage */
3081 if (voltage_level == 0xff01)
3082 return;
3083
7ac9aa5a
AD
3084 switch (crev) {
3085 case 1:
8a83ec5e 3086 args.v1.ucVoltageType = voltage_type;
7ac9aa5a
AD
3087 args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
3088 args.v1.ucVoltageIndex = volt_index;
3089 break;
3090 case 2:
8a83ec5e 3091 args.v2.ucVoltageType = voltage_type;
7ac9aa5a 3092 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
8a83ec5e 3093 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
7ac9aa5a 3094 break;
e83753bb
AD
3095 case 3:
3096 args.v3.ucVoltageType = voltage_type;
3097 args.v3.ucVoltageMode = ATOM_SET_VOLTAGE;
3098 args.v3.usVoltageLevel = cpu_to_le16(voltage_level);
3099 break;
7ac9aa5a
AD
3100 default:
3101 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3102 return;
3103 }
3104
3105 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3106}
3107
ae5b0abb
AD
3108int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
3109 u16 voltage_id, u16 *voltage)
ee4017f4
AD
3110{
3111 union set_voltage args;
3112 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3113 u8 frev, crev;
3114
3115 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3116 return -EINVAL;
3117
3118 switch (crev) {
3119 case 1:
3120 return -EINVAL;
3121 case 2:
3122 args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
3123 args.v2.ucVoltageMode = 0;
3124 args.v2.usVoltageLevel = 0;
3125
3126 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3127
3128 *voltage = le16_to_cpu(args.v2.usVoltageLevel);
3129 break;
e83753bb
AD
3130 case 3:
3131 args.v3.ucVoltageType = voltage_type;
3132 args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
3133 args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
3134
3135 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3136
3137 *voltage = le16_to_cpu(args.v3.usVoltageLevel);
3138 break;
ee4017f4
AD
3139 default:
3140 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3141 return -EINVAL;
3142 }
7ac9aa5a 3143
ee4017f4
AD
3144 return 0;
3145}
7ac9aa5a 3146
beb79f40
AD
3147int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,
3148 u16 *voltage,
3149 u16 leakage_idx)
3150{
3151 return radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
3152}
3153
62c35fd7
AD
3154int radeon_atom_get_leakage_id_from_vbios(struct radeon_device *rdev,
3155 u16 *leakage_id)
3156{
3157 union set_voltage args;
3158 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3159 u8 frev, crev;
3160
3161 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3162 return -EINVAL;
3163
3164 switch (crev) {
3165 case 3:
3166 case 4:
3167 args.v3.ucVoltageType = 0;
3168 args.v3.ucVoltageMode = ATOM_GET_LEAKAGE_ID;
3169 args.v3.usVoltageLevel = 0;
3170
3171 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3172
3173 *leakage_id = le16_to_cpu(args.v3.usVoltageLevel);
3174 break;
3175 default:
3176 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3177 return -EINVAL;
3178 }
3179
3180 return 0;
3181}
3182
3183int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *rdev,
3184 u16 *vddc, u16 *vddci,
3185 u16 virtual_voltage_id,
3186 u16 vbios_voltage_id)
3187{
3188 int index = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);
3189 u8 frev, crev;
3190 u16 data_offset, size;
3191 int i, j;
3192 ATOM_ASIC_PROFILING_INFO_V2_1 *profile;
3193 u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf;
3194
3195 *vddc = 0;
3196 *vddci = 0;
3197
3198 if (!atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3199 &frev, &crev, &data_offset))
3200 return -EINVAL;
3201
3202 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)
3203 (rdev->mode_info.atom_context->bios + data_offset);
3204
3205 switch (frev) {
3206 case 1:
3207 return -EINVAL;
3208 case 2:
3209 switch (crev) {
3210 case 1:
3211 if (size < sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))
3212 return -EINVAL;
3213 leakage_bin = (u16 *)
3214 (rdev->mode_info.atom_context->bios + data_offset +
3215 le16_to_cpu(profile->usLeakageBinArrayOffset));
3216 vddc_id_buf = (u16 *)
3217 (rdev->mode_info.atom_context->bios + data_offset +
3218 le16_to_cpu(profile->usElbVDDC_IdArrayOffset));
3219 vddc_buf = (u16 *)
3220 (rdev->mode_info.atom_context->bios + data_offset +
3221 le16_to_cpu(profile->usElbVDDC_LevelArrayOffset));
3222 vddci_id_buf = (u16 *)
3223 (rdev->mode_info.atom_context->bios + data_offset +
3224 le16_to_cpu(profile->usElbVDDCI_IdArrayOffset));
3225 vddci_buf = (u16 *)
3226 (rdev->mode_info.atom_context->bios + data_offset +
3227 le16_to_cpu(profile->usElbVDDCI_LevelArrayOffset));
3228
3229 if (profile->ucElbVDDC_Num > 0) {
3230 for (i = 0; i < profile->ucElbVDDC_Num; i++) {
3231 if (vddc_id_buf[i] == virtual_voltage_id) {
3232 for (j = 0; j < profile->ucLeakageBinNum; j++) {
3233 if (vbios_voltage_id <= leakage_bin[j]) {
3234 *vddc = vddc_buf[j * profile->ucElbVDDC_Num + i];
3235 break;
3236 }
3237 }
3238 break;
3239 }
3240 }
3241 }
3242 if (profile->ucElbVDDCI_Num > 0) {
3243 for (i = 0; i < profile->ucElbVDDCI_Num; i++) {
3244 if (vddci_id_buf[i] == virtual_voltage_id) {
3245 for (j = 0; j < profile->ucLeakageBinNum; j++) {
3246 if (vbios_voltage_id <= leakage_bin[j]) {
3247 *vddci = vddci_buf[j * profile->ucElbVDDCI_Num + i];
3248 break;
3249 }
3250 }
3251 break;
3252 }
3253 }
3254 }
3255 break;
3256 default:
3257 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3258 return -EINVAL;
3259 }
3260 break;
3261 default:
3262 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3263 return -EINVAL;
3264 }
3265
3266 return 0;
3267}
3268
e9f274b2
AD
3269union get_voltage_info {
3270 struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in;
3271 struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out;
3272};
3273
3274int radeon_atom_get_voltage_evv(struct radeon_device *rdev,
3275 u16 virtual_voltage_id,
3276 u16 *voltage)
3277{
3278 int index = GetIndexIntoMasterTable(COMMAND, GetVoltageInfo);
3279 u32 entry_id;
3280 u32 count = rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count;
3281 union get_voltage_info args;
3282
3283 for (entry_id = 0; entry_id < count; entry_id++) {
3284 if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].v ==
3285 virtual_voltage_id)
3286 break;
3287 }
3288
3289 if (entry_id >= count)
3290 return -EINVAL;
3291
3292 args.in.ucVoltageType = VOLTAGE_TYPE_VDDC;
3293 args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE;
09b6e85f 3294 args.in.usVoltageLevel = cpu_to_le16(virtual_voltage_id);
e9f274b2
AD
3295 args.in.ulSCLKFreq =
3296 cpu_to_le32(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk);
3297
3298 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3299
3300 *voltage = le16_to_cpu(args.evv_out.usVoltageLevel);
3301
3302 return 0;
3303}
3304
ae5b0abb
AD
3305int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
3306 u16 voltage_level, u8 voltage_type,
3307 u32 *gpio_value, u32 *gpio_mask)
3308{
3309 union set_voltage args;
3310 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
3311 u8 frev, crev;
3312
3313 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
3314 return -EINVAL;
3315
3316 switch (crev) {
3317 case 1:
3318 return -EINVAL;
3319 case 2:
3320 args.v2.ucVoltageType = voltage_type;
3321 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK;
3322 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
3323
3324 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3325
3326 *gpio_mask = le32_to_cpu(*(u32 *)&args.v2);
3327
3328 args.v2.ucVoltageType = voltage_type;
3329 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL;
3330 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
3331
3332 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
3333
3334 *gpio_value = le32_to_cpu(*(u32 *)&args.v2);
3335 break;
3336 default:
3337 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3338 return -EINVAL;
3339 }
3340
3341 return 0;
3342}
3343
3344union voltage_object_info {
58653abd
AD
3345 struct _ATOM_VOLTAGE_OBJECT_INFO v1;
3346 struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
3347 struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
ae5b0abb
AD
3348};
3349
779187f2
AD
3350union voltage_object {
3351 struct _ATOM_VOLTAGE_OBJECT v1;
3352 struct _ATOM_VOLTAGE_OBJECT_V2 v2;
3353 union _ATOM_VOLTAGE_OBJECT_V3 v3;
3354};
3355
3356static ATOM_VOLTAGE_OBJECT *atom_lookup_voltage_object_v1(ATOM_VOLTAGE_OBJECT_INFO *v1,
3357 u8 voltage_type)
3358{
6e764764 3359 u32 size = le16_to_cpu(v1->sHeader.usStructureSize);
779187f2
AD
3360 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO, asVoltageObj[0]);
3361 u8 *start = (u8 *)v1;
3362
3363 while (offset < size) {
3364 ATOM_VOLTAGE_OBJECT *vo = (ATOM_VOLTAGE_OBJECT *)(start + offset);
3365 if (vo->ucVoltageType == voltage_type)
3366 return vo;
3367 offset += offsetof(ATOM_VOLTAGE_OBJECT, asFormula.ucVIDAdjustEntries) +
3368 vo->asFormula.ucNumOfVoltageEntries;
3369 }
3370 return NULL;
3371}
3372
3373static ATOM_VOLTAGE_OBJECT_V2 *atom_lookup_voltage_object_v2(ATOM_VOLTAGE_OBJECT_INFO_V2 *v2,
3374 u8 voltage_type)
3375{
6e764764 3376 u32 size = le16_to_cpu(v2->sHeader.usStructureSize);
779187f2
AD
3377 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V2, asVoltageObj[0]);
3378 u8 *start = (u8*)v2;
3379
3380 while (offset < size) {
3381 ATOM_VOLTAGE_OBJECT_V2 *vo = (ATOM_VOLTAGE_OBJECT_V2 *)(start + offset);
3382 if (vo->ucVoltageType == voltage_type)
3383 return vo;
3384 offset += offsetof(ATOM_VOLTAGE_OBJECT_V2, asFormula.asVIDAdjustEntries) +
3385 (vo->asFormula.ucNumOfVoltageEntries * sizeof(VOLTAGE_LUT_ENTRY));
3386 }
3387 return NULL;
3388}
3389
3390static ATOM_VOLTAGE_OBJECT_V3 *atom_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,
3391 u8 voltage_type, u8 voltage_mode)
3392{
6e764764 3393 u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
779187f2
AD
3394 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
3395 u8 *start = (u8*)v3;
3396
3397 while (offset < size) {
3398 ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
3399 if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
3400 (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
3401 return vo;
6e764764 3402 offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
779187f2
AD
3403 }
3404 return NULL;
3405}
3406
ae5b0abb 3407bool
58653abd
AD
3408radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
3409 u8 voltage_type, u8 voltage_mode)
ae5b0abb
AD
3410{
3411 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3412 u8 frev, crev;
3413 u16 data_offset, size;
ae5b0abb 3414 union voltage_object_info *voltage_info;
779187f2 3415 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3416
3417 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3418 &frev, &crev, &data_offset)) {
3419 voltage_info = (union voltage_object_info *)
3420 (rdev->mode_info.atom_context->bios + data_offset);
3421
58653abd 3422 switch (frev) {
ae5b0abb 3423 case 1:
58653abd
AD
3424 case 2:
3425 switch (crev) {
3426 case 1:
779187f2
AD
3427 voltage_object = (union voltage_object *)
3428 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3429 if (voltage_object &&
3430 (voltage_object->v1.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
3431 return true;
58653abd
AD
3432 break;
3433 case 2:
779187f2
AD
3434 voltage_object = (union voltage_object *)
3435 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3436 if (voltage_object &&
3437 (voltage_object->v2.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
3438 return true;
58653abd
AD
3439 break;
3440 default:
3441 DRM_ERROR("unknown voltage object table\n");
3442 return false;
ae5b0abb
AD
3443 }
3444 break;
58653abd
AD
3445 case 3:
3446 switch (crev) {
3447 case 1:
779187f2
AD
3448 if (atom_lookup_voltage_object_v3(&voltage_info->v3,
3449 voltage_type, voltage_mode))
3450 return true;
58653abd
AD
3451 break;
3452 default:
3453 DRM_ERROR("unknown voltage object table\n");
3454 return false;
ae5b0abb
AD
3455 }
3456 break;
3457 default:
3458 DRM_ERROR("unknown voltage object table\n");
3459 return false;
3460 }
3461
3462 }
3463 return false;
3464}
3465
636e2582
AD
3466int radeon_atom_get_svi2_info(struct radeon_device *rdev,
3467 u8 voltage_type,
3468 u8 *svd_gpio_id, u8 *svc_gpio_id)
3469{
3470 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3471 u8 frev, crev;
3472 u16 data_offset, size;
3473 union voltage_object_info *voltage_info;
3474 union voltage_object *voltage_object = NULL;
3475
3476 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3477 &frev, &crev, &data_offset)) {
3478 voltage_info = (union voltage_object_info *)
3479 (rdev->mode_info.atom_context->bios + data_offset);
3480
3481 switch (frev) {
3482 case 3:
3483 switch (crev) {
3484 case 1:
3485 voltage_object = (union voltage_object *)
3486 atom_lookup_voltage_object_v3(&voltage_info->v3,
3487 voltage_type,
3488 VOLTAGE_OBJ_SVID2);
3489 if (voltage_object) {
3490 *svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;
3491 *svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;
3492 } else {
3493 return -EINVAL;
3494 }
3495 break;
3496 default:
3497 DRM_ERROR("unknown voltage object table\n");
3498 return -EINVAL;
3499 }
3500 break;
3501 default:
3502 DRM_ERROR("unknown voltage object table\n");
3503 return -EINVAL;
3504 }
3505
3506 }
3507 return 0;
3508}
3509
ae5b0abb
AD
3510int radeon_atom_get_max_voltage(struct radeon_device *rdev,
3511 u8 voltage_type, u16 *max_voltage)
3512{
3513 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3514 u8 frev, crev;
3515 u16 data_offset, size;
ae5b0abb 3516 union voltage_object_info *voltage_info;
779187f2 3517 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3518
3519 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3520 &frev, &crev, &data_offset)) {
3521 voltage_info = (union voltage_object_info *)
3522 (rdev->mode_info.atom_context->bios + data_offset);
3523
3524 switch (crev) {
3525 case 1:
779187f2
AD
3526 voltage_object = (union voltage_object *)
3527 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3528 if (voltage_object) {
3529 ATOM_VOLTAGE_FORMULA *formula =
3530 &voltage_object->v1.asFormula;
3531 if (formula->ucFlag & 1)
3532 *max_voltage =
3533 le16_to_cpu(formula->usVoltageBaseLevel) +
3534 formula->ucNumOfVoltageEntries / 2 *
3535 le16_to_cpu(formula->usVoltageStep);
3536 else
3537 *max_voltage =
3538 le16_to_cpu(formula->usVoltageBaseLevel) +
3539 (formula->ucNumOfVoltageEntries - 1) *
3540 le16_to_cpu(formula->usVoltageStep);
3541 return 0;
ae5b0abb
AD
3542 }
3543 break;
3544 case 2:
779187f2
AD
3545 voltage_object = (union voltage_object *)
3546 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3547 if (voltage_object) {
3548 ATOM_VOLTAGE_FORMULA_V2 *formula =
3549 &voltage_object->v2.asFormula;
3550 if (formula->ucNumOfVoltageEntries) {
607f2c27
AD
3551 VOLTAGE_LUT_ENTRY *lut = (VOLTAGE_LUT_ENTRY *)
3552 ((u8 *)&formula->asVIDAdjustEntries[0] +
3553 (sizeof(VOLTAGE_LUT_ENTRY) * (formula->ucNumOfVoltageEntries - 1)));
779187f2 3554 *max_voltage =
607f2c27 3555 le16_to_cpu(lut->usVoltageValue);
779187f2 3556 return 0;
ae5b0abb
AD
3557 }
3558 }
3559 break;
3560 default:
3561 DRM_ERROR("unknown voltage object table\n");
3562 return -EINVAL;
3563 }
3564
3565 }
3566 return -EINVAL;
3567}
3568
3569int radeon_atom_get_min_voltage(struct radeon_device *rdev,
3570 u8 voltage_type, u16 *min_voltage)
3571{
3572 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3573 u8 frev, crev;
3574 u16 data_offset, size;
ae5b0abb 3575 union voltage_object_info *voltage_info;
779187f2 3576 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3577
3578 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3579 &frev, &crev, &data_offset)) {
3580 voltage_info = (union voltage_object_info *)
3581 (rdev->mode_info.atom_context->bios + data_offset);
3582
3583 switch (crev) {
3584 case 1:
779187f2
AD
3585 voltage_object = (union voltage_object *)
3586 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3587 if (voltage_object) {
3588 ATOM_VOLTAGE_FORMULA *formula =
3589 &voltage_object->v1.asFormula;
3590 *min_voltage =
3591 le16_to_cpu(formula->usVoltageBaseLevel);
3592 return 0;
ae5b0abb
AD
3593 }
3594 break;
3595 case 2:
779187f2
AD
3596 voltage_object = (union voltage_object *)
3597 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3598 if (voltage_object) {
3599 ATOM_VOLTAGE_FORMULA_V2 *formula =
3600 &voltage_object->v2.asFormula;
3601 if (formula->ucNumOfVoltageEntries) {
3602 *min_voltage =
3603 le16_to_cpu(formula->asVIDAdjustEntries[
3604 0
3605 ].usVoltageValue);
3606 return 0;
ae5b0abb
AD
3607 }
3608 }
3609 break;
3610 default:
3611 DRM_ERROR("unknown voltage object table\n");
3612 return -EINVAL;
3613 }
3614
3615 }
3616 return -EINVAL;
3617}
3618
3619int radeon_atom_get_voltage_step(struct radeon_device *rdev,
3620 u8 voltage_type, u16 *voltage_step)
3621{
3622 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3623 u8 frev, crev;
3624 u16 data_offset, size;
ae5b0abb 3625 union voltage_object_info *voltage_info;
779187f2 3626 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3627
3628 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3629 &frev, &crev, &data_offset)) {
3630 voltage_info = (union voltage_object_info *)
3631 (rdev->mode_info.atom_context->bios + data_offset);
3632
3633 switch (crev) {
3634 case 1:
779187f2
AD
3635 voltage_object = (union voltage_object *)
3636 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
3637 if (voltage_object) {
3638 ATOM_VOLTAGE_FORMULA *formula =
3639 &voltage_object->v1.asFormula;
3640 if (formula->ucFlag & 1)
3641 *voltage_step =
3642 (le16_to_cpu(formula->usVoltageStep) + 1) / 2;
3643 else
3644 *voltage_step =
3645 le16_to_cpu(formula->usVoltageStep);
3646 return 0;
ae5b0abb
AD
3647 }
3648 break;
3649 case 2:
3650 return -EINVAL;
3651 default:
3652 DRM_ERROR("unknown voltage object table\n");
3653 return -EINVAL;
3654 }
3655
3656 }
3657 return -EINVAL;
3658}
3659
3660int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
3661 u8 voltage_type,
3662 u16 nominal_voltage,
3663 u16 *true_voltage)
3664{
3665 u16 min_voltage, max_voltage, voltage_step;
3666
3667 if (radeon_atom_get_max_voltage(rdev, voltage_type, &max_voltage))
3668 return -EINVAL;
3669 if (radeon_atom_get_min_voltage(rdev, voltage_type, &min_voltage))
3670 return -EINVAL;
3671 if (radeon_atom_get_voltage_step(rdev, voltage_type, &voltage_step))
3672 return -EINVAL;
3673
3674 if (nominal_voltage <= min_voltage)
3675 *true_voltage = min_voltage;
3676 else if (nominal_voltage >= max_voltage)
3677 *true_voltage = max_voltage;
3678 else
3679 *true_voltage = min_voltage +
3680 ((nominal_voltage - min_voltage) / voltage_step) *
3681 voltage_step;
3682
3683 return 0;
3684}
3685
3686int radeon_atom_get_voltage_table(struct radeon_device *rdev,
65171944 3687 u8 voltage_type, u8 voltage_mode,
ae5b0abb
AD
3688 struct atom_voltage_table *voltage_table)
3689{
3690 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
3691 u8 frev, crev;
3692 u16 data_offset, size;
779187f2 3693 int i, ret;
ae5b0abb 3694 union voltage_object_info *voltage_info;
779187f2 3695 union voltage_object *voltage_object = NULL;
ae5b0abb
AD
3696
3697 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3698 &frev, &crev, &data_offset)) {
3699 voltage_info = (union voltage_object_info *)
3700 (rdev->mode_info.atom_context->bios + data_offset);
3701
65171944 3702 switch (frev) {
ae5b0abb 3703 case 1:
ae5b0abb 3704 case 2:
65171944
AD
3705 switch (crev) {
3706 case 1:
3707 DRM_ERROR("old table version %d, %d\n", frev, crev);
3708 return -EINVAL;
3709 case 2:
779187f2
AD
3710 voltage_object = (union voltage_object *)
3711 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
3712 if (voltage_object) {
3713 ATOM_VOLTAGE_FORMULA_V2 *formula =
3714 &voltage_object->v2.asFormula;
607f2c27 3715 VOLTAGE_LUT_ENTRY *lut;
779187f2
AD
3716 if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)
3717 return -EINVAL;
607f2c27 3718 lut = &formula->asVIDAdjustEntries[0];
779187f2
AD
3719 for (i = 0; i < formula->ucNumOfVoltageEntries; i++) {
3720 voltage_table->entries[i].value =
607f2c27 3721 le16_to_cpu(lut->usVoltageValue);
779187f2
AD
3722 ret = radeon_atom_get_voltage_gpio_settings(rdev,
3723 voltage_table->entries[i].value,
3724 voltage_type,
3725 &voltage_table->entries[i].smio_low,
3726 &voltage_table->mask_low);
3727 if (ret)
3728 return ret;
607f2c27
AD
3729 lut = (VOLTAGE_LUT_ENTRY *)
3730 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY));
ae5b0abb 3731 }
779187f2
AD
3732 voltage_table->count = formula->ucNumOfVoltageEntries;
3733 return 0;
ae5b0abb 3734 }
65171944
AD
3735 break;
3736 default:
3737 DRM_ERROR("unknown voltage object table\n");
3738 return -EINVAL;
3739 }
3740 break;
3741 case 3:
3742 switch (crev) {
3743 case 1:
779187f2
AD
3744 voltage_object = (union voltage_object *)
3745 atom_lookup_voltage_object_v3(&voltage_info->v3,
3746 voltage_type, voltage_mode);
3747 if (voltage_object) {
3748 ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
3749 &voltage_object->v3.asGpioVoltageObj;
607f2c27 3750 VOLTAGE_LUT_ENTRY_V2 *lut;
779187f2
AD
3751 if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
3752 return -EINVAL;
607f2c27 3753 lut = &gpio->asVolGpioLut[0];
779187f2
AD
3754 for (i = 0; i < gpio->ucGpioEntryNum; i++) {
3755 voltage_table->entries[i].value =
607f2c27 3756 le16_to_cpu(lut->usVoltageValue);
779187f2 3757 voltage_table->entries[i].smio_low =
607f2c27
AD
3758 le32_to_cpu(lut->ulVoltageId);
3759 lut = (VOLTAGE_LUT_ENTRY_V2 *)
3760 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2));
65171944 3761 }
779187f2
AD
3762 voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
3763 voltage_table->count = gpio->ucGpioEntryNum;
3764 voltage_table->phase_delay = gpio->ucPhaseDelay;
3765 return 0;
65171944
AD
3766 }
3767 break;
3768 default:
3769 DRM_ERROR("unknown voltage object table\n");
3770 return -EINVAL;
ae5b0abb
AD
3771 }
3772 break;
3773 default:
3774 DRM_ERROR("unknown voltage object table\n");
3775 return -EINVAL;
3776 }
ae5b0abb
AD
3777 }
3778 return -EINVAL;
3779}
3780
3781union vram_info {
3782 struct _ATOM_VRAM_INFO_V3 v1_3;
3783 struct _ATOM_VRAM_INFO_V4 v1_4;
3784 struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;
3785};
3786
3787int radeon_atom_get_memory_info(struct radeon_device *rdev,
3788 u8 module_index, struct atom_memory_info *mem_info)
3789{
3790 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3791 u8 frev, crev, i;
3792 u16 data_offset, size;
3793 union vram_info *vram_info;
ae5b0abb
AD
3794
3795 memset(mem_info, 0, sizeof(struct atom_memory_info));
3796
3797 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3798 &frev, &crev, &data_offset)) {
3799 vram_info = (union vram_info *)
3800 (rdev->mode_info.atom_context->bios + data_offset);
3801 switch (frev) {
3802 case 1:
3803 switch (crev) {
3804 case 3:
3805 /* r6xx */
3806 if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {
3807 ATOM_VRAM_MODULE_V3 *vram_module =
3808 (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;
ae5b0abb
AD
3809
3810 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3811 if (le16_to_cpu(vram_module->usSize) == 0)
3812 return -EINVAL;
77c7d50a
AD
3813 vram_module = (ATOM_VRAM_MODULE_V3 *)
3814 ((u8 *)vram_module + le16_to_cpu(vram_module->usSize));
ae5b0abb
AD
3815 }
3816 mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;
3817 mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;
3818 } else
3819 return -EINVAL;
3820 break;
3821 case 4:
3822 /* r7xx, evergreen */
3823 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
3824 ATOM_VRAM_MODULE_V4 *vram_module =
3825 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
ae5b0abb
AD
3826
3827 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3828 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3829 return -EINVAL;
77c7d50a
AD
3830 vram_module = (ATOM_VRAM_MODULE_V4 *)
3831 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3832 }
3833 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
3834 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
3835 } else
3836 return -EINVAL;
3837 break;
3838 default:
3839 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3840 return -EINVAL;
3841 }
3842 break;
3843 case 2:
3844 switch (crev) {
3845 case 1:
3846 /* ni */
3847 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
3848 ATOM_VRAM_MODULE_V7 *vram_module =
3849 (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;
ae5b0abb
AD
3850
3851 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3852 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3853 return -EINVAL;
77c7d50a
AD
3854 vram_module = (ATOM_VRAM_MODULE_V7 *)
3855 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3856 }
3857 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
3858 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
3859 } else
3860 return -EINVAL;
3861 break;
3862 default:
3863 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3864 return -EINVAL;
3865 }
3866 break;
3867 default:
3868 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3869 return -EINVAL;
3870 }
3871 return 0;
3872 }
3873 return -EINVAL;
3874}
3875
3876int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
3877 bool gddr5, u8 module_index,
3878 struct atom_memory_clock_range_table *mclk_range_table)
3879{
3880 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3881 u8 frev, crev, i;
3882 u16 data_offset, size;
3883 union vram_info *vram_info;
3884 u32 mem_timing_size = gddr5 ?
3885 sizeof(ATOM_MEMORY_TIMING_FORMAT_V2) : sizeof(ATOM_MEMORY_TIMING_FORMAT);
ae5b0abb
AD
3886
3887 memset(mclk_range_table, 0, sizeof(struct atom_memory_clock_range_table));
3888
3889 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3890 &frev, &crev, &data_offset)) {
3891 vram_info = (union vram_info *)
3892 (rdev->mode_info.atom_context->bios + data_offset);
3893 switch (frev) {
3894 case 1:
3895 switch (crev) {
3896 case 3:
3897 DRM_ERROR("old table version %d, %d\n", frev, crev);
3898 return -EINVAL;
3899 case 4:
3900 /* r7xx, evergreen */
3901 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
3902 ATOM_VRAM_MODULE_V4 *vram_module =
3903 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
607f2c27 3904 ATOM_MEMORY_TIMING_FORMAT *format;
ae5b0abb
AD
3905
3906 for (i = 0; i < module_index; i++) {
ae5b0abb
AD
3907 if (le16_to_cpu(vram_module->usModuleSize) == 0)
3908 return -EINVAL;
77c7d50a
AD
3909 vram_module = (ATOM_VRAM_MODULE_V4 *)
3910 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
ae5b0abb
AD
3911 }
3912 mclk_range_table->num_entries = (u8)
1fa4252a 3913 ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /
ae5b0abb 3914 mem_timing_size);
607f2c27 3915 format = &vram_module->asMemTiming[0];
ae5b0abb 3916 for (i = 0; i < mclk_range_table->num_entries; i++) {
e631227f 3917 mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
607f2c27
AD
3918 format = (ATOM_MEMORY_TIMING_FORMAT *)
3919 ((u8 *)format + mem_timing_size);
ae5b0abb
AD
3920 }
3921 } else
3922 return -EINVAL;
3923 break;
3924 default:
3925 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3926 return -EINVAL;
3927 }
3928 break;
3929 case 2:
3930 DRM_ERROR("new table version %d, %d\n", frev, crev);
3931 return -EINVAL;
3932 default:
3933 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
3934 return -EINVAL;
3935 }
3936 return 0;
3937 }
3938 return -EINVAL;
3939}
3940
3941#define MEM_ID_MASK 0xff000000
3942#define MEM_ID_SHIFT 24
3943#define CLOCK_RANGE_MASK 0x00ffffff
3944#define CLOCK_RANGE_SHIFT 0
3945#define LOW_NIBBLE_MASK 0xf
3946#define DATA_EQU_PREV 0
3947#define DATA_FROM_TABLE 4
3948
3949int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
3950 u8 module_index,
3951 struct atom_mc_reg_table *reg_table)
3952{
3953 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
3954 u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;
3955 u32 i = 0, j;
3956 u16 data_offset, size;
3957 union vram_info *vram_info;
3958
3959 memset(reg_table, 0, sizeof(struct atom_mc_reg_table));
3960
3961 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
3962 &frev, &crev, &data_offset)) {
3963 vram_info = (union vram_info *)
3964 (rdev->mode_info.atom_context->bios + data_offset);
3965 switch (frev) {
3966 case 1:
3967 DRM_ERROR("old table version %d, %d\n", frev, crev);
3968 return -EINVAL;
3969 case 2:
3970 switch (crev) {
3971 case 1:
3972 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
3973 ATOM_INIT_REG_BLOCK *reg_block =
3974 (ATOM_INIT_REG_BLOCK *)
3975 ((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));
3976 ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =
3977 (ATOM_MEMORY_SETTING_DATA_BLOCK *)
3978 ((u8 *)reg_block + (2 * sizeof(u16)) +
3979 le16_to_cpu(reg_block->usRegIndexTblSize));
f90555cb 3980 ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
ae5b0abb
AD
3981 num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
3982 sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
3983 if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
3984 return -EINVAL;
48fa04c3 3985 while (i < num_entries) {
f90555cb 3986 if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
48fa04c3 3987 break;
ae5b0abb 3988 reg_table->mc_reg_address[i].s1 =
f90555cb 3989 (u16)(le16_to_cpu(format->usRegIndex));
ae5b0abb 3990 reg_table->mc_reg_address[i].pre_reg_data =
f90555cb 3991 (u8)(format->ucPreRegDataLength);
ae5b0abb 3992 i++;
f90555cb
AD
3993 format = (ATOM_INIT_REG_INDEX_FORMAT *)
3994 ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
ae5b0abb
AD
3995 }
3996 reg_table->last = i;
d526fbdd 3997 while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) &&
ae5b0abb 3998 (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {
d526fbdd
AD
3999 t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK)
4000 >> MEM_ID_SHIFT);
ae5b0abb
AD
4001 if (module_index == t_mem_id) {
4002 reg_table->mc_reg_table_entry[num_ranges].mclk_max =
d526fbdd
AD
4003 (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK)
4004 >> CLOCK_RANGE_SHIFT);
ae5b0abb
AD
4005 for (i = 0, j = 1; i < reg_table->last; i++) {
4006 if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
4007 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
d526fbdd 4008 (u32)le32_to_cpu(*((u32 *)reg_data + j));
ae5b0abb
AD
4009 j++;
4010 } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
4011 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
4012 reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
4013 }
4014 }
4015 num_ranges++;
4016 }
4da18e26
AD
4017 reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
4018 ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
ae5b0abb 4019 }
d526fbdd 4020 if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK)
ae5b0abb
AD
4021 return -EINVAL;
4022 reg_table->num_entries = num_ranges;
4023 } else
4024 return -EINVAL;
4025 break;
4026 default:
4027 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
4028 return -EINVAL;
4029 }
4030 break;
4031 default:
4032 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
4033 return -EINVAL;
4034 }
4035 return 0;
4036 }
4037 return -EINVAL;
4038}
4039
771fe6b9
JG
4040void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
4041{
4042 struct radeon_device *rdev = dev->dev_private;
4043 uint32_t bios_2_scratch, bios_6_scratch;
4044
4045 if (rdev->family >= CHIP_R600) {
4ce001ab 4046 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
771fe6b9
JG
4047 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
4048 } else {
4ce001ab 4049 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
771fe6b9
JG
4050 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
4051 }
4052
4053 /* let the bios control the backlight */
4054 bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
4055
4056 /* tell the bios not to handle mode switching */
87364760 4057 bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
771fe6b9 4058
6802d4ba
AD
4059 /* clear the vbios dpms state */
4060 if (ASIC_IS_DCE4(rdev))
4061 bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
4062
771fe6b9
JG
4063 if (rdev->family >= CHIP_R600) {
4064 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
4065 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
4066 } else {
4067 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
4068 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
4069 }
4070
4071}
4072
f657c2a7
YZ
4073void radeon_save_bios_scratch_regs(struct radeon_device *rdev)
4074{
4075 uint32_t scratch_reg;
4076 int i;
4077
4078 if (rdev->family >= CHIP_R600)
4079 scratch_reg = R600_BIOS_0_SCRATCH;
4080 else
4081 scratch_reg = RADEON_BIOS_0_SCRATCH;
4082
4083 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
4084 rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));
4085}
4086
4087void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)
4088{
4089 uint32_t scratch_reg;
4090 int i;
4091
4092 if (rdev->family >= CHIP_R600)
4093 scratch_reg = R600_BIOS_0_SCRATCH;
4094 else
4095 scratch_reg = RADEON_BIOS_0_SCRATCH;
4096
4097 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
4098 WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);
4099}
4100
771fe6b9
JG
4101void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
4102{
4103 struct drm_device *dev = encoder->dev;
4104 struct radeon_device *rdev = dev->dev_private;
4105 uint32_t bios_6_scratch;
4106
4107 if (rdev->family >= CHIP_R600)
4108 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
4109 else
4110 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
4111
87364760 4112 if (lock) {
771fe6b9 4113 bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
87364760
AD
4114 bios_6_scratch &= ~ATOM_S6_ACC_MODE;
4115 } else {
771fe6b9 4116 bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
87364760
AD
4117 bios_6_scratch |= ATOM_S6_ACC_MODE;
4118 }
771fe6b9
JG
4119
4120 if (rdev->family >= CHIP_R600)
4121 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
4122 else
4123 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
4124}
4125
4126/* at some point we may want to break this out into individual functions */
4127void
4128radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
4129 struct drm_encoder *encoder,
4130 bool connected)
4131{
4132 struct drm_device *dev = connector->dev;
4133 struct radeon_device *rdev = dev->dev_private;
4134 struct radeon_connector *radeon_connector =
4135 to_radeon_connector(connector);
4136 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4137 uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch;
4138
4139 if (rdev->family >= CHIP_R600) {
4140 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
4141 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
4142 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
4143 } else {
4144 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
4145 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);
4146 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
4147 }
4148
4149 if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
4150 (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
4151 if (connected) {
d9fdaafb 4152 DRM_DEBUG_KMS("TV1 connected\n");
771fe6b9
JG
4153 bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
4154 bios_6_scratch |= ATOM_S6_ACC_REQ_TV1;
4155 } else {
d9fdaafb 4156 DRM_DEBUG_KMS("TV1 disconnected\n");
771fe6b9
JG
4157 bios_0_scratch &= ~ATOM_S0_TV1_MASK;
4158 bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
4159 bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1;
4160 }
4161 }
4162 if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) &&
4163 (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) {
4164 if (connected) {
d9fdaafb 4165 DRM_DEBUG_KMS("CV connected\n");
771fe6b9
JG
4166 bios_3_scratch |= ATOM_S3_CV_ACTIVE;
4167 bios_6_scratch |= ATOM_S6_ACC_REQ_CV;
4168 } else {
d9fdaafb 4169 DRM_DEBUG_KMS("CV disconnected\n");
771fe6b9
JG
4170 bios_0_scratch &= ~ATOM_S0_CV_MASK;
4171 bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
4172 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV;
4173 }
4174 }
4175 if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
4176 (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
4177 if (connected) {
d9fdaafb 4178 DRM_DEBUG_KMS("LCD1 connected\n");
771fe6b9
JG
4179 bios_0_scratch |= ATOM_S0_LCD1;
4180 bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
4181 bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1;
4182 } else {
d9fdaafb 4183 DRM_DEBUG_KMS("LCD1 disconnected\n");
771fe6b9
JG
4184 bios_0_scratch &= ~ATOM_S0_LCD1;
4185 bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
4186 bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1;
4187 }
4188 }
4189 if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
4190 (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
4191 if (connected) {
d9fdaafb 4192 DRM_DEBUG_KMS("CRT1 connected\n");
771fe6b9
JG
4193 bios_0_scratch |= ATOM_S0_CRT1_COLOR;
4194 bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
4195 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1;
4196 } else {
d9fdaafb 4197 DRM_DEBUG_KMS("CRT1 disconnected\n");
771fe6b9
JG
4198 bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
4199 bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
4200 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1;
4201 }
4202 }
4203 if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
4204 (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
4205 if (connected) {
d9fdaafb 4206 DRM_DEBUG_KMS("CRT2 connected\n");
771fe6b9
JG
4207 bios_0_scratch |= ATOM_S0_CRT2_COLOR;
4208 bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
4209 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2;
4210 } else {
d9fdaafb 4211 DRM_DEBUG_KMS("CRT2 disconnected\n");
771fe6b9
JG
4212 bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
4213 bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
4214 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2;
4215 }
4216 }
4217 if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
4218 (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
4219 if (connected) {
d9fdaafb 4220 DRM_DEBUG_KMS("DFP1 connected\n");
771fe6b9
JG
4221 bios_0_scratch |= ATOM_S0_DFP1;
4222 bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
4223 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1;
4224 } else {
d9fdaafb 4225 DRM_DEBUG_KMS("DFP1 disconnected\n");
771fe6b9
JG
4226 bios_0_scratch &= ~ATOM_S0_DFP1;
4227 bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
4228 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1;
4229 }
4230 }
4231 if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
4232 (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
4233 if (connected) {
d9fdaafb 4234 DRM_DEBUG_KMS("DFP2 connected\n");
771fe6b9
JG
4235 bios_0_scratch |= ATOM_S0_DFP2;
4236 bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
4237 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2;
4238 } else {
d9fdaafb 4239 DRM_DEBUG_KMS("DFP2 disconnected\n");
771fe6b9
JG
4240 bios_0_scratch &= ~ATOM_S0_DFP2;
4241 bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
4242 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2;
4243 }
4244 }
4245 if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) &&
4246 (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) {
4247 if (connected) {
d9fdaafb 4248 DRM_DEBUG_KMS("DFP3 connected\n");
771fe6b9
JG
4249 bios_0_scratch |= ATOM_S0_DFP3;
4250 bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
4251 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3;
4252 } else {
d9fdaafb 4253 DRM_DEBUG_KMS("DFP3 disconnected\n");
771fe6b9
JG
4254 bios_0_scratch &= ~ATOM_S0_DFP3;
4255 bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
4256 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3;
4257 }
4258 }
4259 if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) &&
4260 (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) {
4261 if (connected) {
d9fdaafb 4262 DRM_DEBUG_KMS("DFP4 connected\n");
771fe6b9
JG
4263 bios_0_scratch |= ATOM_S0_DFP4;
4264 bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;
4265 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4;
4266 } else {
d9fdaafb 4267 DRM_DEBUG_KMS("DFP4 disconnected\n");
771fe6b9
JG
4268 bios_0_scratch &= ~ATOM_S0_DFP4;
4269 bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;
4270 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4;
4271 }
4272 }
4273 if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) &&
4274 (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) {
4275 if (connected) {
d9fdaafb 4276 DRM_DEBUG_KMS("DFP5 connected\n");
771fe6b9
JG
4277 bios_0_scratch |= ATOM_S0_DFP5;
4278 bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;
4279 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5;
4280 } else {
d9fdaafb 4281 DRM_DEBUG_KMS("DFP5 disconnected\n");
771fe6b9
JG
4282 bios_0_scratch &= ~ATOM_S0_DFP5;
4283 bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;
4284 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;
4285 }
4286 }
6f9f8a61
AD
4287 if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&
4288 (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {
4289 if (connected) {
4290 DRM_DEBUG_KMS("DFP6 connected\n");
4291 bios_0_scratch |= ATOM_S0_DFP6;
4292 bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;
4293 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;
4294 } else {
4295 DRM_DEBUG_KMS("DFP6 disconnected\n");
4296 bios_0_scratch &= ~ATOM_S0_DFP6;
4297 bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;
4298 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;
4299 }
4300 }
771fe6b9
JG
4301
4302 if (rdev->family >= CHIP_R600) {
4303 WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch);
4304 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);
4305 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
4306 } else {
4307 WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
4308 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
4309 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
4310 }
4311}
4312
4313void
4314radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
4315{
4316 struct drm_device *dev = encoder->dev;
4317 struct radeon_device *rdev = dev->dev_private;
4318 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4319 uint32_t bios_3_scratch;
4320
6f9f8a61
AD
4321 if (ASIC_IS_DCE4(rdev))
4322 return;
4323
771fe6b9
JG
4324 if (rdev->family >= CHIP_R600)
4325 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
4326 else
4327 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);
4328
4329 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
4330 bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
4331 bios_3_scratch |= (crtc << 18);
4332 }
4333 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
4334 bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
4335 bios_3_scratch |= (crtc << 24);
4336 }
4337 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
4338 bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
4339 bios_3_scratch |= (crtc << 16);
4340 }
4341 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
4342 bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
4343 bios_3_scratch |= (crtc << 20);
4344 }
4345 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
4346 bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
4347 bios_3_scratch |= (crtc << 17);
4348 }
4349 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
4350 bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
4351 bios_3_scratch |= (crtc << 19);
4352 }
4353 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
4354 bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
4355 bios_3_scratch |= (crtc << 23);
4356 }
4357 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {
4358 bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
4359 bios_3_scratch |= (crtc << 25);
4360 }
4361
4362 if (rdev->family >= CHIP_R600)
4363 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);
4364 else
4365 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
4366}
4367
4368void
4369radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
4370{
4371 struct drm_device *dev = encoder->dev;
4372 struct radeon_device *rdev = dev->dev_private;
4373 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
4374 uint32_t bios_2_scratch;
4375
3ac0eb6d
AD
4376 if (ASIC_IS_DCE4(rdev))
4377 return;
4378
771fe6b9
JG
4379 if (rdev->family >= CHIP_R600)
4380 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
4381 else
4382 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
4383
4384 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
4385 if (on)
4386 bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
4387 else
4388 bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
4389 }
4390 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
4391 if (on)
4392 bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
4393 else
4394 bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
4395 }
4396 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
4397 if (on)
4398 bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
4399 else
4400 bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
4401 }
4402 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
4403 if (on)
4404 bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
4405 else
4406 bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
4407 }
4408 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
4409 if (on)
4410 bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
4411 else
4412 bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
4413 }
4414 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
4415 if (on)
4416 bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
4417 else
4418 bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
4419 }
4420 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
4421 if (on)
4422 bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
4423 else
4424 bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
4425 }
4426 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {
4427 if (on)
4428 bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
4429 else
4430 bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
4431 }
4432 if (radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) {
4433 if (on)
4434 bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;
4435 else
4436 bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;
4437 }
4438 if (radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) {
4439 if (on)
4440 bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;
4441 else
4442 bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;
4443 }
4444
4445 if (rdev->family >= CHIP_R600)
4446 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
4447 else
4448 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
4449}