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