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