2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
23 * Authors: Dave Airlie
27 #include <drm/amdgpu_drm.h>
29 #include "amdgpu_atombios.h"
30 #include "amdgpu_atomfirmware.h"
31 #include "amdgpu_i2c.h"
34 #include "atom-bits.h"
35 #include "atombios_encoders.h"
36 #include "bif/bif_4_1_d.h"
38 static void amdgpu_atombios_lookup_i2c_gpio_quirks(struct amdgpu_device
*adev
,
39 ATOM_GPIO_I2C_ASSIGMENT
*gpio
,
45 static struct amdgpu_i2c_bus_rec
amdgpu_atombios_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT
*gpio
)
47 struct amdgpu_i2c_bus_rec i2c
;
49 memset(&i2c
, 0, sizeof(struct amdgpu_i2c_bus_rec
));
51 i2c
.mask_clk_reg
= le16_to_cpu(gpio
->usClkMaskRegisterIndex
);
52 i2c
.mask_data_reg
= le16_to_cpu(gpio
->usDataMaskRegisterIndex
);
53 i2c
.en_clk_reg
= le16_to_cpu(gpio
->usClkEnRegisterIndex
);
54 i2c
.en_data_reg
= le16_to_cpu(gpio
->usDataEnRegisterIndex
);
55 i2c
.y_clk_reg
= le16_to_cpu(gpio
->usClkY_RegisterIndex
);
56 i2c
.y_data_reg
= le16_to_cpu(gpio
->usDataY_RegisterIndex
);
57 i2c
.a_clk_reg
= le16_to_cpu(gpio
->usClkA_RegisterIndex
);
58 i2c
.a_data_reg
= le16_to_cpu(gpio
->usDataA_RegisterIndex
);
59 i2c
.mask_clk_mask
= (1 << gpio
->ucClkMaskShift
);
60 i2c
.mask_data_mask
= (1 << gpio
->ucDataMaskShift
);
61 i2c
.en_clk_mask
= (1 << gpio
->ucClkEnShift
);
62 i2c
.en_data_mask
= (1 << gpio
->ucDataEnShift
);
63 i2c
.y_clk_mask
= (1 << gpio
->ucClkY_Shift
);
64 i2c
.y_data_mask
= (1 << gpio
->ucDataY_Shift
);
65 i2c
.a_clk_mask
= (1 << gpio
->ucClkA_Shift
);
66 i2c
.a_data_mask
= (1 << gpio
->ucDataA_Shift
);
68 if (gpio
->sucI2cId
.sbfAccess
.bfHW_Capable
)
69 i2c
.hw_capable
= true;
71 i2c
.hw_capable
= false;
73 if (gpio
->sucI2cId
.ucAccess
== 0xa0)
78 i2c
.i2c_id
= gpio
->sucI2cId
.ucAccess
;
88 struct amdgpu_i2c_bus_rec
amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device
*adev
,
91 struct atom_context
*ctx
= adev
->mode_info
.atom_context
;
92 ATOM_GPIO_I2C_ASSIGMENT
*gpio
;
93 struct amdgpu_i2c_bus_rec i2c
;
94 int index
= GetIndexIntoMasterTable(DATA
, GPIO_I2C_Info
);
95 struct _ATOM_GPIO_I2C_INFO
*i2c_info
;
96 uint16_t data_offset
, size
;
99 memset(&i2c
, 0, sizeof(struct amdgpu_i2c_bus_rec
));
102 if (amdgpu_atom_parse_data_header(ctx
, index
, &size
, NULL
, NULL
, &data_offset
)) {
103 i2c_info
= (struct _ATOM_GPIO_I2C_INFO
*)(ctx
->bios
+ data_offset
);
105 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
106 sizeof(ATOM_GPIO_I2C_ASSIGMENT
);
108 gpio
= &i2c_info
->asGPIO_Info
[0];
109 for (i
= 0; i
< num_indices
; i
++) {
111 amdgpu_atombios_lookup_i2c_gpio_quirks(adev
, gpio
, i
);
113 if (gpio
->sucI2cId
.ucAccess
== id
) {
114 i2c
= amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio
);
117 gpio
= (ATOM_GPIO_I2C_ASSIGMENT
*)
118 ((u8
*)gpio
+ sizeof(ATOM_GPIO_I2C_ASSIGMENT
));
125 void amdgpu_atombios_i2c_init(struct amdgpu_device
*adev
)
127 struct atom_context
*ctx
= adev
->mode_info
.atom_context
;
128 ATOM_GPIO_I2C_ASSIGMENT
*gpio
;
129 struct amdgpu_i2c_bus_rec i2c
;
130 int index
= GetIndexIntoMasterTable(DATA
, GPIO_I2C_Info
);
131 struct _ATOM_GPIO_I2C_INFO
*i2c_info
;
132 uint16_t data_offset
, size
;
136 if (amdgpu_atom_parse_data_header(ctx
, index
, &size
, NULL
, NULL
, &data_offset
)) {
137 i2c_info
= (struct _ATOM_GPIO_I2C_INFO
*)(ctx
->bios
+ data_offset
);
139 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
140 sizeof(ATOM_GPIO_I2C_ASSIGMENT
);
142 gpio
= &i2c_info
->asGPIO_Info
[0];
143 for (i
= 0; i
< num_indices
; i
++) {
144 amdgpu_atombios_lookup_i2c_gpio_quirks(adev
, gpio
, i
);
146 i2c
= amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio
);
149 sprintf(stmp
, "0x%x", i2c
.i2c_id
);
150 adev
->i2c_bus
[i
] = amdgpu_i2c_create(adev
->ddev
, &i2c
, stmp
);
152 gpio
= (ATOM_GPIO_I2C_ASSIGMENT
*)
153 ((u8
*)gpio
+ sizeof(ATOM_GPIO_I2C_ASSIGMENT
));
158 struct amdgpu_gpio_rec
159 amdgpu_atombios_lookup_gpio(struct amdgpu_device
*adev
,
162 struct atom_context
*ctx
= adev
->mode_info
.atom_context
;
163 struct amdgpu_gpio_rec gpio
;
164 int index
= GetIndexIntoMasterTable(DATA
, GPIO_Pin_LUT
);
165 struct _ATOM_GPIO_PIN_LUT
*gpio_info
;
166 ATOM_GPIO_PIN_ASSIGNMENT
*pin
;
167 u16 data_offset
, size
;
170 memset(&gpio
, 0, sizeof(struct amdgpu_gpio_rec
));
173 if (amdgpu_atom_parse_data_header(ctx
, index
, &size
, NULL
, NULL
, &data_offset
)) {
174 gpio_info
= (struct _ATOM_GPIO_PIN_LUT
*)(ctx
->bios
+ data_offset
);
176 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
177 sizeof(ATOM_GPIO_PIN_ASSIGNMENT
);
179 pin
= gpio_info
->asGPIO_Pin
;
180 for (i
= 0; i
< num_indices
; i
++) {
181 if (id
== pin
->ucGPIO_ID
) {
182 gpio
.id
= pin
->ucGPIO_ID
;
183 gpio
.reg
= le16_to_cpu(pin
->usGpioPin_AIndex
);
184 gpio
.shift
= pin
->ucGpioPinBitShift
;
185 gpio
.mask
= (1 << pin
->ucGpioPinBitShift
);
189 pin
= (ATOM_GPIO_PIN_ASSIGNMENT
*)
190 ((u8
*)pin
+ sizeof(ATOM_GPIO_PIN_ASSIGNMENT
));
197 static struct amdgpu_hpd
198 amdgpu_atombios_get_hpd_info_from_gpio(struct amdgpu_device
*adev
,
199 struct amdgpu_gpio_rec
*gpio
)
201 struct amdgpu_hpd hpd
;
204 memset(&hpd
, 0, sizeof(struct amdgpu_hpd
));
206 reg
= amdgpu_display_hpd_get_gpio_reg(adev
);
209 if (gpio
->reg
== reg
) {
212 hpd
.hpd
= AMDGPU_HPD_1
;
215 hpd
.hpd
= AMDGPU_HPD_2
;
218 hpd
.hpd
= AMDGPU_HPD_3
;
221 hpd
.hpd
= AMDGPU_HPD_4
;
224 hpd
.hpd
= AMDGPU_HPD_5
;
227 hpd
.hpd
= AMDGPU_HPD_6
;
230 hpd
.hpd
= AMDGPU_HPD_NONE
;
234 hpd
.hpd
= AMDGPU_HPD_NONE
;
238 static const int object_connector_convert
[] = {
239 DRM_MODE_CONNECTOR_Unknown
,
240 DRM_MODE_CONNECTOR_DVII
,
241 DRM_MODE_CONNECTOR_DVII
,
242 DRM_MODE_CONNECTOR_DVID
,
243 DRM_MODE_CONNECTOR_DVID
,
244 DRM_MODE_CONNECTOR_VGA
,
245 DRM_MODE_CONNECTOR_Composite
,
246 DRM_MODE_CONNECTOR_SVIDEO
,
247 DRM_MODE_CONNECTOR_Unknown
,
248 DRM_MODE_CONNECTOR_Unknown
,
249 DRM_MODE_CONNECTOR_9PinDIN
,
250 DRM_MODE_CONNECTOR_Unknown
,
251 DRM_MODE_CONNECTOR_HDMIA
,
252 DRM_MODE_CONNECTOR_HDMIB
,
253 DRM_MODE_CONNECTOR_LVDS
,
254 DRM_MODE_CONNECTOR_9PinDIN
,
255 DRM_MODE_CONNECTOR_Unknown
,
256 DRM_MODE_CONNECTOR_Unknown
,
257 DRM_MODE_CONNECTOR_Unknown
,
258 DRM_MODE_CONNECTOR_DisplayPort
,
259 DRM_MODE_CONNECTOR_eDP
,
260 DRM_MODE_CONNECTOR_Unknown
263 bool amdgpu_atombios_has_dce_engine_info(struct amdgpu_device
*adev
)
265 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
266 struct atom_context
*ctx
= mode_info
->atom_context
;
267 int index
= GetIndexIntoMasterTable(DATA
, Object_Header
);
268 u16 size
, data_offset
;
270 ATOM_DISPLAY_OBJECT_PATH_TABLE
*path_obj
;
271 ATOM_OBJECT_HEADER
*obj_header
;
273 if (!amdgpu_atom_parse_data_header(ctx
, index
, &size
, &frev
, &crev
, &data_offset
))
279 obj_header
= (ATOM_OBJECT_HEADER
*) (ctx
->bios
+ data_offset
);
280 path_obj
= (ATOM_DISPLAY_OBJECT_PATH_TABLE
*)
281 (ctx
->bios
+ data_offset
+
282 le16_to_cpu(obj_header
->usDisplayPathTableOffset
));
284 if (path_obj
->ucNumOfDispPath
)
290 bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device
*adev
)
292 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
293 struct atom_context
*ctx
= mode_info
->atom_context
;
294 int index
= GetIndexIntoMasterTable(DATA
, Object_Header
);
295 u16 size
, data_offset
;
297 ATOM_CONNECTOR_OBJECT_TABLE
*con_obj
;
298 ATOM_ENCODER_OBJECT_TABLE
*enc_obj
;
299 ATOM_OBJECT_TABLE
*router_obj
;
300 ATOM_DISPLAY_OBJECT_PATH_TABLE
*path_obj
;
301 ATOM_OBJECT_HEADER
*obj_header
;
302 int i
, j
, k
, path_size
, device_support
;
304 u16 conn_id
, connector_object_id
;
305 struct amdgpu_i2c_bus_rec ddc_bus
;
306 struct amdgpu_router router
;
307 struct amdgpu_gpio_rec gpio
;
308 struct amdgpu_hpd hpd
;
310 if (!amdgpu_atom_parse_data_header(ctx
, index
, &size
, &frev
, &crev
, &data_offset
))
316 obj_header
= (ATOM_OBJECT_HEADER
*) (ctx
->bios
+ data_offset
);
317 path_obj
= (ATOM_DISPLAY_OBJECT_PATH_TABLE
*)
318 (ctx
->bios
+ data_offset
+
319 le16_to_cpu(obj_header
->usDisplayPathTableOffset
));
320 con_obj
= (ATOM_CONNECTOR_OBJECT_TABLE
*)
321 (ctx
->bios
+ data_offset
+
322 le16_to_cpu(obj_header
->usConnectorObjectTableOffset
));
323 enc_obj
= (ATOM_ENCODER_OBJECT_TABLE
*)
324 (ctx
->bios
+ data_offset
+
325 le16_to_cpu(obj_header
->usEncoderObjectTableOffset
));
326 router_obj
= (ATOM_OBJECT_TABLE
*)
327 (ctx
->bios
+ data_offset
+
328 le16_to_cpu(obj_header
->usRouterObjectTableOffset
));
329 device_support
= le16_to_cpu(obj_header
->usDeviceSupport
);
332 for (i
= 0; i
< path_obj
->ucNumOfDispPath
; i
++) {
333 uint8_t *addr
= (uint8_t *) path_obj
->asDispPath
;
334 ATOM_DISPLAY_OBJECT_PATH
*path
;
336 path
= (ATOM_DISPLAY_OBJECT_PATH
*) addr
;
337 path_size
+= le16_to_cpu(path
->usSize
);
339 if (device_support
& le16_to_cpu(path
->usDeviceTag
)) {
341 (le16_to_cpu(path
->usConnObjectId
) & OBJECT_ID_MASK
)
344 /* Skip TV/CV support */
345 if ((le16_to_cpu(path
->usDeviceTag
) ==
346 ATOM_DEVICE_TV1_SUPPORT
) ||
347 (le16_to_cpu(path
->usDeviceTag
) ==
348 ATOM_DEVICE_CV_SUPPORT
))
351 if (con_obj_id
>= ARRAY_SIZE(object_connector_convert
)) {
352 DRM_ERROR("invalid con_obj_id %d for device tag 0x%04x\n",
353 con_obj_id
, le16_to_cpu(path
->usDeviceTag
));
358 object_connector_convert
[con_obj_id
];
359 connector_object_id
= con_obj_id
;
361 if (connector_type
== DRM_MODE_CONNECTOR_Unknown
)
364 router
.ddc_valid
= false;
365 router
.cd_valid
= false;
366 for (j
= 0; j
< ((le16_to_cpu(path
->usSize
) - 8) / 2); j
++) {
367 uint8_t grph_obj_type
=
368 (le16_to_cpu(path
->usGraphicObjIds
[j
]) &
369 OBJECT_TYPE_MASK
) >> OBJECT_TYPE_SHIFT
;
371 if (grph_obj_type
== GRAPH_OBJECT_TYPE_ENCODER
) {
372 for (k
= 0; k
< enc_obj
->ucNumberOfObjects
; k
++) {
373 u16 encoder_obj
= le16_to_cpu(enc_obj
->asObjects
[k
].usObjectID
);
374 if (le16_to_cpu(path
->usGraphicObjIds
[j
]) == encoder_obj
) {
375 ATOM_COMMON_RECORD_HEADER
*record
= (ATOM_COMMON_RECORD_HEADER
*)
376 (ctx
->bios
+ data_offset
+
377 le16_to_cpu(enc_obj
->asObjects
[k
].usRecordOffset
));
378 ATOM_ENCODER_CAP_RECORD
*cap_record
;
381 while (record
->ucRecordSize
> 0 &&
382 record
->ucRecordType
> 0 &&
383 record
->ucRecordType
<= ATOM_MAX_OBJECT_RECORD_NUMBER
) {
384 switch (record
->ucRecordType
) {
385 case ATOM_ENCODER_CAP_RECORD_TYPE
:
386 cap_record
=(ATOM_ENCODER_CAP_RECORD
*)
388 caps
= le16_to_cpu(cap_record
->usEncoderCap
);
391 record
= (ATOM_COMMON_RECORD_HEADER
*)
392 ((char *)record
+ record
->ucRecordSize
);
394 amdgpu_display_add_encoder(adev
, encoder_obj
,
395 le16_to_cpu(path
->usDeviceTag
),
399 } else if (grph_obj_type
== GRAPH_OBJECT_TYPE_ROUTER
) {
400 for (k
= 0; k
< router_obj
->ucNumberOfObjects
; k
++) {
401 u16 router_obj_id
= le16_to_cpu(router_obj
->asObjects
[k
].usObjectID
);
402 if (le16_to_cpu(path
->usGraphicObjIds
[j
]) == router_obj_id
) {
403 ATOM_COMMON_RECORD_HEADER
*record
= (ATOM_COMMON_RECORD_HEADER
*)
404 (ctx
->bios
+ data_offset
+
405 le16_to_cpu(router_obj
->asObjects
[k
].usRecordOffset
));
406 ATOM_I2C_RECORD
*i2c_record
;
407 ATOM_I2C_ID_CONFIG_ACCESS
*i2c_config
;
408 ATOM_ROUTER_DDC_PATH_SELECT_RECORD
*ddc_path
;
409 ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD
*cd_path
;
410 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT
*router_src_dst_table
=
411 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT
*)
412 (ctx
->bios
+ data_offset
+
413 le16_to_cpu(router_obj
->asObjects
[k
].usSrcDstTableOffset
));
414 u8
*num_dst_objs
= (u8
*)
415 ((u8
*)router_src_dst_table
+ 1 +
416 (router_src_dst_table
->ucNumberOfSrc
* 2));
417 u16
*dst_objs
= (u16
*)(num_dst_objs
+ 1);
420 router
.router_id
= router_obj_id
;
421 for (enum_id
= 0; enum_id
< (*num_dst_objs
); enum_id
++) {
422 if (le16_to_cpu(path
->usConnObjectId
) ==
423 le16_to_cpu(dst_objs
[enum_id
]))
427 while (record
->ucRecordSize
> 0 &&
428 record
->ucRecordType
> 0 &&
429 record
->ucRecordType
<= ATOM_MAX_OBJECT_RECORD_NUMBER
) {
430 switch (record
->ucRecordType
) {
431 case ATOM_I2C_RECORD_TYPE
:
436 (ATOM_I2C_ID_CONFIG_ACCESS
*)
437 &i2c_record
->sucI2cId
;
439 amdgpu_atombios_lookup_i2c_gpio(adev
,
442 router
.i2c_addr
= i2c_record
->ucI2CAddr
>> 1;
444 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE
:
445 ddc_path
= (ATOM_ROUTER_DDC_PATH_SELECT_RECORD
*)
447 router
.ddc_valid
= true;
448 router
.ddc_mux_type
= ddc_path
->ucMuxType
;
449 router
.ddc_mux_control_pin
= ddc_path
->ucMuxControlPin
;
450 router
.ddc_mux_state
= ddc_path
->ucMuxState
[enum_id
];
452 case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE
:
453 cd_path
= (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD
*)
455 router
.cd_valid
= true;
456 router
.cd_mux_type
= cd_path
->ucMuxType
;
457 router
.cd_mux_control_pin
= cd_path
->ucMuxControlPin
;
458 router
.cd_mux_state
= cd_path
->ucMuxState
[enum_id
];
461 record
= (ATOM_COMMON_RECORD_HEADER
*)
462 ((char *)record
+ record
->ucRecordSize
);
469 /* look up gpio for ddc, hpd */
470 ddc_bus
.valid
= false;
471 hpd
.hpd
= AMDGPU_HPD_NONE
;
472 if ((le16_to_cpu(path
->usDeviceTag
) &
473 (ATOM_DEVICE_TV_SUPPORT
| ATOM_DEVICE_CV_SUPPORT
)) == 0) {
474 for (j
= 0; j
< con_obj
->ucNumberOfObjects
; j
++) {
475 if (le16_to_cpu(path
->usConnObjectId
) ==
476 le16_to_cpu(con_obj
->asObjects
[j
].
478 ATOM_COMMON_RECORD_HEADER
480 (ATOM_COMMON_RECORD_HEADER
482 (ctx
->bios
+ data_offset
+
483 le16_to_cpu(con_obj
->
486 ATOM_I2C_RECORD
*i2c_record
;
487 ATOM_HPD_INT_RECORD
*hpd_record
;
488 ATOM_I2C_ID_CONFIG_ACCESS
*i2c_config
;
490 while (record
->ucRecordSize
> 0 &&
491 record
->ucRecordType
> 0 &&
492 record
->ucRecordType
<= ATOM_MAX_OBJECT_RECORD_NUMBER
) {
493 switch (record
->ucRecordType
) {
494 case ATOM_I2C_RECORD_TYPE
:
499 (ATOM_I2C_ID_CONFIG_ACCESS
*)
500 &i2c_record
->sucI2cId
;
501 ddc_bus
= amdgpu_atombios_lookup_i2c_gpio(adev
,
505 case ATOM_HPD_INT_RECORD_TYPE
:
507 (ATOM_HPD_INT_RECORD
*)
509 gpio
= amdgpu_atombios_lookup_gpio(adev
,
510 hpd_record
->ucHPDIntGPIOID
);
511 hpd
= amdgpu_atombios_get_hpd_info_from_gpio(adev
, &gpio
);
512 hpd
.plugged_state
= hpd_record
->ucPlugged_PinState
;
516 (ATOM_COMMON_RECORD_HEADER
527 /* needed for aux chan transactions */
528 ddc_bus
.hpd
= hpd
.hpd
;
530 conn_id
= le16_to_cpu(path
->usConnObjectId
);
532 amdgpu_display_add_connector(adev
,
534 le16_to_cpu(path
->usDeviceTag
),
535 connector_type
, &ddc_bus
,
543 amdgpu_link_encoder_connector(adev
->ddev
);
548 union firmware_info
{
549 ATOM_FIRMWARE_INFO info
;
550 ATOM_FIRMWARE_INFO_V1_2 info_12
;
551 ATOM_FIRMWARE_INFO_V1_3 info_13
;
552 ATOM_FIRMWARE_INFO_V1_4 info_14
;
553 ATOM_FIRMWARE_INFO_V2_1 info_21
;
554 ATOM_FIRMWARE_INFO_V2_2 info_22
;
557 int amdgpu_atombios_get_clock_info(struct amdgpu_device
*adev
)
559 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
560 int index
= GetIndexIntoMasterTable(DATA
, FirmwareInfo
);
562 uint16_t data_offset
;
565 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, NULL
,
566 &frev
, &crev
, &data_offset
)) {
568 struct amdgpu_pll
*ppll
= &adev
->clock
.ppll
[0];
569 struct amdgpu_pll
*spll
= &adev
->clock
.spll
;
570 struct amdgpu_pll
*mpll
= &adev
->clock
.mpll
;
571 union firmware_info
*firmware_info
=
572 (union firmware_info
*)(mode_info
->atom_context
->bios
+
575 ppll
->reference_freq
=
576 le16_to_cpu(firmware_info
->info
.usReferenceClock
);
577 ppll
->reference_div
= 0;
580 le32_to_cpu(firmware_info
->info_12
.ulMinPixelClockPLL_Output
);
582 le32_to_cpu(firmware_info
->info
.ulMaxPixelClockPLL_Output
);
584 ppll
->lcd_pll_out_min
=
585 le16_to_cpu(firmware_info
->info_14
.usLcdMinPixelClockPLL_Output
) * 100;
586 if (ppll
->lcd_pll_out_min
== 0)
587 ppll
->lcd_pll_out_min
= ppll
->pll_out_min
;
588 ppll
->lcd_pll_out_max
=
589 le16_to_cpu(firmware_info
->info_14
.usLcdMaxPixelClockPLL_Output
) * 100;
590 if (ppll
->lcd_pll_out_max
== 0)
591 ppll
->lcd_pll_out_max
= ppll
->pll_out_max
;
593 if (ppll
->pll_out_min
== 0)
594 ppll
->pll_out_min
= 64800;
597 le16_to_cpu(firmware_info
->info
.usMinPixelClockPLL_Input
);
599 le16_to_cpu(firmware_info
->info
.usMaxPixelClockPLL_Input
);
601 ppll
->min_post_div
= 2;
602 ppll
->max_post_div
= 0x7f;
603 ppll
->min_frac_feedback_div
= 0;
604 ppll
->max_frac_feedback_div
= 9;
605 ppll
->min_ref_div
= 2;
606 ppll
->max_ref_div
= 0x3ff;
607 ppll
->min_feedback_div
= 4;
608 ppll
->max_feedback_div
= 0xfff;
611 for (i
= 1; i
< AMDGPU_MAX_PPLL
; i
++)
612 adev
->clock
.ppll
[i
] = *ppll
;
615 spll
->reference_freq
=
616 le16_to_cpu(firmware_info
->info_21
.usCoreReferenceClock
);
617 spll
->reference_div
= 0;
620 le16_to_cpu(firmware_info
->info
.usMinEngineClockPLL_Output
);
622 le32_to_cpu(firmware_info
->info
.ulMaxEngineClockPLL_Output
);
625 if (spll
->pll_out_min
== 0)
626 spll
->pll_out_min
= 64800;
629 le16_to_cpu(firmware_info
->info
.usMinEngineClockPLL_Input
);
631 le16_to_cpu(firmware_info
->info
.usMaxEngineClockPLL_Input
);
633 spll
->min_post_div
= 1;
634 spll
->max_post_div
= 1;
635 spll
->min_ref_div
= 2;
636 spll
->max_ref_div
= 0xff;
637 spll
->min_feedback_div
= 4;
638 spll
->max_feedback_div
= 0xff;
642 mpll
->reference_freq
=
643 le16_to_cpu(firmware_info
->info_21
.usMemoryReferenceClock
);
644 mpll
->reference_div
= 0;
647 le16_to_cpu(firmware_info
->info
.usMinMemoryClockPLL_Output
);
649 le32_to_cpu(firmware_info
->info
.ulMaxMemoryClockPLL_Output
);
652 if (mpll
->pll_out_min
== 0)
653 mpll
->pll_out_min
= 64800;
656 le16_to_cpu(firmware_info
->info
.usMinMemoryClockPLL_Input
);
658 le16_to_cpu(firmware_info
->info
.usMaxMemoryClockPLL_Input
);
660 adev
->clock
.default_sclk
=
661 le32_to_cpu(firmware_info
->info
.ulDefaultEngineClock
);
662 adev
->clock
.default_mclk
=
663 le32_to_cpu(firmware_info
->info
.ulDefaultMemoryClock
);
665 mpll
->min_post_div
= 1;
666 mpll
->max_post_div
= 1;
667 mpll
->min_ref_div
= 2;
668 mpll
->max_ref_div
= 0xff;
669 mpll
->min_feedback_div
= 4;
670 mpll
->max_feedback_div
= 0xff;
674 adev
->clock
.default_dispclk
=
675 le32_to_cpu(firmware_info
->info_21
.ulDefaultDispEngineClkFreq
);
676 /* set a reasonable default for DP */
677 if (adev
->clock
.default_dispclk
< 53900) {
678 DRM_DEBUG("Changing default dispclk from %dMhz to 600Mhz\n",
679 adev
->clock
.default_dispclk
/ 100);
680 adev
->clock
.default_dispclk
= 60000;
681 } else if (adev
->clock
.default_dispclk
<= 60000) {
682 DRM_DEBUG("Changing default dispclk from %dMhz to 625Mhz\n",
683 adev
->clock
.default_dispclk
/ 100);
684 adev
->clock
.default_dispclk
= 62500;
686 adev
->clock
.dp_extclk
=
687 le16_to_cpu(firmware_info
->info_21
.usUniphyDPModeExtClkFreq
);
688 adev
->clock
.current_dispclk
= adev
->clock
.default_dispclk
;
690 adev
->clock
.max_pixel_clock
= le16_to_cpu(firmware_info
->info
.usMaxPixelClock
);
691 if (adev
->clock
.max_pixel_clock
== 0)
692 adev
->clock
.max_pixel_clock
= 40000;
694 /* not technically a clock, but... */
695 adev
->mode_info
.firmware_flags
=
696 le16_to_cpu(firmware_info
->info
.usFirmwareCapability
.susAccess
);
701 adev
->pm
.current_sclk
= adev
->clock
.default_sclk
;
702 adev
->pm
.current_mclk
= adev
->clock
.default_mclk
;
708 ATOM_GFX_INFO_V2_1 info
;
711 int amdgpu_atombios_get_gfx_info(struct amdgpu_device
*adev
)
713 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
714 int index
= GetIndexIntoMasterTable(DATA
, GFX_Info
);
716 uint16_t data_offset
;
719 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, NULL
,
720 &frev
, &crev
, &data_offset
)) {
721 union gfx_info
*gfx_info
= (union gfx_info
*)
722 (mode_info
->atom_context
->bios
+ data_offset
);
724 adev
->gfx
.config
.max_shader_engines
= gfx_info
->info
.max_shader_engines
;
725 adev
->gfx
.config
.max_tile_pipes
= gfx_info
->info
.max_tile_pipes
;
726 adev
->gfx
.config
.max_cu_per_sh
= gfx_info
->info
.max_cu_per_sh
;
727 adev
->gfx
.config
.max_sh_per_se
= gfx_info
->info
.max_sh_per_se
;
728 adev
->gfx
.config
.max_backends_per_se
= gfx_info
->info
.max_backends_per_se
;
729 adev
->gfx
.config
.max_texture_channel_caches
=
730 gfx_info
->info
.max_texture_channel_caches
;
738 struct _ATOM_INTEGRATED_SYSTEM_INFO info
;
739 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2
;
740 struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6
;
741 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7
;
742 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8
;
743 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_9 info_9
;
747 * Return vram width from integrated system info table, if available,
750 int amdgpu_atombios_get_vram_width(struct amdgpu_device
*adev
)
752 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
753 int index
= GetIndexIntoMasterTable(DATA
, IntegratedSystemInfo
);
754 u16 data_offset
, size
;
755 union igp_info
*igp_info
;
758 /* get any igp specific overrides */
759 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, &size
,
760 &frev
, &crev
, &data_offset
)) {
761 igp_info
= (union igp_info
*)
762 (mode_info
->atom_context
->bios
+ data_offset
);
766 return igp_info
->info_8
.ucUMAChannelNumber
* 64;
775 static void amdgpu_atombios_get_igp_ss_overrides(struct amdgpu_device
*adev
,
776 struct amdgpu_atom_ss
*ss
,
779 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
780 int index
= GetIndexIntoMasterTable(DATA
, IntegratedSystemInfo
);
781 u16 data_offset
, size
;
782 union igp_info
*igp_info
;
784 u16 percentage
= 0, rate
= 0;
786 /* get any igp specific overrides */
787 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, &size
,
788 &frev
, &crev
, &data_offset
)) {
789 igp_info
= (union igp_info
*)
790 (mode_info
->atom_context
->bios
+ data_offset
);
794 case ASIC_INTERNAL_SS_ON_TMDS
:
795 percentage
= le16_to_cpu(igp_info
->info_6
.usDVISSPercentage
);
796 rate
= le16_to_cpu(igp_info
->info_6
.usDVISSpreadRateIn10Hz
);
798 case ASIC_INTERNAL_SS_ON_HDMI
:
799 percentage
= le16_to_cpu(igp_info
->info_6
.usHDMISSPercentage
);
800 rate
= le16_to_cpu(igp_info
->info_6
.usHDMISSpreadRateIn10Hz
);
802 case ASIC_INTERNAL_SS_ON_LVDS
:
803 percentage
= le16_to_cpu(igp_info
->info_6
.usLvdsSSPercentage
);
804 rate
= le16_to_cpu(igp_info
->info_6
.usLvdsSSpreadRateIn10Hz
);
810 case ASIC_INTERNAL_SS_ON_TMDS
:
811 percentage
= le16_to_cpu(igp_info
->info_7
.usDVISSPercentage
);
812 rate
= le16_to_cpu(igp_info
->info_7
.usDVISSpreadRateIn10Hz
);
814 case ASIC_INTERNAL_SS_ON_HDMI
:
815 percentage
= le16_to_cpu(igp_info
->info_7
.usHDMISSPercentage
);
816 rate
= le16_to_cpu(igp_info
->info_7
.usHDMISSpreadRateIn10Hz
);
818 case ASIC_INTERNAL_SS_ON_LVDS
:
819 percentage
= le16_to_cpu(igp_info
->info_7
.usLvdsSSPercentage
);
820 rate
= le16_to_cpu(igp_info
->info_7
.usLvdsSSpreadRateIn10Hz
);
826 case ASIC_INTERNAL_SS_ON_TMDS
:
827 percentage
= le16_to_cpu(igp_info
->info_8
.usDVISSPercentage
);
828 rate
= le16_to_cpu(igp_info
->info_8
.usDVISSpreadRateIn10Hz
);
830 case ASIC_INTERNAL_SS_ON_HDMI
:
831 percentage
= le16_to_cpu(igp_info
->info_8
.usHDMISSPercentage
);
832 rate
= le16_to_cpu(igp_info
->info_8
.usHDMISSpreadRateIn10Hz
);
834 case ASIC_INTERNAL_SS_ON_LVDS
:
835 percentage
= le16_to_cpu(igp_info
->info_8
.usLvdsSSPercentage
);
836 rate
= le16_to_cpu(igp_info
->info_8
.usLvdsSSpreadRateIn10Hz
);
842 case ASIC_INTERNAL_SS_ON_TMDS
:
843 percentage
= le16_to_cpu(igp_info
->info_9
.usDVISSPercentage
);
844 rate
= le16_to_cpu(igp_info
->info_9
.usDVISSpreadRateIn10Hz
);
846 case ASIC_INTERNAL_SS_ON_HDMI
:
847 percentage
= le16_to_cpu(igp_info
->info_9
.usHDMISSPercentage
);
848 rate
= le16_to_cpu(igp_info
->info_9
.usHDMISSpreadRateIn10Hz
);
850 case ASIC_INTERNAL_SS_ON_LVDS
:
851 percentage
= le16_to_cpu(igp_info
->info_9
.usLvdsSSPercentage
);
852 rate
= le16_to_cpu(igp_info
->info_9
.usLvdsSSpreadRateIn10Hz
);
857 DRM_ERROR("Unsupported IGP table: %d %d\n", frev
, crev
);
861 ss
->percentage
= percentage
;
868 struct _ATOM_ASIC_INTERNAL_SS_INFO info
;
869 struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2
;
870 struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3
;
873 union asic_ss_assignment
{
874 struct _ATOM_ASIC_SS_ASSIGNMENT v1
;
875 struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2
;
876 struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3
;
879 bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device
*adev
,
880 struct amdgpu_atom_ss
*ss
,
883 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
884 int index
= GetIndexIntoMasterTable(DATA
, ASIC_InternalSS_Info
);
885 uint16_t data_offset
, size
;
886 union asic_ss_info
*ss_info
;
887 union asic_ss_assignment
*ss_assign
;
891 if (id
== ASIC_INTERNAL_MEMORY_SS
) {
892 if (!(adev
->mode_info
.firmware_flags
& ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT
))
895 if (id
== ASIC_INTERNAL_ENGINE_SS
) {
896 if (!(adev
->mode_info
.firmware_flags
& ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT
))
900 memset(ss
, 0, sizeof(struct amdgpu_atom_ss
));
901 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, &size
,
902 &frev
, &crev
, &data_offset
)) {
905 (union asic_ss_info
*)(mode_info
->atom_context
->bios
+ data_offset
);
909 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
910 sizeof(ATOM_ASIC_SS_ASSIGNMENT
);
912 ss_assign
= (union asic_ss_assignment
*)((u8
*)&ss_info
->info
.asSpreadSpectrum
[0]);
913 for (i
= 0; i
< num_indices
; i
++) {
914 if ((ss_assign
->v1
.ucClockIndication
== id
) &&
915 (clock
<= le32_to_cpu(ss_assign
->v1
.ulTargetClockRange
))) {
917 le16_to_cpu(ss_assign
->v1
.usSpreadSpectrumPercentage
);
918 ss
->type
= ss_assign
->v1
.ucSpreadSpectrumMode
;
919 ss
->rate
= le16_to_cpu(ss_assign
->v1
.usSpreadRateInKhz
);
920 ss
->percentage_divider
= 100;
923 ss_assign
= (union asic_ss_assignment
*)
924 ((u8
*)ss_assign
+ sizeof(ATOM_ASIC_SS_ASSIGNMENT
));
928 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
929 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2
);
930 ss_assign
= (union asic_ss_assignment
*)((u8
*)&ss_info
->info_2
.asSpreadSpectrum
[0]);
931 for (i
= 0; i
< num_indices
; i
++) {
932 if ((ss_assign
->v2
.ucClockIndication
== id
) &&
933 (clock
<= le32_to_cpu(ss_assign
->v2
.ulTargetClockRange
))) {
935 le16_to_cpu(ss_assign
->v2
.usSpreadSpectrumPercentage
);
936 ss
->type
= ss_assign
->v2
.ucSpreadSpectrumMode
;
937 ss
->rate
= le16_to_cpu(ss_assign
->v2
.usSpreadRateIn10Hz
);
938 ss
->percentage_divider
= 100;
940 ((id
== ASIC_INTERNAL_ENGINE_SS
) ||
941 (id
== ASIC_INTERNAL_MEMORY_SS
)))
945 ss_assign
= (union asic_ss_assignment
*)
946 ((u8
*)ss_assign
+ sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2
));
950 num_indices
= (size
- sizeof(ATOM_COMMON_TABLE_HEADER
)) /
951 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3
);
952 ss_assign
= (union asic_ss_assignment
*)((u8
*)&ss_info
->info_3
.asSpreadSpectrum
[0]);
953 for (i
= 0; i
< num_indices
; i
++) {
954 if ((ss_assign
->v3
.ucClockIndication
== id
) &&
955 (clock
<= le32_to_cpu(ss_assign
->v3
.ulTargetClockRange
))) {
957 le16_to_cpu(ss_assign
->v3
.usSpreadSpectrumPercentage
);
958 ss
->type
= ss_assign
->v3
.ucSpreadSpectrumMode
;
959 ss
->rate
= le16_to_cpu(ss_assign
->v3
.usSpreadRateIn10Hz
);
960 if (ss_assign
->v3
.ucSpreadSpectrumMode
&
961 SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK
)
962 ss
->percentage_divider
= 1000;
964 ss
->percentage_divider
= 100;
965 if ((id
== ASIC_INTERNAL_ENGINE_SS
) ||
966 (id
== ASIC_INTERNAL_MEMORY_SS
))
968 if (adev
->flags
& AMD_IS_APU
)
969 amdgpu_atombios_get_igp_ss_overrides(adev
, ss
, id
);
972 ss_assign
= (union asic_ss_assignment
*)
973 ((u8
*)ss_assign
+ sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3
));
977 DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev
, crev
);
985 union get_clock_dividers
{
986 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1
;
987 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2
;
988 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3
;
989 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4
;
990 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5
;
991 struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in
;
992 struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out
;
995 int amdgpu_atombios_get_clock_dividers(struct amdgpu_device
*adev
,
999 struct atom_clock_dividers
*dividers
)
1001 union get_clock_dividers args
;
1002 int index
= GetIndexIntoMasterTable(COMMAND
, ComputeMemoryEnginePLL
);
1005 memset(&args
, 0, sizeof(args
));
1006 memset(dividers
, 0, sizeof(struct atom_clock_dividers
));
1008 if (!amdgpu_atom_parse_cmd_header(adev
->mode_info
.atom_context
, index
, &frev
, &crev
))
1015 /* r6xx, r7xx, evergreen, ni, si.
1016 * TODO: add support for asic_type <= CHIP_RV770*/
1017 if (clock_type
== COMPUTE_ENGINE_PLL_PARAM
) {
1018 args
.v3
.ulClockParams
= cpu_to_le32((clock_type
<< 24) | clock
);
1020 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1022 dividers
->post_div
= args
.v3
.ucPostDiv
;
1023 dividers
->enable_post_div
= (args
.v3
.ucCntlFlag
&
1024 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN
) ? true : false;
1025 dividers
->enable_dithen
= (args
.v3
.ucCntlFlag
&
1026 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE
) ? false : true;
1027 dividers
->whole_fb_div
= le16_to_cpu(args
.v3
.ulFbDiv
.usFbDiv
);
1028 dividers
->frac_fb_div
= le16_to_cpu(args
.v3
.ulFbDiv
.usFbDivFrac
);
1029 dividers
->ref_div
= args
.v3
.ucRefDiv
;
1030 dividers
->vco_mode
= (args
.v3
.ucCntlFlag
&
1031 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE
) ? 1 : 0;
1033 /* for SI we use ComputeMemoryClockParam for memory plls */
1034 if (adev
->asic_type
>= CHIP_TAHITI
)
1036 args
.v5
.ulClockParams
= cpu_to_le32((clock_type
<< 24) | clock
);
1038 args
.v5
.ucInputFlag
= ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN
;
1040 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1042 dividers
->post_div
= args
.v5
.ucPostDiv
;
1043 dividers
->enable_post_div
= (args
.v5
.ucCntlFlag
&
1044 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN
) ? true : false;
1045 dividers
->enable_dithen
= (args
.v5
.ucCntlFlag
&
1046 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE
) ? false : true;
1047 dividers
->whole_fb_div
= le16_to_cpu(args
.v5
.ulFbDiv
.usFbDiv
);
1048 dividers
->frac_fb_div
= le16_to_cpu(args
.v5
.ulFbDiv
.usFbDivFrac
);
1049 dividers
->ref_div
= args
.v5
.ucRefDiv
;
1050 dividers
->vco_mode
= (args
.v5
.ucCntlFlag
&
1051 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE
) ? 1 : 0;
1056 args
.v4
.ulClock
= cpu_to_le32(clock
); /* 10 khz */
1058 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1060 dividers
->post_divider
= dividers
->post_div
= args
.v4
.ucPostDiv
;
1061 dividers
->real_clock
= le32_to_cpu(args
.v4
.ulClock
);
1065 /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
1066 args
.v6_in
.ulClock
.ulComputeClockFlag
= clock_type
;
1067 args
.v6_in
.ulClock
.ulClockFreq
= cpu_to_le32(clock
); /* 10 khz */
1069 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1071 dividers
->whole_fb_div
= le16_to_cpu(args
.v6_out
.ulFbDiv
.usFbDiv
);
1072 dividers
->frac_fb_div
= le16_to_cpu(args
.v6_out
.ulFbDiv
.usFbDivFrac
);
1073 dividers
->ref_div
= args
.v6_out
.ucPllRefDiv
;
1074 dividers
->post_div
= args
.v6_out
.ucPllPostDiv
;
1075 dividers
->flags
= args
.v6_out
.ucPllCntlFlag
;
1076 dividers
->real_clock
= le32_to_cpu(args
.v6_out
.ulClock
.ulClock
);
1077 dividers
->post_divider
= args
.v6_out
.ulClock
.ucPostDiv
;
1085 int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device
*adev
,
1088 struct atom_mpll_param
*mpll_param
)
1090 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args
;
1091 int index
= GetIndexIntoMasterTable(COMMAND
, ComputeMemoryClockParam
);
1094 memset(&args
, 0, sizeof(args
));
1095 memset(mpll_param
, 0, sizeof(struct atom_mpll_param
));
1097 if (!amdgpu_atom_parse_cmd_header(adev
->mode_info
.atom_context
, index
, &frev
, &crev
))
1105 args
.ulClock
= cpu_to_le32(clock
); /* 10 khz */
1106 args
.ucInputFlag
= 0;
1108 args
.ucInputFlag
|= MPLL_INPUT_FLAG_STROBE_MODE_EN
;
1110 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1112 mpll_param
->clkfrac
= le16_to_cpu(args
.ulFbDiv
.usFbDivFrac
);
1113 mpll_param
->clkf
= le16_to_cpu(args
.ulFbDiv
.usFbDiv
);
1114 mpll_param
->post_div
= args
.ucPostDiv
;
1115 mpll_param
->dll_speed
= args
.ucDllSpeed
;
1116 mpll_param
->bwcntl
= args
.ucBWCntl
;
1117 mpll_param
->vco_mode
=
1118 (args
.ucPllCntlFlag
& MPLL_CNTL_FLAG_VCO_MODE_MASK
);
1119 mpll_param
->yclk_sel
=
1120 (args
.ucPllCntlFlag
& MPLL_CNTL_FLAG_BYPASS_DQ_PLL
) ? 1 : 0;
1122 (args
.ucPllCntlFlag
& MPLL_CNTL_FLAG_QDR_ENABLE
) ? 1 : 0;
1123 mpll_param
->half_rate
=
1124 (args
.ucPllCntlFlag
& MPLL_CNTL_FLAG_AD_HALF_RATE
) ? 1 : 0;
1136 void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device
*adev
,
1137 u32 eng_clock
, u32 mem_clock
)
1139 SET_ENGINE_CLOCK_PS_ALLOCATION args
;
1140 int index
= GetIndexIntoMasterTable(COMMAND
, DynamicMemorySettings
);
1143 memset(&args
, 0, sizeof(args
));
1145 tmp
= eng_clock
& SET_CLOCK_FREQ_MASK
;
1146 tmp
|= (COMPUTE_ENGINE_PLL_PARAM
<< 24);
1148 args
.ulTargetEngineClock
= cpu_to_le32(tmp
);
1150 args
.sReserved
.ulClock
= cpu_to_le32(mem_clock
& SET_CLOCK_FREQ_MASK
);
1152 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1155 void amdgpu_atombios_get_default_voltages(struct amdgpu_device
*adev
,
1156 u16
*vddc
, u16
*vddci
, u16
*mvdd
)
1158 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
1159 int index
= GetIndexIntoMasterTable(DATA
, FirmwareInfo
);
1162 union firmware_info
*firmware_info
;
1168 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, NULL
,
1169 &frev
, &crev
, &data_offset
)) {
1171 (union firmware_info
*)(mode_info
->atom_context
->bios
+
1173 *vddc
= le16_to_cpu(firmware_info
->info_14
.usBootUpVDDCVoltage
);
1174 if ((frev
== 2) && (crev
>= 2)) {
1175 *vddci
= le16_to_cpu(firmware_info
->info_22
.usBootUpVDDCIVoltage
);
1176 *mvdd
= le16_to_cpu(firmware_info
->info_22
.usBootUpMVDDCVoltage
);
1182 struct _SET_VOLTAGE_PS_ALLOCATION alloc
;
1183 struct _SET_VOLTAGE_PARAMETERS v1
;
1184 struct _SET_VOLTAGE_PARAMETERS_V2 v2
;
1185 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3
;
1188 int amdgpu_atombios_get_max_vddc(struct amdgpu_device
*adev
, u8 voltage_type
,
1189 u16 voltage_id
, u16
*voltage
)
1191 union set_voltage args
;
1192 int index
= GetIndexIntoMasterTable(COMMAND
, SetVoltage
);
1195 if (!amdgpu_atom_parse_cmd_header(adev
->mode_info
.atom_context
, index
, &frev
, &crev
))
1202 args
.v2
.ucVoltageType
= SET_VOLTAGE_GET_MAX_VOLTAGE
;
1203 args
.v2
.ucVoltageMode
= 0;
1204 args
.v2
.usVoltageLevel
= 0;
1206 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1208 *voltage
= le16_to_cpu(args
.v2
.usVoltageLevel
);
1211 args
.v3
.ucVoltageType
= voltage_type
;
1212 args
.v3
.ucVoltageMode
= ATOM_GET_VOLTAGE_LEVEL
;
1213 args
.v3
.usVoltageLevel
= cpu_to_le16(voltage_id
);
1215 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1217 *voltage
= le16_to_cpu(args
.v3
.usVoltageLevel
);
1220 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1227 int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device
*adev
,
1231 return amdgpu_atombios_get_max_vddc(adev
, VOLTAGE_TYPE_VDDC
, leakage_idx
, voltage
);
1234 int amdgpu_atombios_get_leakage_id_from_vbios(struct amdgpu_device
*adev
,
1237 union set_voltage args
;
1238 int index
= GetIndexIntoMasterTable(COMMAND
, SetVoltage
);
1241 if (!amdgpu_atom_parse_cmd_header(adev
->mode_info
.atom_context
, index
, &frev
, &crev
))
1247 args
.v3
.ucVoltageType
= 0;
1248 args
.v3
.ucVoltageMode
= ATOM_GET_LEAKAGE_ID
;
1249 args
.v3
.usVoltageLevel
= 0;
1251 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1253 *leakage_id
= le16_to_cpu(args
.v3
.usVoltageLevel
);
1256 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1263 int amdgpu_atombios_get_leakage_vddc_based_on_leakage_params(struct amdgpu_device
*adev
,
1264 u16
*vddc
, u16
*vddci
,
1265 u16 virtual_voltage_id
,
1266 u16 vbios_voltage_id
)
1268 int index
= GetIndexIntoMasterTable(DATA
, ASIC_ProfilingInfo
);
1270 u16 data_offset
, size
;
1272 ATOM_ASIC_PROFILING_INFO_V2_1
*profile
;
1273 u16
*leakage_bin
, *vddc_id_buf
, *vddc_buf
, *vddci_id_buf
, *vddci_buf
;
1278 if (!amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1279 &frev
, &crev
, &data_offset
))
1282 profile
= (ATOM_ASIC_PROFILING_INFO_V2_1
*)
1283 (adev
->mode_info
.atom_context
->bios
+ data_offset
);
1291 if (size
< sizeof(ATOM_ASIC_PROFILING_INFO_V2_1
))
1293 leakage_bin
= (u16
*)
1294 (adev
->mode_info
.atom_context
->bios
+ data_offset
+
1295 le16_to_cpu(profile
->usLeakageBinArrayOffset
));
1296 vddc_id_buf
= (u16
*)
1297 (adev
->mode_info
.atom_context
->bios
+ data_offset
+
1298 le16_to_cpu(profile
->usElbVDDC_IdArrayOffset
));
1300 (adev
->mode_info
.atom_context
->bios
+ data_offset
+
1301 le16_to_cpu(profile
->usElbVDDC_LevelArrayOffset
));
1302 vddci_id_buf
= (u16
*)
1303 (adev
->mode_info
.atom_context
->bios
+ data_offset
+
1304 le16_to_cpu(profile
->usElbVDDCI_IdArrayOffset
));
1306 (adev
->mode_info
.atom_context
->bios
+ data_offset
+
1307 le16_to_cpu(profile
->usElbVDDCI_LevelArrayOffset
));
1309 if (profile
->ucElbVDDC_Num
> 0) {
1310 for (i
= 0; i
< profile
->ucElbVDDC_Num
; i
++) {
1311 if (vddc_id_buf
[i
] == virtual_voltage_id
) {
1312 for (j
= 0; j
< profile
->ucLeakageBinNum
; j
++) {
1313 if (vbios_voltage_id
<= leakage_bin
[j
]) {
1314 *vddc
= vddc_buf
[j
* profile
->ucElbVDDC_Num
+ i
];
1322 if (profile
->ucElbVDDCI_Num
> 0) {
1323 for (i
= 0; i
< profile
->ucElbVDDCI_Num
; i
++) {
1324 if (vddci_id_buf
[i
] == virtual_voltage_id
) {
1325 for (j
= 0; j
< profile
->ucLeakageBinNum
; j
++) {
1326 if (vbios_voltage_id
<= leakage_bin
[j
]) {
1327 *vddci
= vddci_buf
[j
* profile
->ucElbVDDCI_Num
+ i
];
1337 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1342 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1349 union get_voltage_info
{
1350 struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in
;
1351 struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out
;
1354 int amdgpu_atombios_get_voltage_evv(struct amdgpu_device
*adev
,
1355 u16 virtual_voltage_id
,
1358 int index
= GetIndexIntoMasterTable(COMMAND
, GetVoltageInfo
);
1360 u32 count
= adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
.count
;
1361 union get_voltage_info args
;
1363 for (entry_id
= 0; entry_id
< count
; entry_id
++) {
1364 if (adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
.entries
[entry_id
].v
==
1369 if (entry_id
>= count
)
1372 args
.in
.ucVoltageType
= VOLTAGE_TYPE_VDDC
;
1373 args
.in
.ucVoltageMode
= ATOM_GET_VOLTAGE_EVV_VOLTAGE
;
1374 args
.in
.usVoltageLevel
= cpu_to_le16(virtual_voltage_id
);
1375 args
.in
.ulSCLKFreq
=
1376 cpu_to_le32(adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
.entries
[entry_id
].clk
);
1378 amdgpu_atom_execute_table(adev
->mode_info
.atom_context
, index
, (uint32_t *)&args
);
1380 *voltage
= le16_to_cpu(args
.evv_out
.usVoltageLevel
);
1385 union voltage_object_info
{
1386 struct _ATOM_VOLTAGE_OBJECT_INFO v1
;
1387 struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2
;
1388 struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3
;
1391 union voltage_object
{
1392 struct _ATOM_VOLTAGE_OBJECT v1
;
1393 struct _ATOM_VOLTAGE_OBJECT_V2 v2
;
1394 union _ATOM_VOLTAGE_OBJECT_V3 v3
;
1398 static ATOM_VOLTAGE_OBJECT_V3
*amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1
*v3
,
1399 u8 voltage_type
, u8 voltage_mode
)
1401 u32 size
= le16_to_cpu(v3
->sHeader
.usStructureSize
);
1402 u32 offset
= offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1
, asVoltageObj
[0]);
1403 u8
*start
= (u8
*)v3
;
1405 while (offset
< size
) {
1406 ATOM_VOLTAGE_OBJECT_V3
*vo
= (ATOM_VOLTAGE_OBJECT_V3
*)(start
+ offset
);
1407 if ((vo
->asGpioVoltageObj
.sHeader
.ucVoltageType
== voltage_type
) &&
1408 (vo
->asGpioVoltageObj
.sHeader
.ucVoltageMode
== voltage_mode
))
1410 offset
+= le16_to_cpu(vo
->asGpioVoltageObj
.sHeader
.usSize
);
1415 int amdgpu_atombios_get_svi2_info(struct amdgpu_device
*adev
,
1417 u8
*svd_gpio_id
, u8
*svc_gpio_id
)
1419 int index
= GetIndexIntoMasterTable(DATA
, VoltageObjectInfo
);
1421 u16 data_offset
, size
;
1422 union voltage_object_info
*voltage_info
;
1423 union voltage_object
*voltage_object
= NULL
;
1425 if (amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1426 &frev
, &crev
, &data_offset
)) {
1427 voltage_info
= (union voltage_object_info
*)
1428 (adev
->mode_info
.atom_context
->bios
+ data_offset
);
1434 voltage_object
= (union voltage_object
*)
1435 amdgpu_atombios_lookup_voltage_object_v3(&voltage_info
->v3
,
1438 if (voltage_object
) {
1439 *svd_gpio_id
= voltage_object
->v3
.asSVID2Obj
.ucSVDGpioId
;
1440 *svc_gpio_id
= voltage_object
->v3
.asSVID2Obj
.ucSVCGpioId
;
1446 DRM_ERROR("unknown voltage object table\n");
1451 DRM_ERROR("unknown voltage object table\n");
1460 amdgpu_atombios_is_voltage_gpio(struct amdgpu_device
*adev
,
1461 u8 voltage_type
, u8 voltage_mode
)
1463 int index
= GetIndexIntoMasterTable(DATA
, VoltageObjectInfo
);
1465 u16 data_offset
, size
;
1466 union voltage_object_info
*voltage_info
;
1468 if (amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1469 &frev
, &crev
, &data_offset
)) {
1470 voltage_info
= (union voltage_object_info
*)
1471 (adev
->mode_info
.atom_context
->bios
+ data_offset
);
1477 if (amdgpu_atombios_lookup_voltage_object_v3(&voltage_info
->v3
,
1478 voltage_type
, voltage_mode
))
1482 DRM_ERROR("unknown voltage object table\n");
1487 DRM_ERROR("unknown voltage object table\n");
1495 int amdgpu_atombios_get_voltage_table(struct amdgpu_device
*adev
,
1496 u8 voltage_type
, u8 voltage_mode
,
1497 struct atom_voltage_table
*voltage_table
)
1499 int index
= GetIndexIntoMasterTable(DATA
, VoltageObjectInfo
);
1501 u16 data_offset
, size
;
1503 union voltage_object_info
*voltage_info
;
1504 union voltage_object
*voltage_object
= NULL
;
1506 if (amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1507 &frev
, &crev
, &data_offset
)) {
1508 voltage_info
= (union voltage_object_info
*)
1509 (adev
->mode_info
.atom_context
->bios
+ data_offset
);
1515 voltage_object
= (union voltage_object
*)
1516 amdgpu_atombios_lookup_voltage_object_v3(&voltage_info
->v3
,
1517 voltage_type
, voltage_mode
);
1518 if (voltage_object
) {
1519 ATOM_GPIO_VOLTAGE_OBJECT_V3
*gpio
=
1520 &voltage_object
->v3
.asGpioVoltageObj
;
1521 VOLTAGE_LUT_ENTRY_V2
*lut
;
1522 if (gpio
->ucGpioEntryNum
> MAX_VOLTAGE_ENTRIES
)
1524 lut
= &gpio
->asVolGpioLut
[0];
1525 for (i
= 0; i
< gpio
->ucGpioEntryNum
; i
++) {
1526 voltage_table
->entries
[i
].value
=
1527 le16_to_cpu(lut
->usVoltageValue
);
1528 voltage_table
->entries
[i
].smio_low
=
1529 le32_to_cpu(lut
->ulVoltageId
);
1530 lut
= (VOLTAGE_LUT_ENTRY_V2
*)
1531 ((u8
*)lut
+ sizeof(VOLTAGE_LUT_ENTRY_V2
));
1533 voltage_table
->mask_low
= le32_to_cpu(gpio
->ulGpioMaskVal
);
1534 voltage_table
->count
= gpio
->ucGpioEntryNum
;
1535 voltage_table
->phase_delay
= gpio
->ucPhaseDelay
;
1540 DRM_ERROR("unknown voltage object table\n");
1545 DRM_ERROR("unknown voltage object table\n");
1553 struct _ATOM_VRAM_INFO_V3 v1_3
;
1554 struct _ATOM_VRAM_INFO_V4 v1_4
;
1555 struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1
;
1558 #define MEM_ID_MASK 0xff000000
1559 #define MEM_ID_SHIFT 24
1560 #define CLOCK_RANGE_MASK 0x00ffffff
1561 #define CLOCK_RANGE_SHIFT 0
1562 #define LOW_NIBBLE_MASK 0xf
1563 #define DATA_EQU_PREV 0
1564 #define DATA_FROM_TABLE 4
1566 int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device
*adev
,
1568 struct atom_mc_reg_table
*reg_table
)
1570 int index
= GetIndexIntoMasterTable(DATA
, VRAM_Info
);
1571 u8 frev
, crev
, num_entries
, t_mem_id
, num_ranges
= 0;
1573 u16 data_offset
, size
;
1574 union vram_info
*vram_info
;
1576 memset(reg_table
, 0, sizeof(struct atom_mc_reg_table
));
1578 if (amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1579 &frev
, &crev
, &data_offset
)) {
1580 vram_info
= (union vram_info
*)
1581 (adev
->mode_info
.atom_context
->bios
+ data_offset
);
1584 DRM_ERROR("old table version %d, %d\n", frev
, crev
);
1589 if (module_index
< vram_info
->v2_1
.ucNumOfVRAMModule
) {
1590 ATOM_INIT_REG_BLOCK
*reg_block
=
1591 (ATOM_INIT_REG_BLOCK
*)
1592 ((u8
*)vram_info
+ le16_to_cpu(vram_info
->v2_1
.usMemClkPatchTblOffset
));
1593 ATOM_MEMORY_SETTING_DATA_BLOCK
*reg_data
=
1594 (ATOM_MEMORY_SETTING_DATA_BLOCK
*)
1595 ((u8
*)reg_block
+ (2 * sizeof(u16
)) +
1596 le16_to_cpu(reg_block
->usRegIndexTblSize
));
1597 ATOM_INIT_REG_INDEX_FORMAT
*format
= ®_block
->asRegIndexBuf
[0];
1598 num_entries
= (u8
)((le16_to_cpu(reg_block
->usRegIndexTblSize
)) /
1599 sizeof(ATOM_INIT_REG_INDEX_FORMAT
)) - 1;
1600 if (num_entries
> VBIOS_MC_REGISTER_ARRAY_SIZE
)
1602 while (i
< num_entries
) {
1603 if (format
->ucPreRegDataLength
& ACCESS_PLACEHOLDER
)
1605 reg_table
->mc_reg_address
[i
].s1
=
1606 (u16
)(le16_to_cpu(format
->usRegIndex
));
1607 reg_table
->mc_reg_address
[i
].pre_reg_data
=
1608 (u8
)(format
->ucPreRegDataLength
);
1610 format
= (ATOM_INIT_REG_INDEX_FORMAT
*)
1611 ((u8
*)format
+ sizeof(ATOM_INIT_REG_INDEX_FORMAT
));
1613 reg_table
->last
= i
;
1614 while ((le32_to_cpu(*(u32
*)reg_data
) != END_OF_REG_DATA_BLOCK
) &&
1615 (num_ranges
< VBIOS_MAX_AC_TIMING_ENTRIES
)) {
1616 t_mem_id
= (u8
)((le32_to_cpu(*(u32
*)reg_data
) & MEM_ID_MASK
)
1618 if (module_index
== t_mem_id
) {
1619 reg_table
->mc_reg_table_entry
[num_ranges
].mclk_max
=
1620 (u32
)((le32_to_cpu(*(u32
*)reg_data
) & CLOCK_RANGE_MASK
)
1621 >> CLOCK_RANGE_SHIFT
);
1622 for (i
= 0, j
= 1; i
< reg_table
->last
; i
++) {
1623 if ((reg_table
->mc_reg_address
[i
].pre_reg_data
& LOW_NIBBLE_MASK
) == DATA_FROM_TABLE
) {
1624 reg_table
->mc_reg_table_entry
[num_ranges
].mc_data
[i
] =
1625 (u32
)le32_to_cpu(*((u32
*)reg_data
+ j
));
1627 } else if ((reg_table
->mc_reg_address
[i
].pre_reg_data
& LOW_NIBBLE_MASK
) == DATA_EQU_PREV
) {
1628 reg_table
->mc_reg_table_entry
[num_ranges
].mc_data
[i
] =
1629 reg_table
->mc_reg_table_entry
[num_ranges
].mc_data
[i
- 1];
1634 reg_data
= (ATOM_MEMORY_SETTING_DATA_BLOCK
*)
1635 ((u8
*)reg_data
+ le16_to_cpu(reg_block
->usRegDataBlkSize
));
1637 if (le32_to_cpu(*(u32
*)reg_data
) != END_OF_REG_DATA_BLOCK
)
1639 reg_table
->num_entries
= num_ranges
;
1644 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1649 DRM_ERROR("Unknown table version %d, %d\n", frev
, crev
);
1657 bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device
*adev
)
1659 int index
= GetIndexIntoMasterTable(DATA
, GPUVirtualizationInfo
);
1661 u16 data_offset
, size
;
1663 if (amdgpu_atom_parse_data_header(adev
->mode_info
.atom_context
, index
, &size
,
1664 &frev
, &crev
, &data_offset
))
1670 void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device
*adev
, bool lock
)
1672 uint32_t bios_6_scratch
;
1674 bios_6_scratch
= RREG32(adev
->bios_scratch_reg_offset
+ 6);
1677 bios_6_scratch
|= ATOM_S6_CRITICAL_STATE
;
1678 bios_6_scratch
&= ~ATOM_S6_ACC_MODE
;
1680 bios_6_scratch
&= ~ATOM_S6_CRITICAL_STATE
;
1681 bios_6_scratch
|= ATOM_S6_ACC_MODE
;
1684 WREG32(adev
->bios_scratch_reg_offset
+ 6, bios_6_scratch
);
1687 static void amdgpu_atombios_scratch_regs_init(struct amdgpu_device
*adev
)
1689 uint32_t bios_2_scratch
, bios_6_scratch
;
1691 adev
->bios_scratch_reg_offset
= mmBIOS_SCRATCH_0
;
1693 bios_2_scratch
= RREG32(adev
->bios_scratch_reg_offset
+ 2);
1694 bios_6_scratch
= RREG32(adev
->bios_scratch_reg_offset
+ 6);
1696 /* let the bios control the backlight */
1697 bios_2_scratch
&= ~ATOM_S2_VRI_BRIGHT_ENABLE
;
1699 /* tell the bios not to handle mode switching */
1700 bios_6_scratch
|= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH
;
1702 /* clear the vbios dpms state */
1703 bios_2_scratch
&= ~ATOM_S2_DEVICE_DPMS_STATE
;
1705 WREG32(adev
->bios_scratch_reg_offset
+ 2, bios_2_scratch
);
1706 WREG32(adev
->bios_scratch_reg_offset
+ 6, bios_6_scratch
);
1709 void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device
*adev
,
1712 u32 tmp
= RREG32(adev
->bios_scratch_reg_offset
+ 3);
1715 tmp
|= ATOM_S3_ASIC_GUI_ENGINE_HUNG
;
1717 tmp
&= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG
;
1719 WREG32(adev
->bios_scratch_reg_offset
+ 3, tmp
);
1722 bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device
*adev
)
1724 u32 tmp
= RREG32(adev
->bios_scratch_reg_offset
+ 7);
1726 if (tmp
& ATOM_S7_ASIC_INIT_COMPLETE_MASK
)
1732 /* Atom needs data in little endian format so swap as appropriate when copying
1733 * data to or from atom. Note that atom operates on dw units.
1735 * Use to_le=true when sending data to atom and provide at least
1736 * ALIGN(num_bytes,4) bytes in the dst buffer.
1738 * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
1739 * byes in the src buffer.
1741 void amdgpu_atombios_copy_swap(u8
*dst
, u8
*src
, u8 num_bytes
, bool to_le
)
1744 u32 src_tmp
[5], dst_tmp
[5];
1746 u8 align_num_bytes
= ALIGN(num_bytes
, 4);
1749 memcpy(src_tmp
, src
, num_bytes
);
1750 for (i
= 0; i
< align_num_bytes
/ 4; i
++)
1751 dst_tmp
[i
] = cpu_to_le32(src_tmp
[i
]);
1752 memcpy(dst
, dst_tmp
, align_num_bytes
);
1754 memcpy(src_tmp
, src
, align_num_bytes
);
1755 for (i
= 0; i
< align_num_bytes
/ 4; i
++)
1756 dst_tmp
[i
] = le32_to_cpu(src_tmp
[i
]);
1757 memcpy(dst
, dst_tmp
, num_bytes
);
1760 memcpy(dst
, src
, num_bytes
);
1764 static int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device
*adev
)
1766 struct atom_context
*ctx
= adev
->mode_info
.atom_context
;
1767 int index
= GetIndexIntoMasterTable(DATA
, VRAM_UsageByFirmware
);
1768 uint16_t data_offset
;
1769 int usage_bytes
= 0;
1770 struct _ATOM_VRAM_USAGE_BY_FIRMWARE
*firmware_usage
;
1774 if (amdgpu_atom_parse_data_header(ctx
, index
, NULL
, NULL
, NULL
, &data_offset
)) {
1775 firmware_usage
= (struct _ATOM_VRAM_USAGE_BY_FIRMWARE
*)(ctx
->bios
+ data_offset
);
1777 DRM_DEBUG("atom firmware requested %08x %dkb\n",
1778 le32_to_cpu(firmware_usage
->asFirmwareVramReserveInfo
[0].ulStartAddrUsedByFirmware
),
1779 le16_to_cpu(firmware_usage
->asFirmwareVramReserveInfo
[0].usFirmwareUseInKb
));
1781 start_addr
= firmware_usage
->asFirmwareVramReserveInfo
[0].ulStartAddrUsedByFirmware
;
1782 size
= firmware_usage
->asFirmwareVramReserveInfo
[0].usFirmwareUseInKb
;
1784 if ((uint32_t)(start_addr
& ATOM_VRAM_OPERATION_FLAGS_MASK
) ==
1785 (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION
<<
1786 ATOM_VRAM_OPERATION_FLAGS_SHIFT
)) {
1787 /* Firmware request VRAM reservation for SR-IOV */
1788 adev
->fw_vram_usage
.start_offset
= (start_addr
&
1789 (~ATOM_VRAM_OPERATION_FLAGS_MASK
)) << 10;
1790 adev
->fw_vram_usage
.size
= size
<< 10;
1791 /* Use the default scratch size */
1794 usage_bytes
= le16_to_cpu(firmware_usage
->asFirmwareVramReserveInfo
[0].usFirmwareUseInKb
) * 1024;
1797 ctx
->scratch_size_bytes
= 0;
1798 if (usage_bytes
== 0)
1799 usage_bytes
= 20 * 1024;
1800 /* allocate some scratch memory */
1801 ctx
->scratch
= kzalloc(usage_bytes
, GFP_KERNEL
);
1804 ctx
->scratch_size_bytes
= usage_bytes
;
1808 /* ATOM accessor methods */
1810 * ATOM is an interpreted byte code stored in tables in the vbios. The
1811 * driver registers callbacks to access registers and the interpreter
1812 * in the driver parses the tables and executes then to program specific
1813 * actions (set display modes, asic init, etc.). See amdgpu_atombios.c,
1814 * atombios.h, and atom.c
1818 * cail_pll_read - read PLL register
1820 * @info: atom card_info pointer
1821 * @reg: PLL register offset
1823 * Provides a PLL register accessor for the atom interpreter (r4xx+).
1824 * Returns the value of the PLL register.
1826 static uint32_t cail_pll_read(struct card_info
*info
, uint32_t reg
)
1832 * cail_pll_write - write PLL register
1834 * @info: atom card_info pointer
1835 * @reg: PLL register offset
1836 * @val: value to write to the pll register
1838 * Provides a PLL register accessor for the atom interpreter (r4xx+).
1840 static void cail_pll_write(struct card_info
*info
, uint32_t reg
, uint32_t val
)
1846 * cail_mc_read - read MC (Memory Controller) register
1848 * @info: atom card_info pointer
1849 * @reg: MC register offset
1851 * Provides an MC register accessor for the atom interpreter (r4xx+).
1852 * Returns the value of the MC register.
1854 static uint32_t cail_mc_read(struct card_info
*info
, uint32_t reg
)
1860 * cail_mc_write - write MC (Memory Controller) register
1862 * @info: atom card_info pointer
1863 * @reg: MC register offset
1864 * @val: value to write to the pll register
1866 * Provides a MC register accessor for the atom interpreter (r4xx+).
1868 static void cail_mc_write(struct card_info
*info
, uint32_t reg
, uint32_t val
)
1874 * cail_reg_write - write MMIO register
1876 * @info: atom card_info pointer
1877 * @reg: MMIO register offset
1878 * @val: value to write to the pll register
1880 * Provides a MMIO register accessor for the atom interpreter (r4xx+).
1882 static void cail_reg_write(struct card_info
*info
, uint32_t reg
, uint32_t val
)
1884 struct amdgpu_device
*adev
= info
->dev
->dev_private
;
1890 * cail_reg_read - read MMIO register
1892 * @info: atom card_info pointer
1893 * @reg: MMIO register offset
1895 * Provides an MMIO register accessor for the atom interpreter (r4xx+).
1896 * Returns the value of the MMIO register.
1898 static uint32_t cail_reg_read(struct card_info
*info
, uint32_t reg
)
1900 struct amdgpu_device
*adev
= info
->dev
->dev_private
;
1908 * cail_ioreg_write - write IO register
1910 * @info: atom card_info pointer
1911 * @reg: IO register offset
1912 * @val: value to write to the pll register
1914 * Provides a IO register accessor for the atom interpreter (r4xx+).
1916 static void cail_ioreg_write(struct card_info
*info
, uint32_t reg
, uint32_t val
)
1918 struct amdgpu_device
*adev
= info
->dev
->dev_private
;
1920 WREG32_IO(reg
, val
);
1924 * cail_ioreg_read - read IO register
1926 * @info: atom card_info pointer
1927 * @reg: IO register offset
1929 * Provides an IO register accessor for the atom interpreter (r4xx+).
1930 * Returns the value of the IO register.
1932 static uint32_t cail_ioreg_read(struct card_info
*info
, uint32_t reg
)
1934 struct amdgpu_device
*adev
= info
->dev
->dev_private
;
1941 static ssize_t
amdgpu_atombios_get_vbios_version(struct device
*dev
,
1942 struct device_attribute
*attr
,
1945 struct drm_device
*ddev
= dev_get_drvdata(dev
);
1946 struct amdgpu_device
*adev
= ddev
->dev_private
;
1947 struct atom_context
*ctx
= adev
->mode_info
.atom_context
;
1949 return snprintf(buf
, PAGE_SIZE
, "%s\n", ctx
->vbios_version
);
1952 static DEVICE_ATTR(vbios_version
, 0444, amdgpu_atombios_get_vbios_version
,
1956 * amdgpu_atombios_fini - free the driver info and callbacks for atombios
1958 * @adev: amdgpu_device pointer
1960 * Frees the driver info and register access callbacks for the ATOM
1961 * interpreter (r4xx+).
1962 * Called at driver shutdown.
1964 void amdgpu_atombios_fini(struct amdgpu_device
*adev
)
1966 if (adev
->mode_info
.atom_context
) {
1967 kfree(adev
->mode_info
.atom_context
->scratch
);
1968 kfree(adev
->mode_info
.atom_context
->iio
);
1970 kfree(adev
->mode_info
.atom_context
);
1971 adev
->mode_info
.atom_context
= NULL
;
1972 kfree(adev
->mode_info
.atom_card_info
);
1973 adev
->mode_info
.atom_card_info
= NULL
;
1974 device_remove_file(adev
->dev
, &dev_attr_vbios_version
);
1978 * amdgpu_atombios_init - init the driver info and callbacks for atombios
1980 * @adev: amdgpu_device pointer
1982 * Initializes the driver info and register access callbacks for the
1983 * ATOM interpreter (r4xx+).
1984 * Returns 0 on sucess, -ENOMEM on failure.
1985 * Called at driver startup.
1987 int amdgpu_atombios_init(struct amdgpu_device
*adev
)
1989 struct card_info
*atom_card_info
=
1990 kzalloc(sizeof(struct card_info
), GFP_KERNEL
);
1993 if (!atom_card_info
)
1996 adev
->mode_info
.atom_card_info
= atom_card_info
;
1997 atom_card_info
->dev
= adev
->ddev
;
1998 atom_card_info
->reg_read
= cail_reg_read
;
1999 atom_card_info
->reg_write
= cail_reg_write
;
2000 /* needed for iio ops */
2001 if (adev
->rio_mem
) {
2002 atom_card_info
->ioreg_read
= cail_ioreg_read
;
2003 atom_card_info
->ioreg_write
= cail_ioreg_write
;
2005 DRM_DEBUG("PCI I/O BAR is not found. Using MMIO to access ATOM BIOS\n");
2006 atom_card_info
->ioreg_read
= cail_reg_read
;
2007 atom_card_info
->ioreg_write
= cail_reg_write
;
2009 atom_card_info
->mc_read
= cail_mc_read
;
2010 atom_card_info
->mc_write
= cail_mc_write
;
2011 atom_card_info
->pll_read
= cail_pll_read
;
2012 atom_card_info
->pll_write
= cail_pll_write
;
2014 adev
->mode_info
.atom_context
= amdgpu_atom_parse(atom_card_info
, adev
->bios
);
2015 if (!adev
->mode_info
.atom_context
) {
2016 amdgpu_atombios_fini(adev
);
2020 mutex_init(&adev
->mode_info
.atom_context
->mutex
);
2021 if (adev
->is_atom_fw
) {
2022 amdgpu_atomfirmware_scratch_regs_init(adev
);
2023 amdgpu_atomfirmware_allocate_fb_scratch(adev
);
2025 amdgpu_atombios_scratch_regs_init(adev
);
2026 amdgpu_atombios_allocate_fb_scratch(adev
);
2029 ret
= device_create_file(adev
->dev
, &dev_attr_vbios_version
);
2031 DRM_ERROR("Failed to create device file for VBIOS version\n");