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