.. | .. |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/slab.h> |
---|
| 27 | + |
---|
26 | 28 | #include "dm_services.h" |
---|
27 | 29 | |
---|
28 | 30 | #include "ObjectID.h" |
---|
.. | .. |
---|
109 | 111 | |
---|
110 | 112 | #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) |
---|
111 | 113 | |
---|
112 | | -static void destruct(struct bios_parser *bp) |
---|
| 114 | +static void bios_parser2_destruct(struct bios_parser *bp) |
---|
113 | 115 | { |
---|
114 | 116 | kfree(bp->base.bios_local_image); |
---|
115 | 117 | kfree(bp->base.integrated_info); |
---|
.. | .. |
---|
124 | 126 | return; |
---|
125 | 127 | } |
---|
126 | 128 | |
---|
127 | | - destruct(bp); |
---|
| 129 | + bios_parser2_destruct(bp); |
---|
128 | 130 | |
---|
129 | 131 | kfree(bp); |
---|
130 | 132 | *dcb = NULL; |
---|
.. | .. |
---|
166 | 168 | return count; |
---|
167 | 169 | } |
---|
168 | 170 | |
---|
169 | | -static struct graphics_object_id bios_parser_get_encoder_id( |
---|
170 | | - struct dc_bios *dcb, |
---|
171 | | - uint32_t i) |
---|
172 | | -{ |
---|
173 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
174 | | - struct graphics_object_id object_id = dal_graphics_object_id_init( |
---|
175 | | - 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); |
---|
176 | | - |
---|
177 | | - if (bp->object_info_tbl.v1_4->number_of_path > i) |
---|
178 | | - object_id = object_id_from_bios_object_id( |
---|
179 | | - bp->object_info_tbl.v1_4->display_path[i].encoderobjid); |
---|
180 | | - |
---|
181 | | - return object_id; |
---|
182 | | -} |
---|
183 | | - |
---|
184 | 171 | static struct graphics_object_id bios_parser_get_connector_id( |
---|
185 | 172 | struct dc_bios *dcb, |
---|
186 | 173 | uint8_t i) |
---|
.. | .. |
---|
203 | 190 | |
---|
204 | 191 | return object_id; |
---|
205 | 192 | } |
---|
206 | | - |
---|
207 | | - |
---|
208 | | -/* TODO: GetNumberOfSrc*/ |
---|
209 | | - |
---|
210 | | -static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb, |
---|
211 | | - struct graphics_object_id id) |
---|
212 | | -{ |
---|
213 | | - /* connector has 1 Dest, encoder has 0 Dest */ |
---|
214 | | - switch (id.type) { |
---|
215 | | - case OBJECT_TYPE_ENCODER: |
---|
216 | | - return 0; |
---|
217 | | - case OBJECT_TYPE_CONNECTOR: |
---|
218 | | - return 1; |
---|
219 | | - default: |
---|
220 | | - return 0; |
---|
221 | | - } |
---|
222 | | -} |
---|
223 | | - |
---|
224 | | -/* removed getSrcObjList, getDestObjList*/ |
---|
225 | | - |
---|
226 | 193 | |
---|
227 | 194 | static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, |
---|
228 | 195 | struct graphics_object_id object_id, uint32_t index, |
---|
.. | .. |
---|
283 | 250 | return bp_result; |
---|
284 | 251 | } |
---|
285 | 252 | |
---|
286 | | -static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb, |
---|
287 | | - struct graphics_object_id object_id, uint32_t index, |
---|
288 | | - struct graphics_object_id *dest_object_id) |
---|
289 | | -{ |
---|
290 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
291 | | - unsigned int i; |
---|
292 | | - enum bp_result bp_result = BP_RESULT_BADINPUT; |
---|
293 | | - struct graphics_object_id obj_id = {0}; |
---|
294 | | - struct object_info_table *tbl = &bp->object_info_tbl; |
---|
295 | | - |
---|
296 | | - if (!dest_object_id) |
---|
297 | | - return BP_RESULT_BADINPUT; |
---|
298 | | - |
---|
299 | | - switch (object_id.type) { |
---|
300 | | - case OBJECT_TYPE_ENCODER: |
---|
301 | | - /* TODO: since num of src must be less than 2. |
---|
302 | | - * If found in for loop, should break. |
---|
303 | | - * DAL2 implementation may be changed too |
---|
304 | | - */ |
---|
305 | | - for (i = 0; i < tbl->v1_4->number_of_path; i++) { |
---|
306 | | - obj_id = object_id_from_bios_object_id( |
---|
307 | | - tbl->v1_4->display_path[i].encoderobjid); |
---|
308 | | - if (object_id.type == obj_id.type && |
---|
309 | | - object_id.id == obj_id.id && |
---|
310 | | - object_id.enum_id == |
---|
311 | | - obj_id.enum_id) { |
---|
312 | | - *dest_object_id = |
---|
313 | | - object_id_from_bios_object_id( |
---|
314 | | - tbl->v1_4->display_path[i].display_objid); |
---|
315 | | - /* break; */ |
---|
316 | | - } |
---|
317 | | - } |
---|
318 | | - bp_result = BP_RESULT_OK; |
---|
319 | | - break; |
---|
320 | | - default: |
---|
321 | | - break; |
---|
322 | | - } |
---|
323 | | - |
---|
324 | | - return bp_result; |
---|
325 | | -} |
---|
326 | | - |
---|
327 | | - |
---|
328 | 253 | /* from graphics_object_id, find display path which includes the object_id */ |
---|
329 | 254 | static struct atom_display_object_path_v2 *get_bios_object( |
---|
330 | | - struct bios_parser *bp, |
---|
331 | | - struct graphics_object_id id) |
---|
| 255 | + struct bios_parser *bp, |
---|
| 256 | + struct graphics_object_id id) |
---|
332 | 257 | { |
---|
333 | 258 | unsigned int i; |
---|
334 | 259 | struct graphics_object_id obj_id = {0}; |
---|
.. | .. |
---|
337 | 262 | case OBJECT_TYPE_ENCODER: |
---|
338 | 263 | for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { |
---|
339 | 264 | obj_id = object_id_from_bios_object_id( |
---|
340 | | - bp->object_info_tbl.v1_4->display_path[i].encoderobjid); |
---|
341 | | - if (id.type == obj_id.type && |
---|
342 | | - id.id == obj_id.id && |
---|
343 | | - id.enum_id == obj_id.enum_id) |
---|
344 | | - return |
---|
345 | | - &bp->object_info_tbl.v1_4->display_path[i]; |
---|
| 265 | + bp->object_info_tbl.v1_4->display_path[i].encoderobjid); |
---|
| 266 | + if (id.type == obj_id.type && id.id == obj_id.id |
---|
| 267 | + && id.enum_id == obj_id.enum_id) |
---|
| 268 | + return &bp->object_info_tbl.v1_4->display_path[i]; |
---|
346 | 269 | } |
---|
| 270 | + fallthrough; |
---|
347 | 271 | case OBJECT_TYPE_CONNECTOR: |
---|
348 | 272 | case OBJECT_TYPE_GENERIC: |
---|
349 | 273 | /* Both Generic and Connector Object ID |
---|
350 | 274 | * will be stored on display_objid |
---|
351 | | - */ |
---|
| 275 | + */ |
---|
352 | 276 | for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { |
---|
353 | 277 | obj_id = object_id_from_bios_object_id( |
---|
354 | | - bp->object_info_tbl.v1_4->display_path[i].display_objid |
---|
355 | | - ); |
---|
356 | | - if (id.type == obj_id.type && |
---|
357 | | - id.id == obj_id.id && |
---|
358 | | - id.enum_id == obj_id.enum_id) |
---|
359 | | - return |
---|
360 | | - &bp->object_info_tbl.v1_4->display_path[i]; |
---|
| 278 | + bp->object_info_tbl.v1_4->display_path[i].display_objid); |
---|
| 279 | + if (id.type == obj_id.type && id.id == obj_id.id |
---|
| 280 | + && id.enum_id == obj_id.enum_id) |
---|
| 281 | + return &bp->object_info_tbl.v1_4->display_path[i]; |
---|
361 | 282 | } |
---|
| 283 | + fallthrough; |
---|
362 | 284 | default: |
---|
363 | 285 | return NULL; |
---|
364 | 286 | } |
---|
.. | .. |
---|
372 | 294 | struct atom_display_object_path_v2 *object; |
---|
373 | 295 | struct atom_common_record_header *header; |
---|
374 | 296 | struct atom_i2c_record *record; |
---|
| 297 | + struct atom_i2c_record dummy_record = {0}; |
---|
375 | 298 | struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
376 | 299 | |
---|
377 | 300 | if (!info) |
---|
378 | 301 | return BP_RESULT_BADINPUT; |
---|
| 302 | + |
---|
| 303 | + if (id.type == OBJECT_TYPE_GENERIC) { |
---|
| 304 | + dummy_record.i2c_id = id.id; |
---|
| 305 | + |
---|
| 306 | + if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK) |
---|
| 307 | + return BP_RESULT_OK; |
---|
| 308 | + else |
---|
| 309 | + return BP_RESULT_NORECORD; |
---|
| 310 | + } |
---|
379 | 311 | |
---|
380 | 312 | object = get_bios_object(bp, id); |
---|
381 | 313 | |
---|
.. | .. |
---|
419 | 351 | struct atom_gpio_pin_lut_v2_1 *header; |
---|
420 | 352 | uint32_t count = 0; |
---|
421 | 353 | unsigned int table_index = 0; |
---|
| 354 | + bool find_valid = false; |
---|
| 355 | + struct atom_gpio_pin_assignment *pin; |
---|
422 | 356 | |
---|
423 | 357 | if (!info) |
---|
424 | 358 | return BP_RESULT_BADINPUT; |
---|
.. | .. |
---|
446 | 380 | - sizeof(struct atom_common_table_header)) |
---|
447 | 381 | / sizeof(struct atom_gpio_pin_assignment); |
---|
448 | 382 | |
---|
449 | | - table_index = record->i2c_id & I2C_HW_LANE_MUX; |
---|
| 383 | + pin = (struct atom_gpio_pin_assignment *) header->gpio_pin; |
---|
450 | 384 | |
---|
451 | | - if (count < table_index) { |
---|
452 | | - bool find_valid = false; |
---|
453 | | - |
---|
454 | | - for (table_index = 0; table_index < count; table_index++) { |
---|
455 | | - if (((record->i2c_id & I2C_HW_CAP) == ( |
---|
456 | | - header->gpio_pin[table_index].gpio_id & |
---|
457 | | - I2C_HW_CAP)) && |
---|
458 | | - ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == |
---|
459 | | - (header->gpio_pin[table_index].gpio_id & |
---|
460 | | - I2C_HW_ENGINE_ID_MASK)) && |
---|
461 | | - ((record->i2c_id & I2C_HW_LANE_MUX) == |
---|
462 | | - (header->gpio_pin[table_index].gpio_id & |
---|
463 | | - I2C_HW_LANE_MUX))) { |
---|
464 | | - /* still valid */ |
---|
465 | | - find_valid = true; |
---|
466 | | - break; |
---|
467 | | - } |
---|
| 385 | + for (table_index = 0; table_index < count; table_index++) { |
---|
| 386 | + if (((record->i2c_id & I2C_HW_CAP) == (pin->gpio_id & I2C_HW_CAP)) && |
---|
| 387 | + ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) && |
---|
| 388 | + ((record->i2c_id & I2C_HW_LANE_MUX) == (pin->gpio_id & I2C_HW_LANE_MUX))) { |
---|
| 389 | + /* still valid */ |
---|
| 390 | + find_valid = true; |
---|
| 391 | + break; |
---|
468 | 392 | } |
---|
469 | | - /* If we don't find the entry that we are looking for then |
---|
470 | | - * we will return BP_Result_BadBiosTable. |
---|
471 | | - */ |
---|
472 | | - if (find_valid == false) |
---|
473 | | - return BP_RESULT_BADBIOSTABLE; |
---|
| 393 | + pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment)); |
---|
474 | 394 | } |
---|
| 395 | + |
---|
| 396 | + /* If we don't find the entry that we are looking for then |
---|
| 397 | + * we will return BP_Result_BadBiosTable. |
---|
| 398 | + */ |
---|
| 399 | + if (find_valid == false) |
---|
| 400 | + return BP_RESULT_BADBIOSTABLE; |
---|
475 | 401 | |
---|
476 | 402 | /* get the GPIO_I2C_INFO */ |
---|
477 | 403 | info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false; |
---|
.. | .. |
---|
480 | 406 | info->i2c_slave_address = record->i2c_slave_addr; |
---|
481 | 407 | |
---|
482 | 408 | /* TODO: check how to get register offset for en, Y, etc. */ |
---|
483 | | - info->gpio_info.clk_a_register_index = |
---|
484 | | - le16_to_cpu( |
---|
485 | | - header->gpio_pin[table_index].data_a_reg_index); |
---|
486 | | - info->gpio_info.clk_a_shift = |
---|
487 | | - header->gpio_pin[table_index].gpio_bitshift; |
---|
| 409 | + info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index); |
---|
| 410 | + info->gpio_info.clk_a_shift = pin->gpio_bitshift; |
---|
488 | 411 | |
---|
489 | 412 | return BP_RESULT_OK; |
---|
490 | | -} |
---|
491 | | - |
---|
492 | | -static enum bp_result get_voltage_ddc_info_v4( |
---|
493 | | - uint8_t *i2c_line, |
---|
494 | | - uint32_t index, |
---|
495 | | - struct atom_common_table_header *header, |
---|
496 | | - uint8_t *address) |
---|
497 | | -{ |
---|
498 | | - enum bp_result result = BP_RESULT_NORECORD; |
---|
499 | | - struct atom_voltage_objects_info_v4_1 *info = |
---|
500 | | - (struct atom_voltage_objects_info_v4_1 *) address; |
---|
501 | | - |
---|
502 | | - uint8_t *voltage_current_object = |
---|
503 | | - (uint8_t *) (&(info->voltage_object[0])); |
---|
504 | | - |
---|
505 | | - while ((address + le16_to_cpu(header->structuresize)) > |
---|
506 | | - voltage_current_object) { |
---|
507 | | - struct atom_i2c_voltage_object_v4 *object = |
---|
508 | | - (struct atom_i2c_voltage_object_v4 *) |
---|
509 | | - voltage_current_object; |
---|
510 | | - |
---|
511 | | - if (object->header.voltage_mode == |
---|
512 | | - ATOM_INIT_VOLTAGE_REGULATOR) { |
---|
513 | | - if (object->header.voltage_type == index) { |
---|
514 | | - *i2c_line = object->i2c_id ^ 0x90; |
---|
515 | | - result = BP_RESULT_OK; |
---|
516 | | - break; |
---|
517 | | - } |
---|
518 | | - } |
---|
519 | | - |
---|
520 | | - voltage_current_object += |
---|
521 | | - le16_to_cpu(object->header.object_size); |
---|
522 | | - } |
---|
523 | | - return result; |
---|
524 | | -} |
---|
525 | | - |
---|
526 | | -static enum bp_result bios_parser_get_thermal_ddc_info( |
---|
527 | | - struct dc_bios *dcb, |
---|
528 | | - uint32_t i2c_channel_id, |
---|
529 | | - struct graphics_object_i2c_info *info) |
---|
530 | | -{ |
---|
531 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
532 | | - struct i2c_id_config_access *config; |
---|
533 | | - struct atom_i2c_record record; |
---|
534 | | - |
---|
535 | | - if (!info) |
---|
536 | | - return BP_RESULT_BADINPUT; |
---|
537 | | - |
---|
538 | | - config = (struct i2c_id_config_access *) &i2c_channel_id; |
---|
539 | | - |
---|
540 | | - record.i2c_id = config->bfHW_Capable; |
---|
541 | | - record.i2c_id |= config->bfI2C_LineMux; |
---|
542 | | - record.i2c_id |= config->bfHW_EngineID; |
---|
543 | | - |
---|
544 | | - return get_gpio_i2c_info(bp, &record, info); |
---|
545 | | -} |
---|
546 | | - |
---|
547 | | -static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios *dcb, |
---|
548 | | - uint32_t index, |
---|
549 | | - struct graphics_object_i2c_info *info) |
---|
550 | | -{ |
---|
551 | | - uint8_t i2c_line = 0; |
---|
552 | | - enum bp_result result = BP_RESULT_NORECORD; |
---|
553 | | - uint8_t *voltage_info_address; |
---|
554 | | - struct atom_common_table_header *header; |
---|
555 | | - struct atom_data_revision revision = {0}; |
---|
556 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
557 | | - |
---|
558 | | - if (!DATA_TABLES(voltageobject_info)) |
---|
559 | | - return result; |
---|
560 | | - |
---|
561 | | - voltage_info_address = bios_get_image(&bp->base, |
---|
562 | | - DATA_TABLES(voltageobject_info), |
---|
563 | | - sizeof(struct atom_common_table_header)); |
---|
564 | | - |
---|
565 | | - header = (struct atom_common_table_header *) voltage_info_address; |
---|
566 | | - |
---|
567 | | - get_atom_data_table_revision(header, &revision); |
---|
568 | | - |
---|
569 | | - switch (revision.major) { |
---|
570 | | - case 4: |
---|
571 | | - if (revision.minor != 1) |
---|
572 | | - break; |
---|
573 | | - result = get_voltage_ddc_info_v4(&i2c_line, index, header, |
---|
574 | | - voltage_info_address); |
---|
575 | | - break; |
---|
576 | | - } |
---|
577 | | - |
---|
578 | | - if (result == BP_RESULT_OK) |
---|
579 | | - result = bios_parser_get_thermal_ddc_info(dcb, |
---|
580 | | - i2c_line, info); |
---|
581 | | - |
---|
582 | | - return result; |
---|
583 | 413 | } |
---|
584 | 414 | |
---|
585 | 415 | static enum bp_result bios_parser_get_hpd_info( |
---|
.. | .. |
---|
813 | 643 | { |
---|
814 | 644 | enum bp_result result = BP_RESULT_OK; |
---|
815 | 645 | struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; |
---|
| 646 | + struct atom_smu_info_v3_3 *smu_info = NULL; |
---|
816 | 647 | |
---|
817 | 648 | if (!ss_info) |
---|
818 | 649 | return BP_RESULT_BADINPUT; |
---|
.. | .. |
---|
824 | 655 | DATA_TABLES(dce_info)); |
---|
825 | 656 | if (!disp_cntl_tbl) |
---|
826 | 657 | return BP_RESULT_BADBIOSTABLE; |
---|
| 658 | + |
---|
827 | 659 | |
---|
828 | 660 | ss_info->type.STEP_AND_DELAY_INFO = false; |
---|
829 | 661 | ss_info->spread_percentage_divider = 1000; |
---|
.. | .. |
---|
862 | 694 | * copy it into dce_info |
---|
863 | 695 | */ |
---|
864 | 696 | result = BP_RESULT_UNSUPPORTED; |
---|
| 697 | + break; |
---|
| 698 | + case AS_SIGNAL_TYPE_XGMI: |
---|
| 699 | + smu_info = GET_IMAGE(struct atom_smu_info_v3_3, |
---|
| 700 | + DATA_TABLES(smu_info)); |
---|
| 701 | + if (!smu_info) |
---|
| 702 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 703 | + |
---|
| 704 | + ss_info->spread_spectrum_percentage = |
---|
| 705 | + smu_info->waflclk_ss_percentage; |
---|
| 706 | + ss_info->spread_spectrum_range = |
---|
| 707 | + smu_info->gpuclk_ss_rate_10hz * 10; |
---|
| 708 | + if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) |
---|
| 709 | + ss_info->type.CENTER_MODE = true; |
---|
865 | 710 | break; |
---|
866 | 711 | default: |
---|
867 | 712 | result = BP_RESULT_UNSUPPORTED; |
---|
.. | .. |
---|
984 | 829 | case 1: |
---|
985 | 830 | return get_ss_info_v4_1(bp, signal, index, ss_info); |
---|
986 | 831 | case 2: |
---|
| 832 | + case 3: |
---|
987 | 833 | return get_ss_info_v4_2(bp, signal, index, ss_info); |
---|
988 | 834 | default: |
---|
989 | 835 | break; |
---|
.. | .. |
---|
996 | 842 | return result; |
---|
997 | 843 | } |
---|
998 | 844 | |
---|
999 | | -static enum bp_result get_embedded_panel_info_v2_1( |
---|
| 845 | +static enum bp_result get_soc_bb_info_v4_4( |
---|
1000 | 846 | struct bios_parser *bp, |
---|
1001 | | - struct embedded_panel_info *info) |
---|
| 847 | + struct bp_soc_bb_info *soc_bb_info) |
---|
| 848 | +{ |
---|
| 849 | + enum bp_result result = BP_RESULT_OK; |
---|
| 850 | + struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; |
---|
| 851 | + |
---|
| 852 | + if (!soc_bb_info) |
---|
| 853 | + return BP_RESULT_BADINPUT; |
---|
| 854 | + |
---|
| 855 | + if (!DATA_TABLES(dce_info)) |
---|
| 856 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 857 | + |
---|
| 858 | + if (!DATA_TABLES(smu_info)) |
---|
| 859 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 860 | + |
---|
| 861 | + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, |
---|
| 862 | + DATA_TABLES(dce_info)); |
---|
| 863 | + if (!disp_cntl_tbl) |
---|
| 864 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 865 | + |
---|
| 866 | + soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat; |
---|
| 867 | + soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat; |
---|
| 868 | + soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat; |
---|
| 869 | + |
---|
| 870 | + return result; |
---|
| 871 | +} |
---|
| 872 | + |
---|
| 873 | +static enum bp_result bios_parser_get_soc_bb_info( |
---|
| 874 | + struct dc_bios *dcb, |
---|
| 875 | + struct bp_soc_bb_info *soc_bb_info) |
---|
| 876 | +{ |
---|
| 877 | + struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 878 | + enum bp_result result = BP_RESULT_UNSUPPORTED; |
---|
| 879 | + struct atom_common_table_header *header; |
---|
| 880 | + struct atom_data_revision tbl_revision; |
---|
| 881 | + |
---|
| 882 | + if (!soc_bb_info) /* check for bad input */ |
---|
| 883 | + return BP_RESULT_BADINPUT; |
---|
| 884 | + |
---|
| 885 | + if (!DATA_TABLES(dce_info)) |
---|
| 886 | + return BP_RESULT_UNSUPPORTED; |
---|
| 887 | + |
---|
| 888 | + header = GET_IMAGE(struct atom_common_table_header, |
---|
| 889 | + DATA_TABLES(dce_info)); |
---|
| 890 | + get_atom_data_table_revision(header, &tbl_revision); |
---|
| 891 | + |
---|
| 892 | + switch (tbl_revision.major) { |
---|
| 893 | + case 4: |
---|
| 894 | + switch (tbl_revision.minor) { |
---|
| 895 | + case 1: |
---|
| 896 | + case 2: |
---|
| 897 | + case 3: |
---|
| 898 | + break; |
---|
| 899 | + case 4: |
---|
| 900 | + result = get_soc_bb_info_v4_4(bp, soc_bb_info); |
---|
| 901 | + default: |
---|
| 902 | + break; |
---|
| 903 | + } |
---|
| 904 | + break; |
---|
| 905 | + default: |
---|
| 906 | + break; |
---|
| 907 | + } |
---|
| 908 | + |
---|
| 909 | + return result; |
---|
| 910 | +} |
---|
| 911 | + |
---|
| 912 | +static enum bp_result get_embedded_panel_info_v2_1( |
---|
| 913 | + struct bios_parser *bp, |
---|
| 914 | + struct embedded_panel_info *info) |
---|
1002 | 915 | { |
---|
1003 | 916 | struct lcd_info_v2_1 *lvds; |
---|
1004 | 917 | |
---|
.. | .. |
---|
1021 | 934 | memset(info, 0, sizeof(struct embedded_panel_info)); |
---|
1022 | 935 | |
---|
1023 | 936 | /* We need to convert from 10KHz units into KHz units */ |
---|
1024 | | - info->lcd_timing.pixel_clk = |
---|
1025 | | - le16_to_cpu(lvds->lcd_timing.pixclk) * 10; |
---|
| 937 | + info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10; |
---|
1026 | 938 | /* usHActive does not include borders, according to VBIOS team */ |
---|
1027 | | - info->lcd_timing.horizontal_addressable = |
---|
1028 | | - le16_to_cpu(lvds->lcd_timing.h_active); |
---|
| 939 | + info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active); |
---|
1029 | 940 | /* usHBlanking_Time includes borders, so we should really be |
---|
1030 | 941 | * subtractingborders duing this translation, but LVDS generally |
---|
1031 | 942 | * doesn't have borders, so we should be okay leaving this as is for |
---|
1032 | 943 | * now. May need to revisit if we ever have LVDS with borders |
---|
1033 | 944 | */ |
---|
1034 | | - info->lcd_timing.horizontal_blanking_time = |
---|
1035 | | - le16_to_cpu(lvds->lcd_timing.h_blanking_time); |
---|
| 945 | + info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time); |
---|
1036 | 946 | /* usVActive does not include borders, according to VBIOS team*/ |
---|
1037 | | - info->lcd_timing.vertical_addressable = |
---|
1038 | | - le16_to_cpu(lvds->lcd_timing.v_active); |
---|
| 947 | + info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active); |
---|
1039 | 948 | /* usVBlanking_Time includes borders, so we should really be |
---|
1040 | 949 | * subtracting borders duing this translation, but LVDS generally |
---|
1041 | 950 | * doesn't have borders, so we should be okay leaving this as is for |
---|
1042 | 951 | * now. May need to revisit if we ever have LVDS with borders |
---|
1043 | 952 | */ |
---|
1044 | | - info->lcd_timing.vertical_blanking_time = |
---|
1045 | | - le16_to_cpu(lvds->lcd_timing.v_blanking_time); |
---|
1046 | | - info->lcd_timing.horizontal_sync_offset = |
---|
1047 | | - le16_to_cpu(lvds->lcd_timing.h_sync_offset); |
---|
1048 | | - info->lcd_timing.horizontal_sync_width = |
---|
1049 | | - le16_to_cpu(lvds->lcd_timing.h_sync_width); |
---|
1050 | | - info->lcd_timing.vertical_sync_offset = |
---|
1051 | | - le16_to_cpu(lvds->lcd_timing.v_sync_offset); |
---|
1052 | | - info->lcd_timing.vertical_sync_width = |
---|
1053 | | - le16_to_cpu(lvds->lcd_timing.v_syncwidth); |
---|
| 953 | + info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time); |
---|
| 954 | + info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset); |
---|
| 955 | + info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width); |
---|
| 956 | + info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset); |
---|
| 957 | + info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth); |
---|
1054 | 958 | info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border; |
---|
1055 | 959 | info->lcd_timing.vertical_border = lvds->lcd_timing.v_border; |
---|
1056 | 960 | |
---|
1057 | 961 | /* not provided by VBIOS */ |
---|
1058 | 962 | info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; |
---|
1059 | 963 | |
---|
1060 | | - info->lcd_timing.misc_info.H_SYNC_POLARITY = |
---|
1061 | | - ~(uint32_t) |
---|
1062 | | - (lvds->lcd_timing.miscinfo & ATOM_HSYNC_POLARITY); |
---|
1063 | | - info->lcd_timing.misc_info.V_SYNC_POLARITY = |
---|
1064 | | - ~(uint32_t) |
---|
1065 | | - (lvds->lcd_timing.miscinfo & ATOM_VSYNC_POLARITY); |
---|
| 964 | + info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo |
---|
| 965 | + & ATOM_HSYNC_POLARITY); |
---|
| 966 | + info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo |
---|
| 967 | + & ATOM_VSYNC_POLARITY); |
---|
1066 | 968 | |
---|
1067 | 969 | /* not provided by VBIOS */ |
---|
1068 | 970 | info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; |
---|
1069 | 971 | |
---|
1070 | | - info->lcd_timing.misc_info.H_REPLICATION_BY2 = |
---|
1071 | | - !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2); |
---|
1072 | | - info->lcd_timing.misc_info.V_REPLICATION_BY2 = |
---|
1073 | | - !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2); |
---|
1074 | | - info->lcd_timing.misc_info.COMPOSITE_SYNC = |
---|
1075 | | - !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC); |
---|
1076 | | - info->lcd_timing.misc_info.INTERLACE = |
---|
1077 | | - !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); |
---|
| 972 | + info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo |
---|
| 973 | + & ATOM_H_REPLICATIONBY2); |
---|
| 974 | + info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo |
---|
| 975 | + & ATOM_V_REPLICATIONBY2); |
---|
| 976 | + info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo |
---|
| 977 | + & ATOM_COMPOSITESYNC); |
---|
| 978 | + info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); |
---|
1078 | 979 | |
---|
1079 | 980 | /* not provided by VBIOS*/ |
---|
1080 | 981 | info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; |
---|
1081 | 982 | /* not provided by VBIOS*/ |
---|
1082 | 983 | info->ss_id = 0; |
---|
1083 | 984 | |
---|
1084 | | - info->realtek_eDPToLVDS = |
---|
1085 | | - !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); |
---|
| 985 | + info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); |
---|
1086 | 986 | |
---|
1087 | 987 | return BP_RESULT_OK; |
---|
1088 | 988 | } |
---|
1089 | 989 | |
---|
1090 | 990 | static enum bp_result bios_parser_get_embedded_panel_info( |
---|
1091 | | - struct dc_bios *dcb, |
---|
1092 | | - struct embedded_panel_info *info) |
---|
| 991 | + struct dc_bios *dcb, |
---|
| 992 | + struct embedded_panel_info *info) |
---|
1093 | 993 | { |
---|
1094 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 994 | + struct bios_parser |
---|
| 995 | + *bp = BP_FROM_DCB(dcb); |
---|
1095 | 996 | struct atom_common_table_header *header; |
---|
1096 | 997 | struct atom_data_revision tbl_revision; |
---|
1097 | 998 | |
---|
1098 | 999 | if (!DATA_TABLES(lcd_info)) |
---|
1099 | 1000 | return BP_RESULT_FAILURE; |
---|
1100 | 1001 | |
---|
1101 | | - header = GET_IMAGE(struct atom_common_table_header, |
---|
1102 | | - DATA_TABLES(lcd_info)); |
---|
| 1002 | + header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info)); |
---|
1103 | 1003 | |
---|
1104 | 1004 | if (!header) |
---|
1105 | 1005 | return BP_RESULT_BADBIOSTABLE; |
---|
1106 | 1006 | |
---|
1107 | 1007 | get_atom_data_table_revision(header, &tbl_revision); |
---|
1108 | | - |
---|
1109 | 1008 | |
---|
1110 | 1009 | switch (tbl_revision.major) { |
---|
1111 | 1010 | case 2: |
---|
.. | .. |
---|
1156 | 1055 | break; |
---|
1157 | 1056 | default: |
---|
1158 | 1057 | break; |
---|
1159 | | - }; |
---|
| 1058 | + } |
---|
1160 | 1059 | |
---|
1161 | 1060 | /* Unidentified device ID, return empty support mask. */ |
---|
1162 | 1061 | return 0; |
---|
.. | .. |
---|
1172 | 1071 | |
---|
1173 | 1072 | return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & |
---|
1174 | 1073 | mask) != 0; |
---|
1175 | | -} |
---|
1176 | | - |
---|
1177 | | -static void bios_parser_post_init( |
---|
1178 | | - struct dc_bios *dcb) |
---|
1179 | | -{ |
---|
1180 | | - /* TODO for OPM module. Need implement later */ |
---|
1181 | 1074 | } |
---|
1182 | 1075 | |
---|
1183 | 1076 | static uint32_t bios_parser_get_ss_entry_number( |
---|
.. | .. |
---|
1238 | 1131 | return bp->cmd_tbl.set_dce_clock(bp, bp_params); |
---|
1239 | 1132 | } |
---|
1240 | 1133 | |
---|
1241 | | -static unsigned int bios_parser_get_smu_clock_info( |
---|
1242 | | - struct dc_bios *dcb) |
---|
1243 | | -{ |
---|
1244 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
1245 | | - |
---|
1246 | | - if (!bp->cmd_tbl.get_smu_clock_info) |
---|
1247 | | - return BP_RESULT_FAILURE; |
---|
1248 | | - |
---|
1249 | | - return bp->cmd_tbl.get_smu_clock_info(bp, 0); |
---|
1250 | | -} |
---|
1251 | | - |
---|
1252 | 1134 | static enum bp_result bios_parser_program_crtc_timing( |
---|
1253 | 1135 | struct dc_bios *dcb, |
---|
1254 | 1136 | struct bp_hw_crtc_timing_parameters *bp_params) |
---|
.. | .. |
---|
1274 | 1156 | return bp->cmd_tbl.enable_crtc(bp, id, enable); |
---|
1275 | 1157 | } |
---|
1276 | 1158 | |
---|
1277 | | -static enum bp_result bios_parser_crtc_source_select( |
---|
1278 | | - struct dc_bios *dcb, |
---|
1279 | | - struct bp_crtc_source_select *bp_params) |
---|
1280 | | -{ |
---|
1281 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
1282 | | - |
---|
1283 | | - if (!bp->cmd_tbl.select_crtc_source) |
---|
1284 | | - return BP_RESULT_FAILURE; |
---|
1285 | | - |
---|
1286 | | - return bp->cmd_tbl.select_crtc_source(bp, bp_params); |
---|
1287 | | -} |
---|
1288 | | - |
---|
1289 | 1159 | static enum bp_result bios_parser_enable_disp_power_gating( |
---|
1290 | 1160 | struct dc_bios *dcb, |
---|
1291 | 1161 | enum controller_id controller_id, |
---|
.. | .. |
---|
1300 | 1170 | action); |
---|
1301 | 1171 | } |
---|
1302 | 1172 | |
---|
| 1173 | +static enum bp_result bios_parser_enable_lvtma_control( |
---|
| 1174 | + struct dc_bios *dcb, |
---|
| 1175 | + uint8_t uc_pwr_on) |
---|
| 1176 | +{ |
---|
| 1177 | + struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 1178 | + |
---|
| 1179 | + if (!bp->cmd_tbl.enable_lvtma_control) |
---|
| 1180 | + return BP_RESULT_FAILURE; |
---|
| 1181 | + |
---|
| 1182 | + return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on); |
---|
| 1183 | +} |
---|
| 1184 | + |
---|
1303 | 1185 | static bool bios_parser_is_accelerated_mode( |
---|
1304 | 1186 | struct dc_bios *dcb) |
---|
1305 | 1187 | { |
---|
1306 | 1188 | return bios_is_accelerated_mode(dcb); |
---|
1307 | 1189 | } |
---|
1308 | | - |
---|
1309 | | -static uint32_t bios_parser_get_vga_enabled_displays( |
---|
1310 | | - struct dc_bios *bios) |
---|
1311 | | -{ |
---|
1312 | | - return bios_get_vga_enabled_displays(bios); |
---|
1313 | | -} |
---|
1314 | | - |
---|
1315 | 1190 | |
---|
1316 | 1191 | /** |
---|
1317 | 1192 | * bios_parser_set_scratch_critical_state |
---|
.. | .. |
---|
1353 | 1228 | result = get_firmware_info_v3_2(bp, info); |
---|
1354 | 1229 | break; |
---|
1355 | 1230 | case 3: |
---|
| 1231 | +#ifdef CONFIG_DRM_AMD_DC_DCN3_0 |
---|
| 1232 | + case 4: |
---|
| 1233 | +#endif |
---|
1356 | 1234 | result = get_firmware_info_v3_2(bp, info); |
---|
1357 | 1235 | break; |
---|
1358 | 1236 | default: |
---|
.. | .. |
---|
1410 | 1288 | info->smu_gpu_pll_output_freq = |
---|
1411 | 1289 | bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; |
---|
1412 | 1290 | } |
---|
| 1291 | + |
---|
| 1292 | + info->oem_i2c_present = false; |
---|
1413 | 1293 | |
---|
1414 | 1294 | return BP_RESULT_OK; |
---|
1415 | 1295 | } |
---|
.. | .. |
---|
1489 | 1369 | bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10; |
---|
1490 | 1370 | } |
---|
1491 | 1371 | |
---|
| 1372 | + if (firmware_info->board_i2c_feature_id == 0x2) { |
---|
| 1373 | + info->oem_i2c_present = true; |
---|
| 1374 | + info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; |
---|
| 1375 | + } else { |
---|
| 1376 | + info->oem_i2c_present = false; |
---|
| 1377 | + } |
---|
| 1378 | + |
---|
1492 | 1379 | return BP_RESULT_OK; |
---|
1493 | 1380 | } |
---|
1494 | 1381 | |
---|
.. | .. |
---|
1521 | 1408 | ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; |
---|
1522 | 1409 | info->HDMI_6GB_EN = (record->encodercaps & |
---|
1523 | 1410 | ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; |
---|
| 1411 | + info->DP_IS_USB_C = (record->encodercaps & |
---|
| 1412 | + ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0; |
---|
1524 | 1413 | |
---|
1525 | 1414 | return BP_RESULT_OK; |
---|
1526 | 1415 | } |
---|
.. | .. |
---|
1561 | 1450 | } |
---|
1562 | 1451 | |
---|
1563 | 1452 | return NULL; |
---|
| 1453 | +} |
---|
| 1454 | + |
---|
| 1455 | +static enum bp_result get_vram_info_v23( |
---|
| 1456 | + struct bios_parser *bp, |
---|
| 1457 | + struct dc_vram_info *info) |
---|
| 1458 | +{ |
---|
| 1459 | + struct atom_vram_info_header_v2_3 *info_v23; |
---|
| 1460 | + enum bp_result result = BP_RESULT_OK; |
---|
| 1461 | + |
---|
| 1462 | + info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3, |
---|
| 1463 | + DATA_TABLES(vram_info)); |
---|
| 1464 | + |
---|
| 1465 | + if (info_v23 == NULL) |
---|
| 1466 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 1467 | + |
---|
| 1468 | + info->num_chans = info_v23->vram_module[0].channel_num; |
---|
| 1469 | + info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8; |
---|
| 1470 | + |
---|
| 1471 | + return result; |
---|
| 1472 | +} |
---|
| 1473 | + |
---|
| 1474 | +static enum bp_result get_vram_info_v24( |
---|
| 1475 | + struct bios_parser *bp, |
---|
| 1476 | + struct dc_vram_info *info) |
---|
| 1477 | +{ |
---|
| 1478 | + struct atom_vram_info_header_v2_4 *info_v24; |
---|
| 1479 | + enum bp_result result = BP_RESULT_OK; |
---|
| 1480 | + |
---|
| 1481 | + info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4, |
---|
| 1482 | + DATA_TABLES(vram_info)); |
---|
| 1483 | + |
---|
| 1484 | + if (info_v24 == NULL) |
---|
| 1485 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 1486 | + |
---|
| 1487 | + info->num_chans = info_v24->vram_module[0].channel_num; |
---|
| 1488 | + info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8; |
---|
| 1489 | + |
---|
| 1490 | + return result; |
---|
| 1491 | +} |
---|
| 1492 | + |
---|
| 1493 | +static enum bp_result get_vram_info_v25( |
---|
| 1494 | + struct bios_parser *bp, |
---|
| 1495 | + struct dc_vram_info *info) |
---|
| 1496 | +{ |
---|
| 1497 | + struct atom_vram_info_header_v2_5 *info_v25; |
---|
| 1498 | + enum bp_result result = BP_RESULT_OK; |
---|
| 1499 | + |
---|
| 1500 | + info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5, |
---|
| 1501 | + DATA_TABLES(vram_info)); |
---|
| 1502 | + |
---|
| 1503 | + if (info_v25 == NULL) |
---|
| 1504 | + return BP_RESULT_BADBIOSTABLE; |
---|
| 1505 | + |
---|
| 1506 | + info->num_chans = info_v25->vram_module[0].channel_num; |
---|
| 1507 | + info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8; |
---|
| 1508 | + |
---|
| 1509 | + return result; |
---|
1564 | 1510 | } |
---|
1565 | 1511 | |
---|
1566 | 1512 | /* |
---|
.. | .. |
---|
1606 | 1552 | info->ma_channel_number = info_v11->umachannelnumber; |
---|
1607 | 1553 | info->lvds_ss_percentage = |
---|
1608 | 1554 | le16_to_cpu(info_v11->lvds_ss_percentage); |
---|
| 1555 | + info->dp_ss_control = |
---|
| 1556 | + le16_to_cpu(info_v11->reserved1); |
---|
1609 | 1557 | info->lvds_sspread_rate_in_10hz = |
---|
1610 | 1558 | le16_to_cpu(info_v11->lvds_ss_rate_10hz); |
---|
1611 | 1559 | info->hdmi_ss_percentage = |
---|
.. | .. |
---|
1813 | 1761 | |
---|
1814 | 1762 | struct atom_common_table_header *header; |
---|
1815 | 1763 | struct atom_data_revision revision; |
---|
1816 | | - |
---|
1817 | | - struct clock_voltage_caps temp = {0, 0}; |
---|
1818 | 1764 | uint32_t i; |
---|
1819 | 1765 | uint32_t j; |
---|
1820 | 1766 | |
---|
.. | .. |
---|
1827 | 1773 | /* Don't need to check major revision as they are all 1 */ |
---|
1828 | 1774 | switch (revision.minor) { |
---|
1829 | 1775 | case 11: |
---|
| 1776 | + case 12: |
---|
1830 | 1777 | result = get_integrated_info_v11(bp, info); |
---|
1831 | 1778 | break; |
---|
1832 | 1779 | default: |
---|
.. | .. |
---|
1844 | 1791 | info->disp_clk_voltage[j-1].max_supported_clk |
---|
1845 | 1792 | ) { |
---|
1846 | 1793 | /* swap j and j - 1*/ |
---|
1847 | | - temp = info->disp_clk_voltage[j-1]; |
---|
1848 | | - info->disp_clk_voltage[j-1] = |
---|
1849 | | - info->disp_clk_voltage[j]; |
---|
1850 | | - info->disp_clk_voltage[j] = temp; |
---|
| 1794 | + swap(info->disp_clk_voltage[j - 1], |
---|
| 1795 | + info->disp_clk_voltage[j]); |
---|
1851 | 1796 | } |
---|
1852 | 1797 | } |
---|
1853 | 1798 | } |
---|
1854 | 1799 | |
---|
| 1800 | + return result; |
---|
| 1801 | +} |
---|
| 1802 | + |
---|
| 1803 | +static enum bp_result bios_parser_get_vram_info( |
---|
| 1804 | + struct dc_bios *dcb, |
---|
| 1805 | + struct dc_vram_info *info) |
---|
| 1806 | +{ |
---|
| 1807 | + struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 1808 | + enum bp_result result = BP_RESULT_BADBIOSTABLE; |
---|
| 1809 | + struct atom_common_table_header *header; |
---|
| 1810 | + struct atom_data_revision revision; |
---|
| 1811 | + |
---|
| 1812 | + if (info && DATA_TABLES(vram_info)) { |
---|
| 1813 | + header = GET_IMAGE(struct atom_common_table_header, |
---|
| 1814 | + DATA_TABLES(vram_info)); |
---|
| 1815 | + |
---|
| 1816 | + get_atom_data_table_revision(header, &revision); |
---|
| 1817 | + |
---|
| 1818 | + switch (revision.major) { |
---|
| 1819 | + case 2: |
---|
| 1820 | + switch (revision.minor) { |
---|
| 1821 | + case 3: |
---|
| 1822 | + result = get_vram_info_v23(bp, info); |
---|
| 1823 | + break; |
---|
| 1824 | + case 4: |
---|
| 1825 | + result = get_vram_info_v24(bp, info); |
---|
| 1826 | + break; |
---|
| 1827 | + case 5: |
---|
| 1828 | + result = get_vram_info_v25(bp, info); |
---|
| 1829 | + break; |
---|
| 1830 | + default: |
---|
| 1831 | + break; |
---|
| 1832 | + } |
---|
| 1833 | + break; |
---|
| 1834 | + |
---|
| 1835 | + default: |
---|
| 1836 | + return result; |
---|
| 1837 | + } |
---|
| 1838 | + |
---|
| 1839 | + } |
---|
1855 | 1840 | return result; |
---|
1856 | 1841 | } |
---|
1857 | 1842 | |
---|
.. | .. |
---|
2029 | 2014 | struct board_layout_info *board_layout_info) |
---|
2030 | 2015 | { |
---|
2031 | 2016 | unsigned int i; |
---|
2032 | | - struct bios_parser *bp; |
---|
2033 | 2017 | enum bp_result record_result; |
---|
2034 | 2018 | |
---|
2035 | 2019 | const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { |
---|
.. | .. |
---|
2038 | 2022 | 0, 0 |
---|
2039 | 2023 | }; |
---|
2040 | 2024 | |
---|
2041 | | - bp = BP_FROM_DCB(dcb); |
---|
2042 | 2025 | if (board_layout_info == NULL) { |
---|
2043 | 2026 | DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); |
---|
2044 | 2027 | return BP_RESULT_BADINPUT; |
---|
.. | .. |
---|
2068 | 2051 | return BP_RESULT_OK; |
---|
2069 | 2052 | } |
---|
2070 | 2053 | |
---|
| 2054 | + |
---|
| 2055 | +static uint16_t bios_parser_pack_data_tables( |
---|
| 2056 | + struct dc_bios *dcb, |
---|
| 2057 | + void *dst) |
---|
| 2058 | +{ |
---|
| 2059 | +#ifdef PACK_BIOS_DATA |
---|
| 2060 | + struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 2061 | + struct atom_rom_header_v2_2 *rom_header = NULL; |
---|
| 2062 | + struct atom_rom_header_v2_2 *packed_rom_header = NULL; |
---|
| 2063 | + struct atom_common_table_header *data_tbl_header = NULL; |
---|
| 2064 | + struct atom_master_list_of_data_tables_v2_1 *data_tbl_list = NULL; |
---|
| 2065 | + struct atom_master_data_table_v2_1 *packed_master_data_tbl = NULL; |
---|
| 2066 | + struct atom_data_revision tbl_rev = {0}; |
---|
| 2067 | + uint16_t *rom_header_offset = NULL; |
---|
| 2068 | + const uint8_t *bios = bp->base.bios; |
---|
| 2069 | + uint8_t *bios_dst = (uint8_t *)dst; |
---|
| 2070 | + uint16_t packed_rom_header_offset; |
---|
| 2071 | + uint16_t packed_masterdatatable_offset; |
---|
| 2072 | + uint16_t packed_data_tbl_offset; |
---|
| 2073 | + uint16_t data_tbl_offset; |
---|
| 2074 | + unsigned int i; |
---|
| 2075 | + |
---|
| 2076 | + rom_header_offset = |
---|
| 2077 | + GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER); |
---|
| 2078 | + |
---|
| 2079 | + if (!rom_header_offset) |
---|
| 2080 | + return 0; |
---|
| 2081 | + |
---|
| 2082 | + rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset); |
---|
| 2083 | + |
---|
| 2084 | + if (!rom_header) |
---|
| 2085 | + return 0; |
---|
| 2086 | + |
---|
| 2087 | + get_atom_data_table_revision(&rom_header->table_header, &tbl_rev); |
---|
| 2088 | + if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2)) |
---|
| 2089 | + return 0; |
---|
| 2090 | + |
---|
| 2091 | + get_atom_data_table_revision(&bp->master_data_tbl->table_header, &tbl_rev); |
---|
| 2092 | + if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 1)) |
---|
| 2093 | + return 0; |
---|
| 2094 | + |
---|
| 2095 | + packed_rom_header_offset = |
---|
| 2096 | + OFFSET_TO_ATOM_ROM_HEADER_POINTER + sizeof(*rom_header_offset); |
---|
| 2097 | + |
---|
| 2098 | + packed_masterdatatable_offset = |
---|
| 2099 | + packed_rom_header_offset + rom_header->table_header.structuresize; |
---|
| 2100 | + |
---|
| 2101 | + packed_data_tbl_offset = |
---|
| 2102 | + packed_masterdatatable_offset + |
---|
| 2103 | + bp->master_data_tbl->table_header.structuresize; |
---|
| 2104 | + |
---|
| 2105 | + packed_rom_header = |
---|
| 2106 | + (struct atom_rom_header_v2_2 *)(bios_dst + packed_rom_header_offset); |
---|
| 2107 | + |
---|
| 2108 | + packed_master_data_tbl = |
---|
| 2109 | + (struct atom_master_data_table_v2_1 *)(bios_dst + |
---|
| 2110 | + packed_masterdatatable_offset); |
---|
| 2111 | + |
---|
| 2112 | + memcpy(bios_dst, bios, OFFSET_TO_ATOM_ROM_HEADER_POINTER); |
---|
| 2113 | + |
---|
| 2114 | + *((uint16_t *)(bios_dst + OFFSET_TO_ATOM_ROM_HEADER_POINTER)) = |
---|
| 2115 | + packed_rom_header_offset; |
---|
| 2116 | + |
---|
| 2117 | + memcpy(bios_dst + packed_rom_header_offset, rom_header, |
---|
| 2118 | + rom_header->table_header.structuresize); |
---|
| 2119 | + |
---|
| 2120 | + packed_rom_header->masterdatatable_offset = packed_masterdatatable_offset; |
---|
| 2121 | + |
---|
| 2122 | + memcpy(&packed_master_data_tbl->table_header, |
---|
| 2123 | + &bp->master_data_tbl->table_header, |
---|
| 2124 | + sizeof(bp->master_data_tbl->table_header)); |
---|
| 2125 | + |
---|
| 2126 | + data_tbl_list = &bp->master_data_tbl->listOfdatatables; |
---|
| 2127 | + |
---|
| 2128 | + /* Each data table offset in data table list is 2 bytes, |
---|
| 2129 | + * we can use that to iterate through listOfdatatables |
---|
| 2130 | + * without knowing the name of each member. |
---|
| 2131 | + */ |
---|
| 2132 | + for (i = 0; i < sizeof(*data_tbl_list)/sizeof(uint16_t); i++) { |
---|
| 2133 | + data_tbl_offset = *((uint16_t *)data_tbl_list + i); |
---|
| 2134 | + |
---|
| 2135 | + if (data_tbl_offset) { |
---|
| 2136 | + data_tbl_header = |
---|
| 2137 | + (struct atom_common_table_header *)(bios + data_tbl_offset); |
---|
| 2138 | + |
---|
| 2139 | + memcpy(bios_dst + packed_data_tbl_offset, data_tbl_header, |
---|
| 2140 | + data_tbl_header->structuresize); |
---|
| 2141 | + |
---|
| 2142 | + *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) = |
---|
| 2143 | + packed_data_tbl_offset; |
---|
| 2144 | + |
---|
| 2145 | + packed_data_tbl_offset += data_tbl_header->structuresize; |
---|
| 2146 | + } else { |
---|
| 2147 | + *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) = 0; |
---|
| 2148 | + } |
---|
| 2149 | + } |
---|
| 2150 | + return packed_data_tbl_offset; |
---|
| 2151 | +#endif |
---|
| 2152 | + // TODO: There is data bytes alignment issue, disable it for now. |
---|
| 2153 | + return 0; |
---|
| 2154 | +} |
---|
| 2155 | + |
---|
| 2156 | +static struct atom_dc_golden_table_v1 *bios_get_golden_table( |
---|
| 2157 | + struct bios_parser *bp, |
---|
| 2158 | + uint32_t rev_major, |
---|
| 2159 | + uint32_t rev_minor, |
---|
| 2160 | + uint16_t *dc_golden_table_ver) |
---|
| 2161 | +{ |
---|
| 2162 | + struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL; |
---|
| 2163 | + uint32_t dc_golden_offset = 0; |
---|
| 2164 | + *dc_golden_table_ver = 0; |
---|
| 2165 | + |
---|
| 2166 | + if (!DATA_TABLES(dce_info)) |
---|
| 2167 | + return NULL; |
---|
| 2168 | + |
---|
| 2169 | + /* ver.4.4 or higher */ |
---|
| 2170 | + switch (rev_major) { |
---|
| 2171 | + case 4: |
---|
| 2172 | + switch (rev_minor) { |
---|
| 2173 | + case 4: |
---|
| 2174 | + disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, |
---|
| 2175 | + DATA_TABLES(dce_info)); |
---|
| 2176 | + if (!disp_cntl_tbl_4_4) |
---|
| 2177 | + return NULL; |
---|
| 2178 | + dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset; |
---|
| 2179 | + *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver; |
---|
| 2180 | + break; |
---|
| 2181 | + } |
---|
| 2182 | + break; |
---|
| 2183 | + } |
---|
| 2184 | + |
---|
| 2185 | + if (!dc_golden_offset) |
---|
| 2186 | + return NULL; |
---|
| 2187 | + |
---|
| 2188 | + if (*dc_golden_table_ver != 1) |
---|
| 2189 | + return NULL; |
---|
| 2190 | + |
---|
| 2191 | + return GET_IMAGE(struct atom_dc_golden_table_v1, |
---|
| 2192 | + dc_golden_offset); |
---|
| 2193 | +} |
---|
| 2194 | + |
---|
| 2195 | +static enum bp_result bios_get_atom_dc_golden_table( |
---|
| 2196 | + struct dc_bios *dcb) |
---|
| 2197 | +{ |
---|
| 2198 | + struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
| 2199 | + enum bp_result result = BP_RESULT_OK; |
---|
| 2200 | + struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL; |
---|
| 2201 | + struct atom_common_table_header *header; |
---|
| 2202 | + struct atom_data_revision tbl_revision; |
---|
| 2203 | + uint16_t dc_golden_table_ver = 0; |
---|
| 2204 | + |
---|
| 2205 | + header = GET_IMAGE(struct atom_common_table_header, |
---|
| 2206 | + DATA_TABLES(dce_info)); |
---|
| 2207 | + if (!header) |
---|
| 2208 | + return BP_RESULT_UNSUPPORTED; |
---|
| 2209 | + |
---|
| 2210 | + get_atom_data_table_revision(header, &tbl_revision); |
---|
| 2211 | + |
---|
| 2212 | + atom_dc_golden_table = bios_get_golden_table(bp, |
---|
| 2213 | + tbl_revision.major, |
---|
| 2214 | + tbl_revision.minor, |
---|
| 2215 | + &dc_golden_table_ver); |
---|
| 2216 | + |
---|
| 2217 | + if (!atom_dc_golden_table) |
---|
| 2218 | + return BP_RESULT_UNSUPPORTED; |
---|
| 2219 | + |
---|
| 2220 | + dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver; |
---|
| 2221 | + dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val; |
---|
| 2222 | + dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val; |
---|
| 2223 | + dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val; |
---|
| 2224 | + dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val; |
---|
| 2225 | + dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val; |
---|
| 2226 | + dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val; |
---|
| 2227 | + dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val; |
---|
| 2228 | + dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val; |
---|
| 2229 | + dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val; |
---|
| 2230 | + |
---|
| 2231 | + return result; |
---|
| 2232 | +} |
---|
| 2233 | + |
---|
| 2234 | + |
---|
2071 | 2235 | static const struct dc_vbios_funcs vbios_funcs = { |
---|
2072 | 2236 | .get_connectors_number = bios_parser_get_connectors_number, |
---|
2073 | 2237 | |
---|
2074 | | - .get_encoder_id = bios_parser_get_encoder_id, |
---|
2075 | | - |
---|
2076 | 2238 | .get_connector_id = bios_parser_get_connector_id, |
---|
2077 | | - |
---|
2078 | | - .get_dst_number = bios_parser_get_dst_number, |
---|
2079 | 2239 | |
---|
2080 | 2240 | .get_src_obj = bios_parser_get_src_obj, |
---|
2081 | 2241 | |
---|
2082 | | - .get_dst_obj = bios_parser_get_dst_obj, |
---|
2083 | | - |
---|
2084 | 2242 | .get_i2c_info = bios_parser_get_i2c_info, |
---|
2085 | | - |
---|
2086 | | - .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info, |
---|
2087 | | - |
---|
2088 | | - .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info, |
---|
2089 | 2243 | |
---|
2090 | 2244 | .get_hpd_info = bios_parser_get_hpd_info, |
---|
2091 | 2245 | |
---|
2092 | 2246 | .get_device_tag = bios_parser_get_device_tag, |
---|
2093 | | - |
---|
2094 | | - .get_firmware_info = bios_parser_get_firmware_info, |
---|
2095 | 2247 | |
---|
2096 | 2248 | .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, |
---|
2097 | 2249 | |
---|
.. | .. |
---|
2105 | 2257 | |
---|
2106 | 2258 | .is_device_id_supported = bios_parser_is_device_id_supported, |
---|
2107 | 2259 | |
---|
2108 | | - |
---|
2109 | | - |
---|
2110 | 2260 | .is_accelerated_mode = bios_parser_is_accelerated_mode, |
---|
2111 | | - .get_vga_enabled_displays = bios_parser_get_vga_enabled_displays, |
---|
2112 | 2261 | |
---|
2113 | 2262 | .set_scratch_critical_state = bios_parser_set_scratch_critical_state, |
---|
2114 | 2263 | |
---|
.. | .. |
---|
2126 | 2275 | |
---|
2127 | 2276 | .program_crtc_timing = bios_parser_program_crtc_timing, |
---|
2128 | 2277 | |
---|
2129 | | - /* .blank_crtc = bios_parser_blank_crtc, */ |
---|
2130 | | - |
---|
2131 | | - .crtc_source_select = bios_parser_crtc_source_select, |
---|
2132 | | - |
---|
2133 | | - /* .external_encoder_control = bios_parser_external_encoder_control, */ |
---|
2134 | | - |
---|
2135 | 2278 | .enable_disp_power_gating = bios_parser_enable_disp_power_gating, |
---|
2136 | | - |
---|
2137 | | - .post_init = bios_parser_post_init, |
---|
2138 | 2279 | |
---|
2139 | 2280 | .bios_parser_destroy = firmware_parser_destroy, |
---|
2140 | 2281 | |
---|
2141 | | - .get_smu_clock_info = bios_parser_get_smu_clock_info, |
---|
2142 | | - |
---|
2143 | 2282 | .get_board_layout_info = bios_get_board_layout_info, |
---|
| 2283 | + .pack_data_tables = bios_parser_pack_data_tables, |
---|
| 2284 | + |
---|
| 2285 | + .get_atom_dc_golden_table = bios_get_atom_dc_golden_table, |
---|
| 2286 | + |
---|
| 2287 | + .enable_lvtma_control = bios_parser_enable_lvtma_control, |
---|
| 2288 | + |
---|
| 2289 | + .get_soc_bb_info = bios_parser_get_soc_bb_info, |
---|
2144 | 2290 | }; |
---|
2145 | 2291 | |
---|
2146 | | -static bool bios_parser_construct( |
---|
| 2292 | +static bool bios_parser2_construct( |
---|
2147 | 2293 | struct bios_parser *bp, |
---|
2148 | 2294 | struct bp_init_data *init, |
---|
2149 | 2295 | enum dce_version dce_version) |
---|
.. | .. |
---|
2221 | 2367 | dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); |
---|
2222 | 2368 | |
---|
2223 | 2369 | bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); |
---|
| 2370 | + bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK; |
---|
| 2371 | + bios_parser_get_vram_info(&bp->base, &bp->base.vram_info); |
---|
2224 | 2372 | |
---|
2225 | 2373 | return true; |
---|
2226 | 2374 | } |
---|
.. | .. |
---|
2235 | 2383 | if (!bp) |
---|
2236 | 2384 | return NULL; |
---|
2237 | 2385 | |
---|
2238 | | - if (bios_parser_construct(bp, init, dce_version)) |
---|
| 2386 | + if (bios_parser2_construct(bp, init, dce_version)) |
---|
2239 | 2387 | return &bp->base; |
---|
2240 | 2388 | |
---|
2241 | 2389 | kfree(bp); |
---|