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