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