.. | .. |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/slab.h> |
---|
| 27 | + |
---|
26 | 28 | #include "dm_services.h" |
---|
27 | 29 | |
---|
28 | 30 | #include "atom.h" |
---|
.. | .. |
---|
42 | 44 | #include "bios_parser_interface.h" |
---|
43 | 45 | |
---|
44 | 46 | #include "bios_parser_common.h" |
---|
45 | | -/* TODO remove - only needed for default i2c speed */ |
---|
| 47 | + |
---|
46 | 48 | #include "dc.h" |
---|
47 | 49 | |
---|
48 | 50 | #define THREE_PERCENT_OF_10000 300 |
---|
.. | .. |
---|
52 | 54 | #define DC_LOGGER \ |
---|
53 | 55 | bp->base.ctx->logger |
---|
54 | 56 | |
---|
55 | | -/* GUID to validate external display connection info table (aka OPM module) */ |
---|
56 | | -static const uint8_t ext_display_connection_guid[NUMBER_OF_UCHAR_FOR_GUID] = { |
---|
57 | | - 0x91, 0x6E, 0x57, 0x09, |
---|
58 | | - 0x3F, 0x6D, 0xD2, 0x11, |
---|
59 | | - 0x39, 0x8E, 0x00, 0xA0, |
---|
60 | | - 0xC9, 0x69, 0x72, 0x3B}; |
---|
61 | | - |
---|
62 | 57 | #define DATA_TABLES(table) (bp->master_data_tbl->ListOfDataTables.table) |
---|
63 | 58 | |
---|
64 | 59 | static void get_atom_data_table_revision( |
---|
65 | 60 | ATOM_COMMON_TABLE_HEADER *atom_data_tbl, |
---|
66 | 61 | struct atom_data_revision *tbl_revision); |
---|
67 | | -static uint32_t get_dst_number_from_object(struct bios_parser *bp, |
---|
68 | | - ATOM_OBJECT *object); |
---|
69 | 62 | static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object, |
---|
70 | 63 | uint16_t **id_list); |
---|
71 | | -static uint32_t get_dest_obj_list(struct bios_parser *bp, |
---|
72 | | - ATOM_OBJECT *object, uint16_t **id_list); |
---|
73 | 64 | static ATOM_OBJECT *get_bios_object(struct bios_parser *bp, |
---|
74 | 65 | struct graphics_object_id id); |
---|
75 | 66 | static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, |
---|
.. | .. |
---|
120 | 111 | return NULL; |
---|
121 | 112 | } |
---|
122 | 113 | |
---|
123 | | -static void destruct(struct bios_parser *bp) |
---|
| 114 | +static void bios_parser_destruct(struct bios_parser *bp) |
---|
124 | 115 | { |
---|
125 | 116 | kfree(bp->base.bios_local_image); |
---|
126 | 117 | kfree(bp->base.integrated_info); |
---|
.. | .. |
---|
135 | 126 | return; |
---|
136 | 127 | } |
---|
137 | 128 | |
---|
138 | | - destruct(bp); |
---|
| 129 | + bios_parser_destruct(bp); |
---|
139 | 130 | |
---|
140 | 131 | kfree(bp); |
---|
141 | 132 | *dcb = NULL; |
---|
.. | .. |
---|
161 | 152 | |
---|
162 | 153 | return get_number_of_objects(bp, |
---|
163 | 154 | le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset)); |
---|
164 | | -} |
---|
165 | | - |
---|
166 | | -static struct graphics_object_id bios_parser_get_encoder_id( |
---|
167 | | - struct dc_bios *dcb, |
---|
168 | | - uint32_t i) |
---|
169 | | -{ |
---|
170 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
171 | | - struct graphics_object_id object_id = dal_graphics_object_id_init( |
---|
172 | | - 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); |
---|
173 | | - |
---|
174 | | - uint32_t encoder_table_offset = bp->object_info_tbl_offset |
---|
175 | | - + le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset); |
---|
176 | | - |
---|
177 | | - ATOM_OBJECT_TABLE *tbl = |
---|
178 | | - GET_IMAGE(ATOM_OBJECT_TABLE, encoder_table_offset); |
---|
179 | | - |
---|
180 | | - if (tbl && tbl->ucNumberOfObjects > i) { |
---|
181 | | - const uint16_t id = le16_to_cpu(tbl->asObjects[i].usObjectID); |
---|
182 | | - |
---|
183 | | - object_id = object_id_from_bios_object_id(id); |
---|
184 | | - } |
---|
185 | | - |
---|
186 | | - return object_id; |
---|
187 | 155 | } |
---|
188 | 156 | |
---|
189 | 157 | static struct graphics_object_id bios_parser_get_connector_id( |
---|
.. | .. |
---|
217 | 185 | return object_id; |
---|
218 | 186 | } |
---|
219 | 187 | |
---|
220 | | -static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb, |
---|
221 | | - struct graphics_object_id id) |
---|
222 | | -{ |
---|
223 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
224 | | - ATOM_OBJECT *object = get_bios_object(bp, id); |
---|
225 | | - |
---|
226 | | - return get_dst_number_from_object(bp, object); |
---|
227 | | -} |
---|
228 | | - |
---|
229 | 188 | static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, |
---|
230 | 189 | struct graphics_object_id object_id, uint32_t index, |
---|
231 | 190 | struct graphics_object_id *src_object_id) |
---|
.. | .. |
---|
251 | 210 | return BP_RESULT_BADINPUT; |
---|
252 | 211 | |
---|
253 | 212 | *src_object_id = object_id_from_bios_object_id(id[index]); |
---|
254 | | - |
---|
255 | | - return BP_RESULT_OK; |
---|
256 | | -} |
---|
257 | | - |
---|
258 | | -static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb, |
---|
259 | | - struct graphics_object_id object_id, uint32_t index, |
---|
260 | | - struct graphics_object_id *dest_object_id) |
---|
261 | | -{ |
---|
262 | | - uint32_t number; |
---|
263 | | - uint16_t *id = NULL; |
---|
264 | | - ATOM_OBJECT *object; |
---|
265 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
266 | | - |
---|
267 | | - if (!dest_object_id) |
---|
268 | | - return BP_RESULT_BADINPUT; |
---|
269 | | - |
---|
270 | | - object = get_bios_object(bp, object_id); |
---|
271 | | - |
---|
272 | | - number = get_dest_obj_list(bp, object, &id); |
---|
273 | | - |
---|
274 | | - if (number <= index || !id) |
---|
275 | | - return BP_RESULT_BADINPUT; |
---|
276 | | - |
---|
277 | | - *dest_object_id = object_id_from_bios_object_id(id[index]); |
---|
278 | 213 | |
---|
279 | 214 | return BP_RESULT_OK; |
---|
280 | 215 | } |
---|
.. | .. |
---|
324 | 259 | |
---|
325 | 260 | return BP_RESULT_NORECORD; |
---|
326 | 261 | } |
---|
327 | | - |
---|
328 | | -static enum bp_result get_voltage_ddc_info_v1(uint8_t *i2c_line, |
---|
329 | | - ATOM_COMMON_TABLE_HEADER *header, |
---|
330 | | - uint8_t *address) |
---|
331 | | -{ |
---|
332 | | - enum bp_result result = BP_RESULT_NORECORD; |
---|
333 | | - ATOM_VOLTAGE_OBJECT_INFO *info = |
---|
334 | | - (ATOM_VOLTAGE_OBJECT_INFO *) address; |
---|
335 | | - |
---|
336 | | - uint8_t *voltage_current_object = (uint8_t *) &info->asVoltageObj[0]; |
---|
337 | | - |
---|
338 | | - while ((address + le16_to_cpu(header->usStructureSize)) > voltage_current_object) { |
---|
339 | | - ATOM_VOLTAGE_OBJECT *object = |
---|
340 | | - (ATOM_VOLTAGE_OBJECT *) voltage_current_object; |
---|
341 | | - |
---|
342 | | - if ((object->ucVoltageType == SET_VOLTAGE_INIT_MODE) && |
---|
343 | | - (object->ucVoltageType & |
---|
344 | | - VOLTAGE_CONTROLLED_BY_I2C_MASK)) { |
---|
345 | | - |
---|
346 | | - *i2c_line = object->asControl.ucVoltageControlI2cLine |
---|
347 | | - ^ 0x90; |
---|
348 | | - result = BP_RESULT_OK; |
---|
349 | | - break; |
---|
350 | | - } |
---|
351 | | - |
---|
352 | | - voltage_current_object += object->ucSize; |
---|
353 | | - } |
---|
354 | | - return result; |
---|
355 | | -} |
---|
356 | | - |
---|
357 | | -static enum bp_result get_voltage_ddc_info_v3(uint8_t *i2c_line, |
---|
358 | | - uint32_t index, |
---|
359 | | - ATOM_COMMON_TABLE_HEADER *header, |
---|
360 | | - uint8_t *address) |
---|
361 | | -{ |
---|
362 | | - enum bp_result result = BP_RESULT_NORECORD; |
---|
363 | | - ATOM_VOLTAGE_OBJECT_INFO_V3_1 *info = |
---|
364 | | - (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *) address; |
---|
365 | | - |
---|
366 | | - uint8_t *voltage_current_object = |
---|
367 | | - (uint8_t *) (&(info->asVoltageObj[0])); |
---|
368 | | - |
---|
369 | | - while ((address + le16_to_cpu(header->usStructureSize)) > voltage_current_object) { |
---|
370 | | - ATOM_I2C_VOLTAGE_OBJECT_V3 *object = |
---|
371 | | - (ATOM_I2C_VOLTAGE_OBJECT_V3 *) voltage_current_object; |
---|
372 | | - |
---|
373 | | - if (object->sHeader.ucVoltageMode == |
---|
374 | | - ATOM_INIT_VOLTAGE_REGULATOR) { |
---|
375 | | - if (object->sHeader.ucVoltageType == index) { |
---|
376 | | - *i2c_line = object->ucVoltageControlI2cLine |
---|
377 | | - ^ 0x90; |
---|
378 | | - result = BP_RESULT_OK; |
---|
379 | | - break; |
---|
380 | | - } |
---|
381 | | - } |
---|
382 | | - |
---|
383 | | - voltage_current_object += le16_to_cpu(object->sHeader.usSize); |
---|
384 | | - } |
---|
385 | | - return result; |
---|
386 | | -} |
---|
387 | | - |
---|
388 | | -static enum bp_result bios_parser_get_thermal_ddc_info( |
---|
389 | | - struct dc_bios *dcb, |
---|
390 | | - uint32_t i2c_channel_id, |
---|
391 | | - struct graphics_object_i2c_info *info) |
---|
392 | | -{ |
---|
393 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
394 | | - ATOM_I2C_ID_CONFIG_ACCESS *config; |
---|
395 | | - ATOM_I2C_RECORD record; |
---|
396 | | - |
---|
397 | | - if (!info) |
---|
398 | | - return BP_RESULT_BADINPUT; |
---|
399 | | - |
---|
400 | | - config = (ATOM_I2C_ID_CONFIG_ACCESS *) &i2c_channel_id; |
---|
401 | | - |
---|
402 | | - record.sucI2cId.bfHW_Capable = config->sbfAccess.bfHW_Capable; |
---|
403 | | - record.sucI2cId.bfI2C_LineMux = config->sbfAccess.bfI2C_LineMux; |
---|
404 | | - record.sucI2cId.bfHW_EngineID = config->sbfAccess.bfHW_EngineID; |
---|
405 | | - |
---|
406 | | - return get_gpio_i2c_info(bp, &record, info); |
---|
407 | | -} |
---|
408 | | - |
---|
409 | | -static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios *dcb, |
---|
410 | | - uint32_t index, |
---|
411 | | - struct graphics_object_i2c_info *info) |
---|
412 | | -{ |
---|
413 | | - uint8_t i2c_line = 0; |
---|
414 | | - enum bp_result result = BP_RESULT_NORECORD; |
---|
415 | | - uint8_t *voltage_info_address; |
---|
416 | | - ATOM_COMMON_TABLE_HEADER *header; |
---|
417 | | - struct atom_data_revision revision = {0}; |
---|
418 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
419 | | - |
---|
420 | | - if (!DATA_TABLES(VoltageObjectInfo)) |
---|
421 | | - return result; |
---|
422 | | - |
---|
423 | | - voltage_info_address = bios_get_image(&bp->base, DATA_TABLES(VoltageObjectInfo), sizeof(ATOM_COMMON_TABLE_HEADER)); |
---|
424 | | - |
---|
425 | | - header = (ATOM_COMMON_TABLE_HEADER *) voltage_info_address; |
---|
426 | | - |
---|
427 | | - get_atom_data_table_revision(header, &revision); |
---|
428 | | - |
---|
429 | | - switch (revision.major) { |
---|
430 | | - case 1: |
---|
431 | | - case 2: |
---|
432 | | - result = get_voltage_ddc_info_v1(&i2c_line, header, |
---|
433 | | - voltage_info_address); |
---|
434 | | - break; |
---|
435 | | - case 3: |
---|
436 | | - if (revision.minor != 1) |
---|
437 | | - break; |
---|
438 | | - result = get_voltage_ddc_info_v3(&i2c_line, index, header, |
---|
439 | | - voltage_info_address); |
---|
440 | | - break; |
---|
441 | | - } |
---|
442 | | - |
---|
443 | | - if (result == BP_RESULT_OK) |
---|
444 | | - result = bios_parser_get_thermal_ddc_info(dcb, |
---|
445 | | - i2c_line, info); |
---|
446 | | - |
---|
447 | | - return result; |
---|
448 | | -} |
---|
449 | | - |
---|
450 | | -/* TODO: temporary commented out to suppress 'defined but not used' warning */ |
---|
451 | | -#if 0 |
---|
452 | | -static enum bp_result bios_parser_get_ddc_info_for_i2c_line( |
---|
453 | | - struct bios_parser *bp, |
---|
454 | | - uint8_t i2c_line, struct graphics_object_i2c_info *info) |
---|
455 | | -{ |
---|
456 | | - uint32_t offset; |
---|
457 | | - ATOM_OBJECT *object; |
---|
458 | | - ATOM_OBJECT_TABLE *table; |
---|
459 | | - uint32_t i; |
---|
460 | | - |
---|
461 | | - if (!info) |
---|
462 | | - return BP_RESULT_BADINPUT; |
---|
463 | | - |
---|
464 | | - offset = le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset); |
---|
465 | | - |
---|
466 | | - offset += bp->object_info_tbl_offset; |
---|
467 | | - |
---|
468 | | - table = GET_IMAGE(ATOM_OBJECT_TABLE, offset); |
---|
469 | | - |
---|
470 | | - if (!table) |
---|
471 | | - return BP_RESULT_BADBIOSTABLE; |
---|
472 | | - |
---|
473 | | - for (i = 0; i < table->ucNumberOfObjects; i++) { |
---|
474 | | - object = &table->asObjects[i]; |
---|
475 | | - |
---|
476 | | - if (!object) { |
---|
477 | | - BREAK_TO_DEBUGGER(); /* Invalid object id */ |
---|
478 | | - return BP_RESULT_BADINPUT; |
---|
479 | | - } |
---|
480 | | - |
---|
481 | | - offset = le16_to_cpu(object->usRecordOffset) |
---|
482 | | - + bp->object_info_tbl_offset; |
---|
483 | | - |
---|
484 | | - for (;;) { |
---|
485 | | - ATOM_COMMON_RECORD_HEADER *header = |
---|
486 | | - GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); |
---|
487 | | - |
---|
488 | | - if (!header) |
---|
489 | | - return BP_RESULT_BADBIOSTABLE; |
---|
490 | | - |
---|
491 | | - offset += header->ucRecordSize; |
---|
492 | | - |
---|
493 | | - if (LAST_RECORD_TYPE == header->ucRecordType || |
---|
494 | | - !header->ucRecordSize) |
---|
495 | | - break; |
---|
496 | | - |
---|
497 | | - if (ATOM_I2C_RECORD_TYPE == header->ucRecordType |
---|
498 | | - && sizeof(ATOM_I2C_RECORD) <= |
---|
499 | | - header->ucRecordSize) { |
---|
500 | | - ATOM_I2C_RECORD *record = |
---|
501 | | - (ATOM_I2C_RECORD *) header; |
---|
502 | | - |
---|
503 | | - if (i2c_line != record->sucI2cId.bfI2C_LineMux) |
---|
504 | | - continue; |
---|
505 | | - |
---|
506 | | - /* get the I2C info */ |
---|
507 | | - if (get_gpio_i2c_info(bp, record, info) == |
---|
508 | | - BP_RESULT_OK) |
---|
509 | | - return BP_RESULT_OK; |
---|
510 | | - } |
---|
511 | | - } |
---|
512 | | - } |
---|
513 | | - |
---|
514 | | - return BP_RESULT_NORECORD; |
---|
515 | | -} |
---|
516 | | -#endif |
---|
517 | 262 | |
---|
518 | 263 | static enum bp_result bios_parser_get_hpd_info(struct dc_bios *dcb, |
---|
519 | 264 | struct graphics_object_id id, |
---|
.. | .. |
---|
1092 | 837 | return bp->cmd_tbl.enable_crtc(bp, id, enable); |
---|
1093 | 838 | } |
---|
1094 | 839 | |
---|
1095 | | -static enum bp_result bios_parser_crtc_source_select( |
---|
1096 | | - struct dc_bios *dcb, |
---|
1097 | | - struct bp_crtc_source_select *bp_params) |
---|
1098 | | -{ |
---|
1099 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
1100 | | - |
---|
1101 | | - if (!bp->cmd_tbl.select_crtc_source) |
---|
1102 | | - return BP_RESULT_FAILURE; |
---|
1103 | | - |
---|
1104 | | - return bp->cmd_tbl.select_crtc_source(bp, bp_params); |
---|
1105 | | -} |
---|
1106 | | - |
---|
1107 | 840 | static enum bp_result bios_parser_enable_disp_power_gating( |
---|
1108 | 841 | struct dc_bios *dcb, |
---|
1109 | 842 | enum controller_id controller_id, |
---|
.. | .. |
---|
1127 | 860 | uint32_t mask = get_support_mask_for_device_id(id); |
---|
1128 | 861 | |
---|
1129 | 862 | return (le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport) & mask) != 0; |
---|
1130 | | -} |
---|
1131 | | - |
---|
1132 | | -static enum bp_result bios_parser_crt_control( |
---|
1133 | | - struct dc_bios *dcb, |
---|
1134 | | - enum engine_id engine_id, |
---|
1135 | | - bool enable, |
---|
1136 | | - uint32_t pixel_clock) |
---|
1137 | | -{ |
---|
1138 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
1139 | | - uint8_t standard; |
---|
1140 | | - |
---|
1141 | | - if (!bp->cmd_tbl.dac1_encoder_control && |
---|
1142 | | - engine_id == ENGINE_ID_DACA) |
---|
1143 | | - return BP_RESULT_FAILURE; |
---|
1144 | | - if (!bp->cmd_tbl.dac2_encoder_control && |
---|
1145 | | - engine_id == ENGINE_ID_DACB) |
---|
1146 | | - return BP_RESULT_FAILURE; |
---|
1147 | | - /* validate params */ |
---|
1148 | | - switch (engine_id) { |
---|
1149 | | - case ENGINE_ID_DACA: |
---|
1150 | | - case ENGINE_ID_DACB: |
---|
1151 | | - break; |
---|
1152 | | - default: |
---|
1153 | | - /* unsupported engine */ |
---|
1154 | | - return BP_RESULT_FAILURE; |
---|
1155 | | - } |
---|
1156 | | - |
---|
1157 | | - standard = ATOM_DAC1_PS2; /* == ATOM_DAC2_PS2 */ |
---|
1158 | | - |
---|
1159 | | - if (enable) { |
---|
1160 | | - if (engine_id == ENGINE_ID_DACA) { |
---|
1161 | | - bp->cmd_tbl.dac1_encoder_control(bp, enable, |
---|
1162 | | - pixel_clock, standard); |
---|
1163 | | - if (bp->cmd_tbl.dac1_output_control != NULL) |
---|
1164 | | - bp->cmd_tbl.dac1_output_control(bp, enable); |
---|
1165 | | - } else { |
---|
1166 | | - bp->cmd_tbl.dac2_encoder_control(bp, enable, |
---|
1167 | | - pixel_clock, standard); |
---|
1168 | | - if (bp->cmd_tbl.dac2_output_control != NULL) |
---|
1169 | | - bp->cmd_tbl.dac2_output_control(bp, enable); |
---|
1170 | | - } |
---|
1171 | | - } else { |
---|
1172 | | - if (engine_id == ENGINE_ID_DACA) { |
---|
1173 | | - if (bp->cmd_tbl.dac1_output_control != NULL) |
---|
1174 | | - bp->cmd_tbl.dac1_output_control(bp, enable); |
---|
1175 | | - bp->cmd_tbl.dac1_encoder_control(bp, enable, |
---|
1176 | | - pixel_clock, standard); |
---|
1177 | | - } else { |
---|
1178 | | - if (bp->cmd_tbl.dac2_output_control != NULL) |
---|
1179 | | - bp->cmd_tbl.dac2_output_control(bp, enable); |
---|
1180 | | - bp->cmd_tbl.dac2_encoder_control(bp, enable, |
---|
1181 | | - pixel_clock, standard); |
---|
1182 | | - } |
---|
1183 | | - } |
---|
1184 | | - |
---|
1185 | | - return BP_RESULT_OK; |
---|
1186 | 863 | } |
---|
1187 | 864 | |
---|
1188 | 865 | static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp, |
---|
.. | .. |
---|
1214 | 891 | return (ATOM_HPD_INT_RECORD *) header; |
---|
1215 | 892 | |
---|
1216 | 893 | offset += header->ucRecordSize; |
---|
1217 | | - } |
---|
1218 | | - |
---|
1219 | | - return NULL; |
---|
1220 | | -} |
---|
1221 | | - |
---|
1222 | | -/** |
---|
1223 | | - * Get I2C information of input object id |
---|
1224 | | - * |
---|
1225 | | - * search all records to find the ATOM_I2C_RECORD_TYPE record IR |
---|
1226 | | - */ |
---|
1227 | | -static ATOM_I2C_RECORD *get_i2c_record( |
---|
1228 | | - struct bios_parser *bp, |
---|
1229 | | - ATOM_OBJECT *object) |
---|
1230 | | -{ |
---|
1231 | | - uint32_t offset; |
---|
1232 | | - ATOM_COMMON_RECORD_HEADER *record_header; |
---|
1233 | | - |
---|
1234 | | - if (!object) { |
---|
1235 | | - BREAK_TO_DEBUGGER(); |
---|
1236 | | - /* Invalid object */ |
---|
1237 | | - return NULL; |
---|
1238 | | - } |
---|
1239 | | - |
---|
1240 | | - offset = le16_to_cpu(object->usRecordOffset) |
---|
1241 | | - + bp->object_info_tbl_offset; |
---|
1242 | | - |
---|
1243 | | - for (;;) { |
---|
1244 | | - record_header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); |
---|
1245 | | - |
---|
1246 | | - if (!record_header) |
---|
1247 | | - return NULL; |
---|
1248 | | - |
---|
1249 | | - if (LAST_RECORD_TYPE == record_header->ucRecordType || |
---|
1250 | | - 0 == record_header->ucRecordSize) |
---|
1251 | | - break; |
---|
1252 | | - |
---|
1253 | | - if (ATOM_I2C_RECORD_TYPE == record_header->ucRecordType && |
---|
1254 | | - sizeof(ATOM_I2C_RECORD) <= |
---|
1255 | | - record_header->ucRecordSize) { |
---|
1256 | | - return (ATOM_I2C_RECORD *)record_header; |
---|
1257 | | - } |
---|
1258 | | - |
---|
1259 | | - offset += record_header->ucRecordSize; |
---|
1260 | 894 | } |
---|
1261 | 895 | |
---|
1262 | 896 | return NULL; |
---|
.. | .. |
---|
2356 | 1990 | return NULL; |
---|
2357 | 1991 | } |
---|
2358 | 1992 | |
---|
2359 | | -static uint32_t get_dest_obj_list(struct bios_parser *bp, |
---|
2360 | | - ATOM_OBJECT *object, uint16_t **id_list) |
---|
2361 | | -{ |
---|
2362 | | - uint32_t offset; |
---|
2363 | | - uint8_t *number; |
---|
2364 | | - |
---|
2365 | | - if (!object) { |
---|
2366 | | - BREAK_TO_DEBUGGER(); /* Invalid object id */ |
---|
2367 | | - return 0; |
---|
2368 | | - } |
---|
2369 | | - |
---|
2370 | | - offset = le16_to_cpu(object->usSrcDstTableOffset) |
---|
2371 | | - + bp->object_info_tbl_offset; |
---|
2372 | | - |
---|
2373 | | - number = GET_IMAGE(uint8_t, offset); |
---|
2374 | | - if (!number) |
---|
2375 | | - return 0; |
---|
2376 | | - |
---|
2377 | | - offset += sizeof(uint8_t); |
---|
2378 | | - offset += sizeof(uint16_t) * (*number); |
---|
2379 | | - |
---|
2380 | | - number = GET_IMAGE(uint8_t, offset); |
---|
2381 | | - if ((!number) || (!*number)) |
---|
2382 | | - return 0; |
---|
2383 | | - |
---|
2384 | | - offset += sizeof(uint8_t); |
---|
2385 | | - *id_list = (uint16_t *)bios_get_image(&bp->base, offset, *number * sizeof(uint16_t)); |
---|
2386 | | - |
---|
2387 | | - if (!*id_list) |
---|
2388 | | - return 0; |
---|
2389 | | - |
---|
2390 | | - return *number; |
---|
2391 | | -} |
---|
2392 | | - |
---|
2393 | 1993 | static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object, |
---|
2394 | 1994 | uint16_t **id_list) |
---|
2395 | 1995 | { |
---|
.. | .. |
---|
2417 | 2017 | return *number; |
---|
2418 | 2018 | } |
---|
2419 | 2019 | |
---|
2420 | | -static uint32_t get_dst_number_from_object(struct bios_parser *bp, |
---|
2421 | | - ATOM_OBJECT *object) |
---|
2422 | | -{ |
---|
2423 | | - uint32_t offset; |
---|
2424 | | - uint8_t *number; |
---|
2425 | | - |
---|
2426 | | - if (!object) { |
---|
2427 | | - BREAK_TO_DEBUGGER(); /* Invalid encoder object id*/ |
---|
2428 | | - return 0; |
---|
2429 | | - } |
---|
2430 | | - |
---|
2431 | | - offset = le16_to_cpu(object->usSrcDstTableOffset) |
---|
2432 | | - + bp->object_info_tbl_offset; |
---|
2433 | | - |
---|
2434 | | - number = GET_IMAGE(uint8_t, offset); |
---|
2435 | | - if (!number) |
---|
2436 | | - return 0; |
---|
2437 | | - |
---|
2438 | | - offset += sizeof(uint8_t); |
---|
2439 | | - offset += sizeof(uint16_t) * (*number); |
---|
2440 | | - |
---|
2441 | | - number = GET_IMAGE(uint8_t, offset); |
---|
2442 | | - |
---|
2443 | | - if (!number) |
---|
2444 | | - return 0; |
---|
2445 | | - |
---|
2446 | | - return *number; |
---|
2447 | | -} |
---|
2448 | | - |
---|
2449 | 2020 | static struct device_id device_type_from_device_id(uint16_t device_id) |
---|
2450 | 2021 | { |
---|
2451 | 2022 | |
---|
2452 | | - struct device_id result_device_id; |
---|
| 2023 | + struct device_id result_device_id = {0}; |
---|
2453 | 2024 | |
---|
2454 | 2025 | switch (device_id) { |
---|
2455 | 2026 | case ATOM_DEVICE_LCD1_SUPPORT: |
---|
.. | .. |
---|
2618 | 2189 | break; |
---|
2619 | 2190 | default: |
---|
2620 | 2191 | break; |
---|
2621 | | - }; |
---|
| 2192 | + } |
---|
2622 | 2193 | |
---|
2623 | 2194 | /* Unidentified device ID, return empty support mask. */ |
---|
2624 | 2195 | return 0; |
---|
2625 | | -} |
---|
2626 | | - |
---|
2627 | | -/** |
---|
2628 | | - * HwContext interface for writing MM registers |
---|
2629 | | - */ |
---|
2630 | | - |
---|
2631 | | -static bool i2c_read( |
---|
2632 | | - struct bios_parser *bp, |
---|
2633 | | - struct graphics_object_i2c_info *i2c_info, |
---|
2634 | | - uint8_t *buffer, |
---|
2635 | | - uint32_t length) |
---|
2636 | | -{ |
---|
2637 | | - struct ddc *ddc; |
---|
2638 | | - uint8_t offset[2] = { 0, 0 }; |
---|
2639 | | - bool result = false; |
---|
2640 | | - struct i2c_command cmd; |
---|
2641 | | - struct gpio_ddc_hw_info hw_info = { |
---|
2642 | | - i2c_info->i2c_hw_assist, |
---|
2643 | | - i2c_info->i2c_line }; |
---|
2644 | | - |
---|
2645 | | - ddc = dal_gpio_create_ddc(bp->base.ctx->gpio_service, |
---|
2646 | | - i2c_info->gpio_info.clk_a_register_index, |
---|
2647 | | - (1 << i2c_info->gpio_info.clk_a_shift), &hw_info); |
---|
2648 | | - |
---|
2649 | | - if (!ddc) |
---|
2650 | | - return result; |
---|
2651 | | - |
---|
2652 | | - /*Using SW engine */ |
---|
2653 | | - cmd.engine = I2C_COMMAND_ENGINE_SW; |
---|
2654 | | - cmd.speed = ddc->ctx->dc->caps.i2c_speed_in_khz; |
---|
2655 | | - |
---|
2656 | | - { |
---|
2657 | | - struct i2c_payload payloads[] = { |
---|
2658 | | - { |
---|
2659 | | - .address = i2c_info->i2c_slave_address >> 1, |
---|
2660 | | - .data = offset, |
---|
2661 | | - .length = sizeof(offset), |
---|
2662 | | - .write = true |
---|
2663 | | - }, |
---|
2664 | | - { |
---|
2665 | | - .address = i2c_info->i2c_slave_address >> 1, |
---|
2666 | | - .data = buffer, |
---|
2667 | | - .length = length, |
---|
2668 | | - .write = false |
---|
2669 | | - } |
---|
2670 | | - }; |
---|
2671 | | - |
---|
2672 | | - cmd.payloads = payloads; |
---|
2673 | | - cmd.number_of_payloads = ARRAY_SIZE(payloads); |
---|
2674 | | - |
---|
2675 | | - /* TODO route this through drm i2c_adapter */ |
---|
2676 | | - result = dal_i2caux_submit_i2c_command( |
---|
2677 | | - ddc->ctx->i2caux, |
---|
2678 | | - ddc, |
---|
2679 | | - &cmd); |
---|
2680 | | - } |
---|
2681 | | - |
---|
2682 | | - dal_gpio_destroy_ddc(&ddc); |
---|
2683 | | - |
---|
2684 | | - return result; |
---|
2685 | | -} |
---|
2686 | | - |
---|
2687 | | -/** |
---|
2688 | | - * Read external display connection info table through i2c. |
---|
2689 | | - * validate the GUID and checksum. |
---|
2690 | | - * |
---|
2691 | | - * @return enum bp_result whether all data was sucessfully read |
---|
2692 | | - */ |
---|
2693 | | -static enum bp_result get_ext_display_connection_info( |
---|
2694 | | - struct bios_parser *bp, |
---|
2695 | | - ATOM_OBJECT *opm_object, |
---|
2696 | | - ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO *ext_display_connection_info_tbl) |
---|
2697 | | -{ |
---|
2698 | | - bool config_tbl_present = false; |
---|
2699 | | - ATOM_I2C_RECORD *i2c_record = NULL; |
---|
2700 | | - uint32_t i = 0; |
---|
2701 | | - |
---|
2702 | | - if (opm_object == NULL) |
---|
2703 | | - return BP_RESULT_BADINPUT; |
---|
2704 | | - |
---|
2705 | | - i2c_record = get_i2c_record(bp, opm_object); |
---|
2706 | | - |
---|
2707 | | - if (i2c_record != NULL) { |
---|
2708 | | - ATOM_GPIO_I2C_INFO *gpio_i2c_header; |
---|
2709 | | - struct graphics_object_i2c_info i2c_info; |
---|
2710 | | - |
---|
2711 | | - gpio_i2c_header = GET_IMAGE(ATOM_GPIO_I2C_INFO, |
---|
2712 | | - bp->master_data_tbl->ListOfDataTables.GPIO_I2C_Info); |
---|
2713 | | - |
---|
2714 | | - if (NULL == gpio_i2c_header) |
---|
2715 | | - return BP_RESULT_BADBIOSTABLE; |
---|
2716 | | - |
---|
2717 | | - if (get_gpio_i2c_info(bp, i2c_record, &i2c_info) != |
---|
2718 | | - BP_RESULT_OK) |
---|
2719 | | - return BP_RESULT_BADBIOSTABLE; |
---|
2720 | | - |
---|
2721 | | - if (i2c_read(bp, |
---|
2722 | | - &i2c_info, |
---|
2723 | | - (uint8_t *)ext_display_connection_info_tbl, |
---|
2724 | | - sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO))) { |
---|
2725 | | - config_tbl_present = true; |
---|
2726 | | - } |
---|
2727 | | - } |
---|
2728 | | - |
---|
2729 | | - /* Validate GUID */ |
---|
2730 | | - if (config_tbl_present) |
---|
2731 | | - for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; i++) { |
---|
2732 | | - if (ext_display_connection_info_tbl->ucGuid[i] |
---|
2733 | | - != ext_display_connection_guid[i]) { |
---|
2734 | | - config_tbl_present = false; |
---|
2735 | | - break; |
---|
2736 | | - } |
---|
2737 | | - } |
---|
2738 | | - |
---|
2739 | | - /* Validate checksum */ |
---|
2740 | | - if (config_tbl_present) { |
---|
2741 | | - uint8_t check_sum = 0; |
---|
2742 | | - uint8_t *buf = |
---|
2743 | | - (uint8_t *)ext_display_connection_info_tbl; |
---|
2744 | | - |
---|
2745 | | - for (i = 0; i < sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO); |
---|
2746 | | - i++) { |
---|
2747 | | - check_sum += buf[i]; |
---|
2748 | | - } |
---|
2749 | | - |
---|
2750 | | - if (check_sum != 0) |
---|
2751 | | - config_tbl_present = false; |
---|
2752 | | - } |
---|
2753 | | - |
---|
2754 | | - if (config_tbl_present) |
---|
2755 | | - return BP_RESULT_OK; |
---|
2756 | | - else |
---|
2757 | | - return BP_RESULT_FAILURE; |
---|
2758 | | -} |
---|
2759 | | - |
---|
2760 | | -/* |
---|
2761 | | - * Gets the first device ID in the same group as the given ID for enumerating. |
---|
2762 | | - * For instance, if any DFP device ID is passed, returns the device ID for DFP1. |
---|
2763 | | - * |
---|
2764 | | - * The first device ID in the same group as the passed device ID, or 0 if no |
---|
2765 | | - * matching device group found. |
---|
2766 | | - */ |
---|
2767 | | -static uint32_t enum_first_device_id(uint32_t dev_id) |
---|
2768 | | -{ |
---|
2769 | | - /* Return the first in the group that this ID belongs to. */ |
---|
2770 | | - if (dev_id & ATOM_DEVICE_CRT_SUPPORT) |
---|
2771 | | - return ATOM_DEVICE_CRT1_SUPPORT; |
---|
2772 | | - else if (dev_id & ATOM_DEVICE_DFP_SUPPORT) |
---|
2773 | | - return ATOM_DEVICE_DFP1_SUPPORT; |
---|
2774 | | - else if (dev_id & ATOM_DEVICE_LCD_SUPPORT) |
---|
2775 | | - return ATOM_DEVICE_LCD1_SUPPORT; |
---|
2776 | | - else if (dev_id & ATOM_DEVICE_TV_SUPPORT) |
---|
2777 | | - return ATOM_DEVICE_TV1_SUPPORT; |
---|
2778 | | - else if (dev_id & ATOM_DEVICE_CV_SUPPORT) |
---|
2779 | | - return ATOM_DEVICE_CV_SUPPORT; |
---|
2780 | | - |
---|
2781 | | - /* No group found for this device ID. */ |
---|
2782 | | - |
---|
2783 | | - dm_error("%s: incorrect input %d\n", __func__, dev_id); |
---|
2784 | | - /* No matching support flag for given device ID */ |
---|
2785 | | - return 0; |
---|
2786 | | -} |
---|
2787 | | - |
---|
2788 | | -/* |
---|
2789 | | - * Gets the next device ID in the group for a given device ID. |
---|
2790 | | - * |
---|
2791 | | - * The current device ID being enumerated on. |
---|
2792 | | - * |
---|
2793 | | - * The next device ID in the group, or 0 if no device exists. |
---|
2794 | | - */ |
---|
2795 | | -static uint32_t enum_next_dev_id(uint32_t dev_id) |
---|
2796 | | -{ |
---|
2797 | | - /* Get next device ID in the group. */ |
---|
2798 | | - switch (dev_id) { |
---|
2799 | | - case ATOM_DEVICE_CRT1_SUPPORT: |
---|
2800 | | - return ATOM_DEVICE_CRT2_SUPPORT; |
---|
2801 | | - case ATOM_DEVICE_LCD1_SUPPORT: |
---|
2802 | | - return ATOM_DEVICE_LCD2_SUPPORT; |
---|
2803 | | - case ATOM_DEVICE_DFP1_SUPPORT: |
---|
2804 | | - return ATOM_DEVICE_DFP2_SUPPORT; |
---|
2805 | | - case ATOM_DEVICE_DFP2_SUPPORT: |
---|
2806 | | - return ATOM_DEVICE_DFP3_SUPPORT; |
---|
2807 | | - case ATOM_DEVICE_DFP3_SUPPORT: |
---|
2808 | | - return ATOM_DEVICE_DFP4_SUPPORT; |
---|
2809 | | - case ATOM_DEVICE_DFP4_SUPPORT: |
---|
2810 | | - return ATOM_DEVICE_DFP5_SUPPORT; |
---|
2811 | | - case ATOM_DEVICE_DFP5_SUPPORT: |
---|
2812 | | - return ATOM_DEVICE_DFP6_SUPPORT; |
---|
2813 | | - } |
---|
2814 | | - |
---|
2815 | | - /* Done enumerating through devices. */ |
---|
2816 | | - return 0; |
---|
2817 | | -} |
---|
2818 | | - |
---|
2819 | | -/* |
---|
2820 | | - * Returns the new device tag record for patched BIOS object. |
---|
2821 | | - * |
---|
2822 | | - * [IN] pExtDisplayPath - External display path to copy device tag from. |
---|
2823 | | - * [IN] deviceSupport - Bit vector for device ID support flags. |
---|
2824 | | - * [OUT] pDeviceTag - Device tag structure to fill with patched data. |
---|
2825 | | - * |
---|
2826 | | - * True if a compatible device ID was found, false otherwise. |
---|
2827 | | - */ |
---|
2828 | | -static bool get_patched_device_tag( |
---|
2829 | | - struct bios_parser *bp, |
---|
2830 | | - EXT_DISPLAY_PATH *ext_display_path, |
---|
2831 | | - uint32_t device_support, |
---|
2832 | | - ATOM_CONNECTOR_DEVICE_TAG *device_tag) |
---|
2833 | | -{ |
---|
2834 | | - uint32_t dev_id; |
---|
2835 | | - /* Use fallback behaviour if not supported. */ |
---|
2836 | | - if (!bp->remap_device_tags) { |
---|
2837 | | - device_tag->ulACPIDeviceEnum = |
---|
2838 | | - cpu_to_le32((uint32_t) le16_to_cpu(ext_display_path->usDeviceACPIEnum)); |
---|
2839 | | - device_tag->usDeviceID = |
---|
2840 | | - cpu_to_le16(le16_to_cpu(ext_display_path->usDeviceTag)); |
---|
2841 | | - return true; |
---|
2842 | | - } |
---|
2843 | | - |
---|
2844 | | - /* Find the first unused in the same group. */ |
---|
2845 | | - dev_id = enum_first_device_id(le16_to_cpu(ext_display_path->usDeviceTag)); |
---|
2846 | | - while (dev_id != 0) { |
---|
2847 | | - /* Assign this device ID if supported. */ |
---|
2848 | | - if ((device_support & dev_id) != 0) { |
---|
2849 | | - device_tag->ulACPIDeviceEnum = |
---|
2850 | | - cpu_to_le32((uint32_t) le16_to_cpu(ext_display_path->usDeviceACPIEnum)); |
---|
2851 | | - device_tag->usDeviceID = cpu_to_le16((USHORT) dev_id); |
---|
2852 | | - return true; |
---|
2853 | | - } |
---|
2854 | | - |
---|
2855 | | - dev_id = enum_next_dev_id(dev_id); |
---|
2856 | | - } |
---|
2857 | | - |
---|
2858 | | - /* No compatible device ID found. */ |
---|
2859 | | - return false; |
---|
2860 | | -} |
---|
2861 | | - |
---|
2862 | | -/* |
---|
2863 | | - * Adds a device tag to a BIOS object's device tag record if there is |
---|
2864 | | - * matching device ID supported. |
---|
2865 | | - * |
---|
2866 | | - * pObject - Pointer to the BIOS object to add the device tag to. |
---|
2867 | | - * pExtDisplayPath - Display path to retrieve base device ID from. |
---|
2868 | | - * pDeviceSupport - Pointer to bit vector for supported device IDs. |
---|
2869 | | - */ |
---|
2870 | | -static void add_device_tag_from_ext_display_path( |
---|
2871 | | - struct bios_parser *bp, |
---|
2872 | | - ATOM_OBJECT *object, |
---|
2873 | | - EXT_DISPLAY_PATH *ext_display_path, |
---|
2874 | | - uint32_t *device_support) |
---|
2875 | | -{ |
---|
2876 | | - /* Get device tag record for object. */ |
---|
2877 | | - ATOM_CONNECTOR_DEVICE_TAG *device_tag = NULL; |
---|
2878 | | - ATOM_CONNECTOR_DEVICE_TAG_RECORD *device_tag_record = NULL; |
---|
2879 | | - enum bp_result result = |
---|
2880 | | - bios_parser_get_device_tag_record( |
---|
2881 | | - bp, object, &device_tag_record); |
---|
2882 | | - |
---|
2883 | | - if ((le16_to_cpu(ext_display_path->usDeviceTag) != CONNECTOR_OBJECT_ID_NONE) |
---|
2884 | | - && (result == BP_RESULT_OK)) { |
---|
2885 | | - uint8_t index; |
---|
2886 | | - |
---|
2887 | | - if ((device_tag_record->ucNumberOfDevice == 1) && |
---|
2888 | | - (le16_to_cpu(device_tag_record->asDeviceTag[0].usDeviceID) == 0)) { |
---|
2889 | | - /*Workaround bug in current VBIOS releases where |
---|
2890 | | - * ucNumberOfDevice = 1 but there is no actual device |
---|
2891 | | - * tag data. This w/a is temporary until the updated |
---|
2892 | | - * VBIOS is distributed. */ |
---|
2893 | | - device_tag_record->ucNumberOfDevice = |
---|
2894 | | - device_tag_record->ucNumberOfDevice - 1; |
---|
2895 | | - } |
---|
2896 | | - |
---|
2897 | | - /* Attempt to find a matching device ID. */ |
---|
2898 | | - index = device_tag_record->ucNumberOfDevice; |
---|
2899 | | - device_tag = &device_tag_record->asDeviceTag[index]; |
---|
2900 | | - if (get_patched_device_tag( |
---|
2901 | | - bp, |
---|
2902 | | - ext_display_path, |
---|
2903 | | - *device_support, |
---|
2904 | | - device_tag)) { |
---|
2905 | | - /* Update cached device support to remove assigned ID. |
---|
2906 | | - */ |
---|
2907 | | - *device_support &= ~le16_to_cpu(device_tag->usDeviceID); |
---|
2908 | | - device_tag_record->ucNumberOfDevice++; |
---|
2909 | | - } |
---|
2910 | | - } |
---|
2911 | | -} |
---|
2912 | | - |
---|
2913 | | -/* |
---|
2914 | | - * Read out a single EXT_DISPLAY_PATH from the external display connection info |
---|
2915 | | - * table. The specific entry in the table is determined by the enum_id passed |
---|
2916 | | - * in. |
---|
2917 | | - * |
---|
2918 | | - * EXT_DISPLAY_PATH describing a single Configuration table entry |
---|
2919 | | - */ |
---|
2920 | | - |
---|
2921 | | -#define INVALID_CONNECTOR 0xffff |
---|
2922 | | - |
---|
2923 | | -static EXT_DISPLAY_PATH *get_ext_display_path_entry( |
---|
2924 | | - ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO *config_table, |
---|
2925 | | - uint32_t bios_object_id) |
---|
2926 | | -{ |
---|
2927 | | - EXT_DISPLAY_PATH *ext_display_path; |
---|
2928 | | - uint32_t ext_display_path_index = |
---|
2929 | | - ((bios_object_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT) - 1; |
---|
2930 | | - |
---|
2931 | | - if (ext_display_path_index >= MAX_NUMBER_OF_EXT_DISPLAY_PATH) |
---|
2932 | | - return NULL; |
---|
2933 | | - |
---|
2934 | | - ext_display_path = &config_table->sPath[ext_display_path_index]; |
---|
2935 | | - |
---|
2936 | | - if (le16_to_cpu(ext_display_path->usDeviceConnector) == INVALID_CONNECTOR) |
---|
2937 | | - ext_display_path->usDeviceConnector = cpu_to_le16(0); |
---|
2938 | | - |
---|
2939 | | - return ext_display_path; |
---|
2940 | | -} |
---|
2941 | | - |
---|
2942 | | -/* |
---|
2943 | | - * Get AUX/DDC information of input object id |
---|
2944 | | - * |
---|
2945 | | - * search all records to find the ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE record |
---|
2946 | | - * IR |
---|
2947 | | - */ |
---|
2948 | | -static ATOM_CONNECTOR_AUXDDC_LUT_RECORD *get_ext_connector_aux_ddc_lut_record( |
---|
2949 | | - struct bios_parser *bp, |
---|
2950 | | - ATOM_OBJECT *object) |
---|
2951 | | -{ |
---|
2952 | | - uint32_t offset; |
---|
2953 | | - ATOM_COMMON_RECORD_HEADER *header; |
---|
2954 | | - |
---|
2955 | | - if (!object) { |
---|
2956 | | - BREAK_TO_DEBUGGER(); |
---|
2957 | | - /* Invalid object */ |
---|
2958 | | - return NULL; |
---|
2959 | | - } |
---|
2960 | | - |
---|
2961 | | - offset = le16_to_cpu(object->usRecordOffset) |
---|
2962 | | - + bp->object_info_tbl_offset; |
---|
2963 | | - |
---|
2964 | | - for (;;) { |
---|
2965 | | - header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); |
---|
2966 | | - |
---|
2967 | | - if (!header) |
---|
2968 | | - return NULL; |
---|
2969 | | - |
---|
2970 | | - if (LAST_RECORD_TYPE == header->ucRecordType || |
---|
2971 | | - 0 == header->ucRecordSize) |
---|
2972 | | - break; |
---|
2973 | | - |
---|
2974 | | - if (ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE == |
---|
2975 | | - header->ucRecordType && |
---|
2976 | | - sizeof(ATOM_CONNECTOR_AUXDDC_LUT_RECORD) <= |
---|
2977 | | - header->ucRecordSize) |
---|
2978 | | - return (ATOM_CONNECTOR_AUXDDC_LUT_RECORD *)(header); |
---|
2979 | | - |
---|
2980 | | - offset += header->ucRecordSize; |
---|
2981 | | - } |
---|
2982 | | - |
---|
2983 | | - return NULL; |
---|
2984 | | -} |
---|
2985 | | - |
---|
2986 | | -/* |
---|
2987 | | - * Get AUX/DDC information of input object id |
---|
2988 | | - * |
---|
2989 | | - * search all records to find the ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE record |
---|
2990 | | - * IR |
---|
2991 | | - */ |
---|
2992 | | -static ATOM_CONNECTOR_HPDPIN_LUT_RECORD *get_ext_connector_hpd_pin_lut_record( |
---|
2993 | | - struct bios_parser *bp, |
---|
2994 | | - ATOM_OBJECT *object) |
---|
2995 | | -{ |
---|
2996 | | - uint32_t offset; |
---|
2997 | | - ATOM_COMMON_RECORD_HEADER *header; |
---|
2998 | | - |
---|
2999 | | - if (!object) { |
---|
3000 | | - BREAK_TO_DEBUGGER(); |
---|
3001 | | - /* Invalid object */ |
---|
3002 | | - return NULL; |
---|
3003 | | - } |
---|
3004 | | - |
---|
3005 | | - offset = le16_to_cpu(object->usRecordOffset) |
---|
3006 | | - + bp->object_info_tbl_offset; |
---|
3007 | | - |
---|
3008 | | - for (;;) { |
---|
3009 | | - header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); |
---|
3010 | | - |
---|
3011 | | - if (!header) |
---|
3012 | | - return NULL; |
---|
3013 | | - |
---|
3014 | | - if (LAST_RECORD_TYPE == header->ucRecordType || |
---|
3015 | | - 0 == header->ucRecordSize) |
---|
3016 | | - break; |
---|
3017 | | - |
---|
3018 | | - if (ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE == |
---|
3019 | | - header->ucRecordType && |
---|
3020 | | - sizeof(ATOM_CONNECTOR_HPDPIN_LUT_RECORD) <= |
---|
3021 | | - header->ucRecordSize) |
---|
3022 | | - return (ATOM_CONNECTOR_HPDPIN_LUT_RECORD *)header; |
---|
3023 | | - |
---|
3024 | | - offset += header->ucRecordSize; |
---|
3025 | | - } |
---|
3026 | | - |
---|
3027 | | - return NULL; |
---|
3028 | | -} |
---|
3029 | | - |
---|
3030 | | -/* |
---|
3031 | | - * Check whether we need to patch the VBIOS connector info table with |
---|
3032 | | - * data from an external display connection info table. This is |
---|
3033 | | - * necessary to support MXM boards with an OPM (output personality |
---|
3034 | | - * module). With these designs, the VBIOS connector info table |
---|
3035 | | - * specifies an MXM_CONNECTOR with a unique ID. The driver retrieves |
---|
3036 | | - * the external connection info table through i2c and then looks up the |
---|
3037 | | - * connector ID to find the real connector type (e.g. DFP1). |
---|
3038 | | - * |
---|
3039 | | - */ |
---|
3040 | | -static enum bp_result patch_bios_image_from_ext_display_connection_info( |
---|
3041 | | - struct bios_parser *bp) |
---|
3042 | | -{ |
---|
3043 | | - ATOM_OBJECT_TABLE *connector_tbl; |
---|
3044 | | - uint32_t connector_tbl_offset; |
---|
3045 | | - struct graphics_object_id object_id; |
---|
3046 | | - ATOM_OBJECT *object; |
---|
3047 | | - ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO ext_display_connection_info_tbl; |
---|
3048 | | - EXT_DISPLAY_PATH *ext_display_path; |
---|
3049 | | - ATOM_CONNECTOR_AUXDDC_LUT_RECORD *aux_ddc_lut_record = NULL; |
---|
3050 | | - ATOM_I2C_RECORD *i2c_record = NULL; |
---|
3051 | | - ATOM_CONNECTOR_HPDPIN_LUT_RECORD *hpd_pin_lut_record = NULL; |
---|
3052 | | - ATOM_HPD_INT_RECORD *hpd_record = NULL; |
---|
3053 | | - ATOM_OBJECT_TABLE *encoder_table; |
---|
3054 | | - uint32_t encoder_table_offset; |
---|
3055 | | - ATOM_OBJECT *opm_object = NULL; |
---|
3056 | | - uint32_t i = 0; |
---|
3057 | | - struct graphics_object_id opm_object_id = |
---|
3058 | | - dal_graphics_object_id_init( |
---|
3059 | | - GENERIC_ID_MXM_OPM, |
---|
3060 | | - ENUM_ID_1, |
---|
3061 | | - OBJECT_TYPE_GENERIC); |
---|
3062 | | - ATOM_CONNECTOR_DEVICE_TAG_RECORD *dev_tag_record; |
---|
3063 | | - uint32_t cached_device_support = |
---|
3064 | | - le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport); |
---|
3065 | | - |
---|
3066 | | - uint32_t dst_number; |
---|
3067 | | - uint16_t *dst_object_id_list; |
---|
3068 | | - |
---|
3069 | | - opm_object = get_bios_object(bp, opm_object_id); |
---|
3070 | | - if (!opm_object) |
---|
3071 | | - return BP_RESULT_UNSUPPORTED; |
---|
3072 | | - |
---|
3073 | | - memset(&ext_display_connection_info_tbl, 0, |
---|
3074 | | - sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO)); |
---|
3075 | | - |
---|
3076 | | - connector_tbl_offset = bp->object_info_tbl_offset |
---|
3077 | | - + le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset); |
---|
3078 | | - connector_tbl = GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset); |
---|
3079 | | - |
---|
3080 | | - /* Read Connector info table from EEPROM through i2c */ |
---|
3081 | | - if (get_ext_display_connection_info(bp, |
---|
3082 | | - opm_object, |
---|
3083 | | - &ext_display_connection_info_tbl) != BP_RESULT_OK) { |
---|
3084 | | - |
---|
3085 | | - DC_LOG_WARNING("%s: Failed to read Connection Info Table", __func__); |
---|
3086 | | - return BP_RESULT_UNSUPPORTED; |
---|
3087 | | - } |
---|
3088 | | - |
---|
3089 | | - /* Get pointer to AUX/DDC and HPD LUTs */ |
---|
3090 | | - aux_ddc_lut_record = |
---|
3091 | | - get_ext_connector_aux_ddc_lut_record(bp, opm_object); |
---|
3092 | | - hpd_pin_lut_record = |
---|
3093 | | - get_ext_connector_hpd_pin_lut_record(bp, opm_object); |
---|
3094 | | - |
---|
3095 | | - if ((aux_ddc_lut_record == NULL) || (hpd_pin_lut_record == NULL)) |
---|
3096 | | - return BP_RESULT_UNSUPPORTED; |
---|
3097 | | - |
---|
3098 | | - /* Cache support bits for currently unmapped device types. */ |
---|
3099 | | - if (bp->remap_device_tags) { |
---|
3100 | | - for (i = 0; i < connector_tbl->ucNumberOfObjects; ++i) { |
---|
3101 | | - uint32_t j; |
---|
3102 | | - /* Remove support for all non-MXM connectors. */ |
---|
3103 | | - object = &connector_tbl->asObjects[i]; |
---|
3104 | | - object_id = object_id_from_bios_object_id( |
---|
3105 | | - le16_to_cpu(object->usObjectID)); |
---|
3106 | | - if ((OBJECT_TYPE_CONNECTOR != object_id.type) || |
---|
3107 | | - (CONNECTOR_ID_MXM == object_id.id)) |
---|
3108 | | - continue; |
---|
3109 | | - |
---|
3110 | | - /* Remove support for all device tags. */ |
---|
3111 | | - if (bios_parser_get_device_tag_record( |
---|
3112 | | - bp, object, &dev_tag_record) != BP_RESULT_OK) |
---|
3113 | | - continue; |
---|
3114 | | - |
---|
3115 | | - for (j = 0; j < dev_tag_record->ucNumberOfDevice; ++j) { |
---|
3116 | | - ATOM_CONNECTOR_DEVICE_TAG *device_tag = |
---|
3117 | | - &dev_tag_record->asDeviceTag[j]; |
---|
3118 | | - cached_device_support &= |
---|
3119 | | - ~le16_to_cpu(device_tag->usDeviceID); |
---|
3120 | | - } |
---|
3121 | | - } |
---|
3122 | | - } |
---|
3123 | | - |
---|
3124 | | - /* Find all MXM connector objects and patch them with connector info |
---|
3125 | | - * from the external display connection info table. */ |
---|
3126 | | - for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) { |
---|
3127 | | - uint32_t j; |
---|
3128 | | - |
---|
3129 | | - object = &connector_tbl->asObjects[i]; |
---|
3130 | | - object_id = object_id_from_bios_object_id(le16_to_cpu(object->usObjectID)); |
---|
3131 | | - if ((OBJECT_TYPE_CONNECTOR != object_id.type) || |
---|
3132 | | - (CONNECTOR_ID_MXM != object_id.id)) |
---|
3133 | | - continue; |
---|
3134 | | - |
---|
3135 | | - /* Get the correct connection info table entry based on the enum |
---|
3136 | | - * id. */ |
---|
3137 | | - ext_display_path = get_ext_display_path_entry( |
---|
3138 | | - &ext_display_connection_info_tbl, |
---|
3139 | | - le16_to_cpu(object->usObjectID)); |
---|
3140 | | - if (!ext_display_path) |
---|
3141 | | - return BP_RESULT_FAILURE; |
---|
3142 | | - |
---|
3143 | | - /* Patch device connector ID */ |
---|
3144 | | - object->usObjectID = |
---|
3145 | | - cpu_to_le16(le16_to_cpu(ext_display_path->usDeviceConnector)); |
---|
3146 | | - |
---|
3147 | | - /* Patch device tag, ulACPIDeviceEnum. */ |
---|
3148 | | - add_device_tag_from_ext_display_path( |
---|
3149 | | - bp, |
---|
3150 | | - object, |
---|
3151 | | - ext_display_path, |
---|
3152 | | - &cached_device_support); |
---|
3153 | | - |
---|
3154 | | - /* Patch HPD info */ |
---|
3155 | | - if (ext_display_path->ucExtHPDPINLutIndex < |
---|
3156 | | - MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES) { |
---|
3157 | | - hpd_record = get_hpd_record(bp, object); |
---|
3158 | | - if (hpd_record) { |
---|
3159 | | - uint8_t index = |
---|
3160 | | - ext_display_path->ucExtHPDPINLutIndex; |
---|
3161 | | - hpd_record->ucHPDIntGPIOID = |
---|
3162 | | - hpd_pin_lut_record->ucHPDPINMap[index]; |
---|
3163 | | - } else { |
---|
3164 | | - BREAK_TO_DEBUGGER(); |
---|
3165 | | - /* Invalid hpd record */ |
---|
3166 | | - return BP_RESULT_FAILURE; |
---|
3167 | | - } |
---|
3168 | | - } |
---|
3169 | | - |
---|
3170 | | - /* Patch I2C/AUX info */ |
---|
3171 | | - if (ext_display_path->ucExtHPDPINLutIndex < |
---|
3172 | | - MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES) { |
---|
3173 | | - i2c_record = get_i2c_record(bp, object); |
---|
3174 | | - if (i2c_record) { |
---|
3175 | | - uint8_t index = |
---|
3176 | | - ext_display_path->ucExtAUXDDCLutIndex; |
---|
3177 | | - i2c_record->sucI2cId = |
---|
3178 | | - aux_ddc_lut_record->ucAUXDDCMap[index]; |
---|
3179 | | - } else { |
---|
3180 | | - BREAK_TO_DEBUGGER(); |
---|
3181 | | - /* Invalid I2C record */ |
---|
3182 | | - return BP_RESULT_FAILURE; |
---|
3183 | | - } |
---|
3184 | | - } |
---|
3185 | | - |
---|
3186 | | - /* Merge with other MXM connectors that map to the same physical |
---|
3187 | | - * connector. */ |
---|
3188 | | - for (j = i + 1; |
---|
3189 | | - j < connector_tbl->ucNumberOfObjects; j++) { |
---|
3190 | | - ATOM_OBJECT *next_object; |
---|
3191 | | - struct graphics_object_id next_object_id; |
---|
3192 | | - EXT_DISPLAY_PATH *next_ext_display_path; |
---|
3193 | | - |
---|
3194 | | - next_object = &connector_tbl->asObjects[j]; |
---|
3195 | | - next_object_id = object_id_from_bios_object_id( |
---|
3196 | | - le16_to_cpu(next_object->usObjectID)); |
---|
3197 | | - |
---|
3198 | | - if ((OBJECT_TYPE_CONNECTOR != next_object_id.type) && |
---|
3199 | | - (CONNECTOR_ID_MXM == next_object_id.id)) |
---|
3200 | | - continue; |
---|
3201 | | - |
---|
3202 | | - next_ext_display_path = get_ext_display_path_entry( |
---|
3203 | | - &ext_display_connection_info_tbl, |
---|
3204 | | - le16_to_cpu(next_object->usObjectID)); |
---|
3205 | | - |
---|
3206 | | - if (next_ext_display_path == NULL) |
---|
3207 | | - return BP_RESULT_FAILURE; |
---|
3208 | | - |
---|
3209 | | - /* Merge if using same connector. */ |
---|
3210 | | - if ((le16_to_cpu(next_ext_display_path->usDeviceConnector) == |
---|
3211 | | - le16_to_cpu(ext_display_path->usDeviceConnector)) && |
---|
3212 | | - (le16_to_cpu(ext_display_path->usDeviceConnector) != 0)) { |
---|
3213 | | - /* Clear duplicate connector from table. */ |
---|
3214 | | - next_object->usObjectID = cpu_to_le16(0); |
---|
3215 | | - add_device_tag_from_ext_display_path( |
---|
3216 | | - bp, |
---|
3217 | | - object, |
---|
3218 | | - ext_display_path, |
---|
3219 | | - &cached_device_support); |
---|
3220 | | - } |
---|
3221 | | - } |
---|
3222 | | - } |
---|
3223 | | - |
---|
3224 | | - /* Find all encoders which have an MXM object as their destination. |
---|
3225 | | - * Replace the MXM object with the real connector Id from the external |
---|
3226 | | - * display connection info table */ |
---|
3227 | | - |
---|
3228 | | - encoder_table_offset = bp->object_info_tbl_offset |
---|
3229 | | - + le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset); |
---|
3230 | | - encoder_table = GET_IMAGE(ATOM_OBJECT_TABLE, encoder_table_offset); |
---|
3231 | | - |
---|
3232 | | - for (i = 0; i < encoder_table->ucNumberOfObjects; i++) { |
---|
3233 | | - uint32_t j; |
---|
3234 | | - |
---|
3235 | | - object = &encoder_table->asObjects[i]; |
---|
3236 | | - |
---|
3237 | | - dst_number = get_dest_obj_list(bp, object, &dst_object_id_list); |
---|
3238 | | - |
---|
3239 | | - for (j = 0; j < dst_number; j++) { |
---|
3240 | | - object_id = object_id_from_bios_object_id( |
---|
3241 | | - dst_object_id_list[j]); |
---|
3242 | | - |
---|
3243 | | - if ((OBJECT_TYPE_CONNECTOR != object_id.type) || |
---|
3244 | | - (CONNECTOR_ID_MXM != object_id.id)) |
---|
3245 | | - continue; |
---|
3246 | | - |
---|
3247 | | - /* Get the correct connection info table entry based on |
---|
3248 | | - * the enum id. */ |
---|
3249 | | - ext_display_path = |
---|
3250 | | - get_ext_display_path_entry( |
---|
3251 | | - &ext_display_connection_info_tbl, |
---|
3252 | | - dst_object_id_list[j]); |
---|
3253 | | - |
---|
3254 | | - if (ext_display_path == NULL) |
---|
3255 | | - return BP_RESULT_FAILURE; |
---|
3256 | | - |
---|
3257 | | - dst_object_id_list[j] = |
---|
3258 | | - le16_to_cpu(ext_display_path->usDeviceConnector); |
---|
3259 | | - } |
---|
3260 | | - } |
---|
3261 | | - |
---|
3262 | | - return BP_RESULT_OK; |
---|
3263 | | -} |
---|
3264 | | - |
---|
3265 | | -/* |
---|
3266 | | - * Check whether we need to patch the VBIOS connector info table with |
---|
3267 | | - * data from an external display connection info table. This is |
---|
3268 | | - * necessary to support MXM boards with an OPM (output personality |
---|
3269 | | - * module). With these designs, the VBIOS connector info table |
---|
3270 | | - * specifies an MXM_CONNECTOR with a unique ID. The driver retrieves |
---|
3271 | | - * the external connection info table through i2c and then looks up the |
---|
3272 | | - * connector ID to find the real connector type (e.g. DFP1). |
---|
3273 | | - * |
---|
3274 | | - */ |
---|
3275 | | - |
---|
3276 | | -static void process_ext_display_connection_info(struct bios_parser *bp) |
---|
3277 | | -{ |
---|
3278 | | - ATOM_OBJECT_TABLE *connector_tbl; |
---|
3279 | | - uint32_t connector_tbl_offset; |
---|
3280 | | - struct graphics_object_id object_id; |
---|
3281 | | - ATOM_OBJECT *object; |
---|
3282 | | - bool mxm_connector_found = false; |
---|
3283 | | - bool null_entry_found = false; |
---|
3284 | | - uint32_t i = 0; |
---|
3285 | | - |
---|
3286 | | - connector_tbl_offset = bp->object_info_tbl_offset + |
---|
3287 | | - le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset); |
---|
3288 | | - connector_tbl = GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset); |
---|
3289 | | - |
---|
3290 | | - /* Look for MXM connectors to determine whether we need patch the VBIOS |
---|
3291 | | - * connector info table. Look for null entries to determine whether we |
---|
3292 | | - * need to compact connector table. */ |
---|
3293 | | - for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) { |
---|
3294 | | - object = &connector_tbl->asObjects[i]; |
---|
3295 | | - object_id = object_id_from_bios_object_id(le16_to_cpu(object->usObjectID)); |
---|
3296 | | - |
---|
3297 | | - if ((OBJECT_TYPE_CONNECTOR == object_id.type) && |
---|
3298 | | - (CONNECTOR_ID_MXM == object_id.id)) { |
---|
3299 | | - /* Once we found MXM connector - we can break */ |
---|
3300 | | - mxm_connector_found = true; |
---|
3301 | | - break; |
---|
3302 | | - } else if (OBJECT_TYPE_CONNECTOR != object_id.type) { |
---|
3303 | | - /* We need to continue looping - to check if MXM |
---|
3304 | | - * connector present */ |
---|
3305 | | - null_entry_found = true; |
---|
3306 | | - } |
---|
3307 | | - } |
---|
3308 | | - |
---|
3309 | | - /* Patch BIOS image */ |
---|
3310 | | - if (mxm_connector_found || null_entry_found) { |
---|
3311 | | - uint32_t connectors_num = 0; |
---|
3312 | | - uint8_t *original_bios; |
---|
3313 | | - /* Step 1: Replace bios image with the new copy which will be |
---|
3314 | | - * patched */ |
---|
3315 | | - bp->base.bios_local_image = kzalloc(bp->base.bios_size, |
---|
3316 | | - GFP_KERNEL); |
---|
3317 | | - if (bp->base.bios_local_image == NULL) { |
---|
3318 | | - BREAK_TO_DEBUGGER(); |
---|
3319 | | - /* Failed to alloc bp->base.bios_local_image */ |
---|
3320 | | - return; |
---|
3321 | | - } |
---|
3322 | | - |
---|
3323 | | - memmove(bp->base.bios_local_image, bp->base.bios, bp->base.bios_size); |
---|
3324 | | - original_bios = bp->base.bios; |
---|
3325 | | - bp->base.bios = bp->base.bios_local_image; |
---|
3326 | | - connector_tbl = |
---|
3327 | | - GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset); |
---|
3328 | | - |
---|
3329 | | - /* Step 2: (only if MXM connector found) Patch BIOS image with |
---|
3330 | | - * info from external module */ |
---|
3331 | | - if (mxm_connector_found && |
---|
3332 | | - patch_bios_image_from_ext_display_connection_info(bp) != |
---|
3333 | | - BP_RESULT_OK) { |
---|
3334 | | - /* Patching the bios image has failed. We will copy |
---|
3335 | | - * again original image provided and afterwards |
---|
3336 | | - * only remove null entries */ |
---|
3337 | | - memmove( |
---|
3338 | | - bp->base.bios_local_image, |
---|
3339 | | - original_bios, |
---|
3340 | | - bp->base.bios_size); |
---|
3341 | | - } |
---|
3342 | | - |
---|
3343 | | - /* Step 3: Compact connector table (remove null entries, valid |
---|
3344 | | - * entries moved to beginning) */ |
---|
3345 | | - for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) { |
---|
3346 | | - object = &connector_tbl->asObjects[i]; |
---|
3347 | | - object_id = object_id_from_bios_object_id( |
---|
3348 | | - le16_to_cpu(object->usObjectID)); |
---|
3349 | | - |
---|
3350 | | - if (OBJECT_TYPE_CONNECTOR != object_id.type) |
---|
3351 | | - continue; |
---|
3352 | | - |
---|
3353 | | - if (i != connectors_num) { |
---|
3354 | | - memmove( |
---|
3355 | | - &connector_tbl-> |
---|
3356 | | - asObjects[connectors_num], |
---|
3357 | | - object, |
---|
3358 | | - sizeof(ATOM_OBJECT)); |
---|
3359 | | - } |
---|
3360 | | - ++connectors_num; |
---|
3361 | | - } |
---|
3362 | | - connector_tbl->ucNumberOfObjects = (uint8_t)connectors_num; |
---|
3363 | | - } |
---|
3364 | | -} |
---|
3365 | | - |
---|
3366 | | -static void bios_parser_post_init(struct dc_bios *dcb) |
---|
3367 | | -{ |
---|
3368 | | - struct bios_parser *bp = BP_FROM_DCB(dcb); |
---|
3369 | | - |
---|
3370 | | - process_ext_display_connection_info(bp); |
---|
3371 | 2196 | } |
---|
3372 | 2197 | |
---|
3373 | 2198 | /** |
---|
.. | .. |
---|
3718 | 2543 | |
---|
3719 | 2544 | /* Sort voltage table from low to high*/ |
---|
3720 | 2545 | if (result == BP_RESULT_OK) { |
---|
3721 | | - struct clock_voltage_caps temp = {0, 0}; |
---|
3722 | 2546 | uint32_t i; |
---|
3723 | 2547 | uint32_t j; |
---|
3724 | 2548 | |
---|
.. | .. |
---|
3728 | 2552 | info->disp_clk_voltage[j].max_supported_clk < |
---|
3729 | 2553 | info->disp_clk_voltage[j-1].max_supported_clk) { |
---|
3730 | 2554 | /* swap j and j - 1*/ |
---|
3731 | | - temp = info->disp_clk_voltage[j-1]; |
---|
3732 | | - info->disp_clk_voltage[j-1] = |
---|
3733 | | - info->disp_clk_voltage[j]; |
---|
3734 | | - info->disp_clk_voltage[j] = temp; |
---|
| 2555 | + swap(info->disp_clk_voltage[j - 1], |
---|
| 2556 | + info->disp_clk_voltage[j]); |
---|
3735 | 2557 | } |
---|
3736 | 2558 | } |
---|
3737 | 2559 | } |
---|
.. | .. |
---|
3917 | 2739 | struct board_layout_info *board_layout_info) |
---|
3918 | 2740 | { |
---|
3919 | 2741 | unsigned int i; |
---|
3920 | | - struct bios_parser *bp; |
---|
3921 | 2742 | enum bp_result record_result; |
---|
3922 | 2743 | |
---|
3923 | 2744 | const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { |
---|
.. | .. |
---|
3926 | 2747 | 0, 0 |
---|
3927 | 2748 | }; |
---|
3928 | 2749 | |
---|
3929 | | - bp = BP_FROM_DCB(dcb); |
---|
3930 | 2750 | if (board_layout_info == NULL) { |
---|
3931 | 2751 | DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); |
---|
3932 | 2752 | return BP_RESULT_BADINPUT; |
---|
.. | .. |
---|
3961 | 2781 | static const struct dc_vbios_funcs vbios_funcs = { |
---|
3962 | 2782 | .get_connectors_number = bios_parser_get_connectors_number, |
---|
3963 | 2783 | |
---|
3964 | | - .get_encoder_id = bios_parser_get_encoder_id, |
---|
3965 | | - |
---|
3966 | 2784 | .get_connector_id = bios_parser_get_connector_id, |
---|
3967 | | - |
---|
3968 | | - .get_dst_number = bios_parser_get_dst_number, |
---|
3969 | 2785 | |
---|
3970 | 2786 | .get_src_obj = bios_parser_get_src_obj, |
---|
3971 | 2787 | |
---|
3972 | | - .get_dst_obj = bios_parser_get_dst_obj, |
---|
3973 | | - |
---|
3974 | 2788 | .get_i2c_info = bios_parser_get_i2c_info, |
---|
3975 | | - |
---|
3976 | | - .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info, |
---|
3977 | | - |
---|
3978 | | - .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info, |
---|
3979 | 2789 | |
---|
3980 | 2790 | .get_hpd_info = bios_parser_get_hpd_info, |
---|
3981 | 2791 | |
---|
3982 | 2792 | .get_device_tag = bios_parser_get_device_tag, |
---|
3983 | | - |
---|
3984 | | - .get_firmware_info = bios_parser_get_firmware_info, |
---|
3985 | 2793 | |
---|
3986 | 2794 | .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, |
---|
3987 | 2795 | |
---|
.. | .. |
---|
3995 | 2803 | |
---|
3996 | 2804 | /* bios scratch register communication */ |
---|
3997 | 2805 | .is_accelerated_mode = bios_is_accelerated_mode, |
---|
3998 | | - .get_vga_enabled_displays = bios_get_vga_enabled_displays, |
---|
3999 | 2806 | |
---|
4000 | 2807 | .set_scratch_critical_state = bios_parser_set_scratch_critical_state, |
---|
4001 | 2808 | |
---|
.. | .. |
---|
4005 | 2812 | .encoder_control = bios_parser_encoder_control, |
---|
4006 | 2813 | |
---|
4007 | 2814 | .transmitter_control = bios_parser_transmitter_control, |
---|
4008 | | - |
---|
4009 | | - .crt_control = bios_parser_crt_control, /* not used in DAL3. keep for now in case we need to support VGA on Bonaire */ |
---|
4010 | 2815 | |
---|
4011 | 2816 | .enable_crtc = bios_parser_enable_crtc, |
---|
4012 | 2817 | |
---|
.. | .. |
---|
4020 | 2825 | |
---|
4021 | 2826 | .program_crtc_timing = bios_parser_program_crtc_timing, /* still use. should probably retire and program directly */ |
---|
4022 | 2827 | |
---|
4023 | | - .crtc_source_select = bios_parser_crtc_source_select, /* still use. should probably retire and program directly */ |
---|
4024 | | - |
---|
4025 | 2828 | .program_display_engine_pll = bios_parser_program_display_engine_pll, |
---|
4026 | 2829 | |
---|
4027 | 2830 | .enable_disp_power_gating = bios_parser_enable_disp_power_gating, |
---|
4028 | 2831 | |
---|
4029 | 2832 | /* SW init and patch */ |
---|
4030 | | - .post_init = bios_parser_post_init, /* patch vbios table for mxm module by reading i2c */ |
---|
4031 | 2833 | |
---|
4032 | 2834 | .bios_parser_destroy = bios_parser_destroy, |
---|
4033 | 2835 | |
---|
4034 | 2836 | .get_board_layout_info = bios_get_board_layout_info, |
---|
| 2837 | + |
---|
| 2838 | + .get_atom_dc_golden_table = NULL |
---|
4035 | 2839 | }; |
---|
4036 | 2840 | |
---|
4037 | 2841 | static bool bios_parser_construct( |
---|
.. | .. |
---|
4113 | 2917 | dal_bios_parser_init_cmd_tbl_helper(&bp->cmd_helper, dce_version); |
---|
4114 | 2918 | |
---|
4115 | 2919 | bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); |
---|
| 2920 | + bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK; |
---|
4116 | 2921 | |
---|
4117 | 2922 | return true; |
---|
4118 | 2923 | } |
---|