1fb4d8502Sjsg /* 2fb4d8502Sjsg * Copyright 2012-15 Advanced Micro Devices, Inc. 3fb4d8502Sjsg * 4fb4d8502Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 5fb4d8502Sjsg * copy of this software and associated documentation files (the "Software"), 6fb4d8502Sjsg * to deal in the Software without restriction, including without limitation 7fb4d8502Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8fb4d8502Sjsg * and/or sell copies of the Software, and to permit persons to whom the 9fb4d8502Sjsg * Software is furnished to do so, subject to the following conditions: 10fb4d8502Sjsg * 11fb4d8502Sjsg * The above copyright notice and this permission notice shall be included in 12fb4d8502Sjsg * all copies or substantial portions of the Software. 13fb4d8502Sjsg * 14fb4d8502Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15fb4d8502Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16fb4d8502Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17fb4d8502Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18fb4d8502Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19fb4d8502Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20fb4d8502Sjsg * OTHER DEALINGS IN THE SOFTWARE. 21fb4d8502Sjsg * 22fb4d8502Sjsg * Authors: AMD 23fb4d8502Sjsg * 24fb4d8502Sjsg */ 25fb4d8502Sjsg 26fb4d8502Sjsg #include "dm_services.h" 271bb76ff1Sjsg #include "core_types.h" 28fb4d8502Sjsg 29fb4d8502Sjsg #include "ObjectID.h" 30fb4d8502Sjsg #include "atomfirmware.h" 31fb4d8502Sjsg 32fb4d8502Sjsg #include "dc_bios_types.h" 33fb4d8502Sjsg #include "include/grph_object_ctrl_defs.h" 34fb4d8502Sjsg #include "include/bios_parser_interface.h" 35fb4d8502Sjsg #include "include/logger_interface.h" 36fb4d8502Sjsg 37fb4d8502Sjsg #include "command_table2.h" 38fb4d8502Sjsg 39fb4d8502Sjsg #include "bios_parser_helper.h" 40fb4d8502Sjsg #include "command_table_helper2.h" 41fb4d8502Sjsg #include "bios_parser2.h" 42fb4d8502Sjsg #include "bios_parser_types_internal2.h" 43fb4d8502Sjsg #include "bios_parser_interface.h" 44fb4d8502Sjsg 45fb4d8502Sjsg #include "bios_parser_common.h" 46fb4d8502Sjsg 47fb4d8502Sjsg #define DC_LOGGER \ 48fb4d8502Sjsg bp->base.ctx->logger 49fb4d8502Sjsg 50fb4d8502Sjsg #define LAST_RECORD_TYPE 0xff 51fb4d8502Sjsg #define SMU9_SYSPLL0_ID 0 52fb4d8502Sjsg 53fb4d8502Sjsg static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, 54fb4d8502Sjsg struct atom_i2c_record *record, 55fb4d8502Sjsg struct graphics_object_i2c_info *info); 56fb4d8502Sjsg 57fb4d8502Sjsg static enum bp_result bios_parser_get_firmware_info( 58fb4d8502Sjsg struct dc_bios *dcb, 59fb4d8502Sjsg struct dc_firmware_info *info); 60fb4d8502Sjsg 61fb4d8502Sjsg static enum bp_result bios_parser_get_encoder_cap_info( 62fb4d8502Sjsg struct dc_bios *dcb, 63fb4d8502Sjsg struct graphics_object_id object_id, 64fb4d8502Sjsg struct bp_encoder_cap_info *info); 65fb4d8502Sjsg 66fb4d8502Sjsg static enum bp_result get_firmware_info_v3_1( 67fb4d8502Sjsg struct bios_parser *bp, 68fb4d8502Sjsg struct dc_firmware_info *info); 69fb4d8502Sjsg 70fb4d8502Sjsg static enum bp_result get_firmware_info_v3_2( 71fb4d8502Sjsg struct bios_parser *bp, 72fb4d8502Sjsg struct dc_firmware_info *info); 73fb4d8502Sjsg 741bb76ff1Sjsg static enum bp_result get_firmware_info_v3_4( 751bb76ff1Sjsg struct bios_parser *bp, 761bb76ff1Sjsg struct dc_firmware_info *info); 771bb76ff1Sjsg 78fb4d8502Sjsg static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, 79fb4d8502Sjsg struct atom_display_object_path_v2 *object); 80fb4d8502Sjsg 81fb4d8502Sjsg static struct atom_encoder_caps_record *get_encoder_cap_record( 82fb4d8502Sjsg struct bios_parser *bp, 83fb4d8502Sjsg struct atom_display_object_path_v2 *object); 84fb4d8502Sjsg 85fb4d8502Sjsg #define BIOS_IMAGE_SIZE_OFFSET 2 86fb4d8502Sjsg #define BIOS_IMAGE_SIZE_UNIT 512 87fb4d8502Sjsg 88fb4d8502Sjsg #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) 89fb4d8502Sjsg 90c349dbc7Sjsg static void bios_parser2_destruct(struct bios_parser *bp) 91fb4d8502Sjsg { 92fb4d8502Sjsg kfree(bp->base.bios_local_image); 93fb4d8502Sjsg kfree(bp->base.integrated_info); 94fb4d8502Sjsg } 95fb4d8502Sjsg 96fb4d8502Sjsg static void firmware_parser_destroy(struct dc_bios **dcb) 97fb4d8502Sjsg { 98fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(*dcb); 99fb4d8502Sjsg 100fb4d8502Sjsg if (!bp) { 101fb4d8502Sjsg BREAK_TO_DEBUGGER(); 102fb4d8502Sjsg return; 103fb4d8502Sjsg } 104fb4d8502Sjsg 105c349dbc7Sjsg bios_parser2_destruct(bp); 106fb4d8502Sjsg 107fb4d8502Sjsg kfree(bp); 108fb4d8502Sjsg *dcb = NULL; 109fb4d8502Sjsg } 110fb4d8502Sjsg 111fb4d8502Sjsg static void get_atom_data_table_revision( 112fb4d8502Sjsg struct atom_common_table_header *atom_data_tbl, 113fb4d8502Sjsg struct atom_data_revision *tbl_revision) 114fb4d8502Sjsg { 115fb4d8502Sjsg if (!tbl_revision) 116fb4d8502Sjsg return; 117fb4d8502Sjsg 118fb4d8502Sjsg /* initialize the revision to 0 which is invalid revision */ 119fb4d8502Sjsg tbl_revision->major = 0; 120fb4d8502Sjsg tbl_revision->minor = 0; 121fb4d8502Sjsg 122fb4d8502Sjsg if (!atom_data_tbl) 123fb4d8502Sjsg return; 124fb4d8502Sjsg 125fb4d8502Sjsg tbl_revision->major = 126fb4d8502Sjsg (uint32_t) atom_data_tbl->format_revision & 0x3f; 127fb4d8502Sjsg tbl_revision->minor = 128fb4d8502Sjsg (uint32_t) atom_data_tbl->content_revision & 0x3f; 129fb4d8502Sjsg } 130fb4d8502Sjsg 131fb4d8502Sjsg /* BIOS oject table displaypath is per connector. 132fb4d8502Sjsg * There is extra path not for connector. BIOS fill its encoderid as 0 133fb4d8502Sjsg */ 134fb4d8502Sjsg static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb) 135fb4d8502Sjsg { 136fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 137fb4d8502Sjsg unsigned int count = 0; 138fb4d8502Sjsg unsigned int i; 139fb4d8502Sjsg 1401bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 1411bb76ff1Sjsg default: 1421bb76ff1Sjsg case 4: 1431bb76ff1Sjsg for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) 144fb4d8502Sjsg if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0) 145fb4d8502Sjsg count++; 1461bb76ff1Sjsg 1471bb76ff1Sjsg break; 1481bb76ff1Sjsg 1491bb76ff1Sjsg case 5: 1501bb76ff1Sjsg for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) 1511bb76ff1Sjsg if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0) 1521bb76ff1Sjsg count++; 1531bb76ff1Sjsg 1541bb76ff1Sjsg break; 155fb4d8502Sjsg } 156fb4d8502Sjsg return count; 157fb4d8502Sjsg } 158fb4d8502Sjsg 159fb4d8502Sjsg static struct graphics_object_id bios_parser_get_connector_id( 160fb4d8502Sjsg struct dc_bios *dcb, 161fb4d8502Sjsg uint8_t i) 162fb4d8502Sjsg { 163fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 164fb4d8502Sjsg struct graphics_object_id object_id = dal_graphics_object_id_init( 165fb4d8502Sjsg 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); 166fb4d8502Sjsg struct object_info_table *tbl = &bp->object_info_tbl; 167fb4d8502Sjsg struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4; 168fb4d8502Sjsg 1691bb76ff1Sjsg struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5; 1701bb76ff1Sjsg 1711bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 1721bb76ff1Sjsg default: 1731bb76ff1Sjsg case 4: 174fb4d8502Sjsg if (v1_4->number_of_path > i) { 175fb4d8502Sjsg /* If display_objid is generic object id, the encoderObj 176fb4d8502Sjsg * /extencoderobjId should be 0 177fb4d8502Sjsg */ 178fb4d8502Sjsg if (v1_4->display_path[i].encoderobjid != 0 && 179fb4d8502Sjsg v1_4->display_path[i].display_objid != 0) 180fb4d8502Sjsg object_id = object_id_from_bios_object_id( 181fb4d8502Sjsg v1_4->display_path[i].display_objid); 182fb4d8502Sjsg } 1831bb76ff1Sjsg break; 184fb4d8502Sjsg 1851bb76ff1Sjsg case 5: 1861bb76ff1Sjsg if (v1_5->number_of_path > i) { 1871bb76ff1Sjsg /* If display_objid is generic object id, the encoderObjId 1881bb76ff1Sjsg * should be 0 1891bb76ff1Sjsg */ 1901bb76ff1Sjsg if (v1_5->display_path[i].encoderobjid != 0 && 1911bb76ff1Sjsg v1_5->display_path[i].display_objid != 0) 1921bb76ff1Sjsg object_id = object_id_from_bios_object_id( 1931bb76ff1Sjsg v1_5->display_path[i].display_objid); 1941bb76ff1Sjsg } 1951bb76ff1Sjsg break; 1961bb76ff1Sjsg } 197fb4d8502Sjsg return object_id; 198fb4d8502Sjsg } 199fb4d8502Sjsg 200fb4d8502Sjsg static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, 201fb4d8502Sjsg struct graphics_object_id object_id, uint32_t index, 202fb4d8502Sjsg struct graphics_object_id *src_object_id) 203fb4d8502Sjsg { 204fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 205fb4d8502Sjsg unsigned int i; 206fb4d8502Sjsg enum bp_result bp_result = BP_RESULT_BADINPUT; 207fb4d8502Sjsg struct graphics_object_id obj_id = { 0 }; 208fb4d8502Sjsg struct object_info_table *tbl = &bp->object_info_tbl; 209fb4d8502Sjsg 210fb4d8502Sjsg if (!src_object_id) 211fb4d8502Sjsg return bp_result; 212fb4d8502Sjsg 213fb4d8502Sjsg switch (object_id.type) { 214fb4d8502Sjsg /* Encoder's Source is GPU. BIOS does not provide GPU, since all 215fb4d8502Sjsg * displaypaths point to same GPU (0x1100). Hardcode GPU object type 216fb4d8502Sjsg */ 217fb4d8502Sjsg case OBJECT_TYPE_ENCODER: 218fb4d8502Sjsg /* TODO: since num of src must be less than 2. 219fb4d8502Sjsg * If found in for loop, should break. 220fb4d8502Sjsg * DAL2 implementation may be changed too 221fb4d8502Sjsg */ 2221bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 2231bb76ff1Sjsg default: 2241bb76ff1Sjsg case 4: 225fb4d8502Sjsg for (i = 0; i < tbl->v1_4->number_of_path; i++) { 226fb4d8502Sjsg obj_id = object_id_from_bios_object_id( 227fb4d8502Sjsg tbl->v1_4->display_path[i].encoderobjid); 228fb4d8502Sjsg if (object_id.type == obj_id.type && 229fb4d8502Sjsg object_id.id == obj_id.id && 2301bb76ff1Sjsg object_id.enum_id == obj_id.enum_id) { 231fb4d8502Sjsg *src_object_id = 2321bb76ff1Sjsg object_id_from_bios_object_id( 2331bb76ff1Sjsg 0x1100); 234fb4d8502Sjsg /* break; */ 235fb4d8502Sjsg } 236fb4d8502Sjsg } 237fb4d8502Sjsg bp_result = BP_RESULT_OK; 238fb4d8502Sjsg break; 2391bb76ff1Sjsg 2401bb76ff1Sjsg case 5: 2411bb76ff1Sjsg for (i = 0; i < tbl->v1_5->number_of_path; i++) { 2421bb76ff1Sjsg obj_id = object_id_from_bios_object_id( 2431bb76ff1Sjsg tbl->v1_5->display_path[i].encoderobjid); 2441bb76ff1Sjsg if (object_id.type == obj_id.type && 2451bb76ff1Sjsg object_id.id == obj_id.id && 2461bb76ff1Sjsg object_id.enum_id == obj_id.enum_id) { 2471bb76ff1Sjsg *src_object_id = 2481bb76ff1Sjsg object_id_from_bios_object_id( 2491bb76ff1Sjsg 0x1100); 2501bb76ff1Sjsg /* break; */ 2511bb76ff1Sjsg } 2521bb76ff1Sjsg } 2531bb76ff1Sjsg bp_result = BP_RESULT_OK; 2541bb76ff1Sjsg break; 2551bb76ff1Sjsg } 2561bb76ff1Sjsg break; 257fb4d8502Sjsg case OBJECT_TYPE_CONNECTOR: 2581bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 2591bb76ff1Sjsg default: 2601bb76ff1Sjsg case 4: 261fb4d8502Sjsg for (i = 0; i < tbl->v1_4->number_of_path; i++) { 262fb4d8502Sjsg obj_id = object_id_from_bios_object_id( 2631bb76ff1Sjsg tbl->v1_4->display_path[i] 2641bb76ff1Sjsg .display_objid); 265fb4d8502Sjsg 266fb4d8502Sjsg if (object_id.type == obj_id.type && 267fb4d8502Sjsg object_id.id == obj_id.id && 268fb4d8502Sjsg object_id.enum_id == obj_id.enum_id) { 269fb4d8502Sjsg *src_object_id = 270fb4d8502Sjsg object_id_from_bios_object_id( 2711bb76ff1Sjsg tbl->v1_4 2721bb76ff1Sjsg ->display_path[i] 2731bb76ff1Sjsg .encoderobjid); 274fb4d8502Sjsg /* break; */ 275fb4d8502Sjsg } 276fb4d8502Sjsg } 277fb4d8502Sjsg bp_result = BP_RESULT_OK; 278fb4d8502Sjsg break; 2791bb76ff1Sjsg } 2801bb76ff1Sjsg bp_result = BP_RESULT_OK; 2811bb76ff1Sjsg break; 2821bb76ff1Sjsg case 5: 2831bb76ff1Sjsg for (i = 0; i < tbl->v1_5->number_of_path; i++) { 2841bb76ff1Sjsg obj_id = object_id_from_bios_object_id( 2851bb76ff1Sjsg tbl->v1_5->display_path[i].display_objid); 2861bb76ff1Sjsg 2871bb76ff1Sjsg if (object_id.type == obj_id.type && 2881bb76ff1Sjsg object_id.id == obj_id.id && 2891bb76ff1Sjsg object_id.enum_id == obj_id.enum_id) { 2901bb76ff1Sjsg *src_object_id = object_id_from_bios_object_id( 2911bb76ff1Sjsg tbl->v1_5->display_path[i].encoderobjid); 2921bb76ff1Sjsg /* break; */ 2931bb76ff1Sjsg } 2941bb76ff1Sjsg } 2951bb76ff1Sjsg bp_result = BP_RESULT_OK; 2961bb76ff1Sjsg break; 2971bb76ff1Sjsg 298fb4d8502Sjsg default: 2991bb76ff1Sjsg bp_result = BP_RESULT_OK; 300fb4d8502Sjsg break; 301fb4d8502Sjsg } 302fb4d8502Sjsg 303fb4d8502Sjsg return bp_result; 304fb4d8502Sjsg } 305fb4d8502Sjsg 306fb4d8502Sjsg /* from graphics_object_id, find display path which includes the object_id */ 307fb4d8502Sjsg static struct atom_display_object_path_v2 *get_bios_object( 308fb4d8502Sjsg struct bios_parser *bp, 309fb4d8502Sjsg struct graphics_object_id id) 310fb4d8502Sjsg { 311fb4d8502Sjsg unsigned int i; 312fb4d8502Sjsg struct graphics_object_id obj_id = {0}; 313fb4d8502Sjsg 314fb4d8502Sjsg switch (id.type) { 315fb4d8502Sjsg case OBJECT_TYPE_ENCODER: 316fb4d8502Sjsg for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 317fb4d8502Sjsg obj_id = object_id_from_bios_object_id( 318fb4d8502Sjsg bp->object_info_tbl.v1_4->display_path[i].encoderobjid); 319c349dbc7Sjsg if (id.type == obj_id.type && id.id == obj_id.id 320c349dbc7Sjsg && id.enum_id == obj_id.enum_id) 321c349dbc7Sjsg return &bp->object_info_tbl.v1_4->display_path[i]; 322fb4d8502Sjsg } 323c349dbc7Sjsg fallthrough; 324fb4d8502Sjsg case OBJECT_TYPE_CONNECTOR: 325fb4d8502Sjsg case OBJECT_TYPE_GENERIC: 326fb4d8502Sjsg /* Both Generic and Connector Object ID 327fb4d8502Sjsg * will be stored on display_objid 328fb4d8502Sjsg */ 329fb4d8502Sjsg for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 330fb4d8502Sjsg obj_id = object_id_from_bios_object_id( 331c349dbc7Sjsg bp->object_info_tbl.v1_4->display_path[i].display_objid); 332c349dbc7Sjsg if (id.type == obj_id.type && id.id == obj_id.id 333c349dbc7Sjsg && id.enum_id == obj_id.enum_id) 334c349dbc7Sjsg return &bp->object_info_tbl.v1_4->display_path[i]; 335fb4d8502Sjsg } 336c349dbc7Sjsg fallthrough; 337fb4d8502Sjsg default: 338fb4d8502Sjsg return NULL; 339fb4d8502Sjsg } 340fb4d8502Sjsg } 341fb4d8502Sjsg 3421bb76ff1Sjsg /* from graphics_object_id, find display path which includes the object_id */ 343f005ef32Sjsg static struct atom_display_object_path_v3 *get_bios_object_from_path_v3(struct bios_parser *bp, 3441bb76ff1Sjsg struct graphics_object_id id) 3451bb76ff1Sjsg { 3461bb76ff1Sjsg unsigned int i; 3471bb76ff1Sjsg struct graphics_object_id obj_id = {0}; 3481bb76ff1Sjsg 3491bb76ff1Sjsg switch (id.type) { 3501bb76ff1Sjsg case OBJECT_TYPE_ENCODER: 3511bb76ff1Sjsg for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) { 3521bb76ff1Sjsg obj_id = object_id_from_bios_object_id( 3531bb76ff1Sjsg bp->object_info_tbl.v1_5->display_path[i].encoderobjid); 3541bb76ff1Sjsg if (id.type == obj_id.type && id.id == obj_id.id 3551bb76ff1Sjsg && id.enum_id == obj_id.enum_id) 3561bb76ff1Sjsg return &bp->object_info_tbl.v1_5->display_path[i]; 3571bb76ff1Sjsg } 3581bb76ff1Sjsg break; 3591bb76ff1Sjsg 3601bb76ff1Sjsg case OBJECT_TYPE_CONNECTOR: 3611bb76ff1Sjsg case OBJECT_TYPE_GENERIC: 3621bb76ff1Sjsg /* Both Generic and Connector Object ID 3631bb76ff1Sjsg * will be stored on display_objid 3641bb76ff1Sjsg */ 3651bb76ff1Sjsg for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) { 3661bb76ff1Sjsg obj_id = object_id_from_bios_object_id( 3671bb76ff1Sjsg bp->object_info_tbl.v1_5->display_path[i].display_objid); 3681bb76ff1Sjsg if (id.type == obj_id.type && id.id == obj_id.id 3691bb76ff1Sjsg && id.enum_id == obj_id.enum_id) 3701bb76ff1Sjsg return &bp->object_info_tbl.v1_5->display_path[i]; 3711bb76ff1Sjsg } 3721bb76ff1Sjsg break; 3731bb76ff1Sjsg 3741bb76ff1Sjsg default: 3751bb76ff1Sjsg return NULL; 3761bb76ff1Sjsg } 3771bb76ff1Sjsg 3781bb76ff1Sjsg return NULL; 3791bb76ff1Sjsg } 3801bb76ff1Sjsg 381fb4d8502Sjsg static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, 382fb4d8502Sjsg struct graphics_object_id id, 383fb4d8502Sjsg struct graphics_object_i2c_info *info) 384fb4d8502Sjsg { 385fb4d8502Sjsg uint32_t offset; 386fb4d8502Sjsg struct atom_display_object_path_v2 *object; 3871bb76ff1Sjsg 3881bb76ff1Sjsg struct atom_display_object_path_v3 *object_path_v3; 3891bb76ff1Sjsg 390fb4d8502Sjsg struct atom_common_record_header *header; 391fb4d8502Sjsg struct atom_i2c_record *record; 392c349dbc7Sjsg struct atom_i2c_record dummy_record = {0}; 393fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 394fb4d8502Sjsg 395fb4d8502Sjsg if (!info) 396fb4d8502Sjsg return BP_RESULT_BADINPUT; 397fb4d8502Sjsg 398c349dbc7Sjsg if (id.type == OBJECT_TYPE_GENERIC) { 399c349dbc7Sjsg dummy_record.i2c_id = id.id; 400c349dbc7Sjsg 401c349dbc7Sjsg if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK) 402c349dbc7Sjsg return BP_RESULT_OK; 403c349dbc7Sjsg else 404c349dbc7Sjsg return BP_RESULT_NORECORD; 405c349dbc7Sjsg } 406c349dbc7Sjsg 4071bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 4081bb76ff1Sjsg case 4: 4091bb76ff1Sjsg default: 410fb4d8502Sjsg object = get_bios_object(bp, id); 411fb4d8502Sjsg 412fb4d8502Sjsg if (!object) 413fb4d8502Sjsg return BP_RESULT_BADINPUT; 414fb4d8502Sjsg 415fb4d8502Sjsg offset = object->disp_recordoffset + bp->object_info_tbl_offset; 4161bb76ff1Sjsg break; 4171bb76ff1Sjsg case 5: 4181bb76ff1Sjsg object_path_v3 = get_bios_object_from_path_v3(bp, id); 4191bb76ff1Sjsg 4201bb76ff1Sjsg if (!object_path_v3) 4211bb76ff1Sjsg return BP_RESULT_BADINPUT; 4221bb76ff1Sjsg 4231bb76ff1Sjsg offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset; 4241bb76ff1Sjsg break; 4251bb76ff1Sjsg } 426fb4d8502Sjsg 427fb4d8502Sjsg for (;;) { 428fb4d8502Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 429fb4d8502Sjsg 430fb4d8502Sjsg if (!header) 431fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 432fb4d8502Sjsg 433fb4d8502Sjsg if (header->record_type == LAST_RECORD_TYPE || 434fb4d8502Sjsg !header->record_size) 435fb4d8502Sjsg break; 436fb4d8502Sjsg 437fb4d8502Sjsg if (header->record_type == ATOM_I2C_RECORD_TYPE 438fb4d8502Sjsg && sizeof(struct atom_i2c_record) <= 439fb4d8502Sjsg header->record_size) { 440fb4d8502Sjsg /* get the I2C info */ 441fb4d8502Sjsg record = (struct atom_i2c_record *) header; 442fb4d8502Sjsg 443fb4d8502Sjsg if (get_gpio_i2c_info(bp, record, info) == 444fb4d8502Sjsg BP_RESULT_OK) 445fb4d8502Sjsg return BP_RESULT_OK; 446fb4d8502Sjsg } 447fb4d8502Sjsg 448fb4d8502Sjsg offset += header->record_size; 449fb4d8502Sjsg } 450fb4d8502Sjsg 451fb4d8502Sjsg return BP_RESULT_NORECORD; 452fb4d8502Sjsg } 453fb4d8502Sjsg 454fb4d8502Sjsg static enum bp_result get_gpio_i2c_info( 455fb4d8502Sjsg struct bios_parser *bp, 456fb4d8502Sjsg struct atom_i2c_record *record, 457fb4d8502Sjsg struct graphics_object_i2c_info *info) 458fb4d8502Sjsg { 459fb4d8502Sjsg struct atom_gpio_pin_lut_v2_1 *header; 460fb4d8502Sjsg uint32_t count = 0; 461fb4d8502Sjsg unsigned int table_index = 0; 462c349dbc7Sjsg bool find_valid = false; 4631bb76ff1Sjsg struct atom_gpio_pin_assignment *pin; 464fb4d8502Sjsg 465fb4d8502Sjsg if (!info) 466fb4d8502Sjsg return BP_RESULT_BADINPUT; 467fb4d8502Sjsg 468fb4d8502Sjsg /* get the GPIO_I2C info */ 469fb4d8502Sjsg if (!DATA_TABLES(gpio_pin_lut)) 470fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 471fb4d8502Sjsg 472fb4d8502Sjsg header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 473fb4d8502Sjsg DATA_TABLES(gpio_pin_lut)); 474fb4d8502Sjsg if (!header) 475fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 476fb4d8502Sjsg 477fb4d8502Sjsg if (sizeof(struct atom_common_table_header) + 478fb4d8502Sjsg sizeof(struct atom_gpio_pin_assignment) > 479fb4d8502Sjsg le16_to_cpu(header->table_header.structuresize)) 480fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 481fb4d8502Sjsg 482fb4d8502Sjsg /* TODO: is version change? */ 483fb4d8502Sjsg if (header->table_header.content_revision != 1) 484fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 485fb4d8502Sjsg 486fb4d8502Sjsg /* get data count */ 487fb4d8502Sjsg count = (le16_to_cpu(header->table_header.structuresize) 488fb4d8502Sjsg - sizeof(struct atom_common_table_header)) 489fb4d8502Sjsg / sizeof(struct atom_gpio_pin_assignment); 490fb4d8502Sjsg 4911bb76ff1Sjsg pin = (struct atom_gpio_pin_assignment *) header->gpio_pin; 4921bb76ff1Sjsg 493fb4d8502Sjsg for (table_index = 0; table_index < count; table_index++) { 4941bb76ff1Sjsg if (((record->i2c_id & I2C_HW_CAP) == (pin->gpio_id & I2C_HW_CAP)) && 4951bb76ff1Sjsg ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) && 4961bb76ff1Sjsg ((record->i2c_id & I2C_HW_LANE_MUX) == (pin->gpio_id & I2C_HW_LANE_MUX))) { 497fb4d8502Sjsg /* still valid */ 498fb4d8502Sjsg find_valid = true; 499fb4d8502Sjsg break; 500fb4d8502Sjsg } 5011bb76ff1Sjsg pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment)); 502fb4d8502Sjsg } 503c349dbc7Sjsg 504fb4d8502Sjsg /* If we don't find the entry that we are looking for then 505fb4d8502Sjsg * we will return BP_Result_BadBiosTable. 506fb4d8502Sjsg */ 507fb4d8502Sjsg if (find_valid == false) 508fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 509fb4d8502Sjsg 510fb4d8502Sjsg /* get the GPIO_I2C_INFO */ 511fb4d8502Sjsg info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false; 512fb4d8502Sjsg info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX; 513fb4d8502Sjsg info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4; 514fb4d8502Sjsg info->i2c_slave_address = record->i2c_slave_addr; 515fb4d8502Sjsg 516fb4d8502Sjsg /* TODO: check how to get register offset for en, Y, etc. */ 517ab6bc2c8Sjsg info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index); 518ab6bc2c8Sjsg info->gpio_info.clk_a_shift = pin->gpio_bitshift; 519fb4d8502Sjsg 520fb4d8502Sjsg return BP_RESULT_OK; 521fb4d8502Sjsg } 522fb4d8502Sjsg 523f005ef32Sjsg static struct atom_hpd_int_record *get_hpd_record_for_path_v3(struct bios_parser *bp, 5241bb76ff1Sjsg struct atom_display_object_path_v3 *object) 5251bb76ff1Sjsg { 5261bb76ff1Sjsg struct atom_common_record_header *header; 5271bb76ff1Sjsg uint32_t offset; 5281bb76ff1Sjsg 5291bb76ff1Sjsg if (!object) { 5301bb76ff1Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 5311bb76ff1Sjsg return NULL; 5321bb76ff1Sjsg } 5331bb76ff1Sjsg 5341bb76ff1Sjsg offset = object->disp_recordoffset + bp->object_info_tbl_offset; 5351bb76ff1Sjsg 5361bb76ff1Sjsg for (;;) { 5371bb76ff1Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 5381bb76ff1Sjsg 5391bb76ff1Sjsg if (!header) 5401bb76ff1Sjsg return NULL; 5411bb76ff1Sjsg 5421bb76ff1Sjsg if (header->record_type == ATOM_RECORD_END_TYPE || 5431bb76ff1Sjsg !header->record_size) 5441bb76ff1Sjsg break; 5451bb76ff1Sjsg 5461bb76ff1Sjsg if (header->record_type == ATOM_HPD_INT_RECORD_TYPE 5471bb76ff1Sjsg && sizeof(struct atom_hpd_int_record) <= 5481bb76ff1Sjsg header->record_size) 5491bb76ff1Sjsg return (struct atom_hpd_int_record *) header; 5501bb76ff1Sjsg 5511bb76ff1Sjsg offset += header->record_size; 5521bb76ff1Sjsg } 5531bb76ff1Sjsg 5541bb76ff1Sjsg return NULL; 5551bb76ff1Sjsg } 5561bb76ff1Sjsg 557fb4d8502Sjsg static enum bp_result bios_parser_get_hpd_info( 558fb4d8502Sjsg struct dc_bios *dcb, 559fb4d8502Sjsg struct graphics_object_id id, 560fb4d8502Sjsg struct graphics_object_hpd_info *info) 561fb4d8502Sjsg { 562fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 563fb4d8502Sjsg struct atom_display_object_path_v2 *object; 5641bb76ff1Sjsg struct atom_display_object_path_v3 *object_path_v3; 565fb4d8502Sjsg struct atom_hpd_int_record *record = NULL; 566fb4d8502Sjsg 567fb4d8502Sjsg if (!info) 568fb4d8502Sjsg return BP_RESULT_BADINPUT; 569fb4d8502Sjsg 5701bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 5711bb76ff1Sjsg case 4: 5721bb76ff1Sjsg default: 573fb4d8502Sjsg object = get_bios_object(bp, id); 574fb4d8502Sjsg 575fb4d8502Sjsg if (!object) 576fb4d8502Sjsg return BP_RESULT_BADINPUT; 577fb4d8502Sjsg 578fb4d8502Sjsg record = get_hpd_record(bp, object); 579fb4d8502Sjsg 5801bb76ff1Sjsg break; 5811bb76ff1Sjsg case 5: 5821bb76ff1Sjsg object_path_v3 = get_bios_object_from_path_v3(bp, id); 5831bb76ff1Sjsg 5841bb76ff1Sjsg if (!object_path_v3) 5851bb76ff1Sjsg return BP_RESULT_BADINPUT; 5861bb76ff1Sjsg 5871bb76ff1Sjsg record = get_hpd_record_for_path_v3(bp, object_path_v3); 5881bb76ff1Sjsg break; 5891bb76ff1Sjsg } 5901bb76ff1Sjsg 591fb4d8502Sjsg if (record != NULL) { 592fb4d8502Sjsg info->hpd_int_gpio_uid = record->pin_id; 593fb4d8502Sjsg info->hpd_active = record->plugin_pin_state; 594fb4d8502Sjsg return BP_RESULT_OK; 595fb4d8502Sjsg } 596fb4d8502Sjsg 597fb4d8502Sjsg return BP_RESULT_NORECORD; 598fb4d8502Sjsg } 599fb4d8502Sjsg 600fb4d8502Sjsg static struct atom_hpd_int_record *get_hpd_record( 601fb4d8502Sjsg struct bios_parser *bp, 602fb4d8502Sjsg struct atom_display_object_path_v2 *object) 603fb4d8502Sjsg { 604fb4d8502Sjsg struct atom_common_record_header *header; 605fb4d8502Sjsg uint32_t offset; 606fb4d8502Sjsg 607fb4d8502Sjsg if (!object) { 608fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 609fb4d8502Sjsg return NULL; 610fb4d8502Sjsg } 611fb4d8502Sjsg 612fb4d8502Sjsg offset = le16_to_cpu(object->disp_recordoffset) 613fb4d8502Sjsg + bp->object_info_tbl_offset; 614fb4d8502Sjsg 615fb4d8502Sjsg for (;;) { 616fb4d8502Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 617fb4d8502Sjsg 618fb4d8502Sjsg if (!header) 619fb4d8502Sjsg return NULL; 620fb4d8502Sjsg 621fb4d8502Sjsg if (header->record_type == LAST_RECORD_TYPE || 622fb4d8502Sjsg !header->record_size) 623fb4d8502Sjsg break; 624fb4d8502Sjsg 625fb4d8502Sjsg if (header->record_type == ATOM_HPD_INT_RECORD_TYPE 626fb4d8502Sjsg && sizeof(struct atom_hpd_int_record) <= 627fb4d8502Sjsg header->record_size) 628fb4d8502Sjsg return (struct atom_hpd_int_record *) header; 629fb4d8502Sjsg 630fb4d8502Sjsg offset += header->record_size; 631fb4d8502Sjsg } 632fb4d8502Sjsg 633fb4d8502Sjsg return NULL; 634fb4d8502Sjsg } 635fb4d8502Sjsg 636fb4d8502Sjsg /** 637fb4d8502Sjsg * bios_parser_get_gpio_pin_info 638fb4d8502Sjsg * Get GpioPin information of input gpio id 639fb4d8502Sjsg * 6405ca02815Sjsg * @dcb: pointer to the DC BIOS 6415ca02815Sjsg * @gpio_id: GPIO ID 6425ca02815Sjsg * @info: GpioPin information structure 6435ca02815Sjsg * return: Bios parser result code 6445ca02815Sjsg * note: 645fb4d8502Sjsg * to get the GPIO PIN INFO, we need: 646fb4d8502Sjsg * 1. get the GPIO_ID from other object table, see GetHPDInfo() 647fb4d8502Sjsg * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, 648fb4d8502Sjsg * to get the registerA offset/mask 649fb4d8502Sjsg */ 650fb4d8502Sjsg static enum bp_result bios_parser_get_gpio_pin_info( 651fb4d8502Sjsg struct dc_bios *dcb, 652fb4d8502Sjsg uint32_t gpio_id, 653fb4d8502Sjsg struct gpio_pin_info *info) 654fb4d8502Sjsg { 655fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 656fb4d8502Sjsg struct atom_gpio_pin_lut_v2_1 *header; 657fb4d8502Sjsg uint32_t count = 0; 658fb4d8502Sjsg uint32_t i = 0; 659fb4d8502Sjsg 660fb4d8502Sjsg if (!DATA_TABLES(gpio_pin_lut)) 661fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 662fb4d8502Sjsg 663fb4d8502Sjsg header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 664fb4d8502Sjsg DATA_TABLES(gpio_pin_lut)); 665fb4d8502Sjsg if (!header) 666fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 667fb4d8502Sjsg 668fb4d8502Sjsg if (sizeof(struct atom_common_table_header) + 669fb4d8502Sjsg sizeof(struct atom_gpio_pin_assignment) 670fb4d8502Sjsg > le16_to_cpu(header->table_header.structuresize)) 671fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 672fb4d8502Sjsg 673fb4d8502Sjsg if (header->table_header.content_revision != 1) 674fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 675fb4d8502Sjsg 676fb4d8502Sjsg /* Temporary hard code gpio pin info */ 677fb4d8502Sjsg count = (le16_to_cpu(header->table_header.structuresize) 678fb4d8502Sjsg - sizeof(struct atom_common_table_header)) 679fb4d8502Sjsg / sizeof(struct atom_gpio_pin_assignment); 680fb4d8502Sjsg for (i = 0; i < count; ++i) { 681fb4d8502Sjsg if (header->gpio_pin[i].gpio_id != gpio_id) 682fb4d8502Sjsg continue; 683fb4d8502Sjsg 684fb4d8502Sjsg info->offset = 685fb4d8502Sjsg (uint32_t) le16_to_cpu( 686fb4d8502Sjsg header->gpio_pin[i].data_a_reg_index); 687fb4d8502Sjsg info->offset_y = info->offset + 2; 688fb4d8502Sjsg info->offset_en = info->offset + 1; 689fb4d8502Sjsg info->offset_mask = info->offset - 1; 690fb4d8502Sjsg 691fb4d8502Sjsg info->mask = (uint32_t) (1 << 692fb4d8502Sjsg header->gpio_pin[i].gpio_bitshift); 693fb4d8502Sjsg info->mask_y = info->mask + 2; 694fb4d8502Sjsg info->mask_en = info->mask + 1; 695fb4d8502Sjsg info->mask_mask = info->mask - 1; 696fb4d8502Sjsg 697fb4d8502Sjsg return BP_RESULT_OK; 698fb4d8502Sjsg } 699fb4d8502Sjsg 700fb4d8502Sjsg return BP_RESULT_NORECORD; 701fb4d8502Sjsg } 702fb4d8502Sjsg 703fb4d8502Sjsg static struct device_id device_type_from_device_id(uint16_t device_id) 704fb4d8502Sjsg { 705fb4d8502Sjsg 706fb4d8502Sjsg struct device_id result_device_id; 707fb4d8502Sjsg 708fb4d8502Sjsg result_device_id.raw_device_tag = device_id; 709fb4d8502Sjsg 710fb4d8502Sjsg switch (device_id) { 711fb4d8502Sjsg case ATOM_DISPLAY_LCD1_SUPPORT: 712fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_LCD; 713fb4d8502Sjsg result_device_id.enum_id = 1; 714fb4d8502Sjsg break; 715fb4d8502Sjsg 7165ca02815Sjsg case ATOM_DISPLAY_LCD2_SUPPORT: 7175ca02815Sjsg result_device_id.device_type = DEVICE_TYPE_LCD; 7185ca02815Sjsg result_device_id.enum_id = 2; 7195ca02815Sjsg break; 7205ca02815Sjsg 721fb4d8502Sjsg case ATOM_DISPLAY_DFP1_SUPPORT: 722fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 723fb4d8502Sjsg result_device_id.enum_id = 1; 724fb4d8502Sjsg break; 725fb4d8502Sjsg 726fb4d8502Sjsg case ATOM_DISPLAY_DFP2_SUPPORT: 727fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 728fb4d8502Sjsg result_device_id.enum_id = 2; 729fb4d8502Sjsg break; 730fb4d8502Sjsg 731fb4d8502Sjsg case ATOM_DISPLAY_DFP3_SUPPORT: 732fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 733fb4d8502Sjsg result_device_id.enum_id = 3; 734fb4d8502Sjsg break; 735fb4d8502Sjsg 736fb4d8502Sjsg case ATOM_DISPLAY_DFP4_SUPPORT: 737fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 738fb4d8502Sjsg result_device_id.enum_id = 4; 739fb4d8502Sjsg break; 740fb4d8502Sjsg 741fb4d8502Sjsg case ATOM_DISPLAY_DFP5_SUPPORT: 742fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 743fb4d8502Sjsg result_device_id.enum_id = 5; 744fb4d8502Sjsg break; 745fb4d8502Sjsg 746fb4d8502Sjsg case ATOM_DISPLAY_DFP6_SUPPORT: 747fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 748fb4d8502Sjsg result_device_id.enum_id = 6; 749fb4d8502Sjsg break; 750fb4d8502Sjsg 751fb4d8502Sjsg default: 752fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid device Id */ 753fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_UNKNOWN; 754fb4d8502Sjsg result_device_id.enum_id = 0; 755fb4d8502Sjsg } 756fb4d8502Sjsg return result_device_id; 757fb4d8502Sjsg } 758fb4d8502Sjsg 759fb4d8502Sjsg static enum bp_result bios_parser_get_device_tag( 760fb4d8502Sjsg struct dc_bios *dcb, 761fb4d8502Sjsg struct graphics_object_id connector_object_id, 762fb4d8502Sjsg uint32_t device_tag_index, 763fb4d8502Sjsg struct connector_device_tag_info *info) 764fb4d8502Sjsg { 765fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 766fb4d8502Sjsg struct atom_display_object_path_v2 *object; 767fb4d8502Sjsg 7681bb76ff1Sjsg struct atom_display_object_path_v3 *object_path_v3; 7691bb76ff1Sjsg 7701bb76ff1Sjsg 771fb4d8502Sjsg if (!info) 772fb4d8502Sjsg return BP_RESULT_BADINPUT; 773fb4d8502Sjsg 7741bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 7751bb76ff1Sjsg case 4: 7761bb76ff1Sjsg default: 777fb4d8502Sjsg /* getBiosObject will return MXM object */ 778fb4d8502Sjsg object = get_bios_object(bp, connector_object_id); 779fb4d8502Sjsg 780fb4d8502Sjsg if (!object) { 781fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object id */ 782fb4d8502Sjsg return BP_RESULT_BADINPUT; 783fb4d8502Sjsg } 784fb4d8502Sjsg 785fb4d8502Sjsg info->acpi_device = 0; /* BIOS no longer provides this */ 786fb4d8502Sjsg info->dev_id = device_type_from_device_id(object->device_tag); 7871bb76ff1Sjsg break; 7881bb76ff1Sjsg case 5: 7891bb76ff1Sjsg object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id); 7901bb76ff1Sjsg 7911bb76ff1Sjsg if (!object_path_v3) { 7921bb76ff1Sjsg BREAK_TO_DEBUGGER(); /* Invalid object id */ 7931bb76ff1Sjsg return BP_RESULT_BADINPUT; 7941bb76ff1Sjsg } 7951bb76ff1Sjsg info->acpi_device = 0; /* BIOS no longer provides this */ 7961bb76ff1Sjsg info->dev_id = device_type_from_device_id(object_path_v3->device_tag); 7971bb76ff1Sjsg break; 7981bb76ff1Sjsg } 799fb4d8502Sjsg 800fb4d8502Sjsg return BP_RESULT_OK; 801fb4d8502Sjsg } 802fb4d8502Sjsg 803fb4d8502Sjsg static enum bp_result get_ss_info_v4_1( 804fb4d8502Sjsg struct bios_parser *bp, 805fb4d8502Sjsg uint32_t id, 806fb4d8502Sjsg uint32_t index, 807fb4d8502Sjsg struct spread_spectrum_info *ss_info) 808fb4d8502Sjsg { 809fb4d8502Sjsg enum bp_result result = BP_RESULT_OK; 810fb4d8502Sjsg struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; 811c349dbc7Sjsg struct atom_smu_info_v3_3 *smu_info = NULL; 812fb4d8502Sjsg 813fb4d8502Sjsg if (!ss_info) 814fb4d8502Sjsg return BP_RESULT_BADINPUT; 815fb4d8502Sjsg 816fb4d8502Sjsg if (!DATA_TABLES(dce_info)) 817fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 818fb4d8502Sjsg 819fb4d8502Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, 820fb4d8502Sjsg DATA_TABLES(dce_info)); 821fb4d8502Sjsg if (!disp_cntl_tbl) 822fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 823fb4d8502Sjsg 824c349dbc7Sjsg 825fb4d8502Sjsg ss_info->type.STEP_AND_DELAY_INFO = false; 826fb4d8502Sjsg ss_info->spread_percentage_divider = 1000; 827fb4d8502Sjsg /* BIOS no longer uses target clock. Always enable for now */ 828fb4d8502Sjsg ss_info->target_clock_range = 0xffffffff; 829fb4d8502Sjsg 830fb4d8502Sjsg switch (id) { 831fb4d8502Sjsg case AS_SIGNAL_TYPE_DVI: 832fb4d8502Sjsg ss_info->spread_spectrum_percentage = 833fb4d8502Sjsg disp_cntl_tbl->dvi_ss_percentage; 834fb4d8502Sjsg ss_info->spread_spectrum_range = 835fb4d8502Sjsg disp_cntl_tbl->dvi_ss_rate_10hz * 10; 836fb4d8502Sjsg if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 837fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 8381bb76ff1Sjsg 8391bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 840fb4d8502Sjsg break; 841fb4d8502Sjsg case AS_SIGNAL_TYPE_HDMI: 842fb4d8502Sjsg ss_info->spread_spectrum_percentage = 843fb4d8502Sjsg disp_cntl_tbl->hdmi_ss_percentage; 844fb4d8502Sjsg ss_info->spread_spectrum_range = 845fb4d8502Sjsg disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 846fb4d8502Sjsg if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 847fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 8481bb76ff1Sjsg 8491bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 850fb4d8502Sjsg break; 851fb4d8502Sjsg /* TODO LVDS not support anymore? */ 852fb4d8502Sjsg case AS_SIGNAL_TYPE_DISPLAY_PORT: 853fb4d8502Sjsg ss_info->spread_spectrum_percentage = 854fb4d8502Sjsg disp_cntl_tbl->dp_ss_percentage; 855fb4d8502Sjsg ss_info->spread_spectrum_range = 856fb4d8502Sjsg disp_cntl_tbl->dp_ss_rate_10hz * 10; 857fb4d8502Sjsg if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 858fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 8591bb76ff1Sjsg 8601bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 861fb4d8502Sjsg break; 862fb4d8502Sjsg case AS_SIGNAL_TYPE_GPU_PLL: 863fb4d8502Sjsg /* atom_firmware: DAL only get data from dce_info table. 864fb4d8502Sjsg * if data within smu_info is needed for DAL, VBIOS should 865fb4d8502Sjsg * copy it into dce_info 866fb4d8502Sjsg */ 867fb4d8502Sjsg result = BP_RESULT_UNSUPPORTED; 868fb4d8502Sjsg break; 869c349dbc7Sjsg case AS_SIGNAL_TYPE_XGMI: 870c349dbc7Sjsg smu_info = GET_IMAGE(struct atom_smu_info_v3_3, 871c349dbc7Sjsg DATA_TABLES(smu_info)); 872c349dbc7Sjsg if (!smu_info) 873c349dbc7Sjsg return BP_RESULT_BADBIOSTABLE; 8741bb76ff1Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info->gpuclk_ss_percentage); 875c349dbc7Sjsg ss_info->spread_spectrum_percentage = 876c349dbc7Sjsg smu_info->waflclk_ss_percentage; 877c349dbc7Sjsg ss_info->spread_spectrum_range = 878c349dbc7Sjsg smu_info->gpuclk_ss_rate_10hz * 10; 879c349dbc7Sjsg if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 880c349dbc7Sjsg ss_info->type.CENTER_MODE = true; 8811bb76ff1Sjsg 8821bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_XGMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 883c349dbc7Sjsg break; 884fb4d8502Sjsg default: 885fb4d8502Sjsg result = BP_RESULT_UNSUPPORTED; 886fb4d8502Sjsg } 887fb4d8502Sjsg 888fb4d8502Sjsg return result; 889fb4d8502Sjsg } 890fb4d8502Sjsg 891fb4d8502Sjsg static enum bp_result get_ss_info_v4_2( 892fb4d8502Sjsg struct bios_parser *bp, 893fb4d8502Sjsg uint32_t id, 894fb4d8502Sjsg uint32_t index, 895fb4d8502Sjsg struct spread_spectrum_info *ss_info) 896fb4d8502Sjsg { 897fb4d8502Sjsg enum bp_result result = BP_RESULT_OK; 898fb4d8502Sjsg struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; 899fb4d8502Sjsg struct atom_smu_info_v3_1 *smu_info = NULL; 900fb4d8502Sjsg 901fb4d8502Sjsg if (!ss_info) 902fb4d8502Sjsg return BP_RESULT_BADINPUT; 903fb4d8502Sjsg 904fb4d8502Sjsg if (!DATA_TABLES(dce_info)) 905fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 906fb4d8502Sjsg 907fb4d8502Sjsg if (!DATA_TABLES(smu_info)) 908fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 909fb4d8502Sjsg 910fb4d8502Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, 911fb4d8502Sjsg DATA_TABLES(dce_info)); 912fb4d8502Sjsg if (!disp_cntl_tbl) 913fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 914fb4d8502Sjsg 915fb4d8502Sjsg smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info)); 916fb4d8502Sjsg if (!smu_info) 917fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 918fb4d8502Sjsg 9191bb76ff1Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info->gpuclk_ss_percentage); 920fb4d8502Sjsg ss_info->type.STEP_AND_DELAY_INFO = false; 921fb4d8502Sjsg ss_info->spread_percentage_divider = 1000; 922fb4d8502Sjsg /* BIOS no longer uses target clock. Always enable for now */ 923fb4d8502Sjsg ss_info->target_clock_range = 0xffffffff; 924fb4d8502Sjsg 925fb4d8502Sjsg switch (id) { 926fb4d8502Sjsg case AS_SIGNAL_TYPE_DVI: 927fb4d8502Sjsg ss_info->spread_spectrum_percentage = 928fb4d8502Sjsg disp_cntl_tbl->dvi_ss_percentage; 929fb4d8502Sjsg ss_info->spread_spectrum_range = 930fb4d8502Sjsg disp_cntl_tbl->dvi_ss_rate_10hz * 10; 931fb4d8502Sjsg if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 932fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 9331bb76ff1Sjsg 9341bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 935fb4d8502Sjsg break; 936fb4d8502Sjsg case AS_SIGNAL_TYPE_HDMI: 937fb4d8502Sjsg ss_info->spread_spectrum_percentage = 938fb4d8502Sjsg disp_cntl_tbl->hdmi_ss_percentage; 939fb4d8502Sjsg ss_info->spread_spectrum_range = 940fb4d8502Sjsg disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 941fb4d8502Sjsg if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 942fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 9431bb76ff1Sjsg 9441bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 945fb4d8502Sjsg break; 946fb4d8502Sjsg /* TODO LVDS not support anymore? */ 947fb4d8502Sjsg case AS_SIGNAL_TYPE_DISPLAY_PORT: 948fb4d8502Sjsg ss_info->spread_spectrum_percentage = 949fb4d8502Sjsg smu_info->gpuclk_ss_percentage; 950fb4d8502Sjsg ss_info->spread_spectrum_range = 951fb4d8502Sjsg smu_info->gpuclk_ss_rate_10hz * 10; 952fb4d8502Sjsg if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 953fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 9541bb76ff1Sjsg 9551bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 956fb4d8502Sjsg break; 957fb4d8502Sjsg case AS_SIGNAL_TYPE_GPU_PLL: 958fb4d8502Sjsg /* atom_firmware: DAL only get data from dce_info table. 959fb4d8502Sjsg * if data within smu_info is needed for DAL, VBIOS should 960fb4d8502Sjsg * copy it into dce_info 961fb4d8502Sjsg */ 962fb4d8502Sjsg result = BP_RESULT_UNSUPPORTED; 963fb4d8502Sjsg break; 964fb4d8502Sjsg default: 965fb4d8502Sjsg result = BP_RESULT_UNSUPPORTED; 966fb4d8502Sjsg } 967fb4d8502Sjsg 968fb4d8502Sjsg return result; 969fb4d8502Sjsg } 970fb4d8502Sjsg 9711bb76ff1Sjsg static enum bp_result get_ss_info_v4_5( 9721bb76ff1Sjsg struct bios_parser *bp, 9731bb76ff1Sjsg uint32_t id, 9741bb76ff1Sjsg uint32_t index, 9751bb76ff1Sjsg struct spread_spectrum_info *ss_info) 9761bb76ff1Sjsg { 9771bb76ff1Sjsg enum bp_result result = BP_RESULT_OK; 9781bb76ff1Sjsg struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 9791bb76ff1Sjsg 9801bb76ff1Sjsg if (!ss_info) 9811bb76ff1Sjsg return BP_RESULT_BADINPUT; 9821bb76ff1Sjsg 9831bb76ff1Sjsg if (!DATA_TABLES(dce_info)) 9841bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 9851bb76ff1Sjsg 9861bb76ff1Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 9871bb76ff1Sjsg DATA_TABLES(dce_info)); 9881bb76ff1Sjsg if (!disp_cntl_tbl) 9891bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 9901bb76ff1Sjsg 9911bb76ff1Sjsg ss_info->type.STEP_AND_DELAY_INFO = false; 9921bb76ff1Sjsg ss_info->spread_percentage_divider = 1000; 9931bb76ff1Sjsg /* BIOS no longer uses target clock. Always enable for now */ 9941bb76ff1Sjsg ss_info->target_clock_range = 0xffffffff; 9951bb76ff1Sjsg 9961bb76ff1Sjsg switch (id) { 9971bb76ff1Sjsg case AS_SIGNAL_TYPE_DVI: 9981bb76ff1Sjsg ss_info->spread_spectrum_percentage = 9991bb76ff1Sjsg disp_cntl_tbl->dvi_ss_percentage; 10001bb76ff1Sjsg ss_info->spread_spectrum_range = 10011bb76ff1Sjsg disp_cntl_tbl->dvi_ss_rate_10hz * 10; 10021bb76ff1Sjsg if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 10031bb76ff1Sjsg ss_info->type.CENTER_MODE = true; 10041bb76ff1Sjsg 10051bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 10061bb76ff1Sjsg break; 10071bb76ff1Sjsg case AS_SIGNAL_TYPE_HDMI: 10081bb76ff1Sjsg ss_info->spread_spectrum_percentage = 10091bb76ff1Sjsg disp_cntl_tbl->hdmi_ss_percentage; 10101bb76ff1Sjsg ss_info->spread_spectrum_range = 10111bb76ff1Sjsg disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 10121bb76ff1Sjsg if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 10131bb76ff1Sjsg ss_info->type.CENTER_MODE = true; 10141bb76ff1Sjsg 10151bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 10161bb76ff1Sjsg break; 10171bb76ff1Sjsg case AS_SIGNAL_TYPE_DISPLAY_PORT: 10182d4ce006Sjsg if (bp->base.integrated_info) { 10192d4ce006Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", bp->base.integrated_info->gpuclk_ss_percentage); 10202d4ce006Sjsg ss_info->spread_spectrum_percentage = 10212d4ce006Sjsg bp->base.integrated_info->gpuclk_ss_percentage; 10222d4ce006Sjsg ss_info->type.CENTER_MODE = 10232d4ce006Sjsg bp->base.integrated_info->gpuclk_ss_type; 10242d4ce006Sjsg } else { 10251bb76ff1Sjsg ss_info->spread_spectrum_percentage = 10261bb76ff1Sjsg disp_cntl_tbl->dp_ss_percentage; 10271bb76ff1Sjsg ss_info->spread_spectrum_range = 10281bb76ff1Sjsg disp_cntl_tbl->dp_ss_rate_10hz * 10; 10291bb76ff1Sjsg if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 10301bb76ff1Sjsg ss_info->type.CENTER_MODE = true; 10312d4ce006Sjsg } 10321bb76ff1Sjsg DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage); 10331bb76ff1Sjsg break; 10341bb76ff1Sjsg case AS_SIGNAL_TYPE_GPU_PLL: 10351bb76ff1Sjsg /* atom_smu_info_v4_0 does not have fields for SS for SMU Display PLL anymore. 10361bb76ff1Sjsg * SMU Display PLL supposed to be without spread. 10371bb76ff1Sjsg * Better place for it would be in atom_display_controller_info_v4_5 table. 10381bb76ff1Sjsg */ 10391bb76ff1Sjsg result = BP_RESULT_UNSUPPORTED; 10401bb76ff1Sjsg break; 10411bb76ff1Sjsg default: 10421bb76ff1Sjsg result = BP_RESULT_UNSUPPORTED; 10431bb76ff1Sjsg break; 10441bb76ff1Sjsg } 10451bb76ff1Sjsg 10461bb76ff1Sjsg return result; 10471bb76ff1Sjsg } 10481bb76ff1Sjsg 1049fb4d8502Sjsg /** 1050fb4d8502Sjsg * bios_parser_get_spread_spectrum_info 1051fb4d8502Sjsg * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or 1052fb4d8502Sjsg * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info 1053fb4d8502Sjsg * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info 1054fb4d8502Sjsg * ver 3.1, 1055fb4d8502Sjsg * there is only one entry for each signal /ss id. However, there is 1056fb4d8502Sjsg * no planning of supporting multiple spread Sprectum entry for EverGreen 10575ca02815Sjsg * @dcb: pointer to the DC BIOS 10585ca02815Sjsg * @signal: ASSignalType to be converted to info index 10595ca02815Sjsg * @index: number of entries that match the converted info index 10605ca02815Sjsg * @ss_info: sprectrum information structure, 10615ca02815Sjsg * return: Bios parser result code 1062fb4d8502Sjsg */ 1063fb4d8502Sjsg static enum bp_result bios_parser_get_spread_spectrum_info( 1064fb4d8502Sjsg struct dc_bios *dcb, 1065fb4d8502Sjsg enum as_signal_type signal, 1066fb4d8502Sjsg uint32_t index, 1067fb4d8502Sjsg struct spread_spectrum_info *ss_info) 1068fb4d8502Sjsg { 1069fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1070fb4d8502Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 1071fb4d8502Sjsg struct atom_common_table_header *header; 1072fb4d8502Sjsg struct atom_data_revision tbl_revision; 1073fb4d8502Sjsg 1074fb4d8502Sjsg if (!ss_info) /* check for bad input */ 1075fb4d8502Sjsg return BP_RESULT_BADINPUT; 1076fb4d8502Sjsg 1077fb4d8502Sjsg if (!DATA_TABLES(dce_info)) 1078fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1079fb4d8502Sjsg 1080fb4d8502Sjsg header = GET_IMAGE(struct atom_common_table_header, 1081fb4d8502Sjsg DATA_TABLES(dce_info)); 1082fb4d8502Sjsg get_atom_data_table_revision(header, &tbl_revision); 1083fb4d8502Sjsg 1084fb4d8502Sjsg switch (tbl_revision.major) { 1085fb4d8502Sjsg case 4: 1086fb4d8502Sjsg switch (tbl_revision.minor) { 1087fb4d8502Sjsg case 1: 1088fb4d8502Sjsg return get_ss_info_v4_1(bp, signal, index, ss_info); 1089fb4d8502Sjsg case 2: 1090c349dbc7Sjsg case 3: 10915ca02815Sjsg case 4: 1092fb4d8502Sjsg return get_ss_info_v4_2(bp, signal, index, ss_info); 10931bb76ff1Sjsg case 5: 10941bb76ff1Sjsg return get_ss_info_v4_5(bp, signal, index, ss_info); 10951bb76ff1Sjsg 1096fb4d8502Sjsg default: 10975ca02815Sjsg ASSERT(0); 1098fb4d8502Sjsg break; 1099fb4d8502Sjsg } 1100fb4d8502Sjsg break; 1101fb4d8502Sjsg default: 1102fb4d8502Sjsg break; 1103fb4d8502Sjsg } 1104fb4d8502Sjsg /* there can not be more then one entry for SS Info table */ 1105fb4d8502Sjsg return result; 1106fb4d8502Sjsg } 1107fb4d8502Sjsg 1108ad8b1aafSjsg static enum bp_result get_soc_bb_info_v4_4( 1109ad8b1aafSjsg struct bios_parser *bp, 1110ad8b1aafSjsg struct bp_soc_bb_info *soc_bb_info) 1111ad8b1aafSjsg { 1112ad8b1aafSjsg enum bp_result result = BP_RESULT_OK; 1113ad8b1aafSjsg struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; 1114ad8b1aafSjsg 1115ad8b1aafSjsg if (!soc_bb_info) 1116ad8b1aafSjsg return BP_RESULT_BADINPUT; 1117ad8b1aafSjsg 1118ad8b1aafSjsg if (!DATA_TABLES(dce_info)) 1119ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 1120ad8b1aafSjsg 1121ad8b1aafSjsg if (!DATA_TABLES(smu_info)) 1122ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 1123ad8b1aafSjsg 1124ad8b1aafSjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, 1125ad8b1aafSjsg DATA_TABLES(dce_info)); 1126ad8b1aafSjsg if (!disp_cntl_tbl) 1127ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 1128ad8b1aafSjsg 1129ad8b1aafSjsg soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat; 1130ad8b1aafSjsg soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat; 1131ad8b1aafSjsg soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat; 1132ad8b1aafSjsg 1133ad8b1aafSjsg return result; 1134ad8b1aafSjsg } 1135ad8b1aafSjsg 11361bb76ff1Sjsg static enum bp_result get_soc_bb_info_v4_5( 11371bb76ff1Sjsg struct bios_parser *bp, 11381bb76ff1Sjsg struct bp_soc_bb_info *soc_bb_info) 11391bb76ff1Sjsg { 11401bb76ff1Sjsg enum bp_result result = BP_RESULT_OK; 11411bb76ff1Sjsg struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 11421bb76ff1Sjsg 11431bb76ff1Sjsg if (!soc_bb_info) 11441bb76ff1Sjsg return BP_RESULT_BADINPUT; 11451bb76ff1Sjsg 11461bb76ff1Sjsg if (!DATA_TABLES(dce_info)) 11471bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 11481bb76ff1Sjsg 11491bb76ff1Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 11501bb76ff1Sjsg DATA_TABLES(dce_info)); 11511bb76ff1Sjsg if (!disp_cntl_tbl) 11521bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 11531bb76ff1Sjsg 11541bb76ff1Sjsg soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat; 11551bb76ff1Sjsg soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat; 11561bb76ff1Sjsg soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat; 11571bb76ff1Sjsg 11581bb76ff1Sjsg return result; 11591bb76ff1Sjsg } 11601bb76ff1Sjsg 1161ad8b1aafSjsg static enum bp_result bios_parser_get_soc_bb_info( 1162ad8b1aafSjsg struct dc_bios *dcb, 1163ad8b1aafSjsg struct bp_soc_bb_info *soc_bb_info) 1164ad8b1aafSjsg { 1165ad8b1aafSjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1166ad8b1aafSjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 1167ad8b1aafSjsg struct atom_common_table_header *header; 1168ad8b1aafSjsg struct atom_data_revision tbl_revision; 1169ad8b1aafSjsg 1170ad8b1aafSjsg if (!soc_bb_info) /* check for bad input */ 1171ad8b1aafSjsg return BP_RESULT_BADINPUT; 1172ad8b1aafSjsg 1173ad8b1aafSjsg if (!DATA_TABLES(dce_info)) 1174ad8b1aafSjsg return BP_RESULT_UNSUPPORTED; 1175ad8b1aafSjsg 1176ad8b1aafSjsg header = GET_IMAGE(struct atom_common_table_header, 1177ad8b1aafSjsg DATA_TABLES(dce_info)); 1178ad8b1aafSjsg get_atom_data_table_revision(header, &tbl_revision); 1179ad8b1aafSjsg 1180ad8b1aafSjsg switch (tbl_revision.major) { 1181ad8b1aafSjsg case 4: 1182ad8b1aafSjsg switch (tbl_revision.minor) { 1183ad8b1aafSjsg case 1: 1184ad8b1aafSjsg case 2: 1185ad8b1aafSjsg case 3: 1186ad8b1aafSjsg break; 1187ad8b1aafSjsg case 4: 1188ad8b1aafSjsg result = get_soc_bb_info_v4_4(bp, soc_bb_info); 11895ca02815Sjsg break; 11901bb76ff1Sjsg case 5: 11911bb76ff1Sjsg result = get_soc_bb_info_v4_5(bp, soc_bb_info); 11921bb76ff1Sjsg break; 11935ca02815Sjsg default: 11945ca02815Sjsg break; 11955ca02815Sjsg } 11965ca02815Sjsg break; 11975ca02815Sjsg default: 11985ca02815Sjsg break; 11995ca02815Sjsg } 12005ca02815Sjsg 12015ca02815Sjsg return result; 12025ca02815Sjsg } 12035ca02815Sjsg 12045ca02815Sjsg static enum bp_result get_disp_caps_v4_1( 12055ca02815Sjsg struct bios_parser *bp, 12065ca02815Sjsg uint8_t *dce_caps) 12075ca02815Sjsg { 12085ca02815Sjsg enum bp_result result = BP_RESULT_OK; 12095ca02815Sjsg struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; 12105ca02815Sjsg 12115ca02815Sjsg if (!dce_caps) 12125ca02815Sjsg return BP_RESULT_BADINPUT; 12135ca02815Sjsg 12145ca02815Sjsg if (!DATA_TABLES(dce_info)) 12155ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12165ca02815Sjsg 12175ca02815Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, 12185ca02815Sjsg DATA_TABLES(dce_info)); 12195ca02815Sjsg 12205ca02815Sjsg if (!disp_cntl_tbl) 12215ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12225ca02815Sjsg 12235ca02815Sjsg *dce_caps = disp_cntl_tbl->display_caps; 12245ca02815Sjsg 12255ca02815Sjsg return result; 12265ca02815Sjsg } 12275ca02815Sjsg 12285ca02815Sjsg static enum bp_result get_disp_caps_v4_2( 12295ca02815Sjsg struct bios_parser *bp, 12305ca02815Sjsg uint8_t *dce_caps) 12315ca02815Sjsg { 12325ca02815Sjsg enum bp_result result = BP_RESULT_OK; 12335ca02815Sjsg struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; 12345ca02815Sjsg 12355ca02815Sjsg if (!dce_caps) 12365ca02815Sjsg return BP_RESULT_BADINPUT; 12375ca02815Sjsg 12385ca02815Sjsg if (!DATA_TABLES(dce_info)) 12395ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12405ca02815Sjsg 12415ca02815Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, 12425ca02815Sjsg DATA_TABLES(dce_info)); 12435ca02815Sjsg 12445ca02815Sjsg if (!disp_cntl_tbl) 12455ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12465ca02815Sjsg 12475ca02815Sjsg *dce_caps = disp_cntl_tbl->display_caps; 12485ca02815Sjsg 12495ca02815Sjsg return result; 12505ca02815Sjsg } 12515ca02815Sjsg 12525ca02815Sjsg static enum bp_result get_disp_caps_v4_3( 12535ca02815Sjsg struct bios_parser *bp, 12545ca02815Sjsg uint8_t *dce_caps) 12555ca02815Sjsg { 12565ca02815Sjsg enum bp_result result = BP_RESULT_OK; 12575ca02815Sjsg struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL; 12585ca02815Sjsg 12595ca02815Sjsg if (!dce_caps) 12605ca02815Sjsg return BP_RESULT_BADINPUT; 12615ca02815Sjsg 12625ca02815Sjsg if (!DATA_TABLES(dce_info)) 12635ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12645ca02815Sjsg 12655ca02815Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3, 12665ca02815Sjsg DATA_TABLES(dce_info)); 12675ca02815Sjsg 12685ca02815Sjsg if (!disp_cntl_tbl) 12695ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12705ca02815Sjsg 12715ca02815Sjsg *dce_caps = disp_cntl_tbl->display_caps; 12725ca02815Sjsg 12735ca02815Sjsg return result; 12745ca02815Sjsg } 12755ca02815Sjsg 12765ca02815Sjsg static enum bp_result get_disp_caps_v4_4( 12775ca02815Sjsg struct bios_parser *bp, 12785ca02815Sjsg uint8_t *dce_caps) 12795ca02815Sjsg { 12805ca02815Sjsg enum bp_result result = BP_RESULT_OK; 12815ca02815Sjsg struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; 12825ca02815Sjsg 12835ca02815Sjsg if (!dce_caps) 12845ca02815Sjsg return BP_RESULT_BADINPUT; 12855ca02815Sjsg 12865ca02815Sjsg if (!DATA_TABLES(dce_info)) 12875ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12885ca02815Sjsg 12895ca02815Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, 12905ca02815Sjsg DATA_TABLES(dce_info)); 12915ca02815Sjsg 12925ca02815Sjsg if (!disp_cntl_tbl) 12935ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 12945ca02815Sjsg 12955ca02815Sjsg *dce_caps = disp_cntl_tbl->display_caps; 12965ca02815Sjsg 12975ca02815Sjsg return result; 12985ca02815Sjsg } 12995ca02815Sjsg 13001bb76ff1Sjsg static enum bp_result get_disp_caps_v4_5( 13011bb76ff1Sjsg struct bios_parser *bp, 13021bb76ff1Sjsg uint8_t *dce_caps) 13031bb76ff1Sjsg { 13041bb76ff1Sjsg enum bp_result result = BP_RESULT_OK; 13051bb76ff1Sjsg struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 13061bb76ff1Sjsg 13071bb76ff1Sjsg if (!dce_caps) 13081bb76ff1Sjsg return BP_RESULT_BADINPUT; 13091bb76ff1Sjsg 13101bb76ff1Sjsg if (!DATA_TABLES(dce_info)) 13111bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 13121bb76ff1Sjsg 13131bb76ff1Sjsg disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 13141bb76ff1Sjsg DATA_TABLES(dce_info)); 13151bb76ff1Sjsg 13161bb76ff1Sjsg if (!disp_cntl_tbl) 13171bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 13181bb76ff1Sjsg 13191bb76ff1Sjsg *dce_caps = disp_cntl_tbl->display_caps; 13201bb76ff1Sjsg 13211bb76ff1Sjsg return result; 13221bb76ff1Sjsg } 13231bb76ff1Sjsg 13245ca02815Sjsg static enum bp_result bios_parser_get_lttpr_interop( 13255ca02815Sjsg struct dc_bios *dcb, 13265ca02815Sjsg uint8_t *dce_caps) 13275ca02815Sjsg { 13285ca02815Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 13295ca02815Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 13305ca02815Sjsg struct atom_common_table_header *header; 13315ca02815Sjsg struct atom_data_revision tbl_revision; 13325ca02815Sjsg 13335ca02815Sjsg if (!DATA_TABLES(dce_info)) 13345ca02815Sjsg return BP_RESULT_UNSUPPORTED; 13355ca02815Sjsg 13365ca02815Sjsg header = GET_IMAGE(struct atom_common_table_header, 13375ca02815Sjsg DATA_TABLES(dce_info)); 13385ca02815Sjsg get_atom_data_table_revision(header, &tbl_revision); 13395ca02815Sjsg switch (tbl_revision.major) { 13405ca02815Sjsg case 4: 13415ca02815Sjsg switch (tbl_revision.minor) { 13425ca02815Sjsg case 1: 13435ca02815Sjsg result = get_disp_caps_v4_1(bp, dce_caps); 13445ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 13455ca02815Sjsg break; 13465ca02815Sjsg case 2: 13475ca02815Sjsg result = get_disp_caps_v4_2(bp, dce_caps); 13485ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 13495ca02815Sjsg break; 13505ca02815Sjsg case 3: 13515ca02815Sjsg result = get_disp_caps_v4_3(bp, dce_caps); 13525ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 13535ca02815Sjsg break; 13545ca02815Sjsg case 4: 13555ca02815Sjsg result = get_disp_caps_v4_4(bp, dce_caps); 13565ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 13575ca02815Sjsg break; 13581bb76ff1Sjsg case 5: 13591bb76ff1Sjsg result = get_disp_caps_v4_5(bp, dce_caps); 13601bb76ff1Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 13615ca02815Sjsg break; 13625ca02815Sjsg 13631bb76ff1Sjsg default: 13641bb76ff1Sjsg break; 13651bb76ff1Sjsg } 13661bb76ff1Sjsg break; 13671bb76ff1Sjsg default: 13681bb76ff1Sjsg break; 13691bb76ff1Sjsg } 13701bb76ff1Sjsg DC_LOG_BIOS("DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE: %d tbl_revision.major = %d tbl_revision.minor = %d\n", *dce_caps, tbl_revision.major, tbl_revision.minor); 13715ca02815Sjsg return result; 13725ca02815Sjsg } 13735ca02815Sjsg 13745ca02815Sjsg static enum bp_result bios_parser_get_lttpr_caps( 13755ca02815Sjsg struct dc_bios *dcb, 13765ca02815Sjsg uint8_t *dce_caps) 13775ca02815Sjsg { 13785ca02815Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 13795ca02815Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 13805ca02815Sjsg struct atom_common_table_header *header; 13815ca02815Sjsg struct atom_data_revision tbl_revision; 13825ca02815Sjsg 13835ca02815Sjsg if (!DATA_TABLES(dce_info)) 13845ca02815Sjsg return BP_RESULT_UNSUPPORTED; 13855ca02815Sjsg 13861bb76ff1Sjsg *dce_caps = 0; 13875ca02815Sjsg header = GET_IMAGE(struct atom_common_table_header, 13885ca02815Sjsg DATA_TABLES(dce_info)); 13895ca02815Sjsg get_atom_data_table_revision(header, &tbl_revision); 13905ca02815Sjsg switch (tbl_revision.major) { 13915ca02815Sjsg case 4: 13925ca02815Sjsg switch (tbl_revision.minor) { 13935ca02815Sjsg case 1: 13945ca02815Sjsg result = get_disp_caps_v4_1(bp, dce_caps); 13955ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 13965ca02815Sjsg break; 13975ca02815Sjsg case 2: 13985ca02815Sjsg result = get_disp_caps_v4_2(bp, dce_caps); 13995ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 14005ca02815Sjsg break; 14015ca02815Sjsg case 3: 14025ca02815Sjsg result = get_disp_caps_v4_3(bp, dce_caps); 14035ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 14045ca02815Sjsg break; 14055ca02815Sjsg case 4: 14065ca02815Sjsg result = get_disp_caps_v4_4(bp, dce_caps); 14075ca02815Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 14085ca02815Sjsg break; 14091bb76ff1Sjsg case 5: 14101bb76ff1Sjsg result = get_disp_caps_v4_5(bp, dce_caps); 14111bb76ff1Sjsg *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 14121bb76ff1Sjsg break; 1413ad8b1aafSjsg default: 1414ad8b1aafSjsg break; 1415ad8b1aafSjsg } 1416ad8b1aafSjsg break; 1417ad8b1aafSjsg default: 1418ad8b1aafSjsg break; 1419ad8b1aafSjsg } 14201bb76ff1Sjsg DC_LOG_BIOS("DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE: %d tbl_revision.major = %d tbl_revision.minor = %d\n", *dce_caps, tbl_revision.major, tbl_revision.minor); 14211bb76ff1Sjsg if (dcb->ctx->dc->config.force_bios_enable_lttpr && *dce_caps == 0) { 14221bb76ff1Sjsg *dce_caps = 1; 14231bb76ff1Sjsg DC_LOG_BIOS("DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE: forced enabled"); 14241bb76ff1Sjsg } 1425ad8b1aafSjsg return result; 1426ad8b1aafSjsg } 1427ad8b1aafSjsg 1428fb4d8502Sjsg static enum bp_result get_embedded_panel_info_v2_1( 1429fb4d8502Sjsg struct bios_parser *bp, 1430fb4d8502Sjsg struct embedded_panel_info *info) 1431fb4d8502Sjsg { 1432fb4d8502Sjsg struct lcd_info_v2_1 *lvds; 1433fb4d8502Sjsg 1434fb4d8502Sjsg if (!info) 1435fb4d8502Sjsg return BP_RESULT_BADINPUT; 1436fb4d8502Sjsg 1437fb4d8502Sjsg if (!DATA_TABLES(lcd_info)) 1438fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1439fb4d8502Sjsg 1440fb4d8502Sjsg lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info)); 1441fb4d8502Sjsg 1442fb4d8502Sjsg if (!lvds) 1443fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1444fb4d8502Sjsg 1445fb4d8502Sjsg /* TODO: previous vv1_3, should v2_1 */ 1446fb4d8502Sjsg if (!((lvds->table_header.format_revision == 2) 1447fb4d8502Sjsg && (lvds->table_header.content_revision >= 1))) 1448fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1449fb4d8502Sjsg 1450fb4d8502Sjsg memset(info, 0, sizeof(struct embedded_panel_info)); 1451fb4d8502Sjsg 1452fb4d8502Sjsg /* We need to convert from 10KHz units into KHz units */ 1453c349dbc7Sjsg info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10; 1454fb4d8502Sjsg /* usHActive does not include borders, according to VBIOS team */ 1455c349dbc7Sjsg info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active); 1456fb4d8502Sjsg /* usHBlanking_Time includes borders, so we should really be 1457fb4d8502Sjsg * subtractingborders duing this translation, but LVDS generally 1458fb4d8502Sjsg * doesn't have borders, so we should be okay leaving this as is for 1459fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders 1460fb4d8502Sjsg */ 1461c349dbc7Sjsg info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time); 1462fb4d8502Sjsg /* usVActive does not include borders, according to VBIOS team*/ 1463c349dbc7Sjsg info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active); 1464fb4d8502Sjsg /* usVBlanking_Time includes borders, so we should really be 1465fb4d8502Sjsg * subtracting borders duing this translation, but LVDS generally 1466fb4d8502Sjsg * doesn't have borders, so we should be okay leaving this as is for 1467fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders 1468fb4d8502Sjsg */ 1469c349dbc7Sjsg info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time); 1470c349dbc7Sjsg info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset); 1471c349dbc7Sjsg info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width); 1472c349dbc7Sjsg info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset); 1473c349dbc7Sjsg info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth); 1474fb4d8502Sjsg info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border; 1475fb4d8502Sjsg info->lcd_timing.vertical_border = lvds->lcd_timing.v_border; 1476fb4d8502Sjsg 1477fb4d8502Sjsg /* not provided by VBIOS */ 1478fb4d8502Sjsg info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; 1479fb4d8502Sjsg 1480c349dbc7Sjsg info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 1481c349dbc7Sjsg & ATOM_HSYNC_POLARITY); 1482c349dbc7Sjsg info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 1483c349dbc7Sjsg & ATOM_VSYNC_POLARITY); 1484fb4d8502Sjsg 1485fb4d8502Sjsg /* not provided by VBIOS */ 1486fb4d8502Sjsg info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; 1487fb4d8502Sjsg 1488c349dbc7Sjsg info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 1489c349dbc7Sjsg & ATOM_H_REPLICATIONBY2); 1490c349dbc7Sjsg info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 1491c349dbc7Sjsg & ATOM_V_REPLICATIONBY2); 1492c349dbc7Sjsg info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo 1493c349dbc7Sjsg & ATOM_COMPOSITESYNC); 1494c349dbc7Sjsg info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); 1495fb4d8502Sjsg 1496fb4d8502Sjsg /* not provided by VBIOS*/ 1497fb4d8502Sjsg info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; 1498fb4d8502Sjsg /* not provided by VBIOS*/ 1499fb4d8502Sjsg info->ss_id = 0; 1500fb4d8502Sjsg 1501c349dbc7Sjsg info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); 1502fb4d8502Sjsg 1503fb4d8502Sjsg return BP_RESULT_OK; 1504fb4d8502Sjsg } 1505fb4d8502Sjsg 1506fb4d8502Sjsg static enum bp_result bios_parser_get_embedded_panel_info( 1507fb4d8502Sjsg struct dc_bios *dcb, 1508fb4d8502Sjsg struct embedded_panel_info *info) 1509fb4d8502Sjsg { 1510c349dbc7Sjsg struct bios_parser 1511c349dbc7Sjsg *bp = BP_FROM_DCB(dcb); 1512fb4d8502Sjsg struct atom_common_table_header *header; 1513fb4d8502Sjsg struct atom_data_revision tbl_revision; 1514fb4d8502Sjsg 1515fb4d8502Sjsg if (!DATA_TABLES(lcd_info)) 1516fb4d8502Sjsg return BP_RESULT_FAILURE; 1517fb4d8502Sjsg 1518c349dbc7Sjsg header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info)); 1519fb4d8502Sjsg 1520fb4d8502Sjsg if (!header) 1521fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1522fb4d8502Sjsg 1523fb4d8502Sjsg get_atom_data_table_revision(header, &tbl_revision); 1524fb4d8502Sjsg 1525fb4d8502Sjsg switch (tbl_revision.major) { 1526fb4d8502Sjsg case 2: 1527fb4d8502Sjsg switch (tbl_revision.minor) { 1528fb4d8502Sjsg case 1: 1529fb4d8502Sjsg return get_embedded_panel_info_v2_1(bp, info); 1530fb4d8502Sjsg default: 1531fb4d8502Sjsg break; 1532fb4d8502Sjsg } 15335ca02815Sjsg break; 1534fb4d8502Sjsg default: 1535fb4d8502Sjsg break; 1536fb4d8502Sjsg } 1537fb4d8502Sjsg 1538fb4d8502Sjsg return BP_RESULT_FAILURE; 1539fb4d8502Sjsg } 1540fb4d8502Sjsg 1541fb4d8502Sjsg static uint32_t get_support_mask_for_device_id(struct device_id device_id) 1542fb4d8502Sjsg { 1543fb4d8502Sjsg enum dal_device_type device_type = device_id.device_type; 1544fb4d8502Sjsg uint32_t enum_id = device_id.enum_id; 1545fb4d8502Sjsg 1546fb4d8502Sjsg switch (device_type) { 1547fb4d8502Sjsg case DEVICE_TYPE_LCD: 1548fb4d8502Sjsg switch (enum_id) { 1549fb4d8502Sjsg case 1: 1550fb4d8502Sjsg return ATOM_DISPLAY_LCD1_SUPPORT; 1551fb4d8502Sjsg default: 1552fb4d8502Sjsg break; 1553fb4d8502Sjsg } 1554fb4d8502Sjsg break; 1555fb4d8502Sjsg case DEVICE_TYPE_DFP: 1556fb4d8502Sjsg switch (enum_id) { 1557fb4d8502Sjsg case 1: 1558fb4d8502Sjsg return ATOM_DISPLAY_DFP1_SUPPORT; 1559fb4d8502Sjsg case 2: 1560fb4d8502Sjsg return ATOM_DISPLAY_DFP2_SUPPORT; 1561fb4d8502Sjsg case 3: 1562fb4d8502Sjsg return ATOM_DISPLAY_DFP3_SUPPORT; 1563fb4d8502Sjsg case 4: 1564fb4d8502Sjsg return ATOM_DISPLAY_DFP4_SUPPORT; 1565fb4d8502Sjsg case 5: 1566fb4d8502Sjsg return ATOM_DISPLAY_DFP5_SUPPORT; 1567fb4d8502Sjsg case 6: 1568fb4d8502Sjsg return ATOM_DISPLAY_DFP6_SUPPORT; 1569fb4d8502Sjsg default: 1570fb4d8502Sjsg break; 1571fb4d8502Sjsg } 1572fb4d8502Sjsg break; 1573fb4d8502Sjsg default: 1574fb4d8502Sjsg break; 1575c349dbc7Sjsg } 1576fb4d8502Sjsg 1577fb4d8502Sjsg /* Unidentified device ID, return empty support mask. */ 1578fb4d8502Sjsg return 0; 1579fb4d8502Sjsg } 1580fb4d8502Sjsg 1581fb4d8502Sjsg static bool bios_parser_is_device_id_supported( 1582fb4d8502Sjsg struct dc_bios *dcb, 1583fb4d8502Sjsg struct device_id id) 1584fb4d8502Sjsg { 1585fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1586fb4d8502Sjsg 1587fb4d8502Sjsg uint32_t mask = get_support_mask_for_device_id(id); 1588fb4d8502Sjsg 15891bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 15901bb76ff1Sjsg case 4: 15911bb76ff1Sjsg default: 15921bb76ff1Sjsg return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0; 15931bb76ff1Sjsg break; 15941bb76ff1Sjsg case 5: 15951bb76ff1Sjsg return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0; 15961bb76ff1Sjsg break; 15971bb76ff1Sjsg } 15981bb76ff1Sjsg 15991bb76ff1Sjsg return false; 1600fb4d8502Sjsg } 1601fb4d8502Sjsg 1602fb4d8502Sjsg static uint32_t bios_parser_get_ss_entry_number( 1603fb4d8502Sjsg struct dc_bios *dcb, 1604fb4d8502Sjsg enum as_signal_type signal) 1605fb4d8502Sjsg { 1606fb4d8502Sjsg /* TODO: DAL2 atomfirmware implementation does not need this. 1607fb4d8502Sjsg * why DAL3 need this? 1608fb4d8502Sjsg */ 1609fb4d8502Sjsg return 1; 1610fb4d8502Sjsg } 1611fb4d8502Sjsg 1612fb4d8502Sjsg static enum bp_result bios_parser_transmitter_control( 1613fb4d8502Sjsg struct dc_bios *dcb, 1614fb4d8502Sjsg struct bp_transmitter_control *cntl) 1615fb4d8502Sjsg { 1616fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1617fb4d8502Sjsg 1618fb4d8502Sjsg if (!bp->cmd_tbl.transmitter_control) 1619fb4d8502Sjsg return BP_RESULT_FAILURE; 1620fb4d8502Sjsg 1621fb4d8502Sjsg return bp->cmd_tbl.transmitter_control(bp, cntl); 1622fb4d8502Sjsg } 1623fb4d8502Sjsg 1624fb4d8502Sjsg static enum bp_result bios_parser_encoder_control( 1625fb4d8502Sjsg struct dc_bios *dcb, 1626fb4d8502Sjsg struct bp_encoder_control *cntl) 1627fb4d8502Sjsg { 1628fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1629fb4d8502Sjsg 1630fb4d8502Sjsg if (!bp->cmd_tbl.dig_encoder_control) 1631fb4d8502Sjsg return BP_RESULT_FAILURE; 1632fb4d8502Sjsg 1633fb4d8502Sjsg return bp->cmd_tbl.dig_encoder_control(bp, cntl); 1634fb4d8502Sjsg } 1635fb4d8502Sjsg 1636fb4d8502Sjsg static enum bp_result bios_parser_set_pixel_clock( 1637fb4d8502Sjsg struct dc_bios *dcb, 1638fb4d8502Sjsg struct bp_pixel_clock_parameters *bp_params) 1639fb4d8502Sjsg { 1640fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1641fb4d8502Sjsg 1642fb4d8502Sjsg if (!bp->cmd_tbl.set_pixel_clock) 1643fb4d8502Sjsg return BP_RESULT_FAILURE; 1644fb4d8502Sjsg 1645fb4d8502Sjsg return bp->cmd_tbl.set_pixel_clock(bp, bp_params); 1646fb4d8502Sjsg } 1647fb4d8502Sjsg 1648fb4d8502Sjsg static enum bp_result bios_parser_set_dce_clock( 1649fb4d8502Sjsg struct dc_bios *dcb, 1650fb4d8502Sjsg struct bp_set_dce_clock_parameters *bp_params) 1651fb4d8502Sjsg { 1652fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1653fb4d8502Sjsg 1654fb4d8502Sjsg if (!bp->cmd_tbl.set_dce_clock) 1655fb4d8502Sjsg return BP_RESULT_FAILURE; 1656fb4d8502Sjsg 1657fb4d8502Sjsg return bp->cmd_tbl.set_dce_clock(bp, bp_params); 1658fb4d8502Sjsg } 1659fb4d8502Sjsg 1660fb4d8502Sjsg static enum bp_result bios_parser_program_crtc_timing( 1661fb4d8502Sjsg struct dc_bios *dcb, 1662fb4d8502Sjsg struct bp_hw_crtc_timing_parameters *bp_params) 1663fb4d8502Sjsg { 1664fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1665fb4d8502Sjsg 1666fb4d8502Sjsg if (!bp->cmd_tbl.set_crtc_timing) 1667fb4d8502Sjsg return BP_RESULT_FAILURE; 1668fb4d8502Sjsg 1669fb4d8502Sjsg return bp->cmd_tbl.set_crtc_timing(bp, bp_params); 1670fb4d8502Sjsg } 1671fb4d8502Sjsg 1672fb4d8502Sjsg static enum bp_result bios_parser_enable_crtc( 1673fb4d8502Sjsg struct dc_bios *dcb, 1674fb4d8502Sjsg enum controller_id id, 1675fb4d8502Sjsg bool enable) 1676fb4d8502Sjsg { 1677fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1678fb4d8502Sjsg 1679fb4d8502Sjsg if (!bp->cmd_tbl.enable_crtc) 1680fb4d8502Sjsg return BP_RESULT_FAILURE; 1681fb4d8502Sjsg 1682fb4d8502Sjsg return bp->cmd_tbl.enable_crtc(bp, id, enable); 1683fb4d8502Sjsg } 1684fb4d8502Sjsg 1685fb4d8502Sjsg static enum bp_result bios_parser_enable_disp_power_gating( 1686fb4d8502Sjsg struct dc_bios *dcb, 1687fb4d8502Sjsg enum controller_id controller_id, 1688fb4d8502Sjsg enum bp_pipe_control_action action) 1689fb4d8502Sjsg { 1690fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1691fb4d8502Sjsg 1692fb4d8502Sjsg if (!bp->cmd_tbl.enable_disp_power_gating) 1693fb4d8502Sjsg return BP_RESULT_FAILURE; 1694fb4d8502Sjsg 1695fb4d8502Sjsg return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id, 1696fb4d8502Sjsg action); 1697fb4d8502Sjsg } 1698fb4d8502Sjsg 1699ad8b1aafSjsg static enum bp_result bios_parser_enable_lvtma_control( 1700ad8b1aafSjsg struct dc_bios *dcb, 17015ca02815Sjsg uint8_t uc_pwr_on, 1702c1e59e83Sjsg uint8_t pwrseq_instance, 1703f005ef32Sjsg uint8_t bypass_panel_control_wait) 1704ad8b1aafSjsg { 1705ad8b1aafSjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1706ad8b1aafSjsg 1707ad8b1aafSjsg if (!bp->cmd_tbl.enable_lvtma_control) 1708ad8b1aafSjsg return BP_RESULT_FAILURE; 1709ad8b1aafSjsg 1710c1e59e83Sjsg return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, pwrseq_instance, bypass_panel_control_wait); 1711ad8b1aafSjsg } 1712ad8b1aafSjsg 1713fb4d8502Sjsg static bool bios_parser_is_accelerated_mode( 1714fb4d8502Sjsg struct dc_bios *dcb) 1715fb4d8502Sjsg { 1716fb4d8502Sjsg return bios_is_accelerated_mode(dcb); 1717fb4d8502Sjsg } 1718fb4d8502Sjsg 1719fb4d8502Sjsg /** 17205ca02815Sjsg * bios_parser_set_scratch_critical_state - update critical state bit 17215ca02815Sjsg * in VBIOS scratch register 1722fb4d8502Sjsg * 17235ca02815Sjsg * @dcb: pointer to the DC BIO 17245ca02815Sjsg * @state: set or reset state 1725fb4d8502Sjsg */ 1726fb4d8502Sjsg static void bios_parser_set_scratch_critical_state( 1727fb4d8502Sjsg struct dc_bios *dcb, 1728fb4d8502Sjsg bool state) 1729fb4d8502Sjsg { 1730fb4d8502Sjsg bios_set_scratch_critical_state(dcb, state); 1731fb4d8502Sjsg } 1732fb4d8502Sjsg 17331bb76ff1Sjsg struct atom_dig_transmitter_info_header_v5_3 { 17341bb76ff1Sjsg struct atom_common_table_header table_header; 17351bb76ff1Sjsg uint16_t dpphy_hdmi_settings_offset; 17361bb76ff1Sjsg uint16_t dpphy_dvi_settings_offset; 17371bb76ff1Sjsg uint16_t dpphy_dp_setting_table_offset; 17381bb76ff1Sjsg uint16_t uniphy_xbar_settings_v2_table_offset; 17391bb76ff1Sjsg uint16_t dpphy_internal_reg_overide_offset; 17401bb76ff1Sjsg }; 17411bb76ff1Sjsg 1742fb4d8502Sjsg static enum bp_result bios_parser_get_firmware_info( 1743fb4d8502Sjsg struct dc_bios *dcb, 1744fb4d8502Sjsg struct dc_firmware_info *info) 1745fb4d8502Sjsg { 1746fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 17471bb76ff1Sjsg static enum bp_result result = BP_RESULT_BADBIOSTABLE; 1748fb4d8502Sjsg struct atom_common_table_header *header; 1749fb4d8502Sjsg 1750fb4d8502Sjsg struct atom_data_revision revision; 1751fb4d8502Sjsg 1752fb4d8502Sjsg if (info && DATA_TABLES(firmwareinfo)) { 1753fb4d8502Sjsg header = GET_IMAGE(struct atom_common_table_header, 1754fb4d8502Sjsg DATA_TABLES(firmwareinfo)); 1755fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 1756fb4d8502Sjsg switch (revision.major) { 1757fb4d8502Sjsg case 3: 1758fb4d8502Sjsg switch (revision.minor) { 1759fb4d8502Sjsg case 1: 1760fb4d8502Sjsg result = get_firmware_info_v3_1(bp, info); 1761fb4d8502Sjsg break; 1762fb4d8502Sjsg case 2: 1763fb4d8502Sjsg case 3: 1764fb4d8502Sjsg result = get_firmware_info_v3_2(bp, info); 1765fb4d8502Sjsg break; 17661bb76ff1Sjsg case 4: 17671bb76ff1Sjsg result = get_firmware_info_v3_4(bp, info); 17681bb76ff1Sjsg break; 1769fb4d8502Sjsg default: 1770fb4d8502Sjsg break; 1771fb4d8502Sjsg } 1772fb4d8502Sjsg break; 1773fb4d8502Sjsg default: 1774fb4d8502Sjsg break; 1775fb4d8502Sjsg } 1776fb4d8502Sjsg } 1777fb4d8502Sjsg 1778fb4d8502Sjsg return result; 1779fb4d8502Sjsg } 1780fb4d8502Sjsg 1781fb4d8502Sjsg static enum bp_result get_firmware_info_v3_1( 1782fb4d8502Sjsg struct bios_parser *bp, 1783fb4d8502Sjsg struct dc_firmware_info *info) 1784fb4d8502Sjsg { 1785fb4d8502Sjsg struct atom_firmware_info_v3_1 *firmware_info; 1786fb4d8502Sjsg struct atom_display_controller_info_v4_1 *dce_info = NULL; 1787fb4d8502Sjsg 1788fb4d8502Sjsg if (!info) 1789fb4d8502Sjsg return BP_RESULT_BADINPUT; 1790fb4d8502Sjsg 1791fb4d8502Sjsg firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1, 1792fb4d8502Sjsg DATA_TABLES(firmwareinfo)); 1793fb4d8502Sjsg 1794fb4d8502Sjsg dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1795fb4d8502Sjsg DATA_TABLES(dce_info)); 1796fb4d8502Sjsg 1797fb4d8502Sjsg if (!firmware_info || !dce_info) 1798fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1799fb4d8502Sjsg 1800fb4d8502Sjsg memset(info, 0, sizeof(*info)); 1801fb4d8502Sjsg 1802fb4d8502Sjsg /* Pixel clock pll information. */ 1803fb4d8502Sjsg /* We need to convert from 10KHz units into KHz units */ 1804fb4d8502Sjsg info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1805fb4d8502Sjsg info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10; 1806fb4d8502Sjsg 1807fb4d8502Sjsg /* 27MHz for Vega10: */ 1808fb4d8502Sjsg info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1809fb4d8502Sjsg 1810fb4d8502Sjsg /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1811fb4d8502Sjsg if (info->pll_info.crystal_frequency == 0) 1812fb4d8502Sjsg info->pll_info.crystal_frequency = 27000; 1813fb4d8502Sjsg /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1814fb4d8502Sjsg info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1815fb4d8502Sjsg info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1816fb4d8502Sjsg 1817fb4d8502Sjsg /* Get GPU PLL VCO Clock */ 1818fb4d8502Sjsg 1819fb4d8502Sjsg if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1820fb4d8502Sjsg /* VBIOS gives in 10KHz */ 1821fb4d8502Sjsg info->smu_gpu_pll_output_freq = 1822fb4d8502Sjsg bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1823fb4d8502Sjsg } 1824fb4d8502Sjsg 1825c349dbc7Sjsg info->oem_i2c_present = false; 1826c349dbc7Sjsg 1827fb4d8502Sjsg return BP_RESULT_OK; 1828fb4d8502Sjsg } 1829fb4d8502Sjsg 1830fb4d8502Sjsg static enum bp_result get_firmware_info_v3_2( 1831fb4d8502Sjsg struct bios_parser *bp, 1832fb4d8502Sjsg struct dc_firmware_info *info) 1833fb4d8502Sjsg { 1834fb4d8502Sjsg struct atom_firmware_info_v3_2 *firmware_info; 1835fb4d8502Sjsg struct atom_display_controller_info_v4_1 *dce_info = NULL; 1836fb4d8502Sjsg struct atom_common_table_header *header; 1837fb4d8502Sjsg struct atom_data_revision revision; 1838fb4d8502Sjsg struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL; 1839fb4d8502Sjsg struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL; 1840fb4d8502Sjsg 1841fb4d8502Sjsg if (!info) 1842fb4d8502Sjsg return BP_RESULT_BADINPUT; 1843fb4d8502Sjsg 1844fb4d8502Sjsg firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2, 1845fb4d8502Sjsg DATA_TABLES(firmwareinfo)); 1846fb4d8502Sjsg 1847fb4d8502Sjsg dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1848fb4d8502Sjsg DATA_TABLES(dce_info)); 1849fb4d8502Sjsg 1850fb4d8502Sjsg if (!firmware_info || !dce_info) 1851fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1852fb4d8502Sjsg 1853fb4d8502Sjsg memset(info, 0, sizeof(*info)); 1854fb4d8502Sjsg 1855fb4d8502Sjsg header = GET_IMAGE(struct atom_common_table_header, 1856fb4d8502Sjsg DATA_TABLES(smu_info)); 1857fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 1858fb4d8502Sjsg 1859fb4d8502Sjsg if (revision.minor == 2) { 1860fb4d8502Sjsg /* Vega12 */ 1861fb4d8502Sjsg smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2, 1862fb4d8502Sjsg DATA_TABLES(smu_info)); 1863fb4d8502Sjsg if (!smu_info_v3_2) 1864fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1865fb4d8502Sjsg 1866a8749599Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_2->gpuclk_ss_percentage); 1867a8749599Sjsg 1868fb4d8502Sjsg info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10; 1869fb4d8502Sjsg } else if (revision.minor == 3) { 1870fb4d8502Sjsg /* Vega20 */ 1871fb4d8502Sjsg smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3, 1872fb4d8502Sjsg DATA_TABLES(smu_info)); 1873fb4d8502Sjsg if (!smu_info_v3_3) 1874fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1875fb4d8502Sjsg 1876a8749599Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_3->gpuclk_ss_percentage); 1877a8749599Sjsg 1878fb4d8502Sjsg info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10; 1879fb4d8502Sjsg } 1880fb4d8502Sjsg 1881fb4d8502Sjsg // We need to convert from 10KHz units into KHz units. 1882fb4d8502Sjsg info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1883fb4d8502Sjsg 1884fb4d8502Sjsg /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */ 1885fb4d8502Sjsg info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1886fb4d8502Sjsg /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1887fb4d8502Sjsg if (info->pll_info.crystal_frequency == 0) { 1888fb4d8502Sjsg if (revision.minor == 2) 1889fb4d8502Sjsg info->pll_info.crystal_frequency = 27000; 1890fb4d8502Sjsg else if (revision.minor == 3) 1891fb4d8502Sjsg info->pll_info.crystal_frequency = 100000; 1892fb4d8502Sjsg } 1893fb4d8502Sjsg /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1894fb4d8502Sjsg info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1895fb4d8502Sjsg info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1896fb4d8502Sjsg 1897fb4d8502Sjsg /* Get GPU PLL VCO Clock */ 1898fb4d8502Sjsg if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1899fb4d8502Sjsg if (revision.minor == 2) 1900fb4d8502Sjsg info->smu_gpu_pll_output_freq = 1901fb4d8502Sjsg bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1902fb4d8502Sjsg else if (revision.minor == 3) 1903fb4d8502Sjsg info->smu_gpu_pll_output_freq = 1904fb4d8502Sjsg bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10; 1905fb4d8502Sjsg } 1906fb4d8502Sjsg 1907c349dbc7Sjsg if (firmware_info->board_i2c_feature_id == 0x2) { 1908c349dbc7Sjsg info->oem_i2c_present = true; 1909c349dbc7Sjsg info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; 1910c349dbc7Sjsg } else { 1911c349dbc7Sjsg info->oem_i2c_present = false; 1912c349dbc7Sjsg } 1913c349dbc7Sjsg 1914fb4d8502Sjsg return BP_RESULT_OK; 1915fb4d8502Sjsg } 1916fb4d8502Sjsg 19171bb76ff1Sjsg static enum bp_result get_firmware_info_v3_4( 19181bb76ff1Sjsg struct bios_parser *bp, 19191bb76ff1Sjsg struct dc_firmware_info *info) 19201bb76ff1Sjsg { 19211bb76ff1Sjsg struct atom_firmware_info_v3_4 *firmware_info; 19221bb76ff1Sjsg struct atom_common_table_header *header; 19231bb76ff1Sjsg struct atom_data_revision revision; 19241bb76ff1Sjsg struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL; 19251bb76ff1Sjsg struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL; 19261bb76ff1Sjsg 19271bb76ff1Sjsg struct atom_smu_info_v3_5 *smu_info_v3_5 = NULL; 19281bb76ff1Sjsg struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL; 19291bb76ff1Sjsg struct atom_smu_info_v4_0 *smu_info_v4_0 = NULL; 19301bb76ff1Sjsg 19311bb76ff1Sjsg if (!info) 19321bb76ff1Sjsg return BP_RESULT_BADINPUT; 19331bb76ff1Sjsg 19341bb76ff1Sjsg firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4, 19351bb76ff1Sjsg DATA_TABLES(firmwareinfo)); 19361bb76ff1Sjsg 19371bb76ff1Sjsg if (!firmware_info) 19381bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 19391bb76ff1Sjsg 19401bb76ff1Sjsg memset(info, 0, sizeof(*info)); 19411bb76ff1Sjsg 19421bb76ff1Sjsg header = GET_IMAGE(struct atom_common_table_header, 19431bb76ff1Sjsg DATA_TABLES(dce_info)); 19441bb76ff1Sjsg 19451bb76ff1Sjsg get_atom_data_table_revision(header, &revision); 19461bb76ff1Sjsg 19471bb76ff1Sjsg switch (revision.major) { 19481bb76ff1Sjsg case 4: 19491bb76ff1Sjsg switch (revision.minor) { 19501bb76ff1Sjsg case 5: 19511bb76ff1Sjsg dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5, 19521bb76ff1Sjsg DATA_TABLES(dce_info)); 19531bb76ff1Sjsg 19541bb76ff1Sjsg if (!dce_info_v4_5) 19551bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 19561bb76ff1Sjsg 19571bb76ff1Sjsg /* 100MHz expected */ 19581bb76ff1Sjsg info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10; 19591bb76ff1Sjsg info->dp_phy_ref_clk = dce_info_v4_5->dpphy_refclk_10khz * 10; 19601bb76ff1Sjsg /* 50MHz expected */ 19611bb76ff1Sjsg info->i2c_engine_ref_clk = dce_info_v4_5->i2c_engine_refclk_10khz * 10; 19621bb76ff1Sjsg 19631bb76ff1Sjsg /* For DCN32/321 Display PLL VCO Frequency from dce_info_v4_5 may not be reliable */ 19641bb76ff1Sjsg break; 19651bb76ff1Sjsg 19661bb76ff1Sjsg case 4: 19671bb76ff1Sjsg dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, 19681bb76ff1Sjsg DATA_TABLES(dce_info)); 19691bb76ff1Sjsg 19701bb76ff1Sjsg if (!dce_info_v4_4) 19711bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 19721bb76ff1Sjsg 19731bb76ff1Sjsg /* 100MHz expected */ 19741bb76ff1Sjsg info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10; 19751bb76ff1Sjsg info->dp_phy_ref_clk = dce_info_v4_4->dpphy_refclk_10khz * 10; 19761bb76ff1Sjsg /* 50MHz expected */ 19771bb76ff1Sjsg info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10; 19781bb76ff1Sjsg 19791bb76ff1Sjsg /* Get SMU Display PLL VCO Frequency in KHz*/ 19801bb76ff1Sjsg info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10; 19811bb76ff1Sjsg break; 19821bb76ff1Sjsg 19831bb76ff1Sjsg default: 19841bb76ff1Sjsg /* should not come here, keep as backup, as was before */ 19851bb76ff1Sjsg dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1, 19861bb76ff1Sjsg DATA_TABLES(dce_info)); 19871bb76ff1Sjsg 19881bb76ff1Sjsg if (!dce_info_v4_1) 19891bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 19901bb76ff1Sjsg 19911bb76ff1Sjsg info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10; 19921bb76ff1Sjsg info->dp_phy_ref_clk = dce_info_v4_1->dpphy_refclk_10khz * 10; 19931bb76ff1Sjsg info->i2c_engine_ref_clk = dce_info_v4_1->i2c_engine_refclk_10khz * 10; 19941bb76ff1Sjsg break; 19951bb76ff1Sjsg } 19961bb76ff1Sjsg break; 19971bb76ff1Sjsg 19981bb76ff1Sjsg default: 19991bb76ff1Sjsg ASSERT(0); 20001bb76ff1Sjsg break; 20011bb76ff1Sjsg } 20021bb76ff1Sjsg 20031bb76ff1Sjsg header = GET_IMAGE(struct atom_common_table_header, 20041bb76ff1Sjsg DATA_TABLES(smu_info)); 20051bb76ff1Sjsg get_atom_data_table_revision(header, &revision); 20061bb76ff1Sjsg 20071bb76ff1Sjsg switch (revision.major) { 20081bb76ff1Sjsg case 3: 20091bb76ff1Sjsg switch (revision.minor) { 20101bb76ff1Sjsg case 5: 20111bb76ff1Sjsg smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5, 20121bb76ff1Sjsg DATA_TABLES(smu_info)); 20131bb76ff1Sjsg 20141bb76ff1Sjsg if (!smu_info_v3_5) 20151bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 20161bb76ff1Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_5->gpuclk_ss_percentage); 20171bb76ff1Sjsg info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10; 20181bb76ff1Sjsg break; 20191bb76ff1Sjsg 20201bb76ff1Sjsg default: 20211bb76ff1Sjsg break; 20221bb76ff1Sjsg } 20231bb76ff1Sjsg break; 20241bb76ff1Sjsg 20251bb76ff1Sjsg case 4: 20261bb76ff1Sjsg switch (revision.minor) { 20271bb76ff1Sjsg case 0: 20281bb76ff1Sjsg smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0, 20291bb76ff1Sjsg DATA_TABLES(smu_info)); 20301bb76ff1Sjsg 20311bb76ff1Sjsg if (!smu_info_v4_0) 20321bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 20331bb76ff1Sjsg 20341bb76ff1Sjsg /* For DCN32/321 bootup DCFCLK from smu_info_v4_0 may not be reliable */ 20351bb76ff1Sjsg break; 20361bb76ff1Sjsg 20371bb76ff1Sjsg default: 20381bb76ff1Sjsg break; 20391bb76ff1Sjsg } 20401bb76ff1Sjsg break; 20411bb76ff1Sjsg 20421bb76ff1Sjsg default: 20431bb76ff1Sjsg break; 20441bb76ff1Sjsg } 20451bb76ff1Sjsg 20461bb76ff1Sjsg // We need to convert from 10KHz units into KHz units. 20471bb76ff1Sjsg info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 20481bb76ff1Sjsg 20491bb76ff1Sjsg if (firmware_info->board_i2c_feature_id == 0x2) { 20501bb76ff1Sjsg info->oem_i2c_present = true; 20511bb76ff1Sjsg info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; 20521bb76ff1Sjsg } else { 20531bb76ff1Sjsg info->oem_i2c_present = false; 20541bb76ff1Sjsg } 20551bb76ff1Sjsg 20561bb76ff1Sjsg return BP_RESULT_OK; 20571bb76ff1Sjsg } 20581bb76ff1Sjsg 2059fb4d8502Sjsg static enum bp_result bios_parser_get_encoder_cap_info( 2060fb4d8502Sjsg struct dc_bios *dcb, 2061fb4d8502Sjsg struct graphics_object_id object_id, 2062fb4d8502Sjsg struct bp_encoder_cap_info *info) 2063fb4d8502Sjsg { 2064fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 2065fb4d8502Sjsg struct atom_display_object_path_v2 *object; 2066fb4d8502Sjsg struct atom_encoder_caps_record *record = NULL; 2067fb4d8502Sjsg 2068fb4d8502Sjsg if (!info) 2069fb4d8502Sjsg return BP_RESULT_BADINPUT; 2070fb4d8502Sjsg 2071f005ef32Sjsg #if defined(CONFIG_DRM_AMD_DC_FP) 20721bb76ff1Sjsg /* encoder cap record not available in v1_5 */ 20731bb76ff1Sjsg if (bp->object_info_tbl.revision.minor == 5) 20741bb76ff1Sjsg return BP_RESULT_NORECORD; 20751bb76ff1Sjsg #endif 20761bb76ff1Sjsg 2077fb4d8502Sjsg object = get_bios_object(bp, object_id); 2078fb4d8502Sjsg 2079fb4d8502Sjsg if (!object) 2080fb4d8502Sjsg return BP_RESULT_BADINPUT; 2081fb4d8502Sjsg 2082fb4d8502Sjsg record = get_encoder_cap_record(bp, object); 2083fb4d8502Sjsg if (!record) 2084fb4d8502Sjsg return BP_RESULT_NORECORD; 20851bb76ff1Sjsg DC_LOG_BIOS("record->encodercaps 0x%x for object_id 0x%x", record->encodercaps, object_id.id); 2086fb4d8502Sjsg 2087fb4d8502Sjsg info->DP_HBR2_CAP = (record->encodercaps & 2088fb4d8502Sjsg ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0; 2089fb4d8502Sjsg info->DP_HBR2_EN = (record->encodercaps & 2090fb4d8502Sjsg ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0; 2091fb4d8502Sjsg info->DP_HBR3_EN = (record->encodercaps & 2092fb4d8502Sjsg ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; 2093fb4d8502Sjsg info->HDMI_6GB_EN = (record->encodercaps & 2094fb4d8502Sjsg ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; 20951bb76ff1Sjsg info->IS_DP2_CAPABLE = (record->encodercaps & 20961bb76ff1Sjsg ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0; 20971bb76ff1Sjsg info->DP_UHBR10_EN = (record->encodercaps & 20981bb76ff1Sjsg ATOM_ENCODER_CAP_RECORD_UHBR10_EN) ? 1 : 0; 20991bb76ff1Sjsg info->DP_UHBR13_5_EN = (record->encodercaps & 21001bb76ff1Sjsg ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0; 21011bb76ff1Sjsg info->DP_UHBR20_EN = (record->encodercaps & 21021bb76ff1Sjsg ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0; 2103c349dbc7Sjsg info->DP_IS_USB_C = (record->encodercaps & 2104c349dbc7Sjsg ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0; 21051bb76ff1Sjsg DC_LOG_BIOS("\t info->DP_IS_USB_C %d", info->DP_IS_USB_C); 2106fb4d8502Sjsg 2107fb4d8502Sjsg return BP_RESULT_OK; 2108fb4d8502Sjsg } 2109fb4d8502Sjsg 2110fb4d8502Sjsg 2111fb4d8502Sjsg static struct atom_encoder_caps_record *get_encoder_cap_record( 2112fb4d8502Sjsg struct bios_parser *bp, 2113fb4d8502Sjsg struct atom_display_object_path_v2 *object) 2114fb4d8502Sjsg { 2115fb4d8502Sjsg struct atom_common_record_header *header; 2116fb4d8502Sjsg uint32_t offset; 2117fb4d8502Sjsg 2118fb4d8502Sjsg if (!object) { 2119fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 2120fb4d8502Sjsg return NULL; 2121fb4d8502Sjsg } 2122fb4d8502Sjsg 2123fb4d8502Sjsg offset = object->encoder_recordoffset + bp->object_info_tbl_offset; 2124fb4d8502Sjsg 2125fb4d8502Sjsg for (;;) { 2126fb4d8502Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 2127fb4d8502Sjsg 2128fb4d8502Sjsg if (!header) 2129fb4d8502Sjsg return NULL; 2130fb4d8502Sjsg 2131fb4d8502Sjsg offset += header->record_size; 2132fb4d8502Sjsg 2133fb4d8502Sjsg if (header->record_type == LAST_RECORD_TYPE || 2134fb4d8502Sjsg !header->record_size) 2135fb4d8502Sjsg break; 2136fb4d8502Sjsg 2137fb4d8502Sjsg if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE) 2138fb4d8502Sjsg continue; 2139fb4d8502Sjsg 2140fb4d8502Sjsg if (sizeof(struct atom_encoder_caps_record) <= 2141fb4d8502Sjsg header->record_size) 2142fb4d8502Sjsg return (struct atom_encoder_caps_record *)header; 2143fb4d8502Sjsg } 2144fb4d8502Sjsg 2145fb4d8502Sjsg return NULL; 2146fb4d8502Sjsg } 2147fb4d8502Sjsg 21485ca02815Sjsg static struct atom_disp_connector_caps_record *get_disp_connector_caps_record( 21495ca02815Sjsg struct bios_parser *bp, 21505ca02815Sjsg struct atom_display_object_path_v2 *object) 21515ca02815Sjsg { 21525ca02815Sjsg struct atom_common_record_header *header; 21535ca02815Sjsg uint32_t offset; 21545ca02815Sjsg 21555ca02815Sjsg if (!object) { 21565ca02815Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 21575ca02815Sjsg return NULL; 21585ca02815Sjsg } 21595ca02815Sjsg 21605ca02815Sjsg offset = object->disp_recordoffset + bp->object_info_tbl_offset; 21615ca02815Sjsg 21625ca02815Sjsg for (;;) { 21635ca02815Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 21645ca02815Sjsg 21655ca02815Sjsg if (!header) 21665ca02815Sjsg return NULL; 21675ca02815Sjsg 21685ca02815Sjsg offset += header->record_size; 21695ca02815Sjsg 21705ca02815Sjsg if (header->record_type == LAST_RECORD_TYPE || 21715ca02815Sjsg !header->record_size) 21725ca02815Sjsg break; 21735ca02815Sjsg 21745ca02815Sjsg if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE) 21755ca02815Sjsg continue; 21765ca02815Sjsg 21775ca02815Sjsg if (sizeof(struct atom_disp_connector_caps_record) <= 21785ca02815Sjsg header->record_size) 21795ca02815Sjsg return (struct atom_disp_connector_caps_record *)header; 21805ca02815Sjsg } 21815ca02815Sjsg 21825ca02815Sjsg return NULL; 21835ca02815Sjsg } 21845ca02815Sjsg 2185f005ef32Sjsg static struct atom_connector_caps_record *get_connector_caps_record(struct bios_parser *bp, 21861bb76ff1Sjsg struct atom_display_object_path_v3 *object) 21871bb76ff1Sjsg { 21881bb76ff1Sjsg struct atom_common_record_header *header; 21891bb76ff1Sjsg uint32_t offset; 21901bb76ff1Sjsg 21911bb76ff1Sjsg if (!object) { 21921bb76ff1Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 21931bb76ff1Sjsg return NULL; 21941bb76ff1Sjsg } 21951bb76ff1Sjsg 21961bb76ff1Sjsg offset = object->disp_recordoffset + bp->object_info_tbl_offset; 21971bb76ff1Sjsg 21981bb76ff1Sjsg for (;;) { 21991bb76ff1Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 22001bb76ff1Sjsg 22011bb76ff1Sjsg if (!header) 22021bb76ff1Sjsg return NULL; 22031bb76ff1Sjsg 22041bb76ff1Sjsg offset += header->record_size; 22051bb76ff1Sjsg 22061bb76ff1Sjsg if (header->record_type == ATOM_RECORD_END_TYPE || 22071bb76ff1Sjsg !header->record_size) 22081bb76ff1Sjsg break; 22091bb76ff1Sjsg 22101bb76ff1Sjsg if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE) 22111bb76ff1Sjsg continue; 22121bb76ff1Sjsg 22131bb76ff1Sjsg if (sizeof(struct atom_connector_caps_record) <= header->record_size) 22141bb76ff1Sjsg return (struct atom_connector_caps_record *)header; 22151bb76ff1Sjsg } 22161bb76ff1Sjsg 22171bb76ff1Sjsg return NULL; 22181bb76ff1Sjsg } 22191bb76ff1Sjsg 22205ca02815Sjsg static enum bp_result bios_parser_get_disp_connector_caps_info( 22215ca02815Sjsg struct dc_bios *dcb, 22225ca02815Sjsg struct graphics_object_id object_id, 22235ca02815Sjsg struct bp_disp_connector_caps_info *info) 22245ca02815Sjsg { 22255ca02815Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 22265ca02815Sjsg struct atom_display_object_path_v2 *object; 22271bb76ff1Sjsg 22281bb76ff1Sjsg struct atom_display_object_path_v3 *object_path_v3; 22291bb76ff1Sjsg struct atom_connector_caps_record *record_path_v3; 22301bb76ff1Sjsg 22315ca02815Sjsg struct atom_disp_connector_caps_record *record = NULL; 22325ca02815Sjsg 22335ca02815Sjsg if (!info) 22345ca02815Sjsg return BP_RESULT_BADINPUT; 22355ca02815Sjsg 22361bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 22371bb76ff1Sjsg case 4: 22381bb76ff1Sjsg default: 22395ca02815Sjsg object = get_bios_object(bp, object_id); 22405ca02815Sjsg 22415ca02815Sjsg if (!object) 22425ca02815Sjsg return BP_RESULT_BADINPUT; 22435ca02815Sjsg 22445ca02815Sjsg record = get_disp_connector_caps_record(bp, object); 22455ca02815Sjsg if (!record) 22465ca02815Sjsg return BP_RESULT_NORECORD; 22475ca02815Sjsg 22481bb76ff1Sjsg info->INTERNAL_DISPLAY = 22491bb76ff1Sjsg (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) ? 1 : 0; 22501bb76ff1Sjsg info->INTERNAL_DISPLAY_BL = 22511bb76ff1Sjsg (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) ? 1 : 0; 22521bb76ff1Sjsg break; 22531bb76ff1Sjsg case 5: 22541bb76ff1Sjsg object_path_v3 = get_bios_object_from_path_v3(bp, object_id); 22555ca02815Sjsg 22561bb76ff1Sjsg if (!object_path_v3) 22571bb76ff1Sjsg return BP_RESULT_BADINPUT; 22581bb76ff1Sjsg 22591bb76ff1Sjsg record_path_v3 = get_connector_caps_record(bp, object_path_v3); 22601bb76ff1Sjsg if (!record_path_v3) 22611bb76ff1Sjsg return BP_RESULT_NORECORD; 22621bb76ff1Sjsg 22631bb76ff1Sjsg info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) 22641bb76ff1Sjsg ? 1 : 0; 22651bb76ff1Sjsg info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) 22661bb76ff1Sjsg ? 1 : 0; 22671bb76ff1Sjsg break; 22681bb76ff1Sjsg } 22691bb76ff1Sjsg 22701bb76ff1Sjsg return BP_RESULT_OK; 22711bb76ff1Sjsg } 22721bb76ff1Sjsg 2273f005ef32Sjsg static struct atom_connector_speed_record *get_connector_speed_cap_record(struct bios_parser *bp, 22741bb76ff1Sjsg struct atom_display_object_path_v3 *object) 22751bb76ff1Sjsg { 22761bb76ff1Sjsg struct atom_common_record_header *header; 22771bb76ff1Sjsg uint32_t offset; 22781bb76ff1Sjsg 22791bb76ff1Sjsg if (!object) { 22801bb76ff1Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 22811bb76ff1Sjsg return NULL; 22821bb76ff1Sjsg } 22831bb76ff1Sjsg 22841bb76ff1Sjsg offset = object->disp_recordoffset + bp->object_info_tbl_offset; 22851bb76ff1Sjsg 22861bb76ff1Sjsg for (;;) { 22871bb76ff1Sjsg header = GET_IMAGE(struct atom_common_record_header, offset); 22881bb76ff1Sjsg 22891bb76ff1Sjsg if (!header) 22901bb76ff1Sjsg return NULL; 22911bb76ff1Sjsg 22921bb76ff1Sjsg offset += header->record_size; 22931bb76ff1Sjsg 22941bb76ff1Sjsg if (header->record_type == ATOM_RECORD_END_TYPE || 22951bb76ff1Sjsg !header->record_size) 22961bb76ff1Sjsg break; 22971bb76ff1Sjsg 22981bb76ff1Sjsg if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO) 22991bb76ff1Sjsg continue; 23001bb76ff1Sjsg 23011bb76ff1Sjsg if (sizeof(struct atom_connector_speed_record) <= header->record_size) 23021bb76ff1Sjsg return (struct atom_connector_speed_record *)header; 23031bb76ff1Sjsg } 23041bb76ff1Sjsg 23051bb76ff1Sjsg return NULL; 23061bb76ff1Sjsg } 23071bb76ff1Sjsg 23081bb76ff1Sjsg static enum bp_result bios_parser_get_connector_speed_cap_info( 23091bb76ff1Sjsg struct dc_bios *dcb, 23101bb76ff1Sjsg struct graphics_object_id object_id, 23111bb76ff1Sjsg struct bp_connector_speed_cap_info *info) 23121bb76ff1Sjsg { 23131bb76ff1Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 23141bb76ff1Sjsg struct atom_display_object_path_v3 *object_path_v3; 23151bb76ff1Sjsg //struct atom_connector_speed_record *record = NULL; 23161bb76ff1Sjsg struct atom_connector_speed_record *record; 23171bb76ff1Sjsg 23181bb76ff1Sjsg if (!info) 23191bb76ff1Sjsg return BP_RESULT_BADINPUT; 23201bb76ff1Sjsg 23211bb76ff1Sjsg object_path_v3 = get_bios_object_from_path_v3(bp, object_id); 23221bb76ff1Sjsg 23231bb76ff1Sjsg if (!object_path_v3) 23241bb76ff1Sjsg return BP_RESULT_BADINPUT; 23251bb76ff1Sjsg 23261bb76ff1Sjsg record = get_connector_speed_cap_record(bp, object_path_v3); 23271bb76ff1Sjsg if (!record) 23281bb76ff1Sjsg return BP_RESULT_NORECORD; 23291bb76ff1Sjsg 23301bb76ff1Sjsg info->DP_HBR2_EN = (record->connector_max_speed >= 5400) ? 1 : 0; 23311bb76ff1Sjsg info->DP_HBR3_EN = (record->connector_max_speed >= 8100) ? 1 : 0; 23321bb76ff1Sjsg info->HDMI_6GB_EN = (record->connector_max_speed >= 5940) ? 1 : 0; 23331bb76ff1Sjsg info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0; 23341bb76ff1Sjsg info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0; 23351bb76ff1Sjsg info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0; 23365ca02815Sjsg return BP_RESULT_OK; 23375ca02815Sjsg } 23385ca02815Sjsg 2339ad8b1aafSjsg static enum bp_result get_vram_info_v23( 2340ad8b1aafSjsg struct bios_parser *bp, 2341ad8b1aafSjsg struct dc_vram_info *info) 2342ad8b1aafSjsg { 2343ad8b1aafSjsg struct atom_vram_info_header_v2_3 *info_v23; 23441bb76ff1Sjsg static enum bp_result result = BP_RESULT_OK; 2345ad8b1aafSjsg 2346ad8b1aafSjsg info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3, 2347ad8b1aafSjsg DATA_TABLES(vram_info)); 2348ad8b1aafSjsg 2349ad8b1aafSjsg if (info_v23 == NULL) 2350ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 2351ad8b1aafSjsg 2352ad8b1aafSjsg info->num_chans = info_v23->vram_module[0].channel_num; 2353ad8b1aafSjsg info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8; 2354ad8b1aafSjsg 2355ad8b1aafSjsg return result; 2356ad8b1aafSjsg } 2357ad8b1aafSjsg 2358ad8b1aafSjsg static enum bp_result get_vram_info_v24( 2359ad8b1aafSjsg struct bios_parser *bp, 2360ad8b1aafSjsg struct dc_vram_info *info) 2361ad8b1aafSjsg { 2362ad8b1aafSjsg struct atom_vram_info_header_v2_4 *info_v24; 23631bb76ff1Sjsg static enum bp_result result = BP_RESULT_OK; 2364ad8b1aafSjsg 2365ad8b1aafSjsg info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4, 2366ad8b1aafSjsg DATA_TABLES(vram_info)); 2367ad8b1aafSjsg 2368ad8b1aafSjsg if (info_v24 == NULL) 2369ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 2370ad8b1aafSjsg 2371ad8b1aafSjsg info->num_chans = info_v24->vram_module[0].channel_num; 2372ad8b1aafSjsg info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8; 2373ad8b1aafSjsg 2374ad8b1aafSjsg return result; 2375ad8b1aafSjsg } 2376ad8b1aafSjsg 2377ad8b1aafSjsg static enum bp_result get_vram_info_v25( 2378ad8b1aafSjsg struct bios_parser *bp, 2379ad8b1aafSjsg struct dc_vram_info *info) 2380ad8b1aafSjsg { 2381ad8b1aafSjsg struct atom_vram_info_header_v2_5 *info_v25; 23821bb76ff1Sjsg static enum bp_result result = BP_RESULT_OK; 2383ad8b1aafSjsg 2384ad8b1aafSjsg info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5, 2385ad8b1aafSjsg DATA_TABLES(vram_info)); 2386ad8b1aafSjsg 2387ad8b1aafSjsg if (info_v25 == NULL) 2388ad8b1aafSjsg return BP_RESULT_BADBIOSTABLE; 2389ad8b1aafSjsg 2390ad8b1aafSjsg info->num_chans = info_v25->vram_module[0].channel_num; 2391ad8b1aafSjsg info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8; 2392ad8b1aafSjsg 2393ad8b1aafSjsg return result; 2394ad8b1aafSjsg } 2395ad8b1aafSjsg 23961bb76ff1Sjsg static enum bp_result get_vram_info_v30( 23971bb76ff1Sjsg struct bios_parser *bp, 23981bb76ff1Sjsg struct dc_vram_info *info) 23991bb76ff1Sjsg { 24001bb76ff1Sjsg struct atom_vram_info_header_v3_0 *info_v30; 24011bb76ff1Sjsg enum bp_result result = BP_RESULT_OK; 24021bb76ff1Sjsg 24031bb76ff1Sjsg info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0, 24041bb76ff1Sjsg DATA_TABLES(vram_info)); 24051bb76ff1Sjsg 24061bb76ff1Sjsg if (info_v30 == NULL) 24071bb76ff1Sjsg return BP_RESULT_BADBIOSTABLE; 24081bb76ff1Sjsg 24091bb76ff1Sjsg info->num_chans = info_v30->channel_num; 24101bb76ff1Sjsg info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8; 24111bb76ff1Sjsg 24121bb76ff1Sjsg return result; 24131bb76ff1Sjsg } 24141bb76ff1Sjsg 24151bb76ff1Sjsg 2416fb4d8502Sjsg /* 2417fb4d8502Sjsg * get_integrated_info_v11 2418fb4d8502Sjsg * 2419fb4d8502Sjsg * @brief 2420fb4d8502Sjsg * Get V8 integrated BIOS information 2421fb4d8502Sjsg * 2422fb4d8502Sjsg * @param 2423fb4d8502Sjsg * bios_parser *bp - [in]BIOS parser handler to get master data table 2424fb4d8502Sjsg * integrated_info *info - [out] store and output integrated info 2425fb4d8502Sjsg * 2426fb4d8502Sjsg * @return 24271bb76ff1Sjsg * static enum bp_result - BP_RESULT_OK if information is available, 2428fb4d8502Sjsg * BP_RESULT_BADBIOSTABLE otherwise. 2429fb4d8502Sjsg */ 2430fb4d8502Sjsg static enum bp_result get_integrated_info_v11( 2431fb4d8502Sjsg struct bios_parser *bp, 2432fb4d8502Sjsg struct integrated_info *info) 2433fb4d8502Sjsg { 2434fb4d8502Sjsg struct atom_integrated_system_info_v1_11 *info_v11; 2435fb4d8502Sjsg uint32_t i; 2436fb4d8502Sjsg 2437fb4d8502Sjsg info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11, 2438fb4d8502Sjsg DATA_TABLES(integratedsysteminfo)); 2439fb4d8502Sjsg 2440fb4d8502Sjsg if (info_v11 == NULL) 2441fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 2442fb4d8502Sjsg 2443a8749599Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v11->gpuclk_ss_percentage); 2444a8749599Sjsg 2445fb4d8502Sjsg info->gpu_cap_info = 2446fb4d8502Sjsg le32_to_cpu(info_v11->gpucapinfo); 2447fb4d8502Sjsg /* 2448fb4d8502Sjsg * system_config: Bit[0] = 0 : PCIE power gating disabled 2449fb4d8502Sjsg * = 1 : PCIE power gating enabled 2450fb4d8502Sjsg * Bit[1] = 0 : DDR-PLL shut down disabled 2451fb4d8502Sjsg * = 1 : DDR-PLL shut down enabled 2452fb4d8502Sjsg * Bit[2] = 0 : DDR-PLL power down disabled 2453fb4d8502Sjsg * = 1 : DDR-PLL power down enabled 2454fb4d8502Sjsg */ 2455fb4d8502Sjsg info->system_config = le32_to_cpu(info_v11->system_config); 2456fb4d8502Sjsg info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo); 2457fb4d8502Sjsg info->memory_type = info_v11->memorytype; 2458fb4d8502Sjsg info->ma_channel_number = info_v11->umachannelnumber; 2459fb4d8502Sjsg info->lvds_ss_percentage = 2460fb4d8502Sjsg le16_to_cpu(info_v11->lvds_ss_percentage); 2461c349dbc7Sjsg info->dp_ss_control = 2462c349dbc7Sjsg le16_to_cpu(info_v11->reserved1); 2463fb4d8502Sjsg info->lvds_sspread_rate_in_10hz = 2464fb4d8502Sjsg le16_to_cpu(info_v11->lvds_ss_rate_10hz); 2465fb4d8502Sjsg info->hdmi_ss_percentage = 2466fb4d8502Sjsg le16_to_cpu(info_v11->hdmi_ss_percentage); 2467fb4d8502Sjsg info->hdmi_sspread_rate_in_10hz = 2468fb4d8502Sjsg le16_to_cpu(info_v11->hdmi_ss_rate_10hz); 2469fb4d8502Sjsg info->dvi_ss_percentage = 2470fb4d8502Sjsg le16_to_cpu(info_v11->dvi_ss_percentage); 2471fb4d8502Sjsg info->dvi_sspread_rate_in_10_hz = 2472fb4d8502Sjsg le16_to_cpu(info_v11->dvi_ss_rate_10hz); 2473fb4d8502Sjsg info->lvds_misc = info_v11->lvds_misc; 2474fb4d8502Sjsg for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2475fb4d8502Sjsg info->ext_disp_conn_info.gu_id[i] = 2476fb4d8502Sjsg info_v11->extdispconninfo.guid[i]; 2477fb4d8502Sjsg } 2478fb4d8502Sjsg 2479fb4d8502Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2480fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_connector_id = 2481fb4d8502Sjsg object_id_from_bios_object_id( 2482fb4d8502Sjsg le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid)); 2483fb4d8502Sjsg 2484fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2485fb4d8502Sjsg object_id_from_bios_object_id( 2486fb4d8502Sjsg le16_to_cpu( 2487fb4d8502Sjsg info_v11->extdispconninfo.path[i].ext_encoder_objid)); 2488fb4d8502Sjsg 2489fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_tag = 2490fb4d8502Sjsg le16_to_cpu( 2491fb4d8502Sjsg info_v11->extdispconninfo.path[i].device_tag); 2492fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum = 2493fb4d8502Sjsg le16_to_cpu( 2494fb4d8502Sjsg info_v11->extdispconninfo.path[i].device_acpi_enum); 2495fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2496fb4d8502Sjsg info_v11->extdispconninfo.path[i].auxddclut_index; 2497fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2498fb4d8502Sjsg info_v11->extdispconninfo.path[i].hpdlut_index; 2499fb4d8502Sjsg info->ext_disp_conn_info.path[i].channel_mapping.raw = 2500fb4d8502Sjsg info_v11->extdispconninfo.path[i].channelmapping; 2501fb4d8502Sjsg info->ext_disp_conn_info.path[i].caps = 2502fb4d8502Sjsg le16_to_cpu(info_v11->extdispconninfo.path[i].caps); 2503fb4d8502Sjsg } 2504fb4d8502Sjsg info->ext_disp_conn_info.checksum = 2505fb4d8502Sjsg info_v11->extdispconninfo.checksum; 2506fb4d8502Sjsg 2507fb4d8502Sjsg info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr; 2508fb4d8502Sjsg info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum; 2509fb4d8502Sjsg for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 2510fb4d8502Sjsg info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 2511fb4d8502Sjsg info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2512fb4d8502Sjsg info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 2513fb4d8502Sjsg info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2514fb4d8502Sjsg } 2515fb4d8502Sjsg info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum; 2516fb4d8502Sjsg for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 2517fb4d8502Sjsg info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2518fb4d8502Sjsg info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2519fb4d8502Sjsg info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2520fb4d8502Sjsg info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2521fb4d8502Sjsg } 2522fb4d8502Sjsg 2523fb4d8502Sjsg info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr; 2524fb4d8502Sjsg info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum; 2525fb4d8502Sjsg for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 2526fb4d8502Sjsg info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 2527fb4d8502Sjsg info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2528fb4d8502Sjsg info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 2529fb4d8502Sjsg info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2530fb4d8502Sjsg } 2531fb4d8502Sjsg info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum; 2532fb4d8502Sjsg for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 2533fb4d8502Sjsg info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2534fb4d8502Sjsg info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2535fb4d8502Sjsg info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2536fb4d8502Sjsg info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2537fb4d8502Sjsg } 2538fb4d8502Sjsg 2539fb4d8502Sjsg info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr; 2540fb4d8502Sjsg info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum; 2541fb4d8502Sjsg for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 2542fb4d8502Sjsg info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 2543fb4d8502Sjsg info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2544fb4d8502Sjsg info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 2545fb4d8502Sjsg info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2546fb4d8502Sjsg } 2547fb4d8502Sjsg info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum; 2548fb4d8502Sjsg for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 2549fb4d8502Sjsg info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2550fb4d8502Sjsg info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2551fb4d8502Sjsg info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2552fb4d8502Sjsg info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2553fb4d8502Sjsg } 2554fb4d8502Sjsg 2555fb4d8502Sjsg info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr; 2556fb4d8502Sjsg info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum; 2557fb4d8502Sjsg for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 2558fb4d8502Sjsg info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 2559fb4d8502Sjsg info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2560fb4d8502Sjsg info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 2561fb4d8502Sjsg info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2562fb4d8502Sjsg } 2563fb4d8502Sjsg info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum; 2564fb4d8502Sjsg for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 2565fb4d8502Sjsg info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2566fb4d8502Sjsg info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2567fb4d8502Sjsg info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2568fb4d8502Sjsg info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2569fb4d8502Sjsg } 2570fb4d8502Sjsg 2571fb4d8502Sjsg 2572fb4d8502Sjsg /** TODO - review **/ 2573fb4d8502Sjsg #if 0 2574fb4d8502Sjsg info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock) 2575fb4d8502Sjsg * 10; 2576fb4d8502Sjsg info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10; 2577fb4d8502Sjsg info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10; 2578fb4d8502Sjsg 2579fb4d8502Sjsg for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2580fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2581fb4d8502Sjsg info->disp_clk_voltage[i].max_supported_clk = 2582fb4d8502Sjsg le32_to_cpu(info_v11->sDISPCLK_Voltage[i]. 2583fb4d8502Sjsg ulMaximumSupportedCLK) * 10; 2584fb4d8502Sjsg info->disp_clk_voltage[i].voltage_index = 2585fb4d8502Sjsg le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex); 2586fb4d8502Sjsg } 2587fb4d8502Sjsg 2588fb4d8502Sjsg info->boot_up_req_display_vector = 2589fb4d8502Sjsg le32_to_cpu(info_v11->ulBootUpReqDisplayVector); 2590fb4d8502Sjsg info->boot_up_nb_voltage = 2591fb4d8502Sjsg le16_to_cpu(info_v11->usBootUpNBVoltage); 2592fb4d8502Sjsg info->ext_disp_conn_info_offset = 2593fb4d8502Sjsg le16_to_cpu(info_v11->usExtDispConnInfoOffset); 2594fb4d8502Sjsg info->gmc_restore_reset_time = 2595fb4d8502Sjsg le32_to_cpu(info_v11->ulGMCRestoreResetTime); 2596fb4d8502Sjsg info->minimum_n_clk = 2597fb4d8502Sjsg le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]); 2598fb4d8502Sjsg for (i = 1; i < 4; ++i) 2599fb4d8502Sjsg info->minimum_n_clk = 2600fb4d8502Sjsg info->minimum_n_clk < 2601fb4d8502Sjsg le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ? 2602fb4d8502Sjsg info->minimum_n_clk : le32_to_cpu( 2603fb4d8502Sjsg info_v11->ulNbpStateNClkFreq[i]); 2604fb4d8502Sjsg 2605fb4d8502Sjsg info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk); 2606fb4d8502Sjsg info->ddr_dll_power_up_time = 2607fb4d8502Sjsg le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime); 2608fb4d8502Sjsg info->ddr_pll_power_up_time = 2609fb4d8502Sjsg le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime); 2610fb4d8502Sjsg info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType); 2611fb4d8502Sjsg info->max_lvds_pclk_freq_in_single_link = 2612fb4d8502Sjsg le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 2613fb4d8502Sjsg info->max_lvds_pclk_freq_in_single_link = 2614fb4d8502Sjsg le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 2615fb4d8502Sjsg info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = 2616fb4d8502Sjsg info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; 2617fb4d8502Sjsg info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = 2618fb4d8502Sjsg info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; 2619fb4d8502Sjsg info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = 2620fb4d8502Sjsg info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; 2621fb4d8502Sjsg info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = 2622fb4d8502Sjsg info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; 2623fb4d8502Sjsg info->lvds_pwr_off_seq_de_to_dig_on_in4ms = 2624fb4d8502Sjsg info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; 2625fb4d8502Sjsg info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = 2626fb4d8502Sjsg info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; 2627fb4d8502Sjsg info->lvds_off_to_on_delay_in_4ms = 2628fb4d8502Sjsg info_v11->ucLVDSOffToOnDelay_in4Ms; 2629fb4d8502Sjsg info->lvds_bit_depth_control_val = 2630fb4d8502Sjsg le32_to_cpu(info_v11->ulLCDBitDepthControlVal); 2631fb4d8502Sjsg 2632fb4d8502Sjsg for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { 2633fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2634fb4d8502Sjsg info->avail_s_clk[i].supported_s_clk = 2635fb4d8502Sjsg le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK) 2636fb4d8502Sjsg * 10; 2637fb4d8502Sjsg info->avail_s_clk[i].voltage_index = 2638fb4d8502Sjsg le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex); 2639fb4d8502Sjsg info->avail_s_clk[i].voltage_id = 2640fb4d8502Sjsg le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID); 2641fb4d8502Sjsg } 2642fb4d8502Sjsg #endif /* TODO*/ 2643fb4d8502Sjsg 2644fb4d8502Sjsg return BP_RESULT_OK; 2645fb4d8502Sjsg } 2646fb4d8502Sjsg 26475ca02815Sjsg static enum bp_result get_integrated_info_v2_1( 26485ca02815Sjsg struct bios_parser *bp, 26495ca02815Sjsg struct integrated_info *info) 26505ca02815Sjsg { 26515ca02815Sjsg struct atom_integrated_system_info_v2_1 *info_v2_1; 26525ca02815Sjsg uint32_t i; 26535ca02815Sjsg 26545ca02815Sjsg info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1, 26555ca02815Sjsg DATA_TABLES(integratedsysteminfo)); 26565ca02815Sjsg 26575ca02815Sjsg if (info_v2_1 == NULL) 26585ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 26595ca02815Sjsg 2660a8749599Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_1->gpuclk_ss_percentage); 2661a8749599Sjsg 26625ca02815Sjsg info->gpu_cap_info = 26635ca02815Sjsg le32_to_cpu(info_v2_1->gpucapinfo); 26645ca02815Sjsg /* 26655ca02815Sjsg * system_config: Bit[0] = 0 : PCIE power gating disabled 26665ca02815Sjsg * = 1 : PCIE power gating enabled 26675ca02815Sjsg * Bit[1] = 0 : DDR-PLL shut down disabled 26685ca02815Sjsg * = 1 : DDR-PLL shut down enabled 26695ca02815Sjsg * Bit[2] = 0 : DDR-PLL power down disabled 26705ca02815Sjsg * = 1 : DDR-PLL power down enabled 26715ca02815Sjsg */ 26725ca02815Sjsg info->system_config = le32_to_cpu(info_v2_1->system_config); 26735ca02815Sjsg info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo); 26745ca02815Sjsg info->memory_type = info_v2_1->memorytype; 26755ca02815Sjsg info->ma_channel_number = info_v2_1->umachannelnumber; 26765ca02815Sjsg info->dp_ss_control = 26775ca02815Sjsg le16_to_cpu(info_v2_1->reserved1); 26785ca02815Sjsg 26795ca02815Sjsg for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 26805ca02815Sjsg info->ext_disp_conn_info.gu_id[i] = 26815ca02815Sjsg info_v2_1->extdispconninfo.guid[i]; 26825ca02815Sjsg } 26835ca02815Sjsg 26845ca02815Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 26855ca02815Sjsg info->ext_disp_conn_info.path[i].device_connector_id = 26865ca02815Sjsg object_id_from_bios_object_id( 26875ca02815Sjsg le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid)); 26885ca02815Sjsg 26895ca02815Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 26905ca02815Sjsg object_id_from_bios_object_id( 26915ca02815Sjsg le16_to_cpu( 26925ca02815Sjsg info_v2_1->extdispconninfo.path[i].ext_encoder_objid)); 26935ca02815Sjsg 26945ca02815Sjsg info->ext_disp_conn_info.path[i].device_tag = 26955ca02815Sjsg le16_to_cpu( 26965ca02815Sjsg info_v2_1->extdispconninfo.path[i].device_tag); 26975ca02815Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum = 26985ca02815Sjsg le16_to_cpu( 26995ca02815Sjsg info_v2_1->extdispconninfo.path[i].device_acpi_enum); 27005ca02815Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 27015ca02815Sjsg info_v2_1->extdispconninfo.path[i].auxddclut_index; 27025ca02815Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 27035ca02815Sjsg info_v2_1->extdispconninfo.path[i].hpdlut_index; 27045ca02815Sjsg info->ext_disp_conn_info.path[i].channel_mapping.raw = 27055ca02815Sjsg info_v2_1->extdispconninfo.path[i].channelmapping; 27065ca02815Sjsg info->ext_disp_conn_info.path[i].caps = 27075ca02815Sjsg le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps); 27085ca02815Sjsg } 27095ca02815Sjsg 27105ca02815Sjsg info->ext_disp_conn_info.checksum = 27115ca02815Sjsg info_v2_1->extdispconninfo.checksum; 27125ca02815Sjsg info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr; 27135ca02815Sjsg info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum; 27145ca02815Sjsg for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 27155ca02815Sjsg info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 27165ca02815Sjsg info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 27175ca02815Sjsg info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 27185ca02815Sjsg info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 27195ca02815Sjsg } 27205ca02815Sjsg info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum; 27215ca02815Sjsg for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 27225ca02815Sjsg info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 27235ca02815Sjsg info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 27245ca02815Sjsg info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 27255ca02815Sjsg info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 27265ca02815Sjsg } 27275ca02815Sjsg info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr; 27285ca02815Sjsg info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum; 27295ca02815Sjsg for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 27305ca02815Sjsg info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 27315ca02815Sjsg info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 27325ca02815Sjsg info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 27335ca02815Sjsg info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 27345ca02815Sjsg } 27355ca02815Sjsg info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum; 27365ca02815Sjsg for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 27375ca02815Sjsg info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 27385ca02815Sjsg info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 27395ca02815Sjsg info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 27405ca02815Sjsg info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 27415ca02815Sjsg } 27425ca02815Sjsg info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr; 27435ca02815Sjsg info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum; 27445ca02815Sjsg for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 27455ca02815Sjsg info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 27465ca02815Sjsg info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 27475ca02815Sjsg info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 27485ca02815Sjsg info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 27495ca02815Sjsg } 27505ca02815Sjsg info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum; 27515ca02815Sjsg for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 27525ca02815Sjsg info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 27535ca02815Sjsg info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 27545ca02815Sjsg info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 27555ca02815Sjsg info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 27565ca02815Sjsg } 27575ca02815Sjsg info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr; 27585ca02815Sjsg info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum; 27595ca02815Sjsg for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 27605ca02815Sjsg info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 27615ca02815Sjsg info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 27625ca02815Sjsg info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 27635ca02815Sjsg info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 27645ca02815Sjsg } 27655ca02815Sjsg info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum; 27665ca02815Sjsg for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 27675ca02815Sjsg info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 27685ca02815Sjsg info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 27695ca02815Sjsg info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 27705ca02815Sjsg info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 27715ca02815Sjsg } 27725ca02815Sjsg 27735ca02815Sjsg info->edp1_info.edp_backlight_pwm_hz = 27745ca02815Sjsg le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz); 27755ca02815Sjsg info->edp1_info.edp_ss_percentage = 27765ca02815Sjsg le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage); 27775ca02815Sjsg info->edp1_info.edp_ss_rate_10hz = 27785ca02815Sjsg le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz); 27795ca02815Sjsg info->edp1_info.edp_pwr_on_off_delay = 27805ca02815Sjsg info_v2_1->edp1_info.edp_pwr_on_off_delay; 27815ca02815Sjsg info->edp1_info.edp_pwr_on_vary_bl_to_blon = 27825ca02815Sjsg info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon; 27835ca02815Sjsg info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = 27845ca02815Sjsg info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff; 27855ca02815Sjsg info->edp1_info.edp_panel_bpc = 27865ca02815Sjsg info_v2_1->edp1_info.edp_panel_bpc; 27875ca02815Sjsg info->edp1_info.edp_bootup_bl_level = info_v2_1->edp1_info.edp_bootup_bl_level; 27885ca02815Sjsg 27895ca02815Sjsg info->edp2_info.edp_backlight_pwm_hz = 27905ca02815Sjsg le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz); 27915ca02815Sjsg info->edp2_info.edp_ss_percentage = 27925ca02815Sjsg le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage); 27935ca02815Sjsg info->edp2_info.edp_ss_rate_10hz = 27945ca02815Sjsg le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz); 27955ca02815Sjsg info->edp2_info.edp_pwr_on_off_delay = 27965ca02815Sjsg info_v2_1->edp2_info.edp_pwr_on_off_delay; 27975ca02815Sjsg info->edp2_info.edp_pwr_on_vary_bl_to_blon = 27985ca02815Sjsg info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon; 27995ca02815Sjsg info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = 28005ca02815Sjsg info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff; 28015ca02815Sjsg info->edp2_info.edp_panel_bpc = 28025ca02815Sjsg info_v2_1->edp2_info.edp_panel_bpc; 28035ca02815Sjsg info->edp2_info.edp_bootup_bl_level = 28045ca02815Sjsg info_v2_1->edp2_info.edp_bootup_bl_level; 28055ca02815Sjsg 28065ca02815Sjsg return BP_RESULT_OK; 28075ca02815Sjsg } 28085ca02815Sjsg 28095ca02815Sjsg static enum bp_result get_integrated_info_v2_2( 28105ca02815Sjsg struct bios_parser *bp, 28115ca02815Sjsg struct integrated_info *info) 28125ca02815Sjsg { 28135ca02815Sjsg struct atom_integrated_system_info_v2_2 *info_v2_2; 28145ca02815Sjsg uint32_t i; 28155ca02815Sjsg 28165ca02815Sjsg info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2, 28175ca02815Sjsg DATA_TABLES(integratedsysteminfo)); 28185ca02815Sjsg 28195ca02815Sjsg if (info_v2_2 == NULL) 28205ca02815Sjsg return BP_RESULT_BADBIOSTABLE; 28215ca02815Sjsg 2822a8749599Sjsg DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_2->gpuclk_ss_percentage); 2823a8749599Sjsg 28245ca02815Sjsg info->gpu_cap_info = 28255ca02815Sjsg le32_to_cpu(info_v2_2->gpucapinfo); 28265ca02815Sjsg /* 28275ca02815Sjsg * system_config: Bit[0] = 0 : PCIE power gating disabled 28285ca02815Sjsg * = 1 : PCIE power gating enabled 28295ca02815Sjsg * Bit[1] = 0 : DDR-PLL shut down disabled 28305ca02815Sjsg * = 1 : DDR-PLL shut down enabled 28315ca02815Sjsg * Bit[2] = 0 : DDR-PLL power down disabled 28325ca02815Sjsg * = 1 : DDR-PLL power down enabled 28335ca02815Sjsg */ 28345ca02815Sjsg info->system_config = le32_to_cpu(info_v2_2->system_config); 28355ca02815Sjsg info->cpu_cap_info = le32_to_cpu(info_v2_2->cpucapinfo); 28365ca02815Sjsg info->memory_type = info_v2_2->memorytype; 28375ca02815Sjsg info->ma_channel_number = info_v2_2->umachannelnumber; 28385ca02815Sjsg info->dp_ss_control = 28395ca02815Sjsg le16_to_cpu(info_v2_2->reserved1); 28402d4ce006Sjsg info->gpuclk_ss_percentage = info_v2_2->gpuclk_ss_percentage; 28412d4ce006Sjsg info->gpuclk_ss_type = info_v2_2->gpuclk_ss_type; 28425ca02815Sjsg 28435ca02815Sjsg for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 28445ca02815Sjsg info->ext_disp_conn_info.gu_id[i] = 28455ca02815Sjsg info_v2_2->extdispconninfo.guid[i]; 28465ca02815Sjsg } 28475ca02815Sjsg 28485ca02815Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 28495ca02815Sjsg info->ext_disp_conn_info.path[i].device_connector_id = 28505ca02815Sjsg object_id_from_bios_object_id( 28515ca02815Sjsg le16_to_cpu(info_v2_2->extdispconninfo.path[i].connectorobjid)); 28525ca02815Sjsg 28535ca02815Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 28545ca02815Sjsg object_id_from_bios_object_id( 28555ca02815Sjsg le16_to_cpu( 28565ca02815Sjsg info_v2_2->extdispconninfo.path[i].ext_encoder_objid)); 28575ca02815Sjsg 28585ca02815Sjsg info->ext_disp_conn_info.path[i].device_tag = 28595ca02815Sjsg le16_to_cpu( 28605ca02815Sjsg info_v2_2->extdispconninfo.path[i].device_tag); 28615ca02815Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum = 28625ca02815Sjsg le16_to_cpu( 28635ca02815Sjsg info_v2_2->extdispconninfo.path[i].device_acpi_enum); 28645ca02815Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 28655ca02815Sjsg info_v2_2->extdispconninfo.path[i].auxddclut_index; 28665ca02815Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 28675ca02815Sjsg info_v2_2->extdispconninfo.path[i].hpdlut_index; 28685ca02815Sjsg info->ext_disp_conn_info.path[i].channel_mapping.raw = 28695ca02815Sjsg info_v2_2->extdispconninfo.path[i].channelmapping; 28705ca02815Sjsg info->ext_disp_conn_info.path[i].caps = 28715ca02815Sjsg le16_to_cpu(info_v2_2->extdispconninfo.path[i].caps); 28725ca02815Sjsg } 28735ca02815Sjsg 28745ca02815Sjsg info->ext_disp_conn_info.checksum = 28755ca02815Sjsg info_v2_2->extdispconninfo.checksum; 28761bb76ff1Sjsg info->ext_disp_conn_info.fixdpvoltageswing = 28771bb76ff1Sjsg info_v2_2->extdispconninfo.fixdpvoltageswing; 28785ca02815Sjsg 28795ca02815Sjsg info->edp1_info.edp_backlight_pwm_hz = 28805ca02815Sjsg le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz); 28815ca02815Sjsg info->edp1_info.edp_ss_percentage = 28825ca02815Sjsg le16_to_cpu(info_v2_2->edp1_info.edp_ss_percentage); 28835ca02815Sjsg info->edp1_info.edp_ss_rate_10hz = 28845ca02815Sjsg le16_to_cpu(info_v2_2->edp1_info.edp_ss_rate_10hz); 28855ca02815Sjsg info->edp1_info.edp_pwr_on_off_delay = 28865ca02815Sjsg info_v2_2->edp1_info.edp_pwr_on_off_delay; 28875ca02815Sjsg info->edp1_info.edp_pwr_on_vary_bl_to_blon = 28885ca02815Sjsg info_v2_2->edp1_info.edp_pwr_on_vary_bl_to_blon; 28895ca02815Sjsg info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = 28905ca02815Sjsg info_v2_2->edp1_info.edp_pwr_down_bloff_to_vary_bloff; 28915ca02815Sjsg info->edp1_info.edp_panel_bpc = 28925ca02815Sjsg info_v2_2->edp1_info.edp_panel_bpc; 28935ca02815Sjsg info->edp1_info.edp_bootup_bl_level = 28945ca02815Sjsg 28955ca02815Sjsg info->edp2_info.edp_backlight_pwm_hz = 28965ca02815Sjsg le16_to_cpu(info_v2_2->edp2_info.edp_backlight_pwm_hz); 28975ca02815Sjsg info->edp2_info.edp_ss_percentage = 28985ca02815Sjsg le16_to_cpu(info_v2_2->edp2_info.edp_ss_percentage); 28995ca02815Sjsg info->edp2_info.edp_ss_rate_10hz = 29005ca02815Sjsg le16_to_cpu(info_v2_2->edp2_info.edp_ss_rate_10hz); 29015ca02815Sjsg info->edp2_info.edp_pwr_on_off_delay = 29025ca02815Sjsg info_v2_2->edp2_info.edp_pwr_on_off_delay; 29035ca02815Sjsg info->edp2_info.edp_pwr_on_vary_bl_to_blon = 29045ca02815Sjsg info_v2_2->edp2_info.edp_pwr_on_vary_bl_to_blon; 29055ca02815Sjsg info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = 29065ca02815Sjsg info_v2_2->edp2_info.edp_pwr_down_bloff_to_vary_bloff; 29075ca02815Sjsg info->edp2_info.edp_panel_bpc = 29085ca02815Sjsg info_v2_2->edp2_info.edp_panel_bpc; 29095ca02815Sjsg info->edp2_info.edp_bootup_bl_level = 29105ca02815Sjsg info_v2_2->edp2_info.edp_bootup_bl_level; 29115ca02815Sjsg 29125ca02815Sjsg return BP_RESULT_OK; 29135ca02815Sjsg } 2914fb4d8502Sjsg 2915fb4d8502Sjsg /* 2916fb4d8502Sjsg * construct_integrated_info 2917fb4d8502Sjsg * 2918fb4d8502Sjsg * @brief 2919fb4d8502Sjsg * Get integrated BIOS information based on table revision 2920fb4d8502Sjsg * 2921fb4d8502Sjsg * @param 2922fb4d8502Sjsg * bios_parser *bp - [in]BIOS parser handler to get master data table 2923fb4d8502Sjsg * integrated_info *info - [out] store and output integrated info 2924fb4d8502Sjsg * 2925fb4d8502Sjsg * @return 29261bb76ff1Sjsg * static enum bp_result - BP_RESULT_OK if information is available, 2927fb4d8502Sjsg * BP_RESULT_BADBIOSTABLE otherwise. 2928fb4d8502Sjsg */ 2929fb4d8502Sjsg static enum bp_result construct_integrated_info( 2930fb4d8502Sjsg struct bios_parser *bp, 2931fb4d8502Sjsg struct integrated_info *info) 2932fb4d8502Sjsg { 29331bb76ff1Sjsg static enum bp_result result = BP_RESULT_BADBIOSTABLE; 2934fb4d8502Sjsg 2935fb4d8502Sjsg struct atom_common_table_header *header; 2936fb4d8502Sjsg struct atom_data_revision revision; 29371bb76ff1Sjsg 2938*777bfb8aSjsg int32_t i; 2939*777bfb8aSjsg int32_t j; 2940*777bfb8aSjsg 2941*777bfb8aSjsg if (!info) 2942*777bfb8aSjsg return result; 2943fb4d8502Sjsg 2944fb4d8502Sjsg if (info && DATA_TABLES(integratedsysteminfo)) { 2945fb4d8502Sjsg header = GET_IMAGE(struct atom_common_table_header, 2946fb4d8502Sjsg DATA_TABLES(integratedsysteminfo)); 2947fb4d8502Sjsg 2948fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 2949fb4d8502Sjsg 29505ca02815Sjsg switch (revision.major) { 29515ca02815Sjsg case 1: 2952fb4d8502Sjsg switch (revision.minor) { 2953fb4d8502Sjsg case 11: 2954c349dbc7Sjsg case 12: 2955fb4d8502Sjsg result = get_integrated_info_v11(bp, info); 2956fb4d8502Sjsg break; 2957fb4d8502Sjsg default: 2958fb4d8502Sjsg return result; 2959fb4d8502Sjsg } 29605ca02815Sjsg break; 29615ca02815Sjsg case 2: 29625ca02815Sjsg switch (revision.minor) { 29635ca02815Sjsg case 1: 29645ca02815Sjsg result = get_integrated_info_v2_1(bp, info); 29655ca02815Sjsg break; 29665ca02815Sjsg case 2: 296727d456ebSjsg case 3: 29685ca02815Sjsg result = get_integrated_info_v2_2(bp, info); 29695ca02815Sjsg break; 29705ca02815Sjsg default: 29715ca02815Sjsg return result; 29725ca02815Sjsg } 29735ca02815Sjsg break; 29745ca02815Sjsg default: 29755ca02815Sjsg return result; 29765ca02815Sjsg } 29771bb76ff1Sjsg if (result == BP_RESULT_OK) { 29781bb76ff1Sjsg 29791bb76ff1Sjsg DC_LOG_BIOS("edp1:\n" 29801bb76ff1Sjsg "\tedp_pwr_on_off_delay = %d\n" 29811bb76ff1Sjsg "\tedp_pwr_on_vary_bl_to_blon = %d\n" 29821bb76ff1Sjsg "\tedp_pwr_down_bloff_to_vary_bloff = %d\n" 29831bb76ff1Sjsg "\tedp_bootup_bl_level = %d\n", 29841bb76ff1Sjsg info->edp1_info.edp_pwr_on_off_delay, 29851bb76ff1Sjsg info->edp1_info.edp_pwr_on_vary_bl_to_blon, 29861bb76ff1Sjsg info->edp1_info.edp_pwr_down_bloff_to_vary_bloff, 29871bb76ff1Sjsg info->edp1_info.edp_bootup_bl_level); 29881bb76ff1Sjsg DC_LOG_BIOS("edp2:\n" 29891bb76ff1Sjsg "\tedp_pwr_on_off_delayv = %d\n" 29901bb76ff1Sjsg "\tedp_pwr_on_vary_bl_to_blon = %d\n" 29911bb76ff1Sjsg "\tedp_pwr_down_bloff_to_vary_bloff = %d\n" 29921bb76ff1Sjsg "\tedp_bootup_bl_level = %d\n", 29931bb76ff1Sjsg info->edp2_info.edp_pwr_on_off_delay, 29941bb76ff1Sjsg info->edp2_info.edp_pwr_on_vary_bl_to_blon, 29951bb76ff1Sjsg info->edp2_info.edp_pwr_down_bloff_to_vary_bloff, 29961bb76ff1Sjsg info->edp2_info.edp_bootup_bl_level); 29971bb76ff1Sjsg } 2998fb4d8502Sjsg } 2999fb4d8502Sjsg 3000fb4d8502Sjsg if (result != BP_RESULT_OK) 3001fb4d8502Sjsg return result; 30021bb76ff1Sjsg else { 30031bb76ff1Sjsg // Log each external path 30041bb76ff1Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) { 30051bb76ff1Sjsg if (info->ext_disp_conn_info.path[i].device_tag != 0) 30061bb76ff1Sjsg DC_LOG_BIOS("integrated_info:For EXTERNAL DISPLAY PATH %d --------------\n" 30071bb76ff1Sjsg "DEVICE_TAG: 0x%x\n" 30081bb76ff1Sjsg "DEVICE_ACPI_ENUM: 0x%x\n" 30091bb76ff1Sjsg "DEVICE_CONNECTOR_ID: 0x%x\n" 30101bb76ff1Sjsg "EXT_AUX_DDC_LUT_INDEX: %d\n" 30111bb76ff1Sjsg "EXT_HPD_PIN_LUT_INDEX: %d\n" 30121bb76ff1Sjsg "EXT_ENCODER_OBJ_ID: 0x%x\n" 30131bb76ff1Sjsg "Encoder CAPS: 0x%x\n", 30141bb76ff1Sjsg i, 30151bb76ff1Sjsg info->ext_disp_conn_info.path[i].device_tag, 30161bb76ff1Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum, 30171bb76ff1Sjsg info->ext_disp_conn_info.path[i].device_connector_id.id, 30181bb76ff1Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index, 30191bb76ff1Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index, 30201bb76ff1Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id.id, 30211bb76ff1Sjsg info->ext_disp_conn_info.path[i].caps 30221bb76ff1Sjsg ); 30231bb76ff1Sjsg if (info->ext_disp_conn_info.path[i].caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) 30241bb76ff1Sjsg DC_LOG_BIOS("BIOS EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN on path %d\n", i); 30251bb76ff1Sjsg else if (bp->base.ctx->dc->config.force_bios_fixed_vs) { 30261bb76ff1Sjsg info->ext_disp_conn_info.path[i].caps |= EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN; 30271bb76ff1Sjsg DC_LOG_BIOS("driver forced EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN on path %d\n", i); 30281bb76ff1Sjsg } 30291bb76ff1Sjsg } 30301bb76ff1Sjsg // Log the Checksum and Voltage Swing 30311bb76ff1Sjsg DC_LOG_BIOS("Integrated info table CHECKSUM: %d\n" 30321bb76ff1Sjsg "Integrated info table FIX_DP_VOLTAGE_SWING: %d\n", 30331bb76ff1Sjsg info->ext_disp_conn_info.checksum, 30341bb76ff1Sjsg info->ext_disp_conn_info.fixdpvoltageswing); 30351bb76ff1Sjsg if (bp->base.ctx->dc->config.force_bios_fixed_vs && info->ext_disp_conn_info.fixdpvoltageswing == 0) { 30361bb76ff1Sjsg info->ext_disp_conn_info.fixdpvoltageswing = bp->base.ctx->dc->config.force_bios_fixed_vs & 0xF; 30371bb76ff1Sjsg DC_LOG_BIOS("driver forced fixdpvoltageswing = %d\n", info->ext_disp_conn_info.fixdpvoltageswing); 30381bb76ff1Sjsg } 30391bb76ff1Sjsg } 3040fb4d8502Sjsg /* Sort voltage table from low to high*/ 3041fb4d8502Sjsg for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 3042fb4d8502Sjsg for (j = i; j > 0; --j) { 3043fb4d8502Sjsg if (info->disp_clk_voltage[j].max_supported_clk < 3044f005ef32Sjsg info->disp_clk_voltage[j-1].max_supported_clk) 3045f005ef32Sjsg swap(info->disp_clk_voltage[j-1], info->disp_clk_voltage[j]); 3046fb4d8502Sjsg } 3047fb4d8502Sjsg } 3048fb4d8502Sjsg 3049fb4d8502Sjsg return result; 3050fb4d8502Sjsg } 3051fb4d8502Sjsg 3052ad8b1aafSjsg static enum bp_result bios_parser_get_vram_info( 3053ad8b1aafSjsg struct dc_bios *dcb, 3054ad8b1aafSjsg struct dc_vram_info *info) 3055ad8b1aafSjsg { 3056ad8b1aafSjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 30571bb76ff1Sjsg static enum bp_result result = BP_RESULT_BADBIOSTABLE; 3058ad8b1aafSjsg struct atom_common_table_header *header; 3059ad8b1aafSjsg struct atom_data_revision revision; 3060ad8b1aafSjsg 3061ad8b1aafSjsg if (info && DATA_TABLES(vram_info)) { 3062ad8b1aafSjsg header = GET_IMAGE(struct atom_common_table_header, 3063ad8b1aafSjsg DATA_TABLES(vram_info)); 3064ad8b1aafSjsg 3065ad8b1aafSjsg get_atom_data_table_revision(header, &revision); 3066ad8b1aafSjsg 3067ad8b1aafSjsg switch (revision.major) { 3068ad8b1aafSjsg case 2: 3069ad8b1aafSjsg switch (revision.minor) { 3070ad8b1aafSjsg case 3: 3071ad8b1aafSjsg result = get_vram_info_v23(bp, info); 3072ad8b1aafSjsg break; 3073ad8b1aafSjsg case 4: 3074ad8b1aafSjsg result = get_vram_info_v24(bp, info); 3075ad8b1aafSjsg break; 3076ad8b1aafSjsg case 5: 3077ad8b1aafSjsg result = get_vram_info_v25(bp, info); 3078ad8b1aafSjsg break; 3079ad8b1aafSjsg default: 3080ad8b1aafSjsg break; 3081ad8b1aafSjsg } 3082ad8b1aafSjsg break; 3083ad8b1aafSjsg 30841bb76ff1Sjsg case 3: 30851bb76ff1Sjsg switch (revision.minor) { 30861bb76ff1Sjsg case 0: 30871bb76ff1Sjsg result = get_vram_info_v30(bp, info); 30881bb76ff1Sjsg break; 30891bb76ff1Sjsg default: 30901bb76ff1Sjsg break; 30911bb76ff1Sjsg } 30921bb76ff1Sjsg break; 30931bb76ff1Sjsg 3094ad8b1aafSjsg default: 3095ad8b1aafSjsg return result; 3096ad8b1aafSjsg } 3097ad8b1aafSjsg 3098ad8b1aafSjsg } 3099ad8b1aafSjsg return result; 3100ad8b1aafSjsg } 3101ad8b1aafSjsg 3102fb4d8502Sjsg static struct integrated_info *bios_parser_create_integrated_info( 3103fb4d8502Sjsg struct dc_bios *dcb) 3104fb4d8502Sjsg { 3105fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 3106f005ef32Sjsg struct integrated_info *info; 3107fb4d8502Sjsg 3108fb4d8502Sjsg info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); 3109fb4d8502Sjsg 3110fb4d8502Sjsg if (info == NULL) { 3111fb4d8502Sjsg ASSERT_CRITICAL(0); 3112fb4d8502Sjsg return NULL; 3113fb4d8502Sjsg } 3114fb4d8502Sjsg 3115fb4d8502Sjsg if (construct_integrated_info(bp, info) == BP_RESULT_OK) 3116fb4d8502Sjsg return info; 3117fb4d8502Sjsg 3118fb4d8502Sjsg kfree(info); 3119fb4d8502Sjsg 3120fb4d8502Sjsg return NULL; 3121fb4d8502Sjsg } 3122fb4d8502Sjsg 3123fb4d8502Sjsg static enum bp_result update_slot_layout_info( 3124fb4d8502Sjsg struct dc_bios *dcb, 3125fb4d8502Sjsg unsigned int i, 3126fb4d8502Sjsg struct slot_layout_info *slot_layout_info) 3127fb4d8502Sjsg { 3128fb4d8502Sjsg unsigned int record_offset; 3129fb4d8502Sjsg unsigned int j; 3130fb4d8502Sjsg struct atom_display_object_path_v2 *object; 3131fb4d8502Sjsg struct atom_bracket_layout_record *record; 3132fb4d8502Sjsg struct atom_common_record_header *record_header; 31331bb76ff1Sjsg static enum bp_result result; 3134fb4d8502Sjsg struct bios_parser *bp; 3135fb4d8502Sjsg struct object_info_table *tbl; 3136fb4d8502Sjsg struct display_object_info_table_v1_4 *v1_4; 3137fb4d8502Sjsg 3138fb4d8502Sjsg record = NULL; 3139fb4d8502Sjsg record_header = NULL; 3140fb4d8502Sjsg result = BP_RESULT_NORECORD; 3141fb4d8502Sjsg 3142fb4d8502Sjsg bp = BP_FROM_DCB(dcb); 3143fb4d8502Sjsg tbl = &bp->object_info_tbl; 3144fb4d8502Sjsg v1_4 = tbl->v1_4; 3145fb4d8502Sjsg 3146fb4d8502Sjsg object = &v1_4->display_path[i]; 3147fb4d8502Sjsg record_offset = (unsigned int) 3148fb4d8502Sjsg (object->disp_recordoffset) + 3149fb4d8502Sjsg (unsigned int)(bp->object_info_tbl_offset); 3150fb4d8502Sjsg 3151fb4d8502Sjsg for (;;) { 3152fb4d8502Sjsg 3153fb4d8502Sjsg record_header = (struct atom_common_record_header *) 3154fb4d8502Sjsg GET_IMAGE(struct atom_common_record_header, 3155fb4d8502Sjsg record_offset); 3156fb4d8502Sjsg if (record_header == NULL) { 3157fb4d8502Sjsg result = BP_RESULT_BADBIOSTABLE; 3158fb4d8502Sjsg break; 3159fb4d8502Sjsg } 3160fb4d8502Sjsg 3161fb4d8502Sjsg /* the end of the list */ 3162fb4d8502Sjsg if (record_header->record_type == 0xff || 3163fb4d8502Sjsg record_header->record_size == 0) { 3164fb4d8502Sjsg break; 3165fb4d8502Sjsg } 3166fb4d8502Sjsg 3167fb4d8502Sjsg if (record_header->record_type == 3168fb4d8502Sjsg ATOM_BRACKET_LAYOUT_RECORD_TYPE && 3169fb4d8502Sjsg sizeof(struct atom_bracket_layout_record) 3170fb4d8502Sjsg <= record_header->record_size) { 3171fb4d8502Sjsg record = (struct atom_bracket_layout_record *) 3172fb4d8502Sjsg (record_header); 3173fb4d8502Sjsg result = BP_RESULT_OK; 3174fb4d8502Sjsg break; 3175fb4d8502Sjsg } 3176fb4d8502Sjsg 3177fb4d8502Sjsg record_offset += record_header->record_size; 3178fb4d8502Sjsg } 3179fb4d8502Sjsg 3180fb4d8502Sjsg /* return if the record not found */ 3181fb4d8502Sjsg if (result != BP_RESULT_OK) 3182fb4d8502Sjsg return result; 3183fb4d8502Sjsg 3184fb4d8502Sjsg /* get slot sizes */ 3185fb4d8502Sjsg slot_layout_info->length = record->bracketlen; 3186fb4d8502Sjsg slot_layout_info->width = record->bracketwidth; 3187fb4d8502Sjsg 3188fb4d8502Sjsg /* get info for each connector in the slot */ 3189fb4d8502Sjsg slot_layout_info->num_of_connectors = record->conn_num; 3190fb4d8502Sjsg for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { 3191fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3192fb4d8502Sjsg (enum connector_layout_type) 3193fb4d8502Sjsg (record->conn_info[j].connector_type); 3194fb4d8502Sjsg switch (record->conn_info[j].connector_type) { 3195fb4d8502Sjsg case CONNECTOR_TYPE_DVI_D: 3196fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3197fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_DVI_D; 3198fb4d8502Sjsg slot_layout_info->connectors[j].length = 3199fb4d8502Sjsg CONNECTOR_SIZE_DVI; 3200fb4d8502Sjsg break; 3201fb4d8502Sjsg 3202fb4d8502Sjsg case CONNECTOR_TYPE_HDMI: 3203fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3204fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_HDMI; 3205fb4d8502Sjsg slot_layout_info->connectors[j].length = 3206fb4d8502Sjsg CONNECTOR_SIZE_HDMI; 3207fb4d8502Sjsg break; 3208fb4d8502Sjsg 3209fb4d8502Sjsg case CONNECTOR_TYPE_DISPLAY_PORT: 3210fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3211fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_DP; 3212fb4d8502Sjsg slot_layout_info->connectors[j].length = 3213fb4d8502Sjsg CONNECTOR_SIZE_DP; 3214fb4d8502Sjsg break; 3215fb4d8502Sjsg 3216fb4d8502Sjsg case CONNECTOR_TYPE_MINI_DISPLAY_PORT: 3217fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3218fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_MINI_DP; 3219fb4d8502Sjsg slot_layout_info->connectors[j].length = 3220fb4d8502Sjsg CONNECTOR_SIZE_MINI_DP; 3221fb4d8502Sjsg break; 3222fb4d8502Sjsg 3223fb4d8502Sjsg default: 3224fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 3225fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_UNKNOWN; 3226fb4d8502Sjsg slot_layout_info->connectors[j].length = 3227fb4d8502Sjsg CONNECTOR_SIZE_UNKNOWN; 3228fb4d8502Sjsg } 3229fb4d8502Sjsg 3230fb4d8502Sjsg slot_layout_info->connectors[j].position = 3231fb4d8502Sjsg record->conn_info[j].position; 3232fb4d8502Sjsg slot_layout_info->connectors[j].connector_id = 3233fb4d8502Sjsg object_id_from_bios_object_id( 3234fb4d8502Sjsg record->conn_info[j].connectorobjid); 3235fb4d8502Sjsg } 3236fb4d8502Sjsg return result; 3237fb4d8502Sjsg } 3238fb4d8502Sjsg 32391bb76ff1Sjsg static enum bp_result update_slot_layout_info_v2( 32401bb76ff1Sjsg struct dc_bios *dcb, 32411bb76ff1Sjsg unsigned int i, 32421bb76ff1Sjsg struct slot_layout_info *slot_layout_info) 32431bb76ff1Sjsg { 32441bb76ff1Sjsg unsigned int record_offset; 32451bb76ff1Sjsg struct atom_display_object_path_v3 *object; 32461bb76ff1Sjsg struct atom_bracket_layout_record_v2 *record; 32471bb76ff1Sjsg struct atom_common_record_header *record_header; 32481bb76ff1Sjsg static enum bp_result result; 32491bb76ff1Sjsg struct bios_parser *bp; 32501bb76ff1Sjsg struct object_info_table *tbl; 32511bb76ff1Sjsg struct display_object_info_table_v1_5 *v1_5; 32521bb76ff1Sjsg struct graphics_object_id connector_id; 32531bb76ff1Sjsg 32541bb76ff1Sjsg record = NULL; 32551bb76ff1Sjsg record_header = NULL; 32561bb76ff1Sjsg result = BP_RESULT_NORECORD; 32571bb76ff1Sjsg 32581bb76ff1Sjsg bp = BP_FROM_DCB(dcb); 32591bb76ff1Sjsg tbl = &bp->object_info_tbl; 32601bb76ff1Sjsg v1_5 = tbl->v1_5; 32611bb76ff1Sjsg 32621bb76ff1Sjsg object = &v1_5->display_path[i]; 32631bb76ff1Sjsg record_offset = (unsigned int) 32641bb76ff1Sjsg (object->disp_recordoffset) + 32651bb76ff1Sjsg (unsigned int)(bp->object_info_tbl_offset); 32661bb76ff1Sjsg 32671bb76ff1Sjsg for (;;) { 32681bb76ff1Sjsg 32691bb76ff1Sjsg record_header = (struct atom_common_record_header *) 32701bb76ff1Sjsg GET_IMAGE(struct atom_common_record_header, 32711bb76ff1Sjsg record_offset); 32721bb76ff1Sjsg if (record_header == NULL) { 32731bb76ff1Sjsg result = BP_RESULT_BADBIOSTABLE; 32741bb76ff1Sjsg break; 32751bb76ff1Sjsg } 32761bb76ff1Sjsg 32771bb76ff1Sjsg /* the end of the list */ 32781bb76ff1Sjsg if (record_header->record_type == ATOM_RECORD_END_TYPE || 32791bb76ff1Sjsg record_header->record_size == 0) { 32801bb76ff1Sjsg break; 32811bb76ff1Sjsg } 32821bb76ff1Sjsg 32831bb76ff1Sjsg if (record_header->record_type == 32841bb76ff1Sjsg ATOM_BRACKET_LAYOUT_V2_RECORD_TYPE && 32851bb76ff1Sjsg sizeof(struct atom_bracket_layout_record_v2) 32861bb76ff1Sjsg <= record_header->record_size) { 32871bb76ff1Sjsg record = (struct atom_bracket_layout_record_v2 *) 32881bb76ff1Sjsg (record_header); 32891bb76ff1Sjsg result = BP_RESULT_OK; 32901bb76ff1Sjsg break; 32911bb76ff1Sjsg } 32921bb76ff1Sjsg 32931bb76ff1Sjsg record_offset += record_header->record_size; 32941bb76ff1Sjsg } 32951bb76ff1Sjsg 32961bb76ff1Sjsg /* return if the record not found */ 32971bb76ff1Sjsg if (result != BP_RESULT_OK) 32981bb76ff1Sjsg return result; 32991bb76ff1Sjsg 33001bb76ff1Sjsg /* get slot sizes */ 33011bb76ff1Sjsg connector_id = object_id_from_bios_object_id(object->display_objid); 33021bb76ff1Sjsg 33031bb76ff1Sjsg slot_layout_info->length = record->bracketlen; 33041bb76ff1Sjsg slot_layout_info->width = record->bracketwidth; 33051bb76ff1Sjsg slot_layout_info->num_of_connectors = v1_5->number_of_path; 33061bb76ff1Sjsg slot_layout_info->connectors[i].position = record->conn_num; 33071bb76ff1Sjsg slot_layout_info->connectors[i].connector_id = connector_id; 33081bb76ff1Sjsg 33091bb76ff1Sjsg switch (connector_id.id) { 33101bb76ff1Sjsg case CONNECTOR_ID_SINGLE_LINK_DVID: 33111bb76ff1Sjsg case CONNECTOR_ID_DUAL_LINK_DVID: 33121bb76ff1Sjsg slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DVI_D; 33131bb76ff1Sjsg slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DVI; 33141bb76ff1Sjsg break; 33151bb76ff1Sjsg 33161bb76ff1Sjsg case CONNECTOR_ID_HDMI_TYPE_A: 33171bb76ff1Sjsg slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_HDMI; 33181bb76ff1Sjsg slot_layout_info->connectors[i].length = CONNECTOR_SIZE_HDMI; 33191bb76ff1Sjsg break; 33201bb76ff1Sjsg 33211bb76ff1Sjsg case CONNECTOR_ID_DISPLAY_PORT: 33221bb76ff1Sjsg case CONNECTOR_ID_USBC: 33231bb76ff1Sjsg if (record->mini_type == MINI_TYPE_NORMAL) { 33241bb76ff1Sjsg slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DP; 33251bb76ff1Sjsg slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DP; 33261bb76ff1Sjsg } else { 33271bb76ff1Sjsg slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP; 33281bb76ff1Sjsg slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP; 33291bb76ff1Sjsg } 33301bb76ff1Sjsg break; 33311bb76ff1Sjsg 33321bb76ff1Sjsg default: 33331bb76ff1Sjsg slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN; 33341bb76ff1Sjsg slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN; 33351bb76ff1Sjsg } 33361bb76ff1Sjsg return result; 33371bb76ff1Sjsg } 3338fb4d8502Sjsg 3339fb4d8502Sjsg static enum bp_result get_bracket_layout_record( 3340fb4d8502Sjsg struct dc_bios *dcb, 3341fb4d8502Sjsg unsigned int bracket_layout_id, 3342fb4d8502Sjsg struct slot_layout_info *slot_layout_info) 3343fb4d8502Sjsg { 3344fb4d8502Sjsg unsigned int i; 3345fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 33461bb76ff1Sjsg static enum bp_result result; 3347fb4d8502Sjsg struct object_info_table *tbl; 3348fb4d8502Sjsg struct display_object_info_table_v1_4 *v1_4; 33491bb76ff1Sjsg struct display_object_info_table_v1_5 *v1_5; 3350fb4d8502Sjsg 3351fb4d8502Sjsg if (slot_layout_info == NULL) { 3352fb4d8502Sjsg DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); 3353fb4d8502Sjsg return BP_RESULT_BADINPUT; 3354fb4d8502Sjsg } 3355fb4d8502Sjsg tbl = &bp->object_info_tbl; 3356fb4d8502Sjsg v1_4 = tbl->v1_4; 33571bb76ff1Sjsg v1_5 = tbl->v1_5; 3358fb4d8502Sjsg 3359fb4d8502Sjsg result = BP_RESULT_NORECORD; 33601bb76ff1Sjsg switch (bp->object_info_tbl.revision.minor) { 33611bb76ff1Sjsg case 4: 33621bb76ff1Sjsg default: 3363fb4d8502Sjsg for (i = 0; i < v1_4->number_of_path; ++i) { 3364fb4d8502Sjsg if (bracket_layout_id == 3365fb4d8502Sjsg v1_4->display_path[i].display_objid) { 33661bb76ff1Sjsg result = update_slot_layout_info(dcb, i, slot_layout_info); 3367fb4d8502Sjsg break; 3368fb4d8502Sjsg } 3369fb4d8502Sjsg } 33701bb76ff1Sjsg break; 33711bb76ff1Sjsg case 5: 33721bb76ff1Sjsg for (i = 0; i < v1_5->number_of_path; ++i) 33731bb76ff1Sjsg result = update_slot_layout_info_v2(dcb, i, slot_layout_info); 33741bb76ff1Sjsg break; 33751bb76ff1Sjsg } 3376fb4d8502Sjsg return result; 3377fb4d8502Sjsg } 3378fb4d8502Sjsg 3379fb4d8502Sjsg static enum bp_result bios_get_board_layout_info( 3380fb4d8502Sjsg struct dc_bios *dcb, 3381fb4d8502Sjsg struct board_layout_info *board_layout_info) 3382fb4d8502Sjsg { 3383fb4d8502Sjsg unsigned int i; 33841bb76ff1Sjsg 33851bb76ff1Sjsg struct bios_parser *bp; 33861bb76ff1Sjsg 33871bb76ff1Sjsg static enum bp_result record_result; 33881bb76ff1Sjsg unsigned int max_slots; 3389fb4d8502Sjsg 3390fb4d8502Sjsg const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { 3391fb4d8502Sjsg GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, 3392fb4d8502Sjsg GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, 3393fb4d8502Sjsg 0, 0 3394fb4d8502Sjsg }; 3395fb4d8502Sjsg 33961bb76ff1Sjsg 33971bb76ff1Sjsg bp = BP_FROM_DCB(dcb); 33981bb76ff1Sjsg 3399fb4d8502Sjsg if (board_layout_info == NULL) { 3400fb4d8502Sjsg DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); 3401fb4d8502Sjsg return BP_RESULT_BADINPUT; 3402fb4d8502Sjsg } 3403fb4d8502Sjsg 3404fb4d8502Sjsg board_layout_info->num_of_slots = 0; 34051bb76ff1Sjsg max_slots = MAX_BOARD_SLOTS; 3406fb4d8502Sjsg 34071bb76ff1Sjsg // Assume single slot on v1_5 34081bb76ff1Sjsg if (bp->object_info_tbl.revision.minor == 5) { 34091bb76ff1Sjsg max_slots = 1; 34101bb76ff1Sjsg } 34111bb76ff1Sjsg 34121bb76ff1Sjsg for (i = 0; i < max_slots; ++i) { 3413fb4d8502Sjsg record_result = get_bracket_layout_record(dcb, 3414fb4d8502Sjsg slot_index_to_vbios_id[i], 3415fb4d8502Sjsg &board_layout_info->slots[i]); 3416fb4d8502Sjsg 3417fb4d8502Sjsg if (record_result == BP_RESULT_NORECORD && i > 0) 3418fb4d8502Sjsg break; /* no more slots present in bios */ 3419fb4d8502Sjsg else if (record_result != BP_RESULT_OK) 3420fb4d8502Sjsg return record_result; /* fail */ 3421fb4d8502Sjsg 3422fb4d8502Sjsg ++board_layout_info->num_of_slots; 3423fb4d8502Sjsg } 3424fb4d8502Sjsg 3425fb4d8502Sjsg /* all data is valid */ 3426fb4d8502Sjsg board_layout_info->is_number_of_slots_valid = 1; 3427fb4d8502Sjsg board_layout_info->is_slots_size_valid = 1; 3428fb4d8502Sjsg board_layout_info->is_connector_offsets_valid = 1; 3429fb4d8502Sjsg board_layout_info->is_connector_lengths_valid = 1; 3430fb4d8502Sjsg 3431fb4d8502Sjsg return BP_RESULT_OK; 3432fb4d8502Sjsg } 3433fb4d8502Sjsg 3434ad8b1aafSjsg 3435ad8b1aafSjsg static uint16_t bios_parser_pack_data_tables( 3436ad8b1aafSjsg struct dc_bios *dcb, 3437ad8b1aafSjsg void *dst) 3438ad8b1aafSjsg { 3439ad8b1aafSjsg // TODO: There is data bytes alignment issue, disable it for now. 3440ad8b1aafSjsg return 0; 3441ad8b1aafSjsg } 3442ad8b1aafSjsg 3443ad8b1aafSjsg static struct atom_dc_golden_table_v1 *bios_get_golden_table( 3444ad8b1aafSjsg struct bios_parser *bp, 3445ad8b1aafSjsg uint32_t rev_major, 3446ad8b1aafSjsg uint32_t rev_minor, 3447ad8b1aafSjsg uint16_t *dc_golden_table_ver) 3448ad8b1aafSjsg { 3449ad8b1aafSjsg struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL; 3450ad8b1aafSjsg uint32_t dc_golden_offset = 0; 3451ad8b1aafSjsg *dc_golden_table_ver = 0; 3452ad8b1aafSjsg 3453ad8b1aafSjsg if (!DATA_TABLES(dce_info)) 3454ad8b1aafSjsg return NULL; 3455ad8b1aafSjsg 3456ad8b1aafSjsg /* ver.4.4 or higher */ 3457ad8b1aafSjsg switch (rev_major) { 3458ad8b1aafSjsg case 4: 3459ad8b1aafSjsg switch (rev_minor) { 3460ad8b1aafSjsg case 4: 3461ad8b1aafSjsg disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, 3462ad8b1aafSjsg DATA_TABLES(dce_info)); 3463ad8b1aafSjsg if (!disp_cntl_tbl_4_4) 3464ad8b1aafSjsg return NULL; 3465ad8b1aafSjsg dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset; 3466ad8b1aafSjsg *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver; 3467ad8b1aafSjsg break; 34681bb76ff1Sjsg case 5: 34691bb76ff1Sjsg default: 34701bb76ff1Sjsg /* For atom_display_controller_info_v4_5 there is no need to get golden table from 34711bb76ff1Sjsg * dc_golden_table_offset as all these fields previously in golden table used for AUX 34721bb76ff1Sjsg * pre-charge settings are now available directly in atom_display_controller_info_v4_5. 34731bb76ff1Sjsg */ 34741bb76ff1Sjsg break; 3475ad8b1aafSjsg } 3476ad8b1aafSjsg break; 3477ad8b1aafSjsg } 3478ad8b1aafSjsg 3479ad8b1aafSjsg if (!dc_golden_offset) 3480ad8b1aafSjsg return NULL; 3481ad8b1aafSjsg 3482ad8b1aafSjsg if (*dc_golden_table_ver != 1) 3483ad8b1aafSjsg return NULL; 3484ad8b1aafSjsg 3485ad8b1aafSjsg return GET_IMAGE(struct atom_dc_golden_table_v1, 3486ad8b1aafSjsg dc_golden_offset); 3487ad8b1aafSjsg } 3488ad8b1aafSjsg 3489ad8b1aafSjsg static enum bp_result bios_get_atom_dc_golden_table( 3490ad8b1aafSjsg struct dc_bios *dcb) 3491ad8b1aafSjsg { 3492ad8b1aafSjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 3493ad8b1aafSjsg enum bp_result result = BP_RESULT_OK; 3494ad8b1aafSjsg struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL; 3495ad8b1aafSjsg struct atom_common_table_header *header; 3496ad8b1aafSjsg struct atom_data_revision tbl_revision; 3497ad8b1aafSjsg uint16_t dc_golden_table_ver = 0; 3498ad8b1aafSjsg 3499ad8b1aafSjsg header = GET_IMAGE(struct atom_common_table_header, 3500ad8b1aafSjsg DATA_TABLES(dce_info)); 3501ad8b1aafSjsg if (!header) 3502ad8b1aafSjsg return BP_RESULT_UNSUPPORTED; 3503ad8b1aafSjsg 3504ad8b1aafSjsg get_atom_data_table_revision(header, &tbl_revision); 3505ad8b1aafSjsg 3506ad8b1aafSjsg atom_dc_golden_table = bios_get_golden_table(bp, 3507ad8b1aafSjsg tbl_revision.major, 3508ad8b1aafSjsg tbl_revision.minor, 3509ad8b1aafSjsg &dc_golden_table_ver); 3510ad8b1aafSjsg 3511ad8b1aafSjsg if (!atom_dc_golden_table) 3512ad8b1aafSjsg return BP_RESULT_UNSUPPORTED; 3513ad8b1aafSjsg 3514ad8b1aafSjsg dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver; 3515ad8b1aafSjsg dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val; 3516ad8b1aafSjsg dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val; 3517ad8b1aafSjsg dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val; 3518ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val; 3519ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val; 3520ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val; 3521ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val; 3522ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val; 3523ad8b1aafSjsg dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val; 3524ad8b1aafSjsg 3525ad8b1aafSjsg return result; 3526ad8b1aafSjsg } 3527ad8b1aafSjsg 3528ad8b1aafSjsg 3529fb4d8502Sjsg static const struct dc_vbios_funcs vbios_funcs = { 3530fb4d8502Sjsg .get_connectors_number = bios_parser_get_connectors_number, 3531fb4d8502Sjsg 3532fb4d8502Sjsg .get_connector_id = bios_parser_get_connector_id, 3533fb4d8502Sjsg 3534fb4d8502Sjsg .get_src_obj = bios_parser_get_src_obj, 3535fb4d8502Sjsg 3536fb4d8502Sjsg .get_i2c_info = bios_parser_get_i2c_info, 3537fb4d8502Sjsg 3538fb4d8502Sjsg .get_hpd_info = bios_parser_get_hpd_info, 3539fb4d8502Sjsg 3540fb4d8502Sjsg .get_device_tag = bios_parser_get_device_tag, 3541fb4d8502Sjsg 3542fb4d8502Sjsg .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, 3543fb4d8502Sjsg 3544fb4d8502Sjsg .get_ss_entry_number = bios_parser_get_ss_entry_number, 3545fb4d8502Sjsg 3546fb4d8502Sjsg .get_embedded_panel_info = bios_parser_get_embedded_panel_info, 3547fb4d8502Sjsg 3548fb4d8502Sjsg .get_gpio_pin_info = bios_parser_get_gpio_pin_info, 3549fb4d8502Sjsg 3550fb4d8502Sjsg .get_encoder_cap_info = bios_parser_get_encoder_cap_info, 3551fb4d8502Sjsg 3552fb4d8502Sjsg .is_device_id_supported = bios_parser_is_device_id_supported, 3553fb4d8502Sjsg 3554fb4d8502Sjsg .is_accelerated_mode = bios_parser_is_accelerated_mode, 3555fb4d8502Sjsg 3556fb4d8502Sjsg .set_scratch_critical_state = bios_parser_set_scratch_critical_state, 3557fb4d8502Sjsg 3558fb4d8502Sjsg 3559fb4d8502Sjsg /* COMMANDS */ 3560fb4d8502Sjsg .encoder_control = bios_parser_encoder_control, 3561fb4d8502Sjsg 3562fb4d8502Sjsg .transmitter_control = bios_parser_transmitter_control, 3563fb4d8502Sjsg 3564fb4d8502Sjsg .enable_crtc = bios_parser_enable_crtc, 3565fb4d8502Sjsg 3566fb4d8502Sjsg .set_pixel_clock = bios_parser_set_pixel_clock, 3567fb4d8502Sjsg 3568fb4d8502Sjsg .set_dce_clock = bios_parser_set_dce_clock, 3569fb4d8502Sjsg 3570fb4d8502Sjsg .program_crtc_timing = bios_parser_program_crtc_timing, 3571fb4d8502Sjsg 3572fb4d8502Sjsg .enable_disp_power_gating = bios_parser_enable_disp_power_gating, 3573fb4d8502Sjsg 3574fb4d8502Sjsg .bios_parser_destroy = firmware_parser_destroy, 3575fb4d8502Sjsg 3576fb4d8502Sjsg .get_board_layout_info = bios_get_board_layout_info, 35771bb76ff1Sjsg /* TODO: use this fn in hw init?*/ 3578ad8b1aafSjsg .pack_data_tables = bios_parser_pack_data_tables, 3579ad8b1aafSjsg 3580ad8b1aafSjsg .get_atom_dc_golden_table = bios_get_atom_dc_golden_table, 3581ad8b1aafSjsg 3582ad8b1aafSjsg .enable_lvtma_control = bios_parser_enable_lvtma_control, 3583ad8b1aafSjsg 3584ad8b1aafSjsg .get_soc_bb_info = bios_parser_get_soc_bb_info, 35855ca02815Sjsg 35865ca02815Sjsg .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info, 35875ca02815Sjsg 35885ca02815Sjsg .get_lttpr_caps = bios_parser_get_lttpr_caps, 35895ca02815Sjsg 35905ca02815Sjsg .get_lttpr_interop = bios_parser_get_lttpr_interop, 35911bb76ff1Sjsg 35921bb76ff1Sjsg .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info, 3593fb4d8502Sjsg }; 3594fb4d8502Sjsg 3595c349dbc7Sjsg static bool bios_parser2_construct( 3596fb4d8502Sjsg struct bios_parser *bp, 3597fb4d8502Sjsg struct bp_init_data *init, 3598fb4d8502Sjsg enum dce_version dce_version) 3599fb4d8502Sjsg { 3600fb4d8502Sjsg uint16_t *rom_header_offset = NULL; 3601fb4d8502Sjsg struct atom_rom_header_v2_2 *rom_header = NULL; 3602fb4d8502Sjsg struct display_object_info_table_v1_4 *object_info_tbl; 3603fb4d8502Sjsg struct atom_data_revision tbl_rev = {0}; 3604fb4d8502Sjsg 3605fb4d8502Sjsg if (!init) 3606fb4d8502Sjsg return false; 3607fb4d8502Sjsg 3608fb4d8502Sjsg if (!init->bios) 3609fb4d8502Sjsg return false; 3610fb4d8502Sjsg 3611fb4d8502Sjsg bp->base.funcs = &vbios_funcs; 3612fb4d8502Sjsg bp->base.bios = init->bios; 3613fb4d8502Sjsg bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT; 3614fb4d8502Sjsg 3615fb4d8502Sjsg bp->base.ctx = init->ctx; 3616fb4d8502Sjsg 3617fb4d8502Sjsg bp->base.bios_local_image = NULL; 3618fb4d8502Sjsg 3619fb4d8502Sjsg rom_header_offset = 3620fb4d8502Sjsg GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER); 3621fb4d8502Sjsg 3622fb4d8502Sjsg if (!rom_header_offset) 3623fb4d8502Sjsg return false; 3624fb4d8502Sjsg 3625fb4d8502Sjsg rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset); 3626fb4d8502Sjsg 3627fb4d8502Sjsg if (!rom_header) 3628fb4d8502Sjsg return false; 3629fb4d8502Sjsg 3630fb4d8502Sjsg get_atom_data_table_revision(&rom_header->table_header, &tbl_rev); 3631fb4d8502Sjsg if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2)) 3632fb4d8502Sjsg return false; 3633fb4d8502Sjsg 3634fb4d8502Sjsg bp->master_data_tbl = 3635fb4d8502Sjsg GET_IMAGE(struct atom_master_data_table_v2_1, 3636fb4d8502Sjsg rom_header->masterdatatable_offset); 3637fb4d8502Sjsg 3638fb4d8502Sjsg if (!bp->master_data_tbl) 3639fb4d8502Sjsg return false; 3640fb4d8502Sjsg 3641fb4d8502Sjsg bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo); 3642fb4d8502Sjsg 3643fb4d8502Sjsg if (!bp->object_info_tbl_offset) 3644fb4d8502Sjsg return false; 3645fb4d8502Sjsg 3646fb4d8502Sjsg object_info_tbl = 3647fb4d8502Sjsg GET_IMAGE(struct display_object_info_table_v1_4, 3648fb4d8502Sjsg bp->object_info_tbl_offset); 3649fb4d8502Sjsg 3650fb4d8502Sjsg if (!object_info_tbl) 3651fb4d8502Sjsg return false; 3652fb4d8502Sjsg 3653fb4d8502Sjsg get_atom_data_table_revision(&object_info_tbl->table_header, 3654fb4d8502Sjsg &bp->object_info_tbl.revision); 3655fb4d8502Sjsg 3656fb4d8502Sjsg if (bp->object_info_tbl.revision.major == 1 36571bb76ff1Sjsg && bp->object_info_tbl.revision.minor == 4) { 3658fb4d8502Sjsg struct display_object_info_table_v1_4 *tbl_v1_4; 3659fb4d8502Sjsg 3660fb4d8502Sjsg tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4, 3661fb4d8502Sjsg bp->object_info_tbl_offset); 3662fb4d8502Sjsg if (!tbl_v1_4) 3663fb4d8502Sjsg return false; 3664fb4d8502Sjsg 3665fb4d8502Sjsg bp->object_info_tbl.v1_4 = tbl_v1_4; 36661bb76ff1Sjsg } else if (bp->object_info_tbl.revision.major == 1 36671bb76ff1Sjsg && bp->object_info_tbl.revision.minor == 5) { 36681bb76ff1Sjsg struct display_object_info_table_v1_5 *tbl_v1_5; 36691bb76ff1Sjsg 36701bb76ff1Sjsg tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5, 36711bb76ff1Sjsg bp->object_info_tbl_offset); 36721bb76ff1Sjsg if (!tbl_v1_5) 3673fb4d8502Sjsg return false; 3674fb4d8502Sjsg 36751bb76ff1Sjsg bp->object_info_tbl.v1_5 = tbl_v1_5; 36761bb76ff1Sjsg } else { 36771bb76ff1Sjsg ASSERT(0); 36781bb76ff1Sjsg return false; 36791bb76ff1Sjsg } 36801bb76ff1Sjsg 3681fb4d8502Sjsg dal_firmware_parser_init_cmd_tbl(bp); 3682fb4d8502Sjsg dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); 3683fb4d8502Sjsg 3684fb4d8502Sjsg bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); 3685c349dbc7Sjsg bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK; 3686ad8b1aafSjsg bios_parser_get_vram_info(&bp->base, &bp->base.vram_info); 3687fb4d8502Sjsg 3688fb4d8502Sjsg return true; 3689fb4d8502Sjsg } 3690fb4d8502Sjsg 3691fb4d8502Sjsg struct dc_bios *firmware_parser_create( 3692fb4d8502Sjsg struct bp_init_data *init, 3693fb4d8502Sjsg enum dce_version dce_version) 3694fb4d8502Sjsg { 3695f005ef32Sjsg struct bios_parser *bp; 3696fb4d8502Sjsg 3697fb4d8502Sjsg bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); 3698fb4d8502Sjsg if (!bp) 3699fb4d8502Sjsg return NULL; 3700fb4d8502Sjsg 3701c349dbc7Sjsg if (bios_parser2_construct(bp, init, dce_version)) 3702fb4d8502Sjsg return &bp->base; 3703fb4d8502Sjsg 3704fb4d8502Sjsg kfree(bp); 3705fb4d8502Sjsg return NULL; 3706fb4d8502Sjsg } 3707fb4d8502Sjsg 3708fb4d8502Sjsg 3709