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 26c349dbc7Sjsg #include <linux/slab.h> 27c349dbc7Sjsg 28fb4d8502Sjsg #include "dm_services.h" 29fb4d8502Sjsg 30fb4d8502Sjsg #include "atom.h" 31fb4d8502Sjsg 32fb4d8502Sjsg #include "dc_bios_types.h" 33fb4d8502Sjsg #include "include/gpio_service_interface.h" 34fb4d8502Sjsg #include "include/grph_object_ctrl_defs.h" 35fb4d8502Sjsg #include "include/bios_parser_interface.h" 36fb4d8502Sjsg #include "include/logger_interface.h" 37fb4d8502Sjsg 38fb4d8502Sjsg #include "command_table.h" 39fb4d8502Sjsg #include "bios_parser_helper.h" 40fb4d8502Sjsg #include "command_table_helper.h" 41fb4d8502Sjsg #include "bios_parser.h" 42fb4d8502Sjsg #include "bios_parser_types_internal.h" 43fb4d8502Sjsg #include "bios_parser_interface.h" 44fb4d8502Sjsg 45fb4d8502Sjsg #include "bios_parser_common.h" 46c349dbc7Sjsg 47fb4d8502Sjsg #include "dc.h" 48fb4d8502Sjsg 49fb4d8502Sjsg #define THREE_PERCENT_OF_10000 300 50fb4d8502Sjsg 51fb4d8502Sjsg #define LAST_RECORD_TYPE 0xff 52fb4d8502Sjsg 53fb4d8502Sjsg #define DC_LOGGER \ 54fb4d8502Sjsg bp->base.ctx->logger 55fb4d8502Sjsg 56fb4d8502Sjsg #define DATA_TABLES(table) (bp->master_data_tbl->ListOfDataTables.table) 57fb4d8502Sjsg 58fb4d8502Sjsg static void get_atom_data_table_revision( 59fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *atom_data_tbl, 60fb4d8502Sjsg struct atom_data_revision *tbl_revision); 61fb4d8502Sjsg static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object, 62fb4d8502Sjsg uint16_t **id_list); 63fb4d8502Sjsg static ATOM_OBJECT *get_bios_object(struct bios_parser *bp, 64fb4d8502Sjsg struct graphics_object_id id); 65fb4d8502Sjsg static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, 66fb4d8502Sjsg ATOM_I2C_RECORD *record, 67fb4d8502Sjsg struct graphics_object_i2c_info *info); 68fb4d8502Sjsg static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp, 69fb4d8502Sjsg ATOM_OBJECT *object); 70fb4d8502Sjsg static struct device_id device_type_from_device_id(uint16_t device_id); 71fb4d8502Sjsg static uint32_t signal_to_ss_id(enum as_signal_type signal); 72fb4d8502Sjsg static uint32_t get_support_mask_for_device_id(struct device_id device_id); 73fb4d8502Sjsg static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( 74fb4d8502Sjsg struct bios_parser *bp, 75fb4d8502Sjsg ATOM_OBJECT *object); 76fb4d8502Sjsg 77fb4d8502Sjsg #define BIOS_IMAGE_SIZE_OFFSET 2 78fb4d8502Sjsg #define BIOS_IMAGE_SIZE_UNIT 512 79fb4d8502Sjsg 80fb4d8502Sjsg /*****************************************************************************/ 81fb4d8502Sjsg static bool bios_parser_construct( 82fb4d8502Sjsg struct bios_parser *bp, 83fb4d8502Sjsg struct bp_init_data *init, 84fb4d8502Sjsg enum dce_version dce_version); 85fb4d8502Sjsg 86fb4d8502Sjsg static uint8_t bios_parser_get_connectors_number( 87fb4d8502Sjsg struct dc_bios *dcb); 88fb4d8502Sjsg 89fb4d8502Sjsg static enum bp_result bios_parser_get_embedded_panel_info( 90fb4d8502Sjsg struct dc_bios *dcb, 91fb4d8502Sjsg struct embedded_panel_info *info); 92fb4d8502Sjsg 93fb4d8502Sjsg /*****************************************************************************/ 94fb4d8502Sjsg 95fb4d8502Sjsg struct dc_bios *bios_parser_create( 96fb4d8502Sjsg struct bp_init_data *init, 97fb4d8502Sjsg enum dce_version dce_version) 98fb4d8502Sjsg { 99f005ef32Sjsg struct bios_parser *bp; 100fb4d8502Sjsg 101fb4d8502Sjsg bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); 102fb4d8502Sjsg if (!bp) 103fb4d8502Sjsg return NULL; 104fb4d8502Sjsg 105fb4d8502Sjsg if (bios_parser_construct(bp, init, dce_version)) 106fb4d8502Sjsg return &bp->base; 107fb4d8502Sjsg 108fb4d8502Sjsg kfree(bp); 109fb4d8502Sjsg BREAK_TO_DEBUGGER(); 110fb4d8502Sjsg return NULL; 111fb4d8502Sjsg } 112fb4d8502Sjsg 113c349dbc7Sjsg static void bios_parser_destruct(struct bios_parser *bp) 114fb4d8502Sjsg { 115fb4d8502Sjsg kfree(bp->base.bios_local_image); 116fb4d8502Sjsg kfree(bp->base.integrated_info); 117fb4d8502Sjsg } 118fb4d8502Sjsg 119fb4d8502Sjsg static void bios_parser_destroy(struct dc_bios **dcb) 120fb4d8502Sjsg { 121fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(*dcb); 122fb4d8502Sjsg 123fb4d8502Sjsg if (!bp) { 124fb4d8502Sjsg BREAK_TO_DEBUGGER(); 125fb4d8502Sjsg return; 126fb4d8502Sjsg } 127fb4d8502Sjsg 128c349dbc7Sjsg bios_parser_destruct(bp); 129fb4d8502Sjsg 130fb4d8502Sjsg kfree(bp); 131fb4d8502Sjsg *dcb = NULL; 132fb4d8502Sjsg } 133fb4d8502Sjsg 134fb4d8502Sjsg static uint8_t get_number_of_objects(struct bios_parser *bp, uint32_t offset) 135fb4d8502Sjsg { 136fb4d8502Sjsg ATOM_OBJECT_TABLE *table; 137fb4d8502Sjsg 138fb4d8502Sjsg uint32_t object_table_offset = bp->object_info_tbl_offset + offset; 139fb4d8502Sjsg 140f005ef32Sjsg table = ((ATOM_OBJECT_TABLE *) bios_get_image(&bp->base, 141f005ef32Sjsg object_table_offset, 142f005ef32Sjsg struct_size(table, asObjects, 1))); 143fb4d8502Sjsg 144fb4d8502Sjsg if (!table) 145fb4d8502Sjsg return 0; 146fb4d8502Sjsg else 147fb4d8502Sjsg return table->ucNumberOfObjects; 148fb4d8502Sjsg } 149fb4d8502Sjsg 150fb4d8502Sjsg static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb) 151fb4d8502Sjsg { 152fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 153fb4d8502Sjsg 154fb4d8502Sjsg return get_number_of_objects(bp, 155fb4d8502Sjsg le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset)); 156fb4d8502Sjsg } 157fb4d8502Sjsg 158fb4d8502Sjsg static struct graphics_object_id bios_parser_get_connector_id( 159fb4d8502Sjsg struct dc_bios *dcb, 160fb4d8502Sjsg uint8_t i) 161fb4d8502Sjsg { 162fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 163fb4d8502Sjsg struct graphics_object_id object_id = dal_graphics_object_id_init( 164fb4d8502Sjsg 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); 165fb4d8502Sjsg uint16_t id; 166fb4d8502Sjsg 167fb4d8502Sjsg uint32_t connector_table_offset = bp->object_info_tbl_offset 168fb4d8502Sjsg + le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset); 169fb4d8502Sjsg 170f005ef32Sjsg ATOM_OBJECT_TABLE *tbl = ((ATOM_OBJECT_TABLE *) bios_get_image(&bp->base, 171f005ef32Sjsg connector_table_offset, 172f005ef32Sjsg struct_size(tbl, asObjects, 1))); 173fb4d8502Sjsg 174fb4d8502Sjsg if (!tbl) { 175fb4d8502Sjsg dm_error("Can't get connector table from atom bios.\n"); 176fb4d8502Sjsg return object_id; 177fb4d8502Sjsg } 178fb4d8502Sjsg 179fb4d8502Sjsg if (tbl->ucNumberOfObjects <= i) { 180fb4d8502Sjsg dm_error("Can't find connector id %d in connector table of size %d.\n", 181fb4d8502Sjsg i, tbl->ucNumberOfObjects); 182fb4d8502Sjsg return object_id; 183fb4d8502Sjsg } 184fb4d8502Sjsg 185fb4d8502Sjsg id = le16_to_cpu(tbl->asObjects[i].usObjectID); 186fb4d8502Sjsg object_id = object_id_from_bios_object_id(id); 187fb4d8502Sjsg return object_id; 188fb4d8502Sjsg } 189fb4d8502Sjsg 190fb4d8502Sjsg static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, 191fb4d8502Sjsg struct graphics_object_id object_id, uint32_t index, 192fb4d8502Sjsg struct graphics_object_id *src_object_id) 193fb4d8502Sjsg { 194fb4d8502Sjsg uint32_t number; 195fb4d8502Sjsg uint16_t *id; 196fb4d8502Sjsg ATOM_OBJECT *object; 197fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 198fb4d8502Sjsg 199fb4d8502Sjsg if (!src_object_id) 200fb4d8502Sjsg return BP_RESULT_BADINPUT; 201fb4d8502Sjsg 202fb4d8502Sjsg object = get_bios_object(bp, object_id); 203fb4d8502Sjsg 204fb4d8502Sjsg if (!object) { 205fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object id */ 206fb4d8502Sjsg return BP_RESULT_BADINPUT; 207fb4d8502Sjsg } 208fb4d8502Sjsg 209fb4d8502Sjsg number = get_src_obj_list(bp, object, &id); 210fb4d8502Sjsg 211fb4d8502Sjsg if (number <= index) 212fb4d8502Sjsg return BP_RESULT_BADINPUT; 213fb4d8502Sjsg 214fb4d8502Sjsg *src_object_id = object_id_from_bios_object_id(id[index]); 215fb4d8502Sjsg 216fb4d8502Sjsg return BP_RESULT_OK; 217fb4d8502Sjsg } 218fb4d8502Sjsg 219fb4d8502Sjsg static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, 220fb4d8502Sjsg struct graphics_object_id id, 221fb4d8502Sjsg struct graphics_object_i2c_info *info) 222fb4d8502Sjsg { 223fb4d8502Sjsg uint32_t offset; 224fb4d8502Sjsg ATOM_OBJECT *object; 225fb4d8502Sjsg ATOM_COMMON_RECORD_HEADER *header; 226fb4d8502Sjsg ATOM_I2C_RECORD *record; 227fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 228fb4d8502Sjsg 229fb4d8502Sjsg if (!info) 230fb4d8502Sjsg return BP_RESULT_BADINPUT; 231fb4d8502Sjsg 232fb4d8502Sjsg object = get_bios_object(bp, id); 233fb4d8502Sjsg 234fb4d8502Sjsg if (!object) 235fb4d8502Sjsg return BP_RESULT_BADINPUT; 236fb4d8502Sjsg 237fb4d8502Sjsg offset = le16_to_cpu(object->usRecordOffset) 238fb4d8502Sjsg + bp->object_info_tbl_offset; 239fb4d8502Sjsg 240fb4d8502Sjsg for (;;) { 241fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); 242fb4d8502Sjsg 243fb4d8502Sjsg if (!header) 244fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 245fb4d8502Sjsg 246fb4d8502Sjsg if (LAST_RECORD_TYPE == header->ucRecordType || 247fb4d8502Sjsg !header->ucRecordSize) 248fb4d8502Sjsg break; 249fb4d8502Sjsg 250fb4d8502Sjsg if (ATOM_I2C_RECORD_TYPE == header->ucRecordType 251fb4d8502Sjsg && sizeof(ATOM_I2C_RECORD) <= header->ucRecordSize) { 252fb4d8502Sjsg /* get the I2C info */ 253fb4d8502Sjsg record = (ATOM_I2C_RECORD *) header; 254fb4d8502Sjsg 255fb4d8502Sjsg if (get_gpio_i2c_info(bp, record, info) == BP_RESULT_OK) 256fb4d8502Sjsg return BP_RESULT_OK; 257fb4d8502Sjsg } 258fb4d8502Sjsg 259fb4d8502Sjsg offset += header->ucRecordSize; 260fb4d8502Sjsg } 261fb4d8502Sjsg 262fb4d8502Sjsg return BP_RESULT_NORECORD; 263fb4d8502Sjsg } 264fb4d8502Sjsg 265fb4d8502Sjsg static enum bp_result bios_parser_get_hpd_info(struct dc_bios *dcb, 266fb4d8502Sjsg struct graphics_object_id id, 267fb4d8502Sjsg struct graphics_object_hpd_info *info) 268fb4d8502Sjsg { 269fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 270fb4d8502Sjsg ATOM_OBJECT *object; 271fb4d8502Sjsg ATOM_HPD_INT_RECORD *record = NULL; 272fb4d8502Sjsg 273fb4d8502Sjsg if (!info) 274fb4d8502Sjsg return BP_RESULT_BADINPUT; 275fb4d8502Sjsg 276fb4d8502Sjsg object = get_bios_object(bp, id); 277fb4d8502Sjsg 278fb4d8502Sjsg if (!object) 279fb4d8502Sjsg return BP_RESULT_BADINPUT; 280fb4d8502Sjsg 281fb4d8502Sjsg record = get_hpd_record(bp, object); 282fb4d8502Sjsg 283fb4d8502Sjsg if (record != NULL) { 284fb4d8502Sjsg info->hpd_int_gpio_uid = record->ucHPDIntGPIOID; 285fb4d8502Sjsg info->hpd_active = record->ucPlugged_PinState; 286fb4d8502Sjsg return BP_RESULT_OK; 287fb4d8502Sjsg } 288fb4d8502Sjsg 289fb4d8502Sjsg return BP_RESULT_NORECORD; 290fb4d8502Sjsg } 291fb4d8502Sjsg 292fb4d8502Sjsg static enum bp_result bios_parser_get_device_tag_record( 293fb4d8502Sjsg struct bios_parser *bp, 294fb4d8502Sjsg ATOM_OBJECT *object, 295fb4d8502Sjsg ATOM_CONNECTOR_DEVICE_TAG_RECORD **record) 296fb4d8502Sjsg { 297fb4d8502Sjsg ATOM_COMMON_RECORD_HEADER *header; 298fb4d8502Sjsg uint32_t offset; 299fb4d8502Sjsg 300fb4d8502Sjsg offset = le16_to_cpu(object->usRecordOffset) 301fb4d8502Sjsg + bp->object_info_tbl_offset; 302fb4d8502Sjsg 303fb4d8502Sjsg for (;;) { 304fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); 305fb4d8502Sjsg 306fb4d8502Sjsg if (!header) 307fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 308fb4d8502Sjsg 309fb4d8502Sjsg offset += header->ucRecordSize; 310fb4d8502Sjsg 311fb4d8502Sjsg if (LAST_RECORD_TYPE == header->ucRecordType || 312fb4d8502Sjsg !header->ucRecordSize) 313fb4d8502Sjsg break; 314fb4d8502Sjsg 315fb4d8502Sjsg if (ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE != 316fb4d8502Sjsg header->ucRecordType) 317fb4d8502Sjsg continue; 318fb4d8502Sjsg 319fb4d8502Sjsg if (sizeof(ATOM_CONNECTOR_DEVICE_TAG) > header->ucRecordSize) 320fb4d8502Sjsg continue; 321fb4d8502Sjsg 322fb4d8502Sjsg *record = (ATOM_CONNECTOR_DEVICE_TAG_RECORD *) header; 323fb4d8502Sjsg return BP_RESULT_OK; 324fb4d8502Sjsg } 325fb4d8502Sjsg 326fb4d8502Sjsg return BP_RESULT_NORECORD; 327fb4d8502Sjsg } 328fb4d8502Sjsg 329fb4d8502Sjsg static enum bp_result bios_parser_get_device_tag( 330fb4d8502Sjsg struct dc_bios *dcb, 331fb4d8502Sjsg struct graphics_object_id connector_object_id, 332fb4d8502Sjsg uint32_t device_tag_index, 333fb4d8502Sjsg struct connector_device_tag_info *info) 334fb4d8502Sjsg { 335fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 336fb4d8502Sjsg ATOM_OBJECT *object; 337fb4d8502Sjsg ATOM_CONNECTOR_DEVICE_TAG_RECORD *record = NULL; 338fb4d8502Sjsg ATOM_CONNECTOR_DEVICE_TAG *device_tag; 339fb4d8502Sjsg 340fb4d8502Sjsg if (!info) 341fb4d8502Sjsg return BP_RESULT_BADINPUT; 342fb4d8502Sjsg 343fb4d8502Sjsg /* getBiosObject will return MXM object */ 344fb4d8502Sjsg object = get_bios_object(bp, connector_object_id); 345fb4d8502Sjsg 346fb4d8502Sjsg if (!object) { 347fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object id */ 348fb4d8502Sjsg return BP_RESULT_BADINPUT; 349fb4d8502Sjsg } 350fb4d8502Sjsg 351fb4d8502Sjsg if (bios_parser_get_device_tag_record(bp, object, &record) 352fb4d8502Sjsg != BP_RESULT_OK) 353fb4d8502Sjsg return BP_RESULT_NORECORD; 354fb4d8502Sjsg 355fb4d8502Sjsg if (device_tag_index >= record->ucNumberOfDevice) 356fb4d8502Sjsg return BP_RESULT_NORECORD; 357fb4d8502Sjsg 358fb4d8502Sjsg device_tag = &record->asDeviceTag[device_tag_index]; 359fb4d8502Sjsg 360fb4d8502Sjsg info->acpi_device = le32_to_cpu(device_tag->ulACPIDeviceEnum); 361fb4d8502Sjsg info->dev_id = 362fb4d8502Sjsg device_type_from_device_id(le16_to_cpu(device_tag->usDeviceID)); 363fb4d8502Sjsg 364fb4d8502Sjsg return BP_RESULT_OK; 365fb4d8502Sjsg } 366fb4d8502Sjsg 367fb4d8502Sjsg static enum bp_result get_firmware_info_v1_4( 368fb4d8502Sjsg struct bios_parser *bp, 369fb4d8502Sjsg struct dc_firmware_info *info); 370fb4d8502Sjsg static enum bp_result get_firmware_info_v2_1( 371fb4d8502Sjsg struct bios_parser *bp, 372fb4d8502Sjsg struct dc_firmware_info *info); 373fb4d8502Sjsg static enum bp_result get_firmware_info_v2_2( 374fb4d8502Sjsg struct bios_parser *bp, 375fb4d8502Sjsg struct dc_firmware_info *info); 376fb4d8502Sjsg 377fb4d8502Sjsg static enum bp_result bios_parser_get_firmware_info( 378fb4d8502Sjsg struct dc_bios *dcb, 379fb4d8502Sjsg struct dc_firmware_info *info) 380fb4d8502Sjsg { 381fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 382fb4d8502Sjsg enum bp_result result = BP_RESULT_BADBIOSTABLE; 383fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 384fb4d8502Sjsg struct atom_data_revision revision; 385fb4d8502Sjsg 386fb4d8502Sjsg if (info && DATA_TABLES(FirmwareInfo)) { 387fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, 388fb4d8502Sjsg DATA_TABLES(FirmwareInfo)); 389fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 390fb4d8502Sjsg switch (revision.major) { 391fb4d8502Sjsg case 1: 392fb4d8502Sjsg switch (revision.minor) { 393fb4d8502Sjsg case 4: 394fb4d8502Sjsg result = get_firmware_info_v1_4(bp, info); 395fb4d8502Sjsg break; 396fb4d8502Sjsg default: 397fb4d8502Sjsg break; 398fb4d8502Sjsg } 399fb4d8502Sjsg break; 400fb4d8502Sjsg 401fb4d8502Sjsg case 2: 402fb4d8502Sjsg switch (revision.minor) { 403fb4d8502Sjsg case 1: 404fb4d8502Sjsg result = get_firmware_info_v2_1(bp, info); 405fb4d8502Sjsg break; 406fb4d8502Sjsg case 2: 407fb4d8502Sjsg result = get_firmware_info_v2_2(bp, info); 408fb4d8502Sjsg break; 409fb4d8502Sjsg default: 410fb4d8502Sjsg break; 411fb4d8502Sjsg } 412fb4d8502Sjsg break; 413fb4d8502Sjsg default: 414fb4d8502Sjsg break; 415fb4d8502Sjsg } 416fb4d8502Sjsg } 417fb4d8502Sjsg 418fb4d8502Sjsg return result; 419fb4d8502Sjsg } 420fb4d8502Sjsg 421fb4d8502Sjsg static enum bp_result get_firmware_info_v1_4( 422fb4d8502Sjsg struct bios_parser *bp, 423fb4d8502Sjsg struct dc_firmware_info *info) 424fb4d8502Sjsg { 425fb4d8502Sjsg ATOM_FIRMWARE_INFO_V1_4 *firmware_info = 426fb4d8502Sjsg GET_IMAGE(ATOM_FIRMWARE_INFO_V1_4, 427fb4d8502Sjsg DATA_TABLES(FirmwareInfo)); 428fb4d8502Sjsg 429fb4d8502Sjsg if (!info) 430fb4d8502Sjsg return BP_RESULT_BADINPUT; 431fb4d8502Sjsg 432fb4d8502Sjsg if (!firmware_info) 433fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 434fb4d8502Sjsg 435fb4d8502Sjsg memset(info, 0, sizeof(*info)); 436fb4d8502Sjsg 437fb4d8502Sjsg /* Pixel clock pll information. We need to convert from 10KHz units into 438fb4d8502Sjsg * KHz units */ 439fb4d8502Sjsg info->pll_info.crystal_frequency = 440fb4d8502Sjsg le16_to_cpu(firmware_info->usReferenceClock) * 10; 441fb4d8502Sjsg info->pll_info.min_input_pxl_clk_pll_frequency = 442fb4d8502Sjsg le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10; 443fb4d8502Sjsg info->pll_info.max_input_pxl_clk_pll_frequency = 444fb4d8502Sjsg le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10; 445fb4d8502Sjsg info->pll_info.min_output_pxl_clk_pll_frequency = 446fb4d8502Sjsg le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10; 447fb4d8502Sjsg info->pll_info.max_output_pxl_clk_pll_frequency = 448fb4d8502Sjsg le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10; 449fb4d8502Sjsg 450fb4d8502Sjsg if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) 451fb4d8502Sjsg /* Since there is no information on the SS, report conservative 452fb4d8502Sjsg * value 3% for bandwidth calculation */ 453fb4d8502Sjsg /* unit of 0.01% */ 454fb4d8502Sjsg info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000; 455fb4d8502Sjsg 456fb4d8502Sjsg if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support) 457fb4d8502Sjsg /* Since there is no information on the SS,report conservative 458fb4d8502Sjsg * value 3% for bandwidth calculation */ 459fb4d8502Sjsg /* unit of 0.01% */ 460fb4d8502Sjsg info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000; 461fb4d8502Sjsg 462fb4d8502Sjsg return BP_RESULT_OK; 463fb4d8502Sjsg } 464fb4d8502Sjsg 465fb4d8502Sjsg static enum bp_result get_ss_info_v3_1( 466fb4d8502Sjsg struct bios_parser *bp, 467fb4d8502Sjsg uint32_t id, 468fb4d8502Sjsg uint32_t index, 469fb4d8502Sjsg struct spread_spectrum_info *ss_info); 470fb4d8502Sjsg 471fb4d8502Sjsg static enum bp_result get_firmware_info_v2_1( 472fb4d8502Sjsg struct bios_parser *bp, 473fb4d8502Sjsg struct dc_firmware_info *info) 474fb4d8502Sjsg { 475fb4d8502Sjsg ATOM_FIRMWARE_INFO_V2_1 *firmwareInfo = 476fb4d8502Sjsg GET_IMAGE(ATOM_FIRMWARE_INFO_V2_1, DATA_TABLES(FirmwareInfo)); 477fb4d8502Sjsg struct spread_spectrum_info internalSS; 478fb4d8502Sjsg uint32_t index; 479fb4d8502Sjsg 480fb4d8502Sjsg if (!info) 481fb4d8502Sjsg return BP_RESULT_BADINPUT; 482fb4d8502Sjsg 483fb4d8502Sjsg if (!firmwareInfo) 484fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 485fb4d8502Sjsg 486fb4d8502Sjsg memset(info, 0, sizeof(*info)); 487fb4d8502Sjsg 488fb4d8502Sjsg /* Pixel clock pll information. We need to convert from 10KHz units into 489fb4d8502Sjsg * KHz units */ 490fb4d8502Sjsg info->pll_info.crystal_frequency = 491fb4d8502Sjsg le16_to_cpu(firmwareInfo->usCoreReferenceClock) * 10; 492fb4d8502Sjsg info->pll_info.min_input_pxl_clk_pll_frequency = 493fb4d8502Sjsg le16_to_cpu(firmwareInfo->usMinPixelClockPLL_Input) * 10; 494fb4d8502Sjsg info->pll_info.max_input_pxl_clk_pll_frequency = 495fb4d8502Sjsg le16_to_cpu(firmwareInfo->usMaxPixelClockPLL_Input) * 10; 496fb4d8502Sjsg info->pll_info.min_output_pxl_clk_pll_frequency = 497fb4d8502Sjsg le32_to_cpu(firmwareInfo->ulMinPixelClockPLL_Output) * 10; 498fb4d8502Sjsg info->pll_info.max_output_pxl_clk_pll_frequency = 499fb4d8502Sjsg le32_to_cpu(firmwareInfo->ulMaxPixelClockPLL_Output) * 10; 500fb4d8502Sjsg info->default_display_engine_pll_frequency = 501fb4d8502Sjsg le32_to_cpu(firmwareInfo->ulDefaultDispEngineClkFreq) * 10; 502fb4d8502Sjsg info->external_clock_source_frequency_for_dp = 503fb4d8502Sjsg le16_to_cpu(firmwareInfo->usUniphyDPModeExtClkFreq) * 10; 504fb4d8502Sjsg info->min_allowed_bl_level = firmwareInfo->ucMinAllowedBL_Level; 505fb4d8502Sjsg 506fb4d8502Sjsg /* There should be only one entry in the SS info table for Memory Clock 507fb4d8502Sjsg */ 508fb4d8502Sjsg index = 0; 509fb4d8502Sjsg if (firmwareInfo->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) 510fb4d8502Sjsg /* Since there is no information for external SS, report 511fb4d8502Sjsg * conservative value 3% for bandwidth calculation */ 512fb4d8502Sjsg /* unit of 0.01% */ 513fb4d8502Sjsg info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000; 514fb4d8502Sjsg else if (get_ss_info_v3_1(bp, 515fb4d8502Sjsg ASIC_INTERNAL_MEMORY_SS, index, &internalSS) == BP_RESULT_OK) { 516fb4d8502Sjsg if (internalSS.spread_spectrum_percentage) { 517fb4d8502Sjsg info->feature.memory_clk_ss_percentage = 518fb4d8502Sjsg internalSS.spread_spectrum_percentage; 519fb4d8502Sjsg if (internalSS.type.CENTER_MODE) { 520fb4d8502Sjsg /* if it is centermode, the exact SS Percentage 521fb4d8502Sjsg * will be round up of half of the percentage 522fb4d8502Sjsg * reported in the SS table */ 523fb4d8502Sjsg ++info->feature.memory_clk_ss_percentage; 524fb4d8502Sjsg info->feature.memory_clk_ss_percentage /= 2; 525fb4d8502Sjsg } 526fb4d8502Sjsg } 527fb4d8502Sjsg } 528fb4d8502Sjsg 529fb4d8502Sjsg /* There should be only one entry in the SS info table for Engine Clock 530fb4d8502Sjsg */ 531fb4d8502Sjsg index = 1; 532fb4d8502Sjsg if (firmwareInfo->usFirmwareCapability.sbfAccess.EngineClockSS_Support) 533fb4d8502Sjsg /* Since there is no information for external SS, report 534fb4d8502Sjsg * conservative value 3% for bandwidth calculation */ 535fb4d8502Sjsg /* unit of 0.01% */ 536fb4d8502Sjsg info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000; 537fb4d8502Sjsg else if (get_ss_info_v3_1(bp, 538fb4d8502Sjsg ASIC_INTERNAL_ENGINE_SS, index, &internalSS) == BP_RESULT_OK) { 539fb4d8502Sjsg if (internalSS.spread_spectrum_percentage) { 540fb4d8502Sjsg info->feature.engine_clk_ss_percentage = 541fb4d8502Sjsg internalSS.spread_spectrum_percentage; 542fb4d8502Sjsg if (internalSS.type.CENTER_MODE) { 543fb4d8502Sjsg /* if it is centermode, the exact SS Percentage 544fb4d8502Sjsg * will be round up of half of the percentage 545fb4d8502Sjsg * reported in the SS table */ 546fb4d8502Sjsg ++info->feature.engine_clk_ss_percentage; 547fb4d8502Sjsg info->feature.engine_clk_ss_percentage /= 2; 548fb4d8502Sjsg } 549fb4d8502Sjsg } 550fb4d8502Sjsg } 551fb4d8502Sjsg 552fb4d8502Sjsg return BP_RESULT_OK; 553fb4d8502Sjsg } 554fb4d8502Sjsg 555fb4d8502Sjsg static enum bp_result get_firmware_info_v2_2( 556fb4d8502Sjsg struct bios_parser *bp, 557fb4d8502Sjsg struct dc_firmware_info *info) 558fb4d8502Sjsg { 559fb4d8502Sjsg ATOM_FIRMWARE_INFO_V2_2 *firmware_info; 560fb4d8502Sjsg struct spread_spectrum_info internal_ss; 561fb4d8502Sjsg uint32_t index; 562fb4d8502Sjsg 563fb4d8502Sjsg if (!info) 564fb4d8502Sjsg return BP_RESULT_BADINPUT; 565fb4d8502Sjsg 566fb4d8502Sjsg firmware_info = GET_IMAGE(ATOM_FIRMWARE_INFO_V2_2, 567fb4d8502Sjsg DATA_TABLES(FirmwareInfo)); 568fb4d8502Sjsg 569fb4d8502Sjsg if (!firmware_info) 570fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 571fb4d8502Sjsg 572fb4d8502Sjsg memset(info, 0, sizeof(*info)); 573fb4d8502Sjsg 574fb4d8502Sjsg /* Pixel clock pll information. We need to convert from 10KHz units into 575fb4d8502Sjsg * KHz units */ 576fb4d8502Sjsg info->pll_info.crystal_frequency = 577fb4d8502Sjsg le16_to_cpu(firmware_info->usCoreReferenceClock) * 10; 578fb4d8502Sjsg info->pll_info.min_input_pxl_clk_pll_frequency = 579fb4d8502Sjsg le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10; 580fb4d8502Sjsg info->pll_info.max_input_pxl_clk_pll_frequency = 581fb4d8502Sjsg le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10; 582fb4d8502Sjsg info->pll_info.min_output_pxl_clk_pll_frequency = 583fb4d8502Sjsg le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10; 584fb4d8502Sjsg info->pll_info.max_output_pxl_clk_pll_frequency = 585fb4d8502Sjsg le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10; 586fb4d8502Sjsg info->default_display_engine_pll_frequency = 587fb4d8502Sjsg le32_to_cpu(firmware_info->ulDefaultDispEngineClkFreq) * 10; 588fb4d8502Sjsg info->external_clock_source_frequency_for_dp = 589fb4d8502Sjsg le16_to_cpu(firmware_info->usUniphyDPModeExtClkFreq) * 10; 590fb4d8502Sjsg 591fb4d8502Sjsg /* There should be only one entry in the SS info table for Memory Clock 592fb4d8502Sjsg */ 593fb4d8502Sjsg index = 0; 594fb4d8502Sjsg if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) 595fb4d8502Sjsg /* Since there is no information for external SS, report 596fb4d8502Sjsg * conservative value 3% for bandwidth calculation */ 597fb4d8502Sjsg /* unit of 0.01% */ 598fb4d8502Sjsg info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000; 599fb4d8502Sjsg else if (get_ss_info_v3_1(bp, 600fb4d8502Sjsg ASIC_INTERNAL_MEMORY_SS, index, &internal_ss) == BP_RESULT_OK) { 601fb4d8502Sjsg if (internal_ss.spread_spectrum_percentage) { 602fb4d8502Sjsg info->feature.memory_clk_ss_percentage = 603fb4d8502Sjsg internal_ss.spread_spectrum_percentage; 604fb4d8502Sjsg if (internal_ss.type.CENTER_MODE) { 605fb4d8502Sjsg /* if it is centermode, the exact SS Percentage 606fb4d8502Sjsg * will be round up of half of the percentage 607fb4d8502Sjsg * reported in the SS table */ 608fb4d8502Sjsg ++info->feature.memory_clk_ss_percentage; 609fb4d8502Sjsg info->feature.memory_clk_ss_percentage /= 2; 610fb4d8502Sjsg } 611fb4d8502Sjsg } 612fb4d8502Sjsg } 613fb4d8502Sjsg 614fb4d8502Sjsg /* There should be only one entry in the SS info table for Engine Clock 615fb4d8502Sjsg */ 616fb4d8502Sjsg index = 1; 617fb4d8502Sjsg if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support) 618fb4d8502Sjsg /* Since there is no information for external SS, report 619fb4d8502Sjsg * conservative value 3% for bandwidth calculation */ 620fb4d8502Sjsg /* unit of 0.01% */ 621fb4d8502Sjsg info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000; 622fb4d8502Sjsg else if (get_ss_info_v3_1(bp, 623fb4d8502Sjsg ASIC_INTERNAL_ENGINE_SS, index, &internal_ss) == BP_RESULT_OK) { 624fb4d8502Sjsg if (internal_ss.spread_spectrum_percentage) { 625fb4d8502Sjsg info->feature.engine_clk_ss_percentage = 626fb4d8502Sjsg internal_ss.spread_spectrum_percentage; 627fb4d8502Sjsg if (internal_ss.type.CENTER_MODE) { 628fb4d8502Sjsg /* if it is centermode, the exact SS Percentage 629fb4d8502Sjsg * will be round up of half of the percentage 630fb4d8502Sjsg * reported in the SS table */ 631fb4d8502Sjsg ++info->feature.engine_clk_ss_percentage; 632fb4d8502Sjsg info->feature.engine_clk_ss_percentage /= 2; 633fb4d8502Sjsg } 634fb4d8502Sjsg } 635fb4d8502Sjsg } 636fb4d8502Sjsg 637fb4d8502Sjsg /* Remote Display */ 638fb4d8502Sjsg info->remote_display_config = firmware_info->ucRemoteDisplayConfig; 639fb4d8502Sjsg 640fb4d8502Sjsg /* Is allowed minimum BL level */ 641fb4d8502Sjsg info->min_allowed_bl_level = firmware_info->ucMinAllowedBL_Level; 642fb4d8502Sjsg /* Used starting from CI */ 643fb4d8502Sjsg info->smu_gpu_pll_output_freq = 644fb4d8502Sjsg (uint32_t) (le32_to_cpu(firmware_info->ulGPUPLL_OutputFreq) * 10); 645fb4d8502Sjsg 646fb4d8502Sjsg return BP_RESULT_OK; 647fb4d8502Sjsg } 648fb4d8502Sjsg 649fb4d8502Sjsg static enum bp_result get_ss_info_v3_1( 650fb4d8502Sjsg struct bios_parser *bp, 651fb4d8502Sjsg uint32_t id, 652fb4d8502Sjsg uint32_t index, 653fb4d8502Sjsg struct spread_spectrum_info *ss_info) 654fb4d8502Sjsg { 655fb4d8502Sjsg ATOM_ASIC_INTERNAL_SS_INFO_V3 *ss_table_header_include; 656fb4d8502Sjsg ATOM_ASIC_SS_ASSIGNMENT_V3 *tbl; 657fb4d8502Sjsg uint32_t table_size; 658fb4d8502Sjsg uint32_t i; 659fb4d8502Sjsg uint32_t table_index = 0; 660fb4d8502Sjsg 661fb4d8502Sjsg if (!ss_info) 662fb4d8502Sjsg return BP_RESULT_BADINPUT; 663fb4d8502Sjsg 664fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 665fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 666fb4d8502Sjsg 667f005ef32Sjsg ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, 668f005ef32Sjsg DATA_TABLES(ASIC_InternalSS_Info), 669f005ef32Sjsg struct_size(ss_table_header_include, asSpreadSpectrum, 1))); 670*c6622076Sjsg if (!ss_table_header_include) 671*c6622076Sjsg return BP_RESULT_UNSUPPORTED; 672*c6622076Sjsg 673fb4d8502Sjsg table_size = 674fb4d8502Sjsg (le16_to_cpu(ss_table_header_include->sHeader.usStructureSize) 675fb4d8502Sjsg - sizeof(ATOM_COMMON_TABLE_HEADER)) 676fb4d8502Sjsg / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); 677fb4d8502Sjsg 678fb4d8502Sjsg tbl = (ATOM_ASIC_SS_ASSIGNMENT_V3 *) 679fb4d8502Sjsg &ss_table_header_include->asSpreadSpectrum[0]; 680fb4d8502Sjsg 681fb4d8502Sjsg memset(ss_info, 0, sizeof(struct spread_spectrum_info)); 682fb4d8502Sjsg 683fb4d8502Sjsg for (i = 0; i < table_size; i++) { 684fb4d8502Sjsg if (tbl[i].ucClockIndication != (uint8_t) id) 685fb4d8502Sjsg continue; 686fb4d8502Sjsg 687fb4d8502Sjsg if (table_index != index) { 688fb4d8502Sjsg table_index++; 689fb4d8502Sjsg continue; 690fb4d8502Sjsg } 691fb4d8502Sjsg /* VBIOS introduced new defines for Version 3, same values as 692fb4d8502Sjsg * before, so now use these new ones for Version 3. 693fb4d8502Sjsg * Shouldn't affect field VBIOS's V3 as define values are still 694fb4d8502Sjsg * same. 695fb4d8502Sjsg * #define SS_MODE_V3_CENTRE_SPREAD_MASK 0x01 696fb4d8502Sjsg * #define SS_MODE_V3_EXTERNAL_SS_MASK 0x02 697fb4d8502Sjsg 698fb4d8502Sjsg * Old VBIOS defines: 699fb4d8502Sjsg * #define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001 700fb4d8502Sjsg * #define ATOM_EXTERNAL_SS_MASK 0x00000002 701fb4d8502Sjsg */ 702fb4d8502Sjsg 703fb4d8502Sjsg if (SS_MODE_V3_EXTERNAL_SS_MASK & tbl[i].ucSpreadSpectrumMode) 704fb4d8502Sjsg ss_info->type.EXTERNAL = true; 705fb4d8502Sjsg 706fb4d8502Sjsg if (SS_MODE_V3_CENTRE_SPREAD_MASK & tbl[i].ucSpreadSpectrumMode) 707fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 708fb4d8502Sjsg 709fb4d8502Sjsg /* Older VBIOS (in field) always provides SS percentage in 0.01% 710fb4d8502Sjsg * units set Divider to 100 */ 711fb4d8502Sjsg ss_info->spread_percentage_divider = 100; 712fb4d8502Sjsg 713fb4d8502Sjsg /* #define SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK 0x10 */ 714fb4d8502Sjsg if (SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK 715fb4d8502Sjsg & tbl[i].ucSpreadSpectrumMode) 716fb4d8502Sjsg ss_info->spread_percentage_divider = 1000; 717fb4d8502Sjsg 718fb4d8502Sjsg ss_info->type.STEP_AND_DELAY_INFO = false; 719fb4d8502Sjsg /* convert [10KHz] into [KHz] */ 720fb4d8502Sjsg ss_info->target_clock_range = 721fb4d8502Sjsg le32_to_cpu(tbl[i].ulTargetClockRange) * 10; 722fb4d8502Sjsg ss_info->spread_spectrum_percentage = 723fb4d8502Sjsg (uint32_t)le16_to_cpu(tbl[i].usSpreadSpectrumPercentage); 724fb4d8502Sjsg ss_info->spread_spectrum_range = 725fb4d8502Sjsg (uint32_t)(le16_to_cpu(tbl[i].usSpreadRateIn10Hz) * 10); 726fb4d8502Sjsg 727fb4d8502Sjsg return BP_RESULT_OK; 728fb4d8502Sjsg } 729fb4d8502Sjsg return BP_RESULT_NORECORD; 730fb4d8502Sjsg } 731fb4d8502Sjsg 732fb4d8502Sjsg static enum bp_result bios_parser_transmitter_control( 733fb4d8502Sjsg struct dc_bios *dcb, 734fb4d8502Sjsg struct bp_transmitter_control *cntl) 735fb4d8502Sjsg { 736fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 737fb4d8502Sjsg 738fb4d8502Sjsg if (!bp->cmd_tbl.transmitter_control) 739fb4d8502Sjsg return BP_RESULT_FAILURE; 740fb4d8502Sjsg 741fb4d8502Sjsg return bp->cmd_tbl.transmitter_control(bp, cntl); 742fb4d8502Sjsg } 743fb4d8502Sjsg 744fb4d8502Sjsg static enum bp_result bios_parser_encoder_control( 745fb4d8502Sjsg struct dc_bios *dcb, 746fb4d8502Sjsg struct bp_encoder_control *cntl) 747fb4d8502Sjsg { 748fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 749fb4d8502Sjsg 750fb4d8502Sjsg if (!bp->cmd_tbl.dig_encoder_control) 751fb4d8502Sjsg return BP_RESULT_FAILURE; 752fb4d8502Sjsg 753fb4d8502Sjsg return bp->cmd_tbl.dig_encoder_control(bp, cntl); 754fb4d8502Sjsg } 755fb4d8502Sjsg 756fb4d8502Sjsg static enum bp_result bios_parser_adjust_pixel_clock( 757fb4d8502Sjsg struct dc_bios *dcb, 758fb4d8502Sjsg struct bp_adjust_pixel_clock_parameters *bp_params) 759fb4d8502Sjsg { 760fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 761fb4d8502Sjsg 762fb4d8502Sjsg if (!bp->cmd_tbl.adjust_display_pll) 763fb4d8502Sjsg return BP_RESULT_FAILURE; 764fb4d8502Sjsg 765fb4d8502Sjsg return bp->cmd_tbl.adjust_display_pll(bp, bp_params); 766fb4d8502Sjsg } 767fb4d8502Sjsg 768fb4d8502Sjsg static enum bp_result bios_parser_set_pixel_clock( 769fb4d8502Sjsg struct dc_bios *dcb, 770fb4d8502Sjsg struct bp_pixel_clock_parameters *bp_params) 771fb4d8502Sjsg { 772fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 773fb4d8502Sjsg 774fb4d8502Sjsg if (!bp->cmd_tbl.set_pixel_clock) 775fb4d8502Sjsg return BP_RESULT_FAILURE; 776fb4d8502Sjsg 777fb4d8502Sjsg return bp->cmd_tbl.set_pixel_clock(bp, bp_params); 778fb4d8502Sjsg } 779fb4d8502Sjsg 780fb4d8502Sjsg static enum bp_result bios_parser_set_dce_clock( 781fb4d8502Sjsg struct dc_bios *dcb, 782fb4d8502Sjsg struct bp_set_dce_clock_parameters *bp_params) 783fb4d8502Sjsg { 784fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 785fb4d8502Sjsg 786fb4d8502Sjsg if (!bp->cmd_tbl.set_dce_clock) 787fb4d8502Sjsg return BP_RESULT_FAILURE; 788fb4d8502Sjsg 789fb4d8502Sjsg return bp->cmd_tbl.set_dce_clock(bp, bp_params); 790fb4d8502Sjsg } 791fb4d8502Sjsg 792fb4d8502Sjsg static enum bp_result bios_parser_enable_spread_spectrum_on_ppll( 793fb4d8502Sjsg struct dc_bios *dcb, 794fb4d8502Sjsg struct bp_spread_spectrum_parameters *bp_params, 795fb4d8502Sjsg bool enable) 796fb4d8502Sjsg { 797fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 798fb4d8502Sjsg 799fb4d8502Sjsg if (!bp->cmd_tbl.enable_spread_spectrum_on_ppll) 800fb4d8502Sjsg return BP_RESULT_FAILURE; 801fb4d8502Sjsg 802fb4d8502Sjsg return bp->cmd_tbl.enable_spread_spectrum_on_ppll( 803fb4d8502Sjsg bp, bp_params, enable); 804fb4d8502Sjsg 805fb4d8502Sjsg } 806fb4d8502Sjsg 807fb4d8502Sjsg static enum bp_result bios_parser_program_crtc_timing( 808fb4d8502Sjsg struct dc_bios *dcb, 809fb4d8502Sjsg struct bp_hw_crtc_timing_parameters *bp_params) 810fb4d8502Sjsg { 811fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 812fb4d8502Sjsg 813fb4d8502Sjsg if (!bp->cmd_tbl.set_crtc_timing) 814fb4d8502Sjsg return BP_RESULT_FAILURE; 815fb4d8502Sjsg 816fb4d8502Sjsg return bp->cmd_tbl.set_crtc_timing(bp, bp_params); 817fb4d8502Sjsg } 818fb4d8502Sjsg 819fb4d8502Sjsg static enum bp_result bios_parser_program_display_engine_pll( 820fb4d8502Sjsg struct dc_bios *dcb, 821fb4d8502Sjsg struct bp_pixel_clock_parameters *bp_params) 822fb4d8502Sjsg { 823fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 824fb4d8502Sjsg 825fb4d8502Sjsg if (!bp->cmd_tbl.program_clock) 826fb4d8502Sjsg return BP_RESULT_FAILURE; 827fb4d8502Sjsg 828fb4d8502Sjsg return bp->cmd_tbl.program_clock(bp, bp_params); 829fb4d8502Sjsg 830fb4d8502Sjsg } 831fb4d8502Sjsg 832fb4d8502Sjsg 833fb4d8502Sjsg static enum bp_result bios_parser_enable_crtc( 834fb4d8502Sjsg struct dc_bios *dcb, 835fb4d8502Sjsg enum controller_id id, 836fb4d8502Sjsg bool enable) 837fb4d8502Sjsg { 838fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 839fb4d8502Sjsg 840fb4d8502Sjsg if (!bp->cmd_tbl.enable_crtc) 841fb4d8502Sjsg return BP_RESULT_FAILURE; 842fb4d8502Sjsg 843fb4d8502Sjsg return bp->cmd_tbl.enable_crtc(bp, id, enable); 844fb4d8502Sjsg } 845fb4d8502Sjsg 846fb4d8502Sjsg static enum bp_result bios_parser_enable_disp_power_gating( 847fb4d8502Sjsg struct dc_bios *dcb, 848fb4d8502Sjsg enum controller_id controller_id, 849fb4d8502Sjsg enum bp_pipe_control_action action) 850fb4d8502Sjsg { 851fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 852fb4d8502Sjsg 853fb4d8502Sjsg if (!bp->cmd_tbl.enable_disp_power_gating) 854fb4d8502Sjsg return BP_RESULT_FAILURE; 855fb4d8502Sjsg 856fb4d8502Sjsg return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id, 857fb4d8502Sjsg action); 858fb4d8502Sjsg } 859fb4d8502Sjsg 860fb4d8502Sjsg static bool bios_parser_is_device_id_supported( 861fb4d8502Sjsg struct dc_bios *dcb, 862fb4d8502Sjsg struct device_id id) 863fb4d8502Sjsg { 864fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 865fb4d8502Sjsg 866fb4d8502Sjsg uint32_t mask = get_support_mask_for_device_id(id); 867fb4d8502Sjsg 868fb4d8502Sjsg return (le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport) & mask) != 0; 869fb4d8502Sjsg } 870fb4d8502Sjsg 871fb4d8502Sjsg static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp, 872fb4d8502Sjsg ATOM_OBJECT *object) 873fb4d8502Sjsg { 874fb4d8502Sjsg ATOM_COMMON_RECORD_HEADER *header; 875fb4d8502Sjsg uint32_t offset; 876fb4d8502Sjsg 877fb4d8502Sjsg if (!object) { 878fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 879fb4d8502Sjsg return NULL; 880fb4d8502Sjsg } 881fb4d8502Sjsg 882fb4d8502Sjsg offset = le16_to_cpu(object->usRecordOffset) 883fb4d8502Sjsg + bp->object_info_tbl_offset; 884fb4d8502Sjsg 885fb4d8502Sjsg for (;;) { 886fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); 887fb4d8502Sjsg 888fb4d8502Sjsg if (!header) 889fb4d8502Sjsg return NULL; 890fb4d8502Sjsg 891fb4d8502Sjsg if (LAST_RECORD_TYPE == header->ucRecordType || 892fb4d8502Sjsg !header->ucRecordSize) 893fb4d8502Sjsg break; 894fb4d8502Sjsg 895fb4d8502Sjsg if (ATOM_HPD_INT_RECORD_TYPE == header->ucRecordType 896fb4d8502Sjsg && sizeof(ATOM_HPD_INT_RECORD) <= header->ucRecordSize) 897fb4d8502Sjsg return (ATOM_HPD_INT_RECORD *) header; 898fb4d8502Sjsg 899fb4d8502Sjsg offset += header->ucRecordSize; 900fb4d8502Sjsg } 901fb4d8502Sjsg 902fb4d8502Sjsg return NULL; 903fb4d8502Sjsg } 904fb4d8502Sjsg 905fb4d8502Sjsg static enum bp_result get_ss_info_from_ss_info_table( 906fb4d8502Sjsg struct bios_parser *bp, 907fb4d8502Sjsg uint32_t id, 908fb4d8502Sjsg struct spread_spectrum_info *ss_info); 909fb4d8502Sjsg static enum bp_result get_ss_info_from_tbl( 910fb4d8502Sjsg struct bios_parser *bp, 911fb4d8502Sjsg uint32_t id, 912fb4d8502Sjsg struct spread_spectrum_info *ss_info); 913fb4d8502Sjsg /** 914fb4d8502Sjsg * bios_parser_get_spread_spectrum_info 915fb4d8502Sjsg * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or 916fb4d8502Sjsg * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info 917fb4d8502Sjsg * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info ver 3.1, 918fb4d8502Sjsg * there is only one entry for each signal /ss id. However, there is 919fb4d8502Sjsg * no planning of supporting multiple spread Sprectum entry for EverGreen 9205ca02815Sjsg * @dcb: pointer to the DC BIOS 9215ca02815Sjsg * @signal: ASSignalType to be converted to info index 9225ca02815Sjsg * @index: number of entries that match the converted info index 9235ca02815Sjsg * @ss_info: sprectrum information structure, 9245ca02815Sjsg * return: Bios parser result code 925fb4d8502Sjsg */ 926fb4d8502Sjsg static enum bp_result bios_parser_get_spread_spectrum_info( 927fb4d8502Sjsg struct dc_bios *dcb, 928fb4d8502Sjsg enum as_signal_type signal, 929fb4d8502Sjsg uint32_t index, 930fb4d8502Sjsg struct spread_spectrum_info *ss_info) 931fb4d8502Sjsg { 932fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 933fb4d8502Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 934fb4d8502Sjsg uint32_t clk_id_ss = 0; 935fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 936fb4d8502Sjsg struct atom_data_revision tbl_revision; 937fb4d8502Sjsg 938fb4d8502Sjsg if (!ss_info) /* check for bad input */ 939fb4d8502Sjsg return BP_RESULT_BADINPUT; 940fb4d8502Sjsg /* signal translation */ 941fb4d8502Sjsg clk_id_ss = signal_to_ss_id(signal); 942fb4d8502Sjsg 943fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 944fb4d8502Sjsg if (!index) 945fb4d8502Sjsg return get_ss_info_from_ss_info_table(bp, clk_id_ss, 946fb4d8502Sjsg ss_info); 947fb4d8502Sjsg 948fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, 949fb4d8502Sjsg DATA_TABLES(ASIC_InternalSS_Info)); 950fb4d8502Sjsg get_atom_data_table_revision(header, &tbl_revision); 951fb4d8502Sjsg 952fb4d8502Sjsg switch (tbl_revision.major) { 953fb4d8502Sjsg case 2: 954fb4d8502Sjsg switch (tbl_revision.minor) { 955fb4d8502Sjsg case 1: 956fb4d8502Sjsg /* there can not be more then one entry for Internal 957fb4d8502Sjsg * SS Info table version 2.1 */ 958fb4d8502Sjsg if (!index) 959fb4d8502Sjsg return get_ss_info_from_tbl(bp, clk_id_ss, 960fb4d8502Sjsg ss_info); 961fb4d8502Sjsg break; 962fb4d8502Sjsg default: 963fb4d8502Sjsg break; 964fb4d8502Sjsg } 965fb4d8502Sjsg break; 966fb4d8502Sjsg 967fb4d8502Sjsg case 3: 968fb4d8502Sjsg switch (tbl_revision.minor) { 969fb4d8502Sjsg case 1: 970fb4d8502Sjsg return get_ss_info_v3_1(bp, clk_id_ss, index, ss_info); 971fb4d8502Sjsg default: 972fb4d8502Sjsg break; 973fb4d8502Sjsg } 974fb4d8502Sjsg break; 975fb4d8502Sjsg default: 976fb4d8502Sjsg break; 977fb4d8502Sjsg } 978fb4d8502Sjsg /* there can not be more then one entry for SS Info table */ 979fb4d8502Sjsg return result; 980fb4d8502Sjsg } 981fb4d8502Sjsg 982fb4d8502Sjsg static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( 983fb4d8502Sjsg struct bios_parser *bp, 984fb4d8502Sjsg uint32_t id, 985fb4d8502Sjsg struct spread_spectrum_info *info); 986fb4d8502Sjsg 987fb4d8502Sjsg /** 9885ca02815Sjsg * get_ss_info_from_tbl 989fb4d8502Sjsg * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or 990fb4d8502Sjsg * SS_Info table from the VBIOS 991fb4d8502Sjsg * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or 992fb4d8502Sjsg * SS_Info. 993fb4d8502Sjsg * 9945ca02815Sjsg * @bp: pointer to the BIOS parser 9955ca02815Sjsg * @id: spread sprectrum info index 9965ca02815Sjsg * @ss_info: sprectrum information structure, 9975ca02815Sjsg * return: BIOS parser result code 998fb4d8502Sjsg */ 999fb4d8502Sjsg static enum bp_result get_ss_info_from_tbl( 1000fb4d8502Sjsg struct bios_parser *bp, 1001fb4d8502Sjsg uint32_t id, 1002fb4d8502Sjsg struct spread_spectrum_info *ss_info) 1003fb4d8502Sjsg { 1004fb4d8502Sjsg if (!ss_info) /* check for bad input, if ss_info is not NULL */ 1005fb4d8502Sjsg return BP_RESULT_BADINPUT; 1006fb4d8502Sjsg /* for SS_Info table only support DP and LVDS */ 1007fb4d8502Sjsg if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS) 1008fb4d8502Sjsg return get_ss_info_from_ss_info_table(bp, id, ss_info); 1009fb4d8502Sjsg else 1010fb4d8502Sjsg return get_ss_info_from_internal_ss_info_tbl_V2_1(bp, id, 1011fb4d8502Sjsg ss_info); 1012fb4d8502Sjsg } 1013fb4d8502Sjsg 1014fb4d8502Sjsg /** 1015fb4d8502Sjsg * get_ss_info_from_internal_ss_info_tbl_V2_1 1016fb4d8502Sjsg * Get spread sprectrum information from the ASIC_InternalSS_Info table Ver 2.1 1017fb4d8502Sjsg * from the VBIOS 1018fb4d8502Sjsg * There will not be multiple entry for Ver 2.1 1019fb4d8502Sjsg * 10205ca02815Sjsg * @bp: pointer to the Bios parser 10215ca02815Sjsg * @id: spread sprectrum info index 10225ca02815Sjsg * @info: sprectrum information structure, 10235ca02815Sjsg * return: Bios parser result code 1024fb4d8502Sjsg */ 1025fb4d8502Sjsg static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( 1026fb4d8502Sjsg struct bios_parser *bp, 1027fb4d8502Sjsg uint32_t id, 1028fb4d8502Sjsg struct spread_spectrum_info *info) 1029fb4d8502Sjsg { 1030fb4d8502Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 1031fb4d8502Sjsg ATOM_ASIC_INTERNAL_SS_INFO_V2 *header; 1032fb4d8502Sjsg ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl; 1033fb4d8502Sjsg uint32_t tbl_size, i; 1034fb4d8502Sjsg 1035fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 1036fb4d8502Sjsg return result; 1037fb4d8502Sjsg 1038f005ef32Sjsg header = ((ATOM_ASIC_INTERNAL_SS_INFO_V2 *) bios_get_image( 1039f005ef32Sjsg &bp->base, 1040f005ef32Sjsg DATA_TABLES(ASIC_InternalSS_Info), 1041f005ef32Sjsg struct_size(header, asSpreadSpectrum, 1))); 1042*c6622076Sjsg if (!header) 1043*c6622076Sjsg return result; 1044fb4d8502Sjsg 1045fb4d8502Sjsg memset(info, 0, sizeof(struct spread_spectrum_info)); 1046fb4d8502Sjsg 1047fb4d8502Sjsg tbl_size = (le16_to_cpu(header->sHeader.usStructureSize) 1048fb4d8502Sjsg - sizeof(ATOM_COMMON_TABLE_HEADER)) 1049fb4d8502Sjsg / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); 1050fb4d8502Sjsg 1051fb4d8502Sjsg tbl = (ATOM_ASIC_SS_ASSIGNMENT_V2 *) 1052fb4d8502Sjsg &(header->asSpreadSpectrum[0]); 1053fb4d8502Sjsg for (i = 0; i < tbl_size; i++) { 1054fb4d8502Sjsg result = BP_RESULT_NORECORD; 1055fb4d8502Sjsg 1056fb4d8502Sjsg if (tbl[i].ucClockIndication != (uint8_t)id) 1057fb4d8502Sjsg continue; 1058fb4d8502Sjsg 1059fb4d8502Sjsg if (ATOM_EXTERNAL_SS_MASK 1060fb4d8502Sjsg & tbl[i].ucSpreadSpectrumMode) { 1061fb4d8502Sjsg info->type.EXTERNAL = true; 1062fb4d8502Sjsg } 1063fb4d8502Sjsg if (ATOM_SS_CENTRE_SPREAD_MODE_MASK 1064fb4d8502Sjsg & tbl[i].ucSpreadSpectrumMode) { 1065fb4d8502Sjsg info->type.CENTER_MODE = true; 1066fb4d8502Sjsg } 1067fb4d8502Sjsg info->type.STEP_AND_DELAY_INFO = false; 1068fb4d8502Sjsg /* convert [10KHz] into [KHz] */ 1069fb4d8502Sjsg info->target_clock_range = 1070fb4d8502Sjsg le32_to_cpu(tbl[i].ulTargetClockRange) * 10; 1071fb4d8502Sjsg info->spread_spectrum_percentage = 1072fb4d8502Sjsg (uint32_t)le16_to_cpu(tbl[i].usSpreadSpectrumPercentage); 1073fb4d8502Sjsg info->spread_spectrum_range = 1074fb4d8502Sjsg (uint32_t)(le16_to_cpu(tbl[i].usSpreadRateIn10Hz) * 10); 1075fb4d8502Sjsg result = BP_RESULT_OK; 1076fb4d8502Sjsg break; 1077fb4d8502Sjsg } 1078fb4d8502Sjsg 1079fb4d8502Sjsg return result; 1080fb4d8502Sjsg 1081fb4d8502Sjsg } 1082fb4d8502Sjsg 1083fb4d8502Sjsg /** 1084fb4d8502Sjsg * get_ss_info_from_ss_info_table 1085fb4d8502Sjsg * Get spread sprectrum information from the SS_Info table from the VBIOS 1086fb4d8502Sjsg * if the pointer to info is NULL, indicate the caller what to know the number 1087fb4d8502Sjsg * of entries that matches the id 1088fb4d8502Sjsg * for, the SS_Info table, there should not be more than 1 entry match. 1089fb4d8502Sjsg * 10905ca02815Sjsg * @bp: pointer to the Bios parser 10915ca02815Sjsg * @id: spread sprectrum id 10925ca02815Sjsg * @ss_info: sprectrum information structure, 10935ca02815Sjsg * return: Bios parser result code 1094fb4d8502Sjsg */ 1095fb4d8502Sjsg static enum bp_result get_ss_info_from_ss_info_table( 1096fb4d8502Sjsg struct bios_parser *bp, 1097fb4d8502Sjsg uint32_t id, 1098fb4d8502Sjsg struct spread_spectrum_info *ss_info) 1099fb4d8502Sjsg { 1100fb4d8502Sjsg enum bp_result result = BP_RESULT_UNSUPPORTED; 1101fb4d8502Sjsg ATOM_SPREAD_SPECTRUM_INFO *tbl; 1102fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 1103fb4d8502Sjsg uint32_t table_size; 1104fb4d8502Sjsg uint32_t i; 1105fb4d8502Sjsg uint32_t id_local = SS_ID_UNKNOWN; 1106fb4d8502Sjsg struct atom_data_revision revision; 1107fb4d8502Sjsg 1108fb4d8502Sjsg /* exist of the SS_Info table */ 1109fb4d8502Sjsg /* check for bad input, pSSinfo can not be NULL */ 1110fb4d8502Sjsg if (!DATA_TABLES(SS_Info) || !ss_info) 1111fb4d8502Sjsg return result; 1112fb4d8502Sjsg 1113fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, DATA_TABLES(SS_Info)); 1114fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 1115fb4d8502Sjsg 1116fb4d8502Sjsg tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); 1117*c6622076Sjsg if (!tbl) 1118*c6622076Sjsg return result; 1119fb4d8502Sjsg 1120fb4d8502Sjsg if (1 != revision.major || 2 > revision.minor) 1121fb4d8502Sjsg return result; 1122fb4d8502Sjsg 1123fb4d8502Sjsg /* have to convert from Internal_SS format to SS_Info format */ 1124fb4d8502Sjsg switch (id) { 1125fb4d8502Sjsg case ASIC_INTERNAL_SS_ON_DP: 1126fb4d8502Sjsg id_local = SS_ID_DP1; 1127fb4d8502Sjsg break; 1128fb4d8502Sjsg case ASIC_INTERNAL_SS_ON_LVDS: 1129fb4d8502Sjsg { 1130fb4d8502Sjsg struct embedded_panel_info panel_info; 1131fb4d8502Sjsg 1132fb4d8502Sjsg if (bios_parser_get_embedded_panel_info(&bp->base, &panel_info) 1133fb4d8502Sjsg == BP_RESULT_OK) 1134fb4d8502Sjsg id_local = panel_info.ss_id; 1135fb4d8502Sjsg break; 1136fb4d8502Sjsg } 1137fb4d8502Sjsg default: 1138fb4d8502Sjsg break; 1139fb4d8502Sjsg } 1140fb4d8502Sjsg 1141fb4d8502Sjsg if (id_local == SS_ID_UNKNOWN) 1142fb4d8502Sjsg return result; 1143fb4d8502Sjsg 1144fb4d8502Sjsg table_size = (le16_to_cpu(tbl->sHeader.usStructureSize) - 1145fb4d8502Sjsg sizeof(ATOM_COMMON_TABLE_HEADER)) / 1146fb4d8502Sjsg sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); 1147fb4d8502Sjsg 1148fb4d8502Sjsg for (i = 0; i < table_size; i++) { 1149fb4d8502Sjsg if (id_local != (uint32_t)tbl->asSS_Info[i].ucSS_Id) 1150fb4d8502Sjsg continue; 1151fb4d8502Sjsg 1152fb4d8502Sjsg memset(ss_info, 0, sizeof(struct spread_spectrum_info)); 1153fb4d8502Sjsg 1154fb4d8502Sjsg if (ATOM_EXTERNAL_SS_MASK & 1155fb4d8502Sjsg tbl->asSS_Info[i].ucSpreadSpectrumType) 1156fb4d8502Sjsg ss_info->type.EXTERNAL = true; 1157fb4d8502Sjsg 1158fb4d8502Sjsg if (ATOM_SS_CENTRE_SPREAD_MODE_MASK & 1159fb4d8502Sjsg tbl->asSS_Info[i].ucSpreadSpectrumType) 1160fb4d8502Sjsg ss_info->type.CENTER_MODE = true; 1161fb4d8502Sjsg 1162fb4d8502Sjsg ss_info->type.STEP_AND_DELAY_INFO = true; 1163fb4d8502Sjsg ss_info->spread_spectrum_percentage = 1164fb4d8502Sjsg (uint32_t)le16_to_cpu(tbl->asSS_Info[i].usSpreadSpectrumPercentage); 1165fb4d8502Sjsg ss_info->step_and_delay_info.step = tbl->asSS_Info[i].ucSS_Step; 1166fb4d8502Sjsg ss_info->step_and_delay_info.delay = 1167fb4d8502Sjsg tbl->asSS_Info[i].ucSS_Delay; 1168fb4d8502Sjsg ss_info->step_and_delay_info.recommended_ref_div = 1169fb4d8502Sjsg tbl->asSS_Info[i].ucRecommendedRef_Div; 1170fb4d8502Sjsg ss_info->spread_spectrum_range = 1171fb4d8502Sjsg (uint32_t)tbl->asSS_Info[i].ucSS_Range * 10000; 1172fb4d8502Sjsg 1173fb4d8502Sjsg /* there will be only one entry for each display type in SS_info 1174fb4d8502Sjsg * table */ 1175fb4d8502Sjsg result = BP_RESULT_OK; 1176fb4d8502Sjsg break; 1177fb4d8502Sjsg } 1178fb4d8502Sjsg 1179fb4d8502Sjsg return result; 1180fb4d8502Sjsg } 1181fb4d8502Sjsg static enum bp_result get_embedded_panel_info_v1_2( 1182fb4d8502Sjsg struct bios_parser *bp, 1183fb4d8502Sjsg struct embedded_panel_info *info); 1184fb4d8502Sjsg static enum bp_result get_embedded_panel_info_v1_3( 1185fb4d8502Sjsg struct bios_parser *bp, 1186fb4d8502Sjsg struct embedded_panel_info *info); 1187fb4d8502Sjsg 1188fb4d8502Sjsg static enum bp_result bios_parser_get_embedded_panel_info( 1189fb4d8502Sjsg struct dc_bios *dcb, 1190fb4d8502Sjsg struct embedded_panel_info *info) 1191fb4d8502Sjsg { 1192fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1193fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *hdr; 1194fb4d8502Sjsg 1195fb4d8502Sjsg if (!DATA_TABLES(LCD_Info)) 1196fb4d8502Sjsg return BP_RESULT_FAILURE; 1197fb4d8502Sjsg 1198fb4d8502Sjsg hdr = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, DATA_TABLES(LCD_Info)); 1199fb4d8502Sjsg 1200fb4d8502Sjsg if (!hdr) 1201fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1202fb4d8502Sjsg 1203fb4d8502Sjsg switch (hdr->ucTableFormatRevision) { 1204fb4d8502Sjsg case 1: 1205fb4d8502Sjsg switch (hdr->ucTableContentRevision) { 1206fb4d8502Sjsg case 0: 1207fb4d8502Sjsg case 1: 1208fb4d8502Sjsg case 2: 1209fb4d8502Sjsg return get_embedded_panel_info_v1_2(bp, info); 1210fb4d8502Sjsg case 3: 1211fb4d8502Sjsg return get_embedded_panel_info_v1_3(bp, info); 1212fb4d8502Sjsg default: 1213fb4d8502Sjsg break; 1214fb4d8502Sjsg } 12155ca02815Sjsg break; 1216fb4d8502Sjsg default: 1217fb4d8502Sjsg break; 1218fb4d8502Sjsg } 1219fb4d8502Sjsg 1220fb4d8502Sjsg return BP_RESULT_FAILURE; 1221fb4d8502Sjsg } 1222fb4d8502Sjsg 1223fb4d8502Sjsg static enum bp_result get_embedded_panel_info_v1_2( 1224fb4d8502Sjsg struct bios_parser *bp, 1225fb4d8502Sjsg struct embedded_panel_info *info) 1226fb4d8502Sjsg { 1227fb4d8502Sjsg ATOM_LVDS_INFO_V12 *lvds; 1228fb4d8502Sjsg 1229fb4d8502Sjsg if (!info) 1230fb4d8502Sjsg return BP_RESULT_BADINPUT; 1231fb4d8502Sjsg 1232fb4d8502Sjsg if (!DATA_TABLES(LVDS_Info)) 1233fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1234fb4d8502Sjsg 1235fb4d8502Sjsg lvds = 1236fb4d8502Sjsg GET_IMAGE(ATOM_LVDS_INFO_V12, DATA_TABLES(LVDS_Info)); 1237fb4d8502Sjsg 1238fb4d8502Sjsg if (!lvds) 1239fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1240fb4d8502Sjsg 1241fb4d8502Sjsg if (1 != lvds->sHeader.ucTableFormatRevision 1242fb4d8502Sjsg || 2 > lvds->sHeader.ucTableContentRevision) 1243fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1244fb4d8502Sjsg 1245fb4d8502Sjsg memset(info, 0, sizeof(struct embedded_panel_info)); 1246fb4d8502Sjsg 1247fb4d8502Sjsg /* We need to convert from 10KHz units into KHz units*/ 1248fb4d8502Sjsg info->lcd_timing.pixel_clk = 1249fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10; 1250fb4d8502Sjsg /* usHActive does not include borders, according to VBIOS team*/ 1251fb4d8502Sjsg info->lcd_timing.horizontal_addressable = 1252fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHActive); 1253fb4d8502Sjsg /* usHBlanking_Time includes borders, so we should really be subtracting 1254fb4d8502Sjsg * borders duing this translation, but LVDS generally*/ 1255fb4d8502Sjsg /* doesn't have borders, so we should be okay leaving this as is for 1256fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders*/ 1257fb4d8502Sjsg info->lcd_timing.horizontal_blanking_time = 1258fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time); 1259fb4d8502Sjsg /* usVActive does not include borders, according to VBIOS team*/ 1260fb4d8502Sjsg info->lcd_timing.vertical_addressable = 1261fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVActive); 1262fb4d8502Sjsg /* usVBlanking_Time includes borders, so we should really be subtracting 1263fb4d8502Sjsg * borders duing this translation, but LVDS generally*/ 1264fb4d8502Sjsg /* doesn't have borders, so we should be okay leaving this as is for 1265fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders*/ 1266fb4d8502Sjsg info->lcd_timing.vertical_blanking_time = 1267fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time); 1268fb4d8502Sjsg info->lcd_timing.horizontal_sync_offset = 1269fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHSyncOffset); 1270fb4d8502Sjsg info->lcd_timing.horizontal_sync_width = 1271fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHSyncWidth); 1272fb4d8502Sjsg info->lcd_timing.vertical_sync_offset = 1273fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVSyncOffset); 1274fb4d8502Sjsg info->lcd_timing.vertical_sync_width = 1275fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVSyncWidth); 1276fb4d8502Sjsg info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder; 1277fb4d8502Sjsg info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder; 1278fb4d8502Sjsg info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 1279fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff; 1280fb4d8502Sjsg info->lcd_timing.misc_info.H_SYNC_POLARITY = 1281fb4d8502Sjsg ~(uint32_t) 1282fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity; 1283fb4d8502Sjsg info->lcd_timing.misc_info.V_SYNC_POLARITY = 1284fb4d8502Sjsg ~(uint32_t) 1285fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity; 1286fb4d8502Sjsg info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 1287fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff; 1288fb4d8502Sjsg info->lcd_timing.misc_info.H_REPLICATION_BY2 = 1289fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2; 1290fb4d8502Sjsg info->lcd_timing.misc_info.V_REPLICATION_BY2 = 1291fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2; 1292fb4d8502Sjsg info->lcd_timing.misc_info.COMPOSITE_SYNC = 1293fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync; 1294fb4d8502Sjsg info->lcd_timing.misc_info.INTERLACE = 1295fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace; 1296fb4d8502Sjsg info->lcd_timing.misc_info.DOUBLE_CLOCK = 1297fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock; 1298fb4d8502Sjsg info->ss_id = lvds->ucSS_Id; 1299fb4d8502Sjsg 1300fb4d8502Sjsg { 1301fb4d8502Sjsg uint8_t rr = le16_to_cpu(lvds->usSupportedRefreshRate); 1302fb4d8502Sjsg /* Get minimum supported refresh rate*/ 1303fb4d8502Sjsg if (SUPPORTED_LCD_REFRESHRATE_30Hz & rr) 1304fb4d8502Sjsg info->supported_rr.REFRESH_RATE_30HZ = 1; 1305fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_40Hz & rr) 1306fb4d8502Sjsg info->supported_rr.REFRESH_RATE_40HZ = 1; 1307fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_48Hz & rr) 1308fb4d8502Sjsg info->supported_rr.REFRESH_RATE_48HZ = 1; 1309fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_50Hz & rr) 1310fb4d8502Sjsg info->supported_rr.REFRESH_RATE_50HZ = 1; 1311fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_60Hz & rr) 1312fb4d8502Sjsg info->supported_rr.REFRESH_RATE_60HZ = 1; 1313fb4d8502Sjsg } 1314fb4d8502Sjsg 1315fb4d8502Sjsg /*Drr panel support can be reported by VBIOS*/ 1316fb4d8502Sjsg if (LCDPANEL_CAP_DRR_SUPPORTED 1317fb4d8502Sjsg & lvds->ucLCDPanel_SpecialHandlingCap) 1318fb4d8502Sjsg info->drr_enabled = 1; 1319fb4d8502Sjsg 1320fb4d8502Sjsg if (ATOM_PANEL_MISC_DUAL & lvds->ucLVDS_Misc) 1321fb4d8502Sjsg info->lcd_timing.misc_info.DOUBLE_CLOCK = true; 1322fb4d8502Sjsg 1323fb4d8502Sjsg if (ATOM_PANEL_MISC_888RGB & lvds->ucLVDS_Misc) 1324fb4d8502Sjsg info->lcd_timing.misc_info.RGB888 = true; 1325fb4d8502Sjsg 1326fb4d8502Sjsg info->lcd_timing.misc_info.GREY_LEVEL = 1327fb4d8502Sjsg (uint32_t) (ATOM_PANEL_MISC_GREY_LEVEL & 1328fb4d8502Sjsg lvds->ucLVDS_Misc) >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT; 1329fb4d8502Sjsg 1330fb4d8502Sjsg if (ATOM_PANEL_MISC_SPATIAL & lvds->ucLVDS_Misc) 1331fb4d8502Sjsg info->lcd_timing.misc_info.SPATIAL = true; 1332fb4d8502Sjsg 1333fb4d8502Sjsg if (ATOM_PANEL_MISC_TEMPORAL & lvds->ucLVDS_Misc) 1334fb4d8502Sjsg info->lcd_timing.misc_info.TEMPORAL = true; 1335fb4d8502Sjsg 1336fb4d8502Sjsg if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc) 1337fb4d8502Sjsg info->lcd_timing.misc_info.API_ENABLED = true; 1338fb4d8502Sjsg 1339fb4d8502Sjsg return BP_RESULT_OK; 1340fb4d8502Sjsg } 1341fb4d8502Sjsg 1342fb4d8502Sjsg static enum bp_result get_embedded_panel_info_v1_3( 1343fb4d8502Sjsg struct bios_parser *bp, 1344fb4d8502Sjsg struct embedded_panel_info *info) 1345fb4d8502Sjsg { 1346fb4d8502Sjsg ATOM_LCD_INFO_V13 *lvds; 1347fb4d8502Sjsg 1348fb4d8502Sjsg if (!info) 1349fb4d8502Sjsg return BP_RESULT_BADINPUT; 1350fb4d8502Sjsg 1351fb4d8502Sjsg if (!DATA_TABLES(LCD_Info)) 1352fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1353fb4d8502Sjsg 1354fb4d8502Sjsg lvds = GET_IMAGE(ATOM_LCD_INFO_V13, DATA_TABLES(LCD_Info)); 1355fb4d8502Sjsg 1356fb4d8502Sjsg if (!lvds) 1357fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1358fb4d8502Sjsg 1359fb4d8502Sjsg if (!((1 == lvds->sHeader.ucTableFormatRevision) 1360fb4d8502Sjsg && (3 <= lvds->sHeader.ucTableContentRevision))) 1361fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1362fb4d8502Sjsg 1363fb4d8502Sjsg memset(info, 0, sizeof(struct embedded_panel_info)); 1364fb4d8502Sjsg 1365fb4d8502Sjsg /* We need to convert from 10KHz units into KHz units */ 1366fb4d8502Sjsg info->lcd_timing.pixel_clk = 1367fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10; 1368fb4d8502Sjsg /* usHActive does not include borders, according to VBIOS team */ 1369fb4d8502Sjsg info->lcd_timing.horizontal_addressable = 1370fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHActive); 1371fb4d8502Sjsg /* usHBlanking_Time includes borders, so we should really be subtracting 1372fb4d8502Sjsg * borders duing this translation, but LVDS generally*/ 1373fb4d8502Sjsg /* doesn't have borders, so we should be okay leaving this as is for 1374fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders*/ 1375fb4d8502Sjsg info->lcd_timing.horizontal_blanking_time = 1376fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time); 1377fb4d8502Sjsg /* usVActive does not include borders, according to VBIOS team*/ 1378fb4d8502Sjsg info->lcd_timing.vertical_addressable = 1379fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVActive); 1380fb4d8502Sjsg /* usVBlanking_Time includes borders, so we should really be subtracting 1381fb4d8502Sjsg * borders duing this translation, but LVDS generally*/ 1382fb4d8502Sjsg /* doesn't have borders, so we should be okay leaving this as is for 1383fb4d8502Sjsg * now. May need to revisit if we ever have LVDS with borders*/ 1384fb4d8502Sjsg info->lcd_timing.vertical_blanking_time = 1385fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time); 1386fb4d8502Sjsg info->lcd_timing.horizontal_sync_offset = 1387fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHSyncOffset); 1388fb4d8502Sjsg info->lcd_timing.horizontal_sync_width = 1389fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usHSyncWidth); 1390fb4d8502Sjsg info->lcd_timing.vertical_sync_offset = 1391fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVSyncOffset); 1392fb4d8502Sjsg info->lcd_timing.vertical_sync_width = 1393fb4d8502Sjsg le16_to_cpu(lvds->sLCDTiming.usVSyncWidth); 1394fb4d8502Sjsg info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder; 1395fb4d8502Sjsg info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder; 1396fb4d8502Sjsg info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 1397fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff; 1398fb4d8502Sjsg info->lcd_timing.misc_info.H_SYNC_POLARITY = 1399fb4d8502Sjsg ~(uint32_t) 1400fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity; 1401fb4d8502Sjsg info->lcd_timing.misc_info.V_SYNC_POLARITY = 1402fb4d8502Sjsg ~(uint32_t) 1403fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity; 1404fb4d8502Sjsg info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 1405fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff; 1406fb4d8502Sjsg info->lcd_timing.misc_info.H_REPLICATION_BY2 = 1407fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2; 1408fb4d8502Sjsg info->lcd_timing.misc_info.V_REPLICATION_BY2 = 1409fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2; 1410fb4d8502Sjsg info->lcd_timing.misc_info.COMPOSITE_SYNC = 1411fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync; 1412fb4d8502Sjsg info->lcd_timing.misc_info.INTERLACE = 1413fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace; 1414fb4d8502Sjsg info->lcd_timing.misc_info.DOUBLE_CLOCK = 1415fb4d8502Sjsg lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock; 1416fb4d8502Sjsg info->ss_id = lvds->ucSS_Id; 1417fb4d8502Sjsg 1418fb4d8502Sjsg /* Drr panel support can be reported by VBIOS*/ 1419fb4d8502Sjsg if (LCDPANEL_CAP_V13_DRR_SUPPORTED 1420fb4d8502Sjsg & lvds->ucLCDPanel_SpecialHandlingCap) 1421fb4d8502Sjsg info->drr_enabled = 1; 1422fb4d8502Sjsg 1423fb4d8502Sjsg /* Get supported refresh rate*/ 1424fb4d8502Sjsg if (info->drr_enabled == 1) { 1425fb4d8502Sjsg uint8_t min_rr = 1426fb4d8502Sjsg lvds->sRefreshRateSupport.ucMinRefreshRateForDRR; 1427fb4d8502Sjsg uint8_t rr = lvds->sRefreshRateSupport.ucSupportedRefreshRate; 1428fb4d8502Sjsg 1429fb4d8502Sjsg if (min_rr != 0) { 1430fb4d8502Sjsg if (SUPPORTED_LCD_REFRESHRATE_30Hz & min_rr) 1431fb4d8502Sjsg info->supported_rr.REFRESH_RATE_30HZ = 1; 1432fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_40Hz & min_rr) 1433fb4d8502Sjsg info->supported_rr.REFRESH_RATE_40HZ = 1; 1434fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_48Hz & min_rr) 1435fb4d8502Sjsg info->supported_rr.REFRESH_RATE_48HZ = 1; 1436fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_50Hz & min_rr) 1437fb4d8502Sjsg info->supported_rr.REFRESH_RATE_50HZ = 1; 1438fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_60Hz & min_rr) 1439fb4d8502Sjsg info->supported_rr.REFRESH_RATE_60HZ = 1; 1440fb4d8502Sjsg } else { 1441fb4d8502Sjsg if (SUPPORTED_LCD_REFRESHRATE_30Hz & rr) 1442fb4d8502Sjsg info->supported_rr.REFRESH_RATE_30HZ = 1; 1443fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_40Hz & rr) 1444fb4d8502Sjsg info->supported_rr.REFRESH_RATE_40HZ = 1; 1445fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_48Hz & rr) 1446fb4d8502Sjsg info->supported_rr.REFRESH_RATE_48HZ = 1; 1447fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_50Hz & rr) 1448fb4d8502Sjsg info->supported_rr.REFRESH_RATE_50HZ = 1; 1449fb4d8502Sjsg else if (SUPPORTED_LCD_REFRESHRATE_60Hz & rr) 1450fb4d8502Sjsg info->supported_rr.REFRESH_RATE_60HZ = 1; 1451fb4d8502Sjsg } 1452fb4d8502Sjsg } 1453fb4d8502Sjsg 1454fb4d8502Sjsg if (ATOM_PANEL_MISC_V13_DUAL & lvds->ucLCD_Misc) 1455fb4d8502Sjsg info->lcd_timing.misc_info.DOUBLE_CLOCK = true; 1456fb4d8502Sjsg 1457fb4d8502Sjsg if (ATOM_PANEL_MISC_V13_8BIT_PER_COLOR & lvds->ucLCD_Misc) 1458fb4d8502Sjsg info->lcd_timing.misc_info.RGB888 = true; 1459fb4d8502Sjsg 1460fb4d8502Sjsg info->lcd_timing.misc_info.GREY_LEVEL = 1461fb4d8502Sjsg (uint32_t) (ATOM_PANEL_MISC_V13_GREY_LEVEL & 1462fb4d8502Sjsg lvds->ucLCD_Misc) >> ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT; 1463fb4d8502Sjsg 1464fb4d8502Sjsg return BP_RESULT_OK; 1465fb4d8502Sjsg } 1466fb4d8502Sjsg 1467fb4d8502Sjsg /** 14685ca02815Sjsg * bios_parser_get_encoder_cap_info - get encoder capability 14695ca02815Sjsg * information of input object id 1470fb4d8502Sjsg * 14715ca02815Sjsg * @dcb: pointer to the DC BIOS 14725ca02815Sjsg * @object_id: object id 14735ca02815Sjsg * @info: encoder cap information structure 1474fb4d8502Sjsg * 14755ca02815Sjsg * return: Bios parser result code 1476fb4d8502Sjsg */ 1477fb4d8502Sjsg static enum bp_result bios_parser_get_encoder_cap_info( 1478fb4d8502Sjsg struct dc_bios *dcb, 1479fb4d8502Sjsg struct graphics_object_id object_id, 1480fb4d8502Sjsg struct bp_encoder_cap_info *info) 1481fb4d8502Sjsg { 1482fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1483fb4d8502Sjsg ATOM_OBJECT *object; 1484fb4d8502Sjsg ATOM_ENCODER_CAP_RECORD_V2 *record = NULL; 1485fb4d8502Sjsg 1486fb4d8502Sjsg if (!info) 1487fb4d8502Sjsg return BP_RESULT_BADINPUT; 1488fb4d8502Sjsg 1489fb4d8502Sjsg object = get_bios_object(bp, object_id); 1490fb4d8502Sjsg 1491fb4d8502Sjsg if (!object) 1492fb4d8502Sjsg return BP_RESULT_BADINPUT; 1493fb4d8502Sjsg 1494fb4d8502Sjsg record = get_encoder_cap_record(bp, object); 1495fb4d8502Sjsg if (!record) 1496fb4d8502Sjsg return BP_RESULT_NORECORD; 1497fb4d8502Sjsg 1498fb4d8502Sjsg info->DP_HBR2_EN = record->usHBR2En; 1499fb4d8502Sjsg info->DP_HBR3_EN = record->usHBR3En; 1500fb4d8502Sjsg info->HDMI_6GB_EN = record->usHDMI6GEn; 1501fb4d8502Sjsg return BP_RESULT_OK; 1502fb4d8502Sjsg } 1503fb4d8502Sjsg 1504fb4d8502Sjsg /** 15055ca02815Sjsg * get_encoder_cap_record - Get encoder cap record for the object 1506fb4d8502Sjsg * 15075ca02815Sjsg * @bp: pointer to the BIOS parser 15085ca02815Sjsg * @object: ATOM object 15095ca02815Sjsg * return: atom encoder cap record 15105ca02815Sjsg * note: search all records to find the ATOM_ENCODER_CAP_RECORD_V2 record 1511fb4d8502Sjsg */ 1512fb4d8502Sjsg static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( 1513fb4d8502Sjsg struct bios_parser *bp, 1514fb4d8502Sjsg ATOM_OBJECT *object) 1515fb4d8502Sjsg { 1516fb4d8502Sjsg ATOM_COMMON_RECORD_HEADER *header; 1517fb4d8502Sjsg uint32_t offset; 1518fb4d8502Sjsg 1519fb4d8502Sjsg if (!object) { 1520fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object */ 1521fb4d8502Sjsg return NULL; 1522fb4d8502Sjsg } 1523fb4d8502Sjsg 1524fb4d8502Sjsg offset = le16_to_cpu(object->usRecordOffset) 1525fb4d8502Sjsg + bp->object_info_tbl_offset; 1526fb4d8502Sjsg 1527fb4d8502Sjsg for (;;) { 1528fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset); 1529fb4d8502Sjsg 1530fb4d8502Sjsg if (!header) 1531fb4d8502Sjsg return NULL; 1532fb4d8502Sjsg 1533fb4d8502Sjsg offset += header->ucRecordSize; 1534fb4d8502Sjsg 1535fb4d8502Sjsg if (LAST_RECORD_TYPE == header->ucRecordType || 1536fb4d8502Sjsg !header->ucRecordSize) 1537fb4d8502Sjsg break; 1538fb4d8502Sjsg 1539fb4d8502Sjsg if (ATOM_ENCODER_CAP_RECORD_TYPE != header->ucRecordType) 1540fb4d8502Sjsg continue; 1541fb4d8502Sjsg 1542fb4d8502Sjsg if (sizeof(ATOM_ENCODER_CAP_RECORD_V2) <= header->ucRecordSize) 1543fb4d8502Sjsg return (ATOM_ENCODER_CAP_RECORD_V2 *)header; 1544fb4d8502Sjsg } 1545fb4d8502Sjsg 1546fb4d8502Sjsg return NULL; 1547fb4d8502Sjsg } 1548fb4d8502Sjsg 1549fb4d8502Sjsg static uint32_t get_ss_entry_number( 1550fb4d8502Sjsg struct bios_parser *bp, 1551fb4d8502Sjsg uint32_t id); 1552fb4d8502Sjsg static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( 1553fb4d8502Sjsg struct bios_parser *bp, 1554fb4d8502Sjsg uint32_t id); 1555fb4d8502Sjsg static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( 1556fb4d8502Sjsg struct bios_parser *bp, 1557fb4d8502Sjsg uint32_t id); 1558fb4d8502Sjsg static uint32_t get_ss_entry_number_from_ss_info_tbl( 1559fb4d8502Sjsg struct bios_parser *bp, 1560fb4d8502Sjsg uint32_t id); 1561fb4d8502Sjsg 1562fb4d8502Sjsg /** 15635ca02815Sjsg * bios_parser_get_ss_entry_number 1564fb4d8502Sjsg * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table from 1565fb4d8502Sjsg * the VBIOS that match the SSid (to be converted from signal) 1566fb4d8502Sjsg * 15675ca02815Sjsg * @dcb: pointer to the DC BIOS 15685ca02815Sjsg * @signal: ASSignalType to be converted to SSid 15695ca02815Sjsg * return: number of SS Entry that match the signal 1570fb4d8502Sjsg */ 1571fb4d8502Sjsg static uint32_t bios_parser_get_ss_entry_number( 1572fb4d8502Sjsg struct dc_bios *dcb, 1573fb4d8502Sjsg enum as_signal_type signal) 1574fb4d8502Sjsg { 1575fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1576fb4d8502Sjsg uint32_t ss_id = 0; 1577fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 1578fb4d8502Sjsg struct atom_data_revision revision; 1579fb4d8502Sjsg 1580fb4d8502Sjsg ss_id = signal_to_ss_id(signal); 1581fb4d8502Sjsg 1582fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 1583fb4d8502Sjsg return get_ss_entry_number_from_ss_info_tbl(bp, ss_id); 1584fb4d8502Sjsg 1585fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, 1586fb4d8502Sjsg DATA_TABLES(ASIC_InternalSS_Info)); 1587fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 1588fb4d8502Sjsg 1589fb4d8502Sjsg switch (revision.major) { 1590fb4d8502Sjsg case 2: 1591fb4d8502Sjsg switch (revision.minor) { 1592fb4d8502Sjsg case 1: 1593fb4d8502Sjsg return get_ss_entry_number(bp, ss_id); 1594fb4d8502Sjsg default: 1595fb4d8502Sjsg break; 1596fb4d8502Sjsg } 1597fb4d8502Sjsg break; 1598fb4d8502Sjsg case 3: 1599fb4d8502Sjsg switch (revision.minor) { 1600fb4d8502Sjsg case 1: 1601fb4d8502Sjsg return 1602fb4d8502Sjsg get_ss_entry_number_from_internal_ss_info_tbl_V3_1( 1603fb4d8502Sjsg bp, ss_id); 1604fb4d8502Sjsg default: 1605fb4d8502Sjsg break; 1606fb4d8502Sjsg } 1607fb4d8502Sjsg break; 1608fb4d8502Sjsg default: 1609fb4d8502Sjsg break; 1610fb4d8502Sjsg } 1611fb4d8502Sjsg 1612fb4d8502Sjsg return 0; 1613fb4d8502Sjsg } 1614fb4d8502Sjsg 1615fb4d8502Sjsg /** 1616fb4d8502Sjsg * get_ss_entry_number_from_ss_info_tbl 1617fb4d8502Sjsg * Get Number of spread spectrum entry from the SS_Info table from the VBIOS. 1618fb4d8502Sjsg * 16195ca02815Sjsg * @bp: pointer to the BIOS parser 16205ca02815Sjsg * @id: spread spectrum id 16215ca02815Sjsg * return: number of SS Entry that match the id 16225ca02815Sjsg * note: There can only be one entry for each id for SS_Info Table 1623fb4d8502Sjsg */ 1624fb4d8502Sjsg static uint32_t get_ss_entry_number_from_ss_info_tbl( 1625fb4d8502Sjsg struct bios_parser *bp, 1626fb4d8502Sjsg uint32_t id) 1627fb4d8502Sjsg { 1628fb4d8502Sjsg ATOM_SPREAD_SPECTRUM_INFO *tbl; 1629fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 1630fb4d8502Sjsg uint32_t table_size; 1631fb4d8502Sjsg uint32_t i; 1632fb4d8502Sjsg uint32_t number = 0; 1633fb4d8502Sjsg uint32_t id_local = SS_ID_UNKNOWN; 1634fb4d8502Sjsg struct atom_data_revision revision; 1635fb4d8502Sjsg 1636fb4d8502Sjsg /* SS_Info table exist */ 1637fb4d8502Sjsg if (!DATA_TABLES(SS_Info)) 1638fb4d8502Sjsg return number; 1639fb4d8502Sjsg 1640fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, 1641fb4d8502Sjsg DATA_TABLES(SS_Info)); 1642fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 1643fb4d8502Sjsg 1644fb4d8502Sjsg tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, 1645fb4d8502Sjsg DATA_TABLES(SS_Info)); 1646*c6622076Sjsg if (!tbl) 1647*c6622076Sjsg return number; 1648fb4d8502Sjsg 1649fb4d8502Sjsg if (1 != revision.major || 2 > revision.minor) 1650fb4d8502Sjsg return number; 1651fb4d8502Sjsg 1652fb4d8502Sjsg /* have to convert from Internal_SS format to SS_Info format */ 1653fb4d8502Sjsg switch (id) { 1654fb4d8502Sjsg case ASIC_INTERNAL_SS_ON_DP: 1655fb4d8502Sjsg id_local = SS_ID_DP1; 1656fb4d8502Sjsg break; 1657fb4d8502Sjsg case ASIC_INTERNAL_SS_ON_LVDS: { 1658fb4d8502Sjsg struct embedded_panel_info panel_info; 1659fb4d8502Sjsg 1660fb4d8502Sjsg if (bios_parser_get_embedded_panel_info(&bp->base, &panel_info) 1661fb4d8502Sjsg == BP_RESULT_OK) 1662fb4d8502Sjsg id_local = panel_info.ss_id; 1663fb4d8502Sjsg break; 1664fb4d8502Sjsg } 1665fb4d8502Sjsg default: 1666fb4d8502Sjsg break; 1667fb4d8502Sjsg } 1668fb4d8502Sjsg 1669fb4d8502Sjsg if (id_local == SS_ID_UNKNOWN) 1670fb4d8502Sjsg return number; 1671fb4d8502Sjsg 1672fb4d8502Sjsg table_size = (le16_to_cpu(tbl->sHeader.usStructureSize) - 1673fb4d8502Sjsg sizeof(ATOM_COMMON_TABLE_HEADER)) / 1674fb4d8502Sjsg sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); 1675fb4d8502Sjsg 1676fb4d8502Sjsg for (i = 0; i < table_size; i++) 1677fb4d8502Sjsg if (id_local == (uint32_t)tbl->asSS_Info[i].ucSS_Id) { 1678fb4d8502Sjsg number = 1; 1679fb4d8502Sjsg break; 1680fb4d8502Sjsg } 1681fb4d8502Sjsg 1682fb4d8502Sjsg return number; 1683fb4d8502Sjsg } 1684fb4d8502Sjsg 1685fb4d8502Sjsg /** 1686fb4d8502Sjsg * get_ss_entry_number 1687fb4d8502Sjsg * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or 1688fb4d8502Sjsg * SS_Info table from the VBIOS 1689fb4d8502Sjsg * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or 1690fb4d8502Sjsg * SS_Info. 1691fb4d8502Sjsg * 16925ca02815Sjsg * @bp: pointer to the BIOS parser 16935ca02815Sjsg * @id: spread sprectrum info index 16945ca02815Sjsg * return: Bios parser result code 1695fb4d8502Sjsg */ 1696fb4d8502Sjsg static uint32_t get_ss_entry_number(struct bios_parser *bp, uint32_t id) 1697fb4d8502Sjsg { 1698fb4d8502Sjsg if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS) 1699fb4d8502Sjsg return get_ss_entry_number_from_ss_info_tbl(bp, id); 1700fb4d8502Sjsg 1701fb4d8502Sjsg return get_ss_entry_number_from_internal_ss_info_tbl_v2_1(bp, id); 1702fb4d8502Sjsg } 1703fb4d8502Sjsg 1704fb4d8502Sjsg /** 1705fb4d8502Sjsg * get_ss_entry_number_from_internal_ss_info_tbl_v2_1 1706fb4d8502Sjsg * Get NUmber of spread sprectrum entry from the ASIC_InternalSS_Info table 1707fb4d8502Sjsg * Ver 2.1 from the VBIOS 1708fb4d8502Sjsg * There will not be multiple entry for Ver 2.1 1709fb4d8502Sjsg * 17105ca02815Sjsg * @bp: pointer to the BIOS parser 17115ca02815Sjsg * @id: spread sprectrum info index 17125ca02815Sjsg * return: number of SS Entry that match the id 1713fb4d8502Sjsg */ 1714fb4d8502Sjsg static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( 1715fb4d8502Sjsg struct bios_parser *bp, 1716fb4d8502Sjsg uint32_t id) 1717fb4d8502Sjsg { 1718fb4d8502Sjsg ATOM_ASIC_INTERNAL_SS_INFO_V2 *header_include; 1719fb4d8502Sjsg ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl; 1720fb4d8502Sjsg uint32_t size; 1721fb4d8502Sjsg uint32_t i; 1722fb4d8502Sjsg 1723fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 1724fb4d8502Sjsg return 0; 1725fb4d8502Sjsg 1726f005ef32Sjsg header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V2 *) bios_get_image( 1727f005ef32Sjsg &bp->base, 1728f005ef32Sjsg DATA_TABLES(ASIC_InternalSS_Info), 1729f005ef32Sjsg struct_size(header_include, asSpreadSpectrum, 1))); 1730*c6622076Sjsg if (!header_include) 1731*c6622076Sjsg return 0; 1732fb4d8502Sjsg 1733fb4d8502Sjsg size = (le16_to_cpu(header_include->sHeader.usStructureSize) 1734fb4d8502Sjsg - sizeof(ATOM_COMMON_TABLE_HEADER)) 1735fb4d8502Sjsg / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); 1736fb4d8502Sjsg 1737fb4d8502Sjsg tbl = (ATOM_ASIC_SS_ASSIGNMENT_V2 *) 1738fb4d8502Sjsg &header_include->asSpreadSpectrum[0]; 1739fb4d8502Sjsg for (i = 0; i < size; i++) 1740fb4d8502Sjsg if (tbl[i].ucClockIndication == (uint8_t)id) 1741fb4d8502Sjsg return 1; 1742fb4d8502Sjsg 1743fb4d8502Sjsg return 0; 1744fb4d8502Sjsg } 1745fb4d8502Sjsg /** 17465ca02815Sjsg * get_ss_entry_number_from_internal_ss_info_tbl_V3_1 1747fb4d8502Sjsg * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table of 1748fb4d8502Sjsg * the VBIOS that matches id 1749fb4d8502Sjsg * 17505ca02815Sjsg * @bp: pointer to the BIOS parser 17515ca02815Sjsg * @id: spread sprectrum id 17525ca02815Sjsg * return: number of SS Entry that match the id 1753fb4d8502Sjsg */ 1754fb4d8502Sjsg static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( 1755fb4d8502Sjsg struct bios_parser *bp, 1756fb4d8502Sjsg uint32_t id) 1757fb4d8502Sjsg { 1758fb4d8502Sjsg uint32_t number = 0; 1759fb4d8502Sjsg ATOM_ASIC_INTERNAL_SS_INFO_V3 *header_include; 1760fb4d8502Sjsg ATOM_ASIC_SS_ASSIGNMENT_V3 *tbl; 1761fb4d8502Sjsg uint32_t size; 1762fb4d8502Sjsg uint32_t i; 1763fb4d8502Sjsg 1764fb4d8502Sjsg if (!DATA_TABLES(ASIC_InternalSS_Info)) 1765fb4d8502Sjsg return number; 1766fb4d8502Sjsg 1767f005ef32Sjsg header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, 1768f005ef32Sjsg DATA_TABLES(ASIC_InternalSS_Info), 1769f005ef32Sjsg struct_size(header_include, asSpreadSpectrum, 1))); 1770*c6622076Sjsg if (!header_include) 1771*c6622076Sjsg return number; 1772*c6622076Sjsg 1773fb4d8502Sjsg size = (le16_to_cpu(header_include->sHeader.usStructureSize) - 1774fb4d8502Sjsg sizeof(ATOM_COMMON_TABLE_HEADER)) / 1775fb4d8502Sjsg sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); 1776fb4d8502Sjsg 1777fb4d8502Sjsg tbl = (ATOM_ASIC_SS_ASSIGNMENT_V3 *) 1778fb4d8502Sjsg &header_include->asSpreadSpectrum[0]; 1779fb4d8502Sjsg 1780fb4d8502Sjsg for (i = 0; i < size; i++) 1781fb4d8502Sjsg if (tbl[i].ucClockIndication == (uint8_t)id) 1782fb4d8502Sjsg number++; 1783fb4d8502Sjsg 1784fb4d8502Sjsg return number; 1785fb4d8502Sjsg } 1786fb4d8502Sjsg 1787fb4d8502Sjsg /** 1788fb4d8502Sjsg * bios_parser_get_gpio_pin_info 1789fb4d8502Sjsg * Get GpioPin information of input gpio id 1790fb4d8502Sjsg * 17915ca02815Sjsg * @dcb: pointer to the DC BIOS 17925ca02815Sjsg * @gpio_id: GPIO ID 17935ca02815Sjsg * @info: GpioPin information structure 17945ca02815Sjsg * return: Bios parser result code 17955ca02815Sjsg * note: 1796fb4d8502Sjsg * to get the GPIO PIN INFO, we need: 1797fb4d8502Sjsg * 1. get the GPIO_ID from other object table, see GetHPDInfo() 1798fb4d8502Sjsg * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, to get the registerA 1799fb4d8502Sjsg * offset/mask 1800fb4d8502Sjsg */ 1801fb4d8502Sjsg static enum bp_result bios_parser_get_gpio_pin_info( 1802fb4d8502Sjsg struct dc_bios *dcb, 1803fb4d8502Sjsg uint32_t gpio_id, 1804fb4d8502Sjsg struct gpio_pin_info *info) 1805fb4d8502Sjsg { 1806fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 1807fb4d8502Sjsg ATOM_GPIO_PIN_LUT *header; 1808fb4d8502Sjsg uint32_t count = 0; 1809fb4d8502Sjsg uint32_t i = 0; 1810fb4d8502Sjsg 1811fb4d8502Sjsg if (!DATA_TABLES(GPIO_Pin_LUT)) 1812fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1813fb4d8502Sjsg 1814f005ef32Sjsg header = ((ATOM_GPIO_PIN_LUT *) bios_get_image(&bp->base, 1815f005ef32Sjsg DATA_TABLES(GPIO_Pin_LUT), 1816f005ef32Sjsg struct_size(header, asGPIO_Pin, 1))); 1817fb4d8502Sjsg if (!header) 1818fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1819fb4d8502Sjsg 1820f005ef32Sjsg if (sizeof(ATOM_COMMON_TABLE_HEADER) + struct_size(header, asGPIO_Pin, 1) 1821fb4d8502Sjsg > le16_to_cpu(header->sHeader.usStructureSize)) 1822fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1823fb4d8502Sjsg 1824fb4d8502Sjsg if (1 != header->sHeader.ucTableContentRevision) 1825fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1826fb4d8502Sjsg 1827fb4d8502Sjsg count = (le16_to_cpu(header->sHeader.usStructureSize) 1828fb4d8502Sjsg - sizeof(ATOM_COMMON_TABLE_HEADER)) 1829fb4d8502Sjsg / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); 1830fb4d8502Sjsg for (i = 0; i < count; ++i) { 1831fb4d8502Sjsg if (header->asGPIO_Pin[i].ucGPIO_ID != gpio_id) 1832fb4d8502Sjsg continue; 1833fb4d8502Sjsg 1834fb4d8502Sjsg info->offset = 1835fb4d8502Sjsg (uint32_t) le16_to_cpu(header->asGPIO_Pin[i].usGpioPin_AIndex); 1836fb4d8502Sjsg info->offset_y = info->offset + 2; 1837fb4d8502Sjsg info->offset_en = info->offset + 1; 1838fb4d8502Sjsg info->offset_mask = info->offset - 1; 1839fb4d8502Sjsg 1840fb4d8502Sjsg info->mask = (uint32_t) (1 << 1841fb4d8502Sjsg header->asGPIO_Pin[i].ucGpioPinBitShift); 1842fb4d8502Sjsg info->mask_y = info->mask + 2; 1843fb4d8502Sjsg info->mask_en = info->mask + 1; 1844fb4d8502Sjsg info->mask_mask = info->mask - 1; 1845fb4d8502Sjsg 1846fb4d8502Sjsg return BP_RESULT_OK; 1847fb4d8502Sjsg } 1848fb4d8502Sjsg 1849fb4d8502Sjsg return BP_RESULT_NORECORD; 1850fb4d8502Sjsg } 1851fb4d8502Sjsg 1852fb4d8502Sjsg static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, 1853fb4d8502Sjsg ATOM_I2C_RECORD *record, 1854fb4d8502Sjsg struct graphics_object_i2c_info *info) 1855fb4d8502Sjsg { 1856fb4d8502Sjsg ATOM_GPIO_I2C_INFO *header; 1857fb4d8502Sjsg uint32_t count = 0; 1858fb4d8502Sjsg 1859fb4d8502Sjsg if (!info) 1860fb4d8502Sjsg return BP_RESULT_BADINPUT; 1861fb4d8502Sjsg 1862fb4d8502Sjsg /* get the GPIO_I2C info */ 1863fb4d8502Sjsg if (!DATA_TABLES(GPIO_I2C_Info)) 1864fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1865fb4d8502Sjsg 1866fb4d8502Sjsg header = GET_IMAGE(ATOM_GPIO_I2C_INFO, DATA_TABLES(GPIO_I2C_Info)); 1867fb4d8502Sjsg if (!header) 1868fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1869fb4d8502Sjsg 1870fb4d8502Sjsg if (sizeof(ATOM_COMMON_TABLE_HEADER) + sizeof(ATOM_GPIO_I2C_ASSIGMENT) 1871fb4d8502Sjsg > le16_to_cpu(header->sHeader.usStructureSize)) 1872fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1873fb4d8502Sjsg 1874fb4d8502Sjsg if (1 != header->sHeader.ucTableContentRevision) 1875fb4d8502Sjsg return BP_RESULT_UNSUPPORTED; 1876fb4d8502Sjsg 1877fb4d8502Sjsg /* get data count */ 1878fb4d8502Sjsg count = (le16_to_cpu(header->sHeader.usStructureSize) 1879fb4d8502Sjsg - sizeof(ATOM_COMMON_TABLE_HEADER)) 1880fb4d8502Sjsg / sizeof(ATOM_GPIO_I2C_ASSIGMENT); 1881fb4d8502Sjsg if (count < record->sucI2cId.bfI2C_LineMux) 1882fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 1883fb4d8502Sjsg 1884fb4d8502Sjsg /* get the GPIO_I2C_INFO */ 1885fb4d8502Sjsg info->i2c_hw_assist = record->sucI2cId.bfHW_Capable; 1886fb4d8502Sjsg info->i2c_line = record->sucI2cId.bfI2C_LineMux; 1887fb4d8502Sjsg info->i2c_engine_id = record->sucI2cId.bfHW_EngineID; 1888fb4d8502Sjsg info->i2c_slave_address = record->ucI2CAddr; 1889fb4d8502Sjsg 1890fb4d8502Sjsg info->gpio_info.clk_mask_register_index = 1891fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkMaskRegisterIndex); 1892fb4d8502Sjsg info->gpio_info.clk_en_register_index = 1893fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkEnRegisterIndex); 1894fb4d8502Sjsg info->gpio_info.clk_y_register_index = 1895fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkY_RegisterIndex); 1896fb4d8502Sjsg info->gpio_info.clk_a_register_index = 1897fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkA_RegisterIndex); 1898fb4d8502Sjsg info->gpio_info.data_mask_register_index = 1899fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataMaskRegisterIndex); 1900fb4d8502Sjsg info->gpio_info.data_en_register_index = 1901fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataEnRegisterIndex); 1902fb4d8502Sjsg info->gpio_info.data_y_register_index = 1903fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataY_RegisterIndex); 1904fb4d8502Sjsg info->gpio_info.data_a_register_index = 1905fb4d8502Sjsg le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataA_RegisterIndex); 1906fb4d8502Sjsg 1907fb4d8502Sjsg info->gpio_info.clk_mask_shift = 1908fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucClkMaskShift; 1909fb4d8502Sjsg info->gpio_info.clk_en_shift = 1910fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucClkEnShift; 1911fb4d8502Sjsg info->gpio_info.clk_y_shift = 1912fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucClkY_Shift; 1913fb4d8502Sjsg info->gpio_info.clk_a_shift = 1914fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucClkA_Shift; 1915fb4d8502Sjsg info->gpio_info.data_mask_shift = 1916fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucDataMaskShift; 1917fb4d8502Sjsg info->gpio_info.data_en_shift = 1918fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucDataEnShift; 1919fb4d8502Sjsg info->gpio_info.data_y_shift = 1920fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucDataY_Shift; 1921fb4d8502Sjsg info->gpio_info.data_a_shift = 1922fb4d8502Sjsg header->asGPIO_Info[info->i2c_line].ucDataA_Shift; 1923fb4d8502Sjsg 1924fb4d8502Sjsg return BP_RESULT_OK; 1925fb4d8502Sjsg } 1926fb4d8502Sjsg 1927fb4d8502Sjsg static bool dal_graphics_object_id_is_valid(struct graphics_object_id id) 1928fb4d8502Sjsg { 1929fb4d8502Sjsg bool rc = true; 1930fb4d8502Sjsg 1931fb4d8502Sjsg switch (id.type) { 1932fb4d8502Sjsg case OBJECT_TYPE_UNKNOWN: 1933fb4d8502Sjsg rc = false; 1934fb4d8502Sjsg break; 1935fb4d8502Sjsg case OBJECT_TYPE_GPU: 1936fb4d8502Sjsg case OBJECT_TYPE_ENGINE: 1937fb4d8502Sjsg /* do NOT check for id.id == 0 */ 1938fb4d8502Sjsg if (id.enum_id == ENUM_ID_UNKNOWN) 1939fb4d8502Sjsg rc = false; 1940fb4d8502Sjsg break; 1941fb4d8502Sjsg default: 1942fb4d8502Sjsg if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN) 1943fb4d8502Sjsg rc = false; 1944fb4d8502Sjsg break; 1945fb4d8502Sjsg } 1946fb4d8502Sjsg 1947fb4d8502Sjsg return rc; 1948fb4d8502Sjsg } 1949fb4d8502Sjsg 1950fb4d8502Sjsg static bool dal_graphics_object_id_is_equal( 1951fb4d8502Sjsg struct graphics_object_id id1, 1952fb4d8502Sjsg struct graphics_object_id id2) 1953fb4d8502Sjsg { 1954fb4d8502Sjsg if (false == dal_graphics_object_id_is_valid(id1)) { 1955fb4d8502Sjsg dm_output_to_console( 1956fb4d8502Sjsg "%s: Warning: comparing invalid object 'id1'!\n", __func__); 1957fb4d8502Sjsg return false; 1958fb4d8502Sjsg } 1959fb4d8502Sjsg 1960fb4d8502Sjsg if (false == dal_graphics_object_id_is_valid(id2)) { 1961fb4d8502Sjsg dm_output_to_console( 1962fb4d8502Sjsg "%s: Warning: comparing invalid object 'id2'!\n", __func__); 1963fb4d8502Sjsg return false; 1964fb4d8502Sjsg } 1965fb4d8502Sjsg 1966fb4d8502Sjsg if (id1.id == id2.id && id1.enum_id == id2.enum_id 1967fb4d8502Sjsg && id1.type == id2.type) 1968fb4d8502Sjsg return true; 1969fb4d8502Sjsg 1970fb4d8502Sjsg return false; 1971fb4d8502Sjsg } 1972fb4d8502Sjsg 1973fb4d8502Sjsg static ATOM_OBJECT *get_bios_object(struct bios_parser *bp, 1974fb4d8502Sjsg struct graphics_object_id id) 1975fb4d8502Sjsg { 1976fb4d8502Sjsg uint32_t offset; 1977fb4d8502Sjsg ATOM_OBJECT_TABLE *tbl; 1978fb4d8502Sjsg uint32_t i; 1979fb4d8502Sjsg 1980fb4d8502Sjsg switch (id.type) { 1981fb4d8502Sjsg case OBJECT_TYPE_ENCODER: 1982fb4d8502Sjsg offset = le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset); 1983fb4d8502Sjsg break; 1984fb4d8502Sjsg 1985fb4d8502Sjsg case OBJECT_TYPE_CONNECTOR: 1986fb4d8502Sjsg offset = le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset); 1987fb4d8502Sjsg break; 1988fb4d8502Sjsg 1989fb4d8502Sjsg case OBJECT_TYPE_ROUTER: 1990fb4d8502Sjsg offset = le16_to_cpu(bp->object_info_tbl.v1_1->usRouterObjectTableOffset); 1991fb4d8502Sjsg break; 1992fb4d8502Sjsg 1993fb4d8502Sjsg case OBJECT_TYPE_GENERIC: 1994fb4d8502Sjsg if (bp->object_info_tbl.revision.minor < 3) 1995fb4d8502Sjsg return NULL; 1996fb4d8502Sjsg offset = le16_to_cpu(bp->object_info_tbl.v1_3->usMiscObjectTableOffset); 1997fb4d8502Sjsg break; 1998fb4d8502Sjsg 1999fb4d8502Sjsg default: 2000fb4d8502Sjsg return NULL; 2001fb4d8502Sjsg } 2002fb4d8502Sjsg 2003fb4d8502Sjsg offset += bp->object_info_tbl_offset; 2004fb4d8502Sjsg 2005f005ef32Sjsg tbl = ((ATOM_OBJECT_TABLE *) bios_get_image(&bp->base, offset, 2006f005ef32Sjsg struct_size(tbl, asObjects, 1))); 2007fb4d8502Sjsg if (!tbl) 2008fb4d8502Sjsg return NULL; 2009fb4d8502Sjsg 2010fb4d8502Sjsg for (i = 0; i < tbl->ucNumberOfObjects; i++) 2011fb4d8502Sjsg if (dal_graphics_object_id_is_equal(id, 2012fb4d8502Sjsg object_id_from_bios_object_id( 2013fb4d8502Sjsg le16_to_cpu(tbl->asObjects[i].usObjectID)))) 2014fb4d8502Sjsg return &tbl->asObjects[i]; 2015fb4d8502Sjsg 2016fb4d8502Sjsg return NULL; 2017fb4d8502Sjsg } 2018fb4d8502Sjsg 2019fb4d8502Sjsg static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object, 2020fb4d8502Sjsg uint16_t **id_list) 2021fb4d8502Sjsg { 2022fb4d8502Sjsg uint32_t offset; 2023fb4d8502Sjsg uint8_t *number; 2024fb4d8502Sjsg 2025fb4d8502Sjsg if (!object) { 2026fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid object id */ 2027fb4d8502Sjsg return 0; 2028fb4d8502Sjsg } 2029fb4d8502Sjsg 2030fb4d8502Sjsg offset = le16_to_cpu(object->usSrcDstTableOffset) 2031fb4d8502Sjsg + bp->object_info_tbl_offset; 2032fb4d8502Sjsg 2033fb4d8502Sjsg number = GET_IMAGE(uint8_t, offset); 2034fb4d8502Sjsg if (!number) 2035fb4d8502Sjsg return 0; 2036fb4d8502Sjsg 2037fb4d8502Sjsg offset += sizeof(uint8_t); 2038fb4d8502Sjsg *id_list = (uint16_t *)bios_get_image(&bp->base, offset, *number * sizeof(uint16_t)); 2039fb4d8502Sjsg 2040fb4d8502Sjsg if (!*id_list) 2041fb4d8502Sjsg return 0; 2042fb4d8502Sjsg 2043fb4d8502Sjsg return *number; 2044fb4d8502Sjsg } 2045fb4d8502Sjsg 2046fb4d8502Sjsg static struct device_id device_type_from_device_id(uint16_t device_id) 2047fb4d8502Sjsg { 2048fb4d8502Sjsg 2049c349dbc7Sjsg struct device_id result_device_id = {0}; 2050fb4d8502Sjsg 2051fb4d8502Sjsg switch (device_id) { 2052fb4d8502Sjsg case ATOM_DEVICE_LCD1_SUPPORT: 2053fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_LCD; 2054fb4d8502Sjsg result_device_id.enum_id = 1; 2055fb4d8502Sjsg break; 2056fb4d8502Sjsg 2057fb4d8502Sjsg case ATOM_DEVICE_LCD2_SUPPORT: 2058fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_LCD; 2059fb4d8502Sjsg result_device_id.enum_id = 2; 2060fb4d8502Sjsg break; 2061fb4d8502Sjsg 2062fb4d8502Sjsg case ATOM_DEVICE_CRT1_SUPPORT: 2063fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_CRT; 2064fb4d8502Sjsg result_device_id.enum_id = 1; 2065fb4d8502Sjsg break; 2066fb4d8502Sjsg 2067fb4d8502Sjsg case ATOM_DEVICE_CRT2_SUPPORT: 2068fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_CRT; 2069fb4d8502Sjsg result_device_id.enum_id = 2; 2070fb4d8502Sjsg break; 2071fb4d8502Sjsg 2072fb4d8502Sjsg case ATOM_DEVICE_DFP1_SUPPORT: 2073fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2074fb4d8502Sjsg result_device_id.enum_id = 1; 2075fb4d8502Sjsg break; 2076fb4d8502Sjsg 2077fb4d8502Sjsg case ATOM_DEVICE_DFP2_SUPPORT: 2078fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2079fb4d8502Sjsg result_device_id.enum_id = 2; 2080fb4d8502Sjsg break; 2081fb4d8502Sjsg 2082fb4d8502Sjsg case ATOM_DEVICE_DFP3_SUPPORT: 2083fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2084fb4d8502Sjsg result_device_id.enum_id = 3; 2085fb4d8502Sjsg break; 2086fb4d8502Sjsg 2087fb4d8502Sjsg case ATOM_DEVICE_DFP4_SUPPORT: 2088fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2089fb4d8502Sjsg result_device_id.enum_id = 4; 2090fb4d8502Sjsg break; 2091fb4d8502Sjsg 2092fb4d8502Sjsg case ATOM_DEVICE_DFP5_SUPPORT: 2093fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2094fb4d8502Sjsg result_device_id.enum_id = 5; 2095fb4d8502Sjsg break; 2096fb4d8502Sjsg 2097fb4d8502Sjsg case ATOM_DEVICE_DFP6_SUPPORT: 2098fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_DFP; 2099fb4d8502Sjsg result_device_id.enum_id = 6; 2100fb4d8502Sjsg break; 2101fb4d8502Sjsg 2102fb4d8502Sjsg default: 2103fb4d8502Sjsg BREAK_TO_DEBUGGER(); /* Invalid device Id */ 2104fb4d8502Sjsg result_device_id.device_type = DEVICE_TYPE_UNKNOWN; 2105fb4d8502Sjsg result_device_id.enum_id = 0; 2106fb4d8502Sjsg } 2107fb4d8502Sjsg return result_device_id; 2108fb4d8502Sjsg } 2109fb4d8502Sjsg 2110fb4d8502Sjsg static void get_atom_data_table_revision( 2111fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *atom_data_tbl, 2112fb4d8502Sjsg struct atom_data_revision *tbl_revision) 2113fb4d8502Sjsg { 2114fb4d8502Sjsg if (!tbl_revision) 2115fb4d8502Sjsg return; 2116fb4d8502Sjsg 2117fb4d8502Sjsg /* initialize the revision to 0 which is invalid revision */ 2118fb4d8502Sjsg tbl_revision->major = 0; 2119fb4d8502Sjsg tbl_revision->minor = 0; 2120fb4d8502Sjsg 2121fb4d8502Sjsg if (!atom_data_tbl) 2122fb4d8502Sjsg return; 2123fb4d8502Sjsg 2124fb4d8502Sjsg tbl_revision->major = 2125fb4d8502Sjsg (uint32_t) GET_DATA_TABLE_MAJOR_REVISION(atom_data_tbl); 2126fb4d8502Sjsg tbl_revision->minor = 2127fb4d8502Sjsg (uint32_t) GET_DATA_TABLE_MINOR_REVISION(atom_data_tbl); 2128fb4d8502Sjsg } 2129fb4d8502Sjsg 2130fb4d8502Sjsg static uint32_t signal_to_ss_id(enum as_signal_type signal) 2131fb4d8502Sjsg { 2132fb4d8502Sjsg uint32_t clk_id_ss = 0; 2133fb4d8502Sjsg 2134fb4d8502Sjsg switch (signal) { 2135fb4d8502Sjsg case AS_SIGNAL_TYPE_DVI: 2136fb4d8502Sjsg clk_id_ss = ASIC_INTERNAL_SS_ON_TMDS; 2137fb4d8502Sjsg break; 2138fb4d8502Sjsg case AS_SIGNAL_TYPE_HDMI: 2139fb4d8502Sjsg clk_id_ss = ASIC_INTERNAL_SS_ON_HDMI; 2140fb4d8502Sjsg break; 2141fb4d8502Sjsg case AS_SIGNAL_TYPE_LVDS: 2142fb4d8502Sjsg clk_id_ss = ASIC_INTERNAL_SS_ON_LVDS; 2143fb4d8502Sjsg break; 2144fb4d8502Sjsg case AS_SIGNAL_TYPE_DISPLAY_PORT: 2145fb4d8502Sjsg clk_id_ss = ASIC_INTERNAL_SS_ON_DP; 2146fb4d8502Sjsg break; 2147fb4d8502Sjsg case AS_SIGNAL_TYPE_GPU_PLL: 2148fb4d8502Sjsg clk_id_ss = ASIC_INTERNAL_GPUPLL_SS; 2149fb4d8502Sjsg break; 2150fb4d8502Sjsg default: 2151fb4d8502Sjsg break; 2152fb4d8502Sjsg } 2153fb4d8502Sjsg return clk_id_ss; 2154fb4d8502Sjsg } 2155fb4d8502Sjsg 2156fb4d8502Sjsg static uint32_t get_support_mask_for_device_id(struct device_id device_id) 2157fb4d8502Sjsg { 2158fb4d8502Sjsg enum dal_device_type device_type = device_id.device_type; 2159fb4d8502Sjsg uint32_t enum_id = device_id.enum_id; 2160fb4d8502Sjsg 2161fb4d8502Sjsg switch (device_type) { 2162fb4d8502Sjsg case DEVICE_TYPE_LCD: 2163fb4d8502Sjsg switch (enum_id) { 2164fb4d8502Sjsg case 1: 2165fb4d8502Sjsg return ATOM_DEVICE_LCD1_SUPPORT; 2166fb4d8502Sjsg case 2: 2167fb4d8502Sjsg return ATOM_DEVICE_LCD2_SUPPORT; 2168fb4d8502Sjsg default: 2169fb4d8502Sjsg break; 2170fb4d8502Sjsg } 2171fb4d8502Sjsg break; 2172fb4d8502Sjsg case DEVICE_TYPE_CRT: 2173fb4d8502Sjsg switch (enum_id) { 2174fb4d8502Sjsg case 1: 2175fb4d8502Sjsg return ATOM_DEVICE_CRT1_SUPPORT; 2176fb4d8502Sjsg case 2: 2177fb4d8502Sjsg return ATOM_DEVICE_CRT2_SUPPORT; 2178fb4d8502Sjsg default: 2179fb4d8502Sjsg break; 2180fb4d8502Sjsg } 2181fb4d8502Sjsg break; 2182fb4d8502Sjsg case DEVICE_TYPE_DFP: 2183fb4d8502Sjsg switch (enum_id) { 2184fb4d8502Sjsg case 1: 2185fb4d8502Sjsg return ATOM_DEVICE_DFP1_SUPPORT; 2186fb4d8502Sjsg case 2: 2187fb4d8502Sjsg return ATOM_DEVICE_DFP2_SUPPORT; 2188fb4d8502Sjsg case 3: 2189fb4d8502Sjsg return ATOM_DEVICE_DFP3_SUPPORT; 2190fb4d8502Sjsg case 4: 2191fb4d8502Sjsg return ATOM_DEVICE_DFP4_SUPPORT; 2192fb4d8502Sjsg case 5: 2193fb4d8502Sjsg return ATOM_DEVICE_DFP5_SUPPORT; 2194fb4d8502Sjsg case 6: 2195fb4d8502Sjsg return ATOM_DEVICE_DFP6_SUPPORT; 2196fb4d8502Sjsg default: 2197fb4d8502Sjsg break; 2198fb4d8502Sjsg } 2199fb4d8502Sjsg break; 2200fb4d8502Sjsg case DEVICE_TYPE_CV: 2201fb4d8502Sjsg switch (enum_id) { 2202fb4d8502Sjsg case 1: 2203fb4d8502Sjsg return ATOM_DEVICE_CV_SUPPORT; 2204fb4d8502Sjsg default: 2205fb4d8502Sjsg break; 2206fb4d8502Sjsg } 2207fb4d8502Sjsg break; 2208fb4d8502Sjsg case DEVICE_TYPE_TV: 2209fb4d8502Sjsg switch (enum_id) { 2210fb4d8502Sjsg case 1: 2211fb4d8502Sjsg return ATOM_DEVICE_TV1_SUPPORT; 2212fb4d8502Sjsg default: 2213fb4d8502Sjsg break; 2214fb4d8502Sjsg } 2215fb4d8502Sjsg break; 2216fb4d8502Sjsg default: 2217fb4d8502Sjsg break; 2218c349dbc7Sjsg } 2219fb4d8502Sjsg 2220fb4d8502Sjsg /* Unidentified device ID, return empty support mask. */ 2221fb4d8502Sjsg return 0; 2222fb4d8502Sjsg } 2223fb4d8502Sjsg 2224fb4d8502Sjsg /** 22255ca02815Sjsg * bios_parser_set_scratch_critical_state - update critical state 22265ca02815Sjsg * bit in VBIOS scratch register 22275ca02815Sjsg * @dcb: pointer to the DC BIOS 22285ca02815Sjsg * @state: set or reset state 2229fb4d8502Sjsg */ 2230fb4d8502Sjsg static void bios_parser_set_scratch_critical_state( 2231fb4d8502Sjsg struct dc_bios *dcb, 2232fb4d8502Sjsg bool state) 2233fb4d8502Sjsg { 2234fb4d8502Sjsg bios_set_scratch_critical_state(dcb, state); 2235fb4d8502Sjsg } 2236fb4d8502Sjsg 2237fb4d8502Sjsg /* 2238fb4d8502Sjsg * get_integrated_info_v8 2239fb4d8502Sjsg * 2240fb4d8502Sjsg * @brief 2241fb4d8502Sjsg * Get V8 integrated BIOS information 2242fb4d8502Sjsg * 2243fb4d8502Sjsg * @param 2244fb4d8502Sjsg * bios_parser *bp - [in]BIOS parser handler to get master data table 2245fb4d8502Sjsg * integrated_info *info - [out] store and output integrated info 2246fb4d8502Sjsg * 22475ca02815Sjsg * return: 2248fb4d8502Sjsg * enum bp_result - BP_RESULT_OK if information is available, 2249fb4d8502Sjsg * BP_RESULT_BADBIOSTABLE otherwise. 2250fb4d8502Sjsg */ 2251fb4d8502Sjsg static enum bp_result get_integrated_info_v8( 2252fb4d8502Sjsg struct bios_parser *bp, 2253fb4d8502Sjsg struct integrated_info *info) 2254fb4d8502Sjsg { 2255fb4d8502Sjsg ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *info_v8; 2256fb4d8502Sjsg uint32_t i; 2257fb4d8502Sjsg 2258fb4d8502Sjsg info_v8 = GET_IMAGE(ATOM_INTEGRATED_SYSTEM_INFO_V1_8, 2259fb4d8502Sjsg bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo); 2260fb4d8502Sjsg 2261fb4d8502Sjsg if (info_v8 == NULL) 2262fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 2263fb4d8502Sjsg info->boot_up_engine_clock = le32_to_cpu(info_v8->ulBootUpEngineClock) * 10; 2264fb4d8502Sjsg info->dentist_vco_freq = le32_to_cpu(info_v8->ulDentistVCOFreq) * 10; 2265fb4d8502Sjsg info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10; 2266fb4d8502Sjsg 2267fb4d8502Sjsg for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2268fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2269fb4d8502Sjsg info->disp_clk_voltage[i].max_supported_clk = 2270fb4d8502Sjsg le32_to_cpu(info_v8->sDISPCLK_Voltage[i]. 2271fb4d8502Sjsg ulMaximumSupportedCLK) * 10; 2272fb4d8502Sjsg info->disp_clk_voltage[i].voltage_index = 2273fb4d8502Sjsg le32_to_cpu(info_v8->sDISPCLK_Voltage[i].ulVoltageIndex); 2274fb4d8502Sjsg } 2275fb4d8502Sjsg 2276fb4d8502Sjsg info->boot_up_req_display_vector = 2277fb4d8502Sjsg le32_to_cpu(info_v8->ulBootUpReqDisplayVector); 2278fb4d8502Sjsg info->gpu_cap_info = 2279fb4d8502Sjsg le32_to_cpu(info_v8->ulGPUCapInfo); 2280fb4d8502Sjsg 2281fb4d8502Sjsg /* 2282fb4d8502Sjsg * system_config: Bit[0] = 0 : PCIE power gating disabled 2283fb4d8502Sjsg * = 1 : PCIE power gating enabled 2284fb4d8502Sjsg * Bit[1] = 0 : DDR-PLL shut down disabled 2285fb4d8502Sjsg * = 1 : DDR-PLL shut down enabled 2286fb4d8502Sjsg * Bit[2] = 0 : DDR-PLL power down disabled 2287fb4d8502Sjsg * = 1 : DDR-PLL power down enabled 2288fb4d8502Sjsg */ 2289fb4d8502Sjsg info->system_config = le32_to_cpu(info_v8->ulSystemConfig); 2290fb4d8502Sjsg info->cpu_cap_info = le32_to_cpu(info_v8->ulCPUCapInfo); 2291fb4d8502Sjsg info->boot_up_nb_voltage = 2292fb4d8502Sjsg le16_to_cpu(info_v8->usBootUpNBVoltage); 2293fb4d8502Sjsg info->ext_disp_conn_info_offset = 2294fb4d8502Sjsg le16_to_cpu(info_v8->usExtDispConnInfoOffset); 2295fb4d8502Sjsg info->memory_type = info_v8->ucMemoryType; 2296fb4d8502Sjsg info->ma_channel_number = info_v8->ucUMAChannelNumber; 2297fb4d8502Sjsg info->gmc_restore_reset_time = 2298fb4d8502Sjsg le32_to_cpu(info_v8->ulGMCRestoreResetTime); 2299fb4d8502Sjsg 2300fb4d8502Sjsg info->minimum_n_clk = 2301fb4d8502Sjsg le32_to_cpu(info_v8->ulNbpStateNClkFreq[0]); 2302fb4d8502Sjsg for (i = 1; i < 4; ++i) 2303fb4d8502Sjsg info->minimum_n_clk = 2304fb4d8502Sjsg info->minimum_n_clk < le32_to_cpu(info_v8->ulNbpStateNClkFreq[i]) ? 2305fb4d8502Sjsg info->minimum_n_clk : le32_to_cpu(info_v8->ulNbpStateNClkFreq[i]); 2306fb4d8502Sjsg 2307fb4d8502Sjsg info->idle_n_clk = le32_to_cpu(info_v8->ulIdleNClk); 2308fb4d8502Sjsg info->ddr_dll_power_up_time = 2309fb4d8502Sjsg le32_to_cpu(info_v8->ulDDR_DLL_PowerUpTime); 2310fb4d8502Sjsg info->ddr_pll_power_up_time = 2311fb4d8502Sjsg le32_to_cpu(info_v8->ulDDR_PLL_PowerUpTime); 2312fb4d8502Sjsg info->pcie_clk_ss_type = le16_to_cpu(info_v8->usPCIEClkSSType); 2313fb4d8502Sjsg info->lvds_ss_percentage = 2314fb4d8502Sjsg le16_to_cpu(info_v8->usLvdsSSPercentage); 2315fb4d8502Sjsg info->lvds_sspread_rate_in_10hz = 2316fb4d8502Sjsg le16_to_cpu(info_v8->usLvdsSSpreadRateIn10Hz); 2317fb4d8502Sjsg info->hdmi_ss_percentage = 2318fb4d8502Sjsg le16_to_cpu(info_v8->usHDMISSPercentage); 2319fb4d8502Sjsg info->hdmi_sspread_rate_in_10hz = 2320fb4d8502Sjsg le16_to_cpu(info_v8->usHDMISSpreadRateIn10Hz); 2321fb4d8502Sjsg info->dvi_ss_percentage = 2322fb4d8502Sjsg le16_to_cpu(info_v8->usDVISSPercentage); 2323fb4d8502Sjsg info->dvi_sspread_rate_in_10_hz = 2324fb4d8502Sjsg le16_to_cpu(info_v8->usDVISSpreadRateIn10Hz); 2325fb4d8502Sjsg 2326fb4d8502Sjsg info->max_lvds_pclk_freq_in_single_link = 2327fb4d8502Sjsg le16_to_cpu(info_v8->usMaxLVDSPclkFreqInSingleLink); 2328fb4d8502Sjsg info->lvds_misc = info_v8->ucLvdsMisc; 2329fb4d8502Sjsg info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = 2330fb4d8502Sjsg info_v8->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; 2331fb4d8502Sjsg info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = 2332fb4d8502Sjsg info_v8->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; 2333fb4d8502Sjsg info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = 2334fb4d8502Sjsg info_v8->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; 2335fb4d8502Sjsg info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = 2336fb4d8502Sjsg info_v8->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; 2337fb4d8502Sjsg info->lvds_pwr_off_seq_de_to_dig_on_in4ms = 2338fb4d8502Sjsg info_v8->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; 2339fb4d8502Sjsg info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = 2340fb4d8502Sjsg info_v8->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; 2341fb4d8502Sjsg info->lvds_off_to_on_delay_in_4ms = 2342fb4d8502Sjsg info_v8->ucLVDSOffToOnDelay_in4Ms; 2343fb4d8502Sjsg info->lvds_bit_depth_control_val = 2344fb4d8502Sjsg le32_to_cpu(info_v8->ulLCDBitDepthControlVal); 2345fb4d8502Sjsg 2346fb4d8502Sjsg for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { 2347fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2348fb4d8502Sjsg info->avail_s_clk[i].supported_s_clk = 2349fb4d8502Sjsg le32_to_cpu(info_v8->sAvail_SCLK[i].ulSupportedSCLK) * 10; 2350fb4d8502Sjsg info->avail_s_clk[i].voltage_index = 2351fb4d8502Sjsg le16_to_cpu(info_v8->sAvail_SCLK[i].usVoltageIndex); 2352fb4d8502Sjsg info->avail_s_clk[i].voltage_id = 2353fb4d8502Sjsg le16_to_cpu(info_v8->sAvail_SCLK[i].usVoltageID); 2354fb4d8502Sjsg } 2355fb4d8502Sjsg 2356fb4d8502Sjsg for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2357fb4d8502Sjsg info->ext_disp_conn_info.gu_id[i] = 2358fb4d8502Sjsg info_v8->sExtDispConnInfo.ucGuid[i]; 2359fb4d8502Sjsg } 2360fb4d8502Sjsg 2361fb4d8502Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2362fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_connector_id = 2363fb4d8502Sjsg object_id_from_bios_object_id( 2364fb4d8502Sjsg le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceConnector)); 2365fb4d8502Sjsg 2366fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2367fb4d8502Sjsg object_id_from_bios_object_id( 2368fb4d8502Sjsg le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usExtEncoderObjId)); 2369fb4d8502Sjsg 2370fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_tag = 2371fb4d8502Sjsg le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceTag); 2372fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum = 2373fb4d8502Sjsg le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceACPIEnum); 2374fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2375fb4d8502Sjsg info_v8->sExtDispConnInfo.sPath[i].ucExtAUXDDCLutIndex; 2376fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2377fb4d8502Sjsg info_v8->sExtDispConnInfo.sPath[i].ucExtHPDPINLutIndex; 2378fb4d8502Sjsg info->ext_disp_conn_info.path[i].channel_mapping.raw = 2379fb4d8502Sjsg info_v8->sExtDispConnInfo.sPath[i].ucChannelMapping; 2380fb4d8502Sjsg } 2381fb4d8502Sjsg info->ext_disp_conn_info.checksum = 2382fb4d8502Sjsg info_v8->sExtDispConnInfo.ucChecksum; 2383fb4d8502Sjsg 2384fb4d8502Sjsg return BP_RESULT_OK; 2385fb4d8502Sjsg } 2386fb4d8502Sjsg 2387fb4d8502Sjsg /* 2388fb4d8502Sjsg * get_integrated_info_v8 2389fb4d8502Sjsg * 2390fb4d8502Sjsg * @brief 2391fb4d8502Sjsg * Get V8 integrated BIOS information 2392fb4d8502Sjsg * 2393fb4d8502Sjsg * @param 2394fb4d8502Sjsg * bios_parser *bp - [in]BIOS parser handler to get master data table 2395fb4d8502Sjsg * integrated_info *info - [out] store and output integrated info 2396fb4d8502Sjsg * 23975ca02815Sjsg * return: 2398fb4d8502Sjsg * enum bp_result - BP_RESULT_OK if information is available, 2399fb4d8502Sjsg * BP_RESULT_BADBIOSTABLE otherwise. 2400fb4d8502Sjsg */ 2401fb4d8502Sjsg static enum bp_result get_integrated_info_v9( 2402fb4d8502Sjsg struct bios_parser *bp, 2403fb4d8502Sjsg struct integrated_info *info) 2404fb4d8502Sjsg { 2405fb4d8502Sjsg ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *info_v9; 2406fb4d8502Sjsg uint32_t i; 2407fb4d8502Sjsg 2408fb4d8502Sjsg info_v9 = GET_IMAGE(ATOM_INTEGRATED_SYSTEM_INFO_V1_9, 2409fb4d8502Sjsg bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo); 2410fb4d8502Sjsg 2411fb4d8502Sjsg if (!info_v9) 2412fb4d8502Sjsg return BP_RESULT_BADBIOSTABLE; 2413fb4d8502Sjsg 2414fb4d8502Sjsg info->boot_up_engine_clock = le32_to_cpu(info_v9->ulBootUpEngineClock) * 10; 2415fb4d8502Sjsg info->dentist_vco_freq = le32_to_cpu(info_v9->ulDentistVCOFreq) * 10; 2416fb4d8502Sjsg info->boot_up_uma_clock = le32_to_cpu(info_v9->ulBootUpUMAClock) * 10; 2417fb4d8502Sjsg 2418fb4d8502Sjsg for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2419fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2420fb4d8502Sjsg info->disp_clk_voltage[i].max_supported_clk = 2421fb4d8502Sjsg le32_to_cpu(info_v9->sDISPCLK_Voltage[i].ulMaximumSupportedCLK) * 10; 2422fb4d8502Sjsg info->disp_clk_voltage[i].voltage_index = 2423fb4d8502Sjsg le32_to_cpu(info_v9->sDISPCLK_Voltage[i].ulVoltageIndex); 2424fb4d8502Sjsg } 2425fb4d8502Sjsg 2426fb4d8502Sjsg info->boot_up_req_display_vector = 2427fb4d8502Sjsg le32_to_cpu(info_v9->ulBootUpReqDisplayVector); 2428fb4d8502Sjsg info->gpu_cap_info = le32_to_cpu(info_v9->ulGPUCapInfo); 2429fb4d8502Sjsg 2430fb4d8502Sjsg /* 2431fb4d8502Sjsg * system_config: Bit[0] = 0 : PCIE power gating disabled 2432fb4d8502Sjsg * = 1 : PCIE power gating enabled 2433fb4d8502Sjsg * Bit[1] = 0 : DDR-PLL shut down disabled 2434fb4d8502Sjsg * = 1 : DDR-PLL shut down enabled 2435fb4d8502Sjsg * Bit[2] = 0 : DDR-PLL power down disabled 2436fb4d8502Sjsg * = 1 : DDR-PLL power down enabled 2437fb4d8502Sjsg */ 2438fb4d8502Sjsg info->system_config = le32_to_cpu(info_v9->ulSystemConfig); 2439fb4d8502Sjsg info->cpu_cap_info = le32_to_cpu(info_v9->ulCPUCapInfo); 2440fb4d8502Sjsg info->boot_up_nb_voltage = le16_to_cpu(info_v9->usBootUpNBVoltage); 2441fb4d8502Sjsg info->ext_disp_conn_info_offset = le16_to_cpu(info_v9->usExtDispConnInfoOffset); 2442fb4d8502Sjsg info->memory_type = info_v9->ucMemoryType; 2443fb4d8502Sjsg info->ma_channel_number = info_v9->ucUMAChannelNumber; 2444fb4d8502Sjsg info->gmc_restore_reset_time = le32_to_cpu(info_v9->ulGMCRestoreResetTime); 2445fb4d8502Sjsg 2446fb4d8502Sjsg info->minimum_n_clk = le32_to_cpu(info_v9->ulNbpStateNClkFreq[0]); 2447fb4d8502Sjsg for (i = 1; i < 4; ++i) 2448fb4d8502Sjsg info->minimum_n_clk = 2449fb4d8502Sjsg info->minimum_n_clk < le32_to_cpu(info_v9->ulNbpStateNClkFreq[i]) ? 2450fb4d8502Sjsg info->minimum_n_clk : le32_to_cpu(info_v9->ulNbpStateNClkFreq[i]); 2451fb4d8502Sjsg 2452fb4d8502Sjsg info->idle_n_clk = le32_to_cpu(info_v9->ulIdleNClk); 2453fb4d8502Sjsg info->ddr_dll_power_up_time = le32_to_cpu(info_v9->ulDDR_DLL_PowerUpTime); 2454fb4d8502Sjsg info->ddr_pll_power_up_time = le32_to_cpu(info_v9->ulDDR_PLL_PowerUpTime); 2455fb4d8502Sjsg info->pcie_clk_ss_type = le16_to_cpu(info_v9->usPCIEClkSSType); 2456fb4d8502Sjsg info->lvds_ss_percentage = le16_to_cpu(info_v9->usLvdsSSPercentage); 2457fb4d8502Sjsg info->lvds_sspread_rate_in_10hz = le16_to_cpu(info_v9->usLvdsSSpreadRateIn10Hz); 2458fb4d8502Sjsg info->hdmi_ss_percentage = le16_to_cpu(info_v9->usHDMISSPercentage); 2459fb4d8502Sjsg info->hdmi_sspread_rate_in_10hz = le16_to_cpu(info_v9->usHDMISSpreadRateIn10Hz); 2460fb4d8502Sjsg info->dvi_ss_percentage = le16_to_cpu(info_v9->usDVISSPercentage); 2461fb4d8502Sjsg info->dvi_sspread_rate_in_10_hz = le16_to_cpu(info_v9->usDVISSpreadRateIn10Hz); 2462fb4d8502Sjsg 2463fb4d8502Sjsg info->max_lvds_pclk_freq_in_single_link = 2464fb4d8502Sjsg le16_to_cpu(info_v9->usMaxLVDSPclkFreqInSingleLink); 2465fb4d8502Sjsg info->lvds_misc = info_v9->ucLvdsMisc; 2466fb4d8502Sjsg info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = 2467fb4d8502Sjsg info_v9->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; 2468fb4d8502Sjsg info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = 2469fb4d8502Sjsg info_v9->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; 2470fb4d8502Sjsg info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = 2471fb4d8502Sjsg info_v9->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; 2472fb4d8502Sjsg info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = 2473fb4d8502Sjsg info_v9->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; 2474fb4d8502Sjsg info->lvds_pwr_off_seq_de_to_dig_on_in4ms = 2475fb4d8502Sjsg info_v9->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; 2476fb4d8502Sjsg info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = 2477fb4d8502Sjsg info_v9->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; 2478fb4d8502Sjsg info->lvds_off_to_on_delay_in_4ms = 2479fb4d8502Sjsg info_v9->ucLVDSOffToOnDelay_in4Ms; 2480fb4d8502Sjsg info->lvds_bit_depth_control_val = 2481fb4d8502Sjsg le32_to_cpu(info_v9->ulLCDBitDepthControlVal); 2482fb4d8502Sjsg 2483fb4d8502Sjsg for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { 2484fb4d8502Sjsg /* Convert [10KHz] into [KHz] */ 2485fb4d8502Sjsg info->avail_s_clk[i].supported_s_clk = 2486fb4d8502Sjsg le32_to_cpu(info_v9->sAvail_SCLK[i].ulSupportedSCLK) * 10; 2487fb4d8502Sjsg info->avail_s_clk[i].voltage_index = 2488fb4d8502Sjsg le16_to_cpu(info_v9->sAvail_SCLK[i].usVoltageIndex); 2489fb4d8502Sjsg info->avail_s_clk[i].voltage_id = 2490fb4d8502Sjsg le16_to_cpu(info_v9->sAvail_SCLK[i].usVoltageID); 2491fb4d8502Sjsg } 2492fb4d8502Sjsg 2493fb4d8502Sjsg for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2494fb4d8502Sjsg info->ext_disp_conn_info.gu_id[i] = 2495fb4d8502Sjsg info_v9->sExtDispConnInfo.ucGuid[i]; 2496fb4d8502Sjsg } 2497fb4d8502Sjsg 2498fb4d8502Sjsg for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2499fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_connector_id = 2500fb4d8502Sjsg object_id_from_bios_object_id( 2501fb4d8502Sjsg le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceConnector)); 2502fb4d8502Sjsg 2503fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2504fb4d8502Sjsg object_id_from_bios_object_id( 2505fb4d8502Sjsg le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usExtEncoderObjId)); 2506fb4d8502Sjsg 2507fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_tag = 2508fb4d8502Sjsg le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceTag); 2509fb4d8502Sjsg info->ext_disp_conn_info.path[i].device_acpi_enum = 2510fb4d8502Sjsg le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceACPIEnum); 2511fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2512fb4d8502Sjsg info_v9->sExtDispConnInfo.sPath[i].ucExtAUXDDCLutIndex; 2513fb4d8502Sjsg info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2514fb4d8502Sjsg info_v9->sExtDispConnInfo.sPath[i].ucExtHPDPINLutIndex; 2515fb4d8502Sjsg info->ext_disp_conn_info.path[i].channel_mapping.raw = 2516fb4d8502Sjsg info_v9->sExtDispConnInfo.sPath[i].ucChannelMapping; 2517fb4d8502Sjsg } 2518fb4d8502Sjsg info->ext_disp_conn_info.checksum = 2519fb4d8502Sjsg info_v9->sExtDispConnInfo.ucChecksum; 2520fb4d8502Sjsg 2521fb4d8502Sjsg return BP_RESULT_OK; 2522fb4d8502Sjsg } 2523fb4d8502Sjsg 2524fb4d8502Sjsg /* 2525fb4d8502Sjsg * construct_integrated_info 2526fb4d8502Sjsg * 2527fb4d8502Sjsg * @brief 2528fb4d8502Sjsg * Get integrated BIOS information based on table revision 2529fb4d8502Sjsg * 2530fb4d8502Sjsg * @param 2531fb4d8502Sjsg * bios_parser *bp - [in]BIOS parser handler to get master data table 2532fb4d8502Sjsg * integrated_info *info - [out] store and output integrated info 2533fb4d8502Sjsg * 25345ca02815Sjsg * return: 2535fb4d8502Sjsg * enum bp_result - BP_RESULT_OK if information is available, 2536fb4d8502Sjsg * BP_RESULT_BADBIOSTABLE otherwise. 2537fb4d8502Sjsg */ 2538fb4d8502Sjsg static enum bp_result construct_integrated_info( 2539fb4d8502Sjsg struct bios_parser *bp, 2540fb4d8502Sjsg struct integrated_info *info) 2541fb4d8502Sjsg { 2542fb4d8502Sjsg enum bp_result result = BP_RESULT_BADBIOSTABLE; 2543fb4d8502Sjsg 2544fb4d8502Sjsg ATOM_COMMON_TABLE_HEADER *header; 2545fb4d8502Sjsg struct atom_data_revision revision; 2546fb4d8502Sjsg 2547fb4d8502Sjsg if (bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo) { 2548fb4d8502Sjsg header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, 2549fb4d8502Sjsg bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo); 2550fb4d8502Sjsg 2551fb4d8502Sjsg get_atom_data_table_revision(header, &revision); 2552fb4d8502Sjsg 2553fb4d8502Sjsg /* Don't need to check major revision as they are all 1 */ 2554fb4d8502Sjsg switch (revision.minor) { 2555fb4d8502Sjsg case 8: 2556fb4d8502Sjsg result = get_integrated_info_v8(bp, info); 2557fb4d8502Sjsg break; 2558fb4d8502Sjsg case 9: 2559fb4d8502Sjsg result = get_integrated_info_v9(bp, info); 2560fb4d8502Sjsg break; 2561fb4d8502Sjsg default: 2562fb4d8502Sjsg return result; 2563fb4d8502Sjsg 2564fb4d8502Sjsg } 2565fb4d8502Sjsg } 2566fb4d8502Sjsg 2567fb4d8502Sjsg /* Sort voltage table from low to high*/ 2568fb4d8502Sjsg if (result == BP_RESULT_OK) { 2569777bfb8aSjsg int32_t i; 2570777bfb8aSjsg int32_t j; 2571fb4d8502Sjsg 2572fb4d8502Sjsg for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2573fb4d8502Sjsg for (j = i; j > 0; --j) { 2574fb4d8502Sjsg if ( 2575fb4d8502Sjsg info->disp_clk_voltage[j].max_supported_clk < 2576fb4d8502Sjsg info->disp_clk_voltage[j-1].max_supported_clk) { 2577fb4d8502Sjsg /* swap j and j - 1*/ 2578c349dbc7Sjsg swap(info->disp_clk_voltage[j - 1], 2579c349dbc7Sjsg info->disp_clk_voltage[j]); 2580fb4d8502Sjsg } 2581fb4d8502Sjsg } 2582fb4d8502Sjsg } 2583fb4d8502Sjsg 2584fb4d8502Sjsg } 2585fb4d8502Sjsg 2586fb4d8502Sjsg return result; 2587fb4d8502Sjsg } 2588fb4d8502Sjsg 2589fb4d8502Sjsg static struct integrated_info *bios_parser_create_integrated_info( 2590fb4d8502Sjsg struct dc_bios *dcb) 2591fb4d8502Sjsg { 2592fb4d8502Sjsg struct bios_parser *bp = BP_FROM_DCB(dcb); 2593f005ef32Sjsg struct integrated_info *info; 2594fb4d8502Sjsg 2595fb4d8502Sjsg info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); 2596fb4d8502Sjsg 2597fb4d8502Sjsg if (info == NULL) { 2598fb4d8502Sjsg ASSERT_CRITICAL(0); 2599fb4d8502Sjsg return NULL; 2600fb4d8502Sjsg } 2601fb4d8502Sjsg 2602fb4d8502Sjsg if (construct_integrated_info(bp, info) == BP_RESULT_OK) 2603fb4d8502Sjsg return info; 2604fb4d8502Sjsg 2605fb4d8502Sjsg kfree(info); 2606fb4d8502Sjsg 2607fb4d8502Sjsg return NULL; 2608fb4d8502Sjsg } 2609fb4d8502Sjsg 2610f005ef32Sjsg static enum bp_result update_slot_layout_info(struct dc_bios *dcb, 2611fb4d8502Sjsg unsigned int i, 2612fb4d8502Sjsg struct slot_layout_info *slot_layout_info, 2613fb4d8502Sjsg unsigned int record_offset) 2614fb4d8502Sjsg { 2615fb4d8502Sjsg unsigned int j; 2616fb4d8502Sjsg struct bios_parser *bp; 2617fb4d8502Sjsg ATOM_BRACKET_LAYOUT_RECORD *record; 2618fb4d8502Sjsg ATOM_COMMON_RECORD_HEADER *record_header; 2619fb4d8502Sjsg enum bp_result result = BP_RESULT_NORECORD; 2620fb4d8502Sjsg 2621fb4d8502Sjsg bp = BP_FROM_DCB(dcb); 2622fb4d8502Sjsg record = NULL; 2623fb4d8502Sjsg record_header = NULL; 2624fb4d8502Sjsg 2625fb4d8502Sjsg for (;;) { 2626fb4d8502Sjsg 2627f005ef32Sjsg record_header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, record_offset); 2628fb4d8502Sjsg if (record_header == NULL) { 2629fb4d8502Sjsg result = BP_RESULT_BADBIOSTABLE; 2630fb4d8502Sjsg break; 2631fb4d8502Sjsg } 2632fb4d8502Sjsg 2633fb4d8502Sjsg /* the end of the list */ 2634fb4d8502Sjsg if (record_header->ucRecordType == 0xff || 2635fb4d8502Sjsg record_header->ucRecordSize == 0) { 2636fb4d8502Sjsg break; 2637fb4d8502Sjsg } 2638fb4d8502Sjsg 2639fb4d8502Sjsg if (record_header->ucRecordType == 2640fb4d8502Sjsg ATOM_BRACKET_LAYOUT_RECORD_TYPE && 2641f005ef32Sjsg struct_size(record, asConnInfo, 1) 2642fb4d8502Sjsg <= record_header->ucRecordSize) { 2643fb4d8502Sjsg record = (ATOM_BRACKET_LAYOUT_RECORD *) 2644fb4d8502Sjsg (record_header); 2645fb4d8502Sjsg result = BP_RESULT_OK; 2646fb4d8502Sjsg break; 2647fb4d8502Sjsg } 2648fb4d8502Sjsg 2649fb4d8502Sjsg record_offset += record_header->ucRecordSize; 2650fb4d8502Sjsg } 2651fb4d8502Sjsg 2652fb4d8502Sjsg /* return if the record not found */ 2653fb4d8502Sjsg if (result != BP_RESULT_OK) 2654fb4d8502Sjsg return result; 2655fb4d8502Sjsg 2656fb4d8502Sjsg /* get slot sizes */ 2657fb4d8502Sjsg slot_layout_info->length = record->ucLength; 2658fb4d8502Sjsg slot_layout_info->width = record->ucWidth; 2659fb4d8502Sjsg 2660fb4d8502Sjsg /* get info for each connector in the slot */ 2661fb4d8502Sjsg slot_layout_info->num_of_connectors = record->ucConnNum; 2662fb4d8502Sjsg for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { 2663fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2664fb4d8502Sjsg (enum connector_layout_type) 2665fb4d8502Sjsg (record->asConnInfo[j].ucConnectorType); 2666fb4d8502Sjsg switch (record->asConnInfo[j].ucConnectorType) { 2667fb4d8502Sjsg case CONNECTOR_TYPE_DVI_D: 2668fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2669fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_DVI_D; 2670fb4d8502Sjsg slot_layout_info->connectors[j].length = 2671fb4d8502Sjsg CONNECTOR_SIZE_DVI; 2672fb4d8502Sjsg break; 2673fb4d8502Sjsg 2674fb4d8502Sjsg case CONNECTOR_TYPE_HDMI: 2675fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2676fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_HDMI; 2677fb4d8502Sjsg slot_layout_info->connectors[j].length = 2678fb4d8502Sjsg CONNECTOR_SIZE_HDMI; 2679fb4d8502Sjsg break; 2680fb4d8502Sjsg 2681fb4d8502Sjsg case CONNECTOR_TYPE_DISPLAY_PORT: 2682fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2683fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_DP; 2684fb4d8502Sjsg slot_layout_info->connectors[j].length = 2685fb4d8502Sjsg CONNECTOR_SIZE_DP; 2686fb4d8502Sjsg break; 2687fb4d8502Sjsg 2688fb4d8502Sjsg case CONNECTOR_TYPE_MINI_DISPLAY_PORT: 2689fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2690fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_MINI_DP; 2691fb4d8502Sjsg slot_layout_info->connectors[j].length = 2692fb4d8502Sjsg CONNECTOR_SIZE_MINI_DP; 2693fb4d8502Sjsg break; 2694fb4d8502Sjsg 2695fb4d8502Sjsg default: 2696fb4d8502Sjsg slot_layout_info->connectors[j].connector_type = 2697fb4d8502Sjsg CONNECTOR_LAYOUT_TYPE_UNKNOWN; 2698fb4d8502Sjsg slot_layout_info->connectors[j].length = 2699fb4d8502Sjsg CONNECTOR_SIZE_UNKNOWN; 2700fb4d8502Sjsg } 2701fb4d8502Sjsg 2702fb4d8502Sjsg slot_layout_info->connectors[j].position = 2703fb4d8502Sjsg record->asConnInfo[j].ucPosition; 2704fb4d8502Sjsg slot_layout_info->connectors[j].connector_id = 2705fb4d8502Sjsg object_id_from_bios_object_id( 2706fb4d8502Sjsg record->asConnInfo[j].usConnectorObjectId); 2707fb4d8502Sjsg } 2708fb4d8502Sjsg return result; 2709fb4d8502Sjsg } 2710fb4d8502Sjsg 2711fb4d8502Sjsg 2712f005ef32Sjsg static enum bp_result get_bracket_layout_record(struct dc_bios *dcb, 2713fb4d8502Sjsg unsigned int bracket_layout_id, 2714fb4d8502Sjsg struct slot_layout_info *slot_layout_info) 2715fb4d8502Sjsg { 2716fb4d8502Sjsg unsigned int i; 2717fb4d8502Sjsg unsigned int record_offset; 2718fb4d8502Sjsg struct bios_parser *bp; 2719fb4d8502Sjsg enum bp_result result; 2720fb4d8502Sjsg ATOM_OBJECT *object; 2721fb4d8502Sjsg ATOM_OBJECT_TABLE *object_table; 2722fb4d8502Sjsg unsigned int genericTableOffset; 2723fb4d8502Sjsg 2724fb4d8502Sjsg bp = BP_FROM_DCB(dcb); 2725fb4d8502Sjsg object = NULL; 2726fb4d8502Sjsg if (slot_layout_info == NULL) { 2727fb4d8502Sjsg DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); 2728fb4d8502Sjsg return BP_RESULT_BADINPUT; 2729fb4d8502Sjsg } 2730fb4d8502Sjsg 2731fb4d8502Sjsg 2732fb4d8502Sjsg genericTableOffset = bp->object_info_tbl_offset + 2733fb4d8502Sjsg bp->object_info_tbl.v1_3->usMiscObjectTableOffset; 2734f005ef32Sjsg object_table = ((ATOM_OBJECT_TABLE *) bios_get_image(&bp->base, 2735f005ef32Sjsg genericTableOffset, 2736f005ef32Sjsg struct_size(object_table, asObjects, 1))); 2737fb4d8502Sjsg if (!object_table) 2738fb4d8502Sjsg return BP_RESULT_FAILURE; 2739fb4d8502Sjsg 2740fb4d8502Sjsg result = BP_RESULT_NORECORD; 2741fb4d8502Sjsg for (i = 0; i < object_table->ucNumberOfObjects; ++i) { 2742fb4d8502Sjsg 2743fb4d8502Sjsg if (bracket_layout_id == 2744fb4d8502Sjsg object_table->asObjects[i].usObjectID) { 2745fb4d8502Sjsg 2746fb4d8502Sjsg object = &object_table->asObjects[i]; 2747fb4d8502Sjsg record_offset = object->usRecordOffset + 2748fb4d8502Sjsg bp->object_info_tbl_offset; 2749fb4d8502Sjsg 2750fb4d8502Sjsg result = update_slot_layout_info(dcb, i, 2751fb4d8502Sjsg slot_layout_info, record_offset); 2752fb4d8502Sjsg break; 2753fb4d8502Sjsg } 2754fb4d8502Sjsg } 2755fb4d8502Sjsg return result; 2756fb4d8502Sjsg } 2757fb4d8502Sjsg 2758fb4d8502Sjsg static enum bp_result bios_get_board_layout_info( 2759fb4d8502Sjsg struct dc_bios *dcb, 2760fb4d8502Sjsg struct board_layout_info *board_layout_info) 2761fb4d8502Sjsg { 2762fb4d8502Sjsg unsigned int i; 2763fb4d8502Sjsg enum bp_result record_result; 2764fb4d8502Sjsg 2765fb4d8502Sjsg const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { 2766fb4d8502Sjsg GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, 2767fb4d8502Sjsg GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, 2768fb4d8502Sjsg 0, 0 2769fb4d8502Sjsg }; 2770fb4d8502Sjsg 2771fb4d8502Sjsg if (board_layout_info == NULL) { 2772fb4d8502Sjsg DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); 2773fb4d8502Sjsg return BP_RESULT_BADINPUT; 2774fb4d8502Sjsg } 2775fb4d8502Sjsg 2776fb4d8502Sjsg board_layout_info->num_of_slots = 0; 2777fb4d8502Sjsg 2778fb4d8502Sjsg for (i = 0; i < MAX_BOARD_SLOTS; ++i) { 2779fb4d8502Sjsg record_result = get_bracket_layout_record(dcb, 2780fb4d8502Sjsg slot_index_to_vbios_id[i], 2781fb4d8502Sjsg &board_layout_info->slots[i]); 2782fb4d8502Sjsg 2783fb4d8502Sjsg if (record_result == BP_RESULT_NORECORD && i > 0) 2784fb4d8502Sjsg break; /* no more slots present in bios */ 2785fb4d8502Sjsg else if (record_result != BP_RESULT_OK) 2786fb4d8502Sjsg return record_result; /* fail */ 2787fb4d8502Sjsg 2788fb4d8502Sjsg ++board_layout_info->num_of_slots; 2789fb4d8502Sjsg } 2790fb4d8502Sjsg 2791fb4d8502Sjsg /* all data is valid */ 2792fb4d8502Sjsg board_layout_info->is_number_of_slots_valid = 1; 2793fb4d8502Sjsg board_layout_info->is_slots_size_valid = 1; 2794fb4d8502Sjsg board_layout_info->is_connector_offsets_valid = 1; 2795fb4d8502Sjsg board_layout_info->is_connector_lengths_valid = 1; 2796fb4d8502Sjsg 2797fb4d8502Sjsg return BP_RESULT_OK; 2798fb4d8502Sjsg } 2799fb4d8502Sjsg 2800fb4d8502Sjsg /******************************************************************************/ 2801fb4d8502Sjsg 2802fb4d8502Sjsg static const struct dc_vbios_funcs vbios_funcs = { 2803fb4d8502Sjsg .get_connectors_number = bios_parser_get_connectors_number, 2804fb4d8502Sjsg 2805fb4d8502Sjsg .get_connector_id = bios_parser_get_connector_id, 2806fb4d8502Sjsg 2807fb4d8502Sjsg .get_src_obj = bios_parser_get_src_obj, 2808fb4d8502Sjsg 2809fb4d8502Sjsg .get_i2c_info = bios_parser_get_i2c_info, 2810fb4d8502Sjsg 2811fb4d8502Sjsg .get_hpd_info = bios_parser_get_hpd_info, 2812fb4d8502Sjsg 2813fb4d8502Sjsg .get_device_tag = bios_parser_get_device_tag, 2814fb4d8502Sjsg 2815fb4d8502Sjsg .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, 2816fb4d8502Sjsg 2817fb4d8502Sjsg .get_ss_entry_number = bios_parser_get_ss_entry_number, 2818fb4d8502Sjsg 2819fb4d8502Sjsg .get_embedded_panel_info = bios_parser_get_embedded_panel_info, 2820fb4d8502Sjsg 2821fb4d8502Sjsg .get_gpio_pin_info = bios_parser_get_gpio_pin_info, 2822fb4d8502Sjsg 2823fb4d8502Sjsg .get_encoder_cap_info = bios_parser_get_encoder_cap_info, 2824fb4d8502Sjsg 2825fb4d8502Sjsg /* bios scratch register communication */ 2826fb4d8502Sjsg .is_accelerated_mode = bios_is_accelerated_mode, 2827fb4d8502Sjsg 2828fb4d8502Sjsg .set_scratch_critical_state = bios_parser_set_scratch_critical_state, 2829fb4d8502Sjsg 2830fb4d8502Sjsg .is_device_id_supported = bios_parser_is_device_id_supported, 2831fb4d8502Sjsg 2832fb4d8502Sjsg /* COMMANDS */ 2833fb4d8502Sjsg .encoder_control = bios_parser_encoder_control, 2834fb4d8502Sjsg 2835fb4d8502Sjsg .transmitter_control = bios_parser_transmitter_control, 2836fb4d8502Sjsg 2837fb4d8502Sjsg .enable_crtc = bios_parser_enable_crtc, 2838fb4d8502Sjsg 2839fb4d8502Sjsg .adjust_pixel_clock = bios_parser_adjust_pixel_clock, 2840fb4d8502Sjsg 2841fb4d8502Sjsg .set_pixel_clock = bios_parser_set_pixel_clock, 2842fb4d8502Sjsg 2843fb4d8502Sjsg .set_dce_clock = bios_parser_set_dce_clock, 2844fb4d8502Sjsg 2845fb4d8502Sjsg .enable_spread_spectrum_on_ppll = bios_parser_enable_spread_spectrum_on_ppll, 2846fb4d8502Sjsg 2847fb4d8502Sjsg .program_crtc_timing = bios_parser_program_crtc_timing, /* still use. should probably retire and program directly */ 2848fb4d8502Sjsg 2849fb4d8502Sjsg .program_display_engine_pll = bios_parser_program_display_engine_pll, 2850fb4d8502Sjsg 2851fb4d8502Sjsg .enable_disp_power_gating = bios_parser_enable_disp_power_gating, 2852fb4d8502Sjsg 2853fb4d8502Sjsg /* SW init and patch */ 2854fb4d8502Sjsg 2855fb4d8502Sjsg .bios_parser_destroy = bios_parser_destroy, 2856fb4d8502Sjsg 2857fb4d8502Sjsg .get_board_layout_info = bios_get_board_layout_info, 2858ad8b1aafSjsg 2859ad8b1aafSjsg .get_atom_dc_golden_table = NULL 2860fb4d8502Sjsg }; 2861fb4d8502Sjsg 2862fb4d8502Sjsg static bool bios_parser_construct( 2863fb4d8502Sjsg struct bios_parser *bp, 2864fb4d8502Sjsg struct bp_init_data *init, 2865fb4d8502Sjsg enum dce_version dce_version) 2866fb4d8502Sjsg { 2867fb4d8502Sjsg uint16_t *rom_header_offset = NULL; 2868fb4d8502Sjsg ATOM_ROM_HEADER *rom_header = NULL; 2869fb4d8502Sjsg ATOM_OBJECT_HEADER *object_info_tbl; 2870fb4d8502Sjsg struct atom_data_revision tbl_rev = {0}; 2871fb4d8502Sjsg 2872fb4d8502Sjsg if (!init) 2873fb4d8502Sjsg return false; 2874fb4d8502Sjsg 2875fb4d8502Sjsg if (!init->bios) 2876fb4d8502Sjsg return false; 2877fb4d8502Sjsg 2878fb4d8502Sjsg bp->base.funcs = &vbios_funcs; 2879fb4d8502Sjsg bp->base.bios = init->bios; 2880fb4d8502Sjsg bp->base.bios_size = bp->base.bios[BIOS_IMAGE_SIZE_OFFSET] * BIOS_IMAGE_SIZE_UNIT; 2881fb4d8502Sjsg 2882fb4d8502Sjsg bp->base.ctx = init->ctx; 2883fb4d8502Sjsg bp->base.bios_local_image = NULL; 2884fb4d8502Sjsg 2885fb4d8502Sjsg rom_header_offset = 2886fb4d8502Sjsg GET_IMAGE(uint16_t, OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER); 2887fb4d8502Sjsg 2888fb4d8502Sjsg if (!rom_header_offset) 2889fb4d8502Sjsg return false; 2890fb4d8502Sjsg 2891fb4d8502Sjsg rom_header = GET_IMAGE(ATOM_ROM_HEADER, *rom_header_offset); 2892fb4d8502Sjsg 2893fb4d8502Sjsg if (!rom_header) 2894fb4d8502Sjsg return false; 2895fb4d8502Sjsg 2896fb4d8502Sjsg get_atom_data_table_revision(&rom_header->sHeader, &tbl_rev); 2897fb4d8502Sjsg if (tbl_rev.major >= 2 && tbl_rev.minor >= 2) 2898fb4d8502Sjsg return false; 2899fb4d8502Sjsg 2900fb4d8502Sjsg bp->master_data_tbl = 2901fb4d8502Sjsg GET_IMAGE(ATOM_MASTER_DATA_TABLE, 2902fb4d8502Sjsg rom_header->usMasterDataTableOffset); 2903fb4d8502Sjsg 2904fb4d8502Sjsg if (!bp->master_data_tbl) 2905fb4d8502Sjsg return false; 2906fb4d8502Sjsg 2907fb4d8502Sjsg bp->object_info_tbl_offset = DATA_TABLES(Object_Header); 2908fb4d8502Sjsg 2909fb4d8502Sjsg if (!bp->object_info_tbl_offset) 2910fb4d8502Sjsg return false; 2911fb4d8502Sjsg 2912fb4d8502Sjsg object_info_tbl = 2913fb4d8502Sjsg GET_IMAGE(ATOM_OBJECT_HEADER, bp->object_info_tbl_offset); 2914fb4d8502Sjsg 2915fb4d8502Sjsg if (!object_info_tbl) 2916fb4d8502Sjsg return false; 2917fb4d8502Sjsg 2918fb4d8502Sjsg get_atom_data_table_revision(&object_info_tbl->sHeader, 2919fb4d8502Sjsg &bp->object_info_tbl.revision); 2920fb4d8502Sjsg 2921fb4d8502Sjsg if (bp->object_info_tbl.revision.major == 1 2922fb4d8502Sjsg && bp->object_info_tbl.revision.minor >= 3) { 2923fb4d8502Sjsg ATOM_OBJECT_HEADER_V3 *tbl_v3; 2924fb4d8502Sjsg 2925fb4d8502Sjsg tbl_v3 = GET_IMAGE(ATOM_OBJECT_HEADER_V3, 2926fb4d8502Sjsg bp->object_info_tbl_offset); 2927fb4d8502Sjsg if (!tbl_v3) 2928fb4d8502Sjsg return false; 2929fb4d8502Sjsg 2930fb4d8502Sjsg bp->object_info_tbl.v1_3 = tbl_v3; 2931fb4d8502Sjsg } else if (bp->object_info_tbl.revision.major == 1 2932fb4d8502Sjsg && bp->object_info_tbl.revision.minor >= 1) 2933fb4d8502Sjsg bp->object_info_tbl.v1_1 = object_info_tbl; 2934fb4d8502Sjsg else 2935fb4d8502Sjsg return false; 2936fb4d8502Sjsg 2937fb4d8502Sjsg dal_bios_parser_init_cmd_tbl(bp); 2938fb4d8502Sjsg dal_bios_parser_init_cmd_tbl_helper(&bp->cmd_helper, dce_version); 2939fb4d8502Sjsg 2940fb4d8502Sjsg bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); 2941c349dbc7Sjsg bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK; 2942fb4d8502Sjsg 2943fb4d8502Sjsg return true; 2944fb4d8502Sjsg } 2945fb4d8502Sjsg 2946fb4d8502Sjsg /******************************************************************************/ 2947