linux/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012-15 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include <linux/slab.h>
  27
  28#include "dm_services.h"
  29
  30#include "ObjectID.h"
  31#include "atomfirmware.h"
  32
  33#include "dc_bios_types.h"
  34#include "include/grph_object_ctrl_defs.h"
  35#include "include/bios_parser_interface.h"
  36#include "include/i2caux_interface.h"
  37#include "include/logger_interface.h"
  38
  39#include "command_table2.h"
  40
  41#include "bios_parser_helper.h"
  42#include "command_table_helper2.h"
  43#include "bios_parser2.h"
  44#include "bios_parser_types_internal2.h"
  45#include "bios_parser_interface.h"
  46
  47#include "bios_parser_common.h"
  48
  49/* Temporarily add in defines until ObjectID.h patch is updated in a few days */
  50#ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
  51#define GENERIC_OBJECT_ID_BRACKET_LAYOUT          0x05
  52#endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */
  53
  54#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
  55#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1   \
  56        (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
  57        GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
  58        GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
  59#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */
  60
  61#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
  62#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2   \
  63        (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
  64        GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
  65        GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
  66#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */
  67
  68#define DC_LOGGER \
  69        bp->base.ctx->logger
  70
  71#define LAST_RECORD_TYPE 0xff
  72#define SMU9_SYSPLL0_ID  0
  73
  74struct i2c_id_config_access {
  75        uint8_t bfI2C_LineMux:4;
  76        uint8_t bfHW_EngineID:3;
  77        uint8_t bfHW_Capable:1;
  78        uint8_t ucAccess;
  79};
  80
  81static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
  82        struct atom_i2c_record *record,
  83        struct graphics_object_i2c_info *info);
  84
  85static enum bp_result bios_parser_get_firmware_info(
  86        struct dc_bios *dcb,
  87        struct dc_firmware_info *info);
  88
  89static enum bp_result bios_parser_get_encoder_cap_info(
  90        struct dc_bios *dcb,
  91        struct graphics_object_id object_id,
  92        struct bp_encoder_cap_info *info);
  93
  94static enum bp_result get_firmware_info_v3_1(
  95        struct bios_parser *bp,
  96        struct dc_firmware_info *info);
  97
  98static enum bp_result get_firmware_info_v3_2(
  99        struct bios_parser *bp,
 100        struct dc_firmware_info *info);
 101
 102static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
 103                struct atom_display_object_path_v2 *object);
 104
 105static struct atom_encoder_caps_record *get_encoder_cap_record(
 106        struct bios_parser *bp,
 107        struct atom_display_object_path_v2 *object);
 108
 109#define BIOS_IMAGE_SIZE_OFFSET 2
 110#define BIOS_IMAGE_SIZE_UNIT 512
 111
 112#define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
 113
 114static void bios_parser2_destruct(struct bios_parser *bp)
 115{
 116        kfree(bp->base.bios_local_image);
 117        kfree(bp->base.integrated_info);
 118}
 119
 120static void firmware_parser_destroy(struct dc_bios **dcb)
 121{
 122        struct bios_parser *bp = BP_FROM_DCB(*dcb);
 123
 124        if (!bp) {
 125                BREAK_TO_DEBUGGER();
 126                return;
 127        }
 128
 129        bios_parser2_destruct(bp);
 130
 131        kfree(bp);
 132        *dcb = NULL;
 133}
 134
 135static void get_atom_data_table_revision(
 136        struct atom_common_table_header *atom_data_tbl,
 137        struct atom_data_revision *tbl_revision)
 138{
 139        if (!tbl_revision)
 140                return;
 141
 142        /* initialize the revision to 0 which is invalid revision */
 143        tbl_revision->major = 0;
 144        tbl_revision->minor = 0;
 145
 146        if (!atom_data_tbl)
 147                return;
 148
 149        tbl_revision->major =
 150                        (uint32_t) atom_data_tbl->format_revision & 0x3f;
 151        tbl_revision->minor =
 152                        (uint32_t) atom_data_tbl->content_revision & 0x3f;
 153}
 154
 155/* BIOS oject table displaypath is per connector.
 156 * There is extra path not for connector. BIOS fill its encoderid as 0
 157 */
 158static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
 159{
 160        struct bios_parser *bp = BP_FROM_DCB(dcb);
 161        unsigned int count = 0;
 162        unsigned int i;
 163
 164        for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
 165                if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
 166                        count++;
 167        }
 168        return count;
 169}
 170
 171static struct graphics_object_id bios_parser_get_connector_id(
 172        struct dc_bios *dcb,
 173        uint8_t i)
 174{
 175        struct bios_parser *bp = BP_FROM_DCB(dcb);
 176        struct graphics_object_id object_id = dal_graphics_object_id_init(
 177                0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
 178        struct object_info_table *tbl = &bp->object_info_tbl;
 179        struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
 180
 181        if (v1_4->number_of_path > i) {
 182                /* If display_objid is generic object id,  the encoderObj
 183                 * /extencoderobjId should be 0
 184                 */
 185                if (v1_4->display_path[i].encoderobjid != 0 &&
 186                                v1_4->display_path[i].display_objid != 0)
 187                        object_id = object_id_from_bios_object_id(
 188                                        v1_4->display_path[i].display_objid);
 189        }
 190
 191        return object_id;
 192}
 193
 194static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
 195        struct graphics_object_id object_id, uint32_t index,
 196        struct graphics_object_id *src_object_id)
 197{
 198        struct bios_parser *bp = BP_FROM_DCB(dcb);
 199        unsigned int i;
 200        enum bp_result  bp_result = BP_RESULT_BADINPUT;
 201        struct graphics_object_id obj_id = {0};
 202        struct object_info_table *tbl = &bp->object_info_tbl;
 203
 204        if (!src_object_id)
 205                return bp_result;
 206
 207        switch (object_id.type) {
 208        /* Encoder's Source is GPU.  BIOS does not provide GPU, since all
 209         * displaypaths point to same GPU (0x1100).  Hardcode GPU object type
 210         */
 211        case OBJECT_TYPE_ENCODER:
 212                /* TODO: since num of src must be less than 2.
 213                 * If found in for loop, should break.
 214                 * DAL2 implementation may be changed too
 215                 */
 216                for (i = 0; i < tbl->v1_4->number_of_path; i++) {
 217                        obj_id = object_id_from_bios_object_id(
 218                        tbl->v1_4->display_path[i].encoderobjid);
 219                        if (object_id.type == obj_id.type &&
 220                                        object_id.id == obj_id.id &&
 221                                                object_id.enum_id ==
 222                                                        obj_id.enum_id) {
 223                                *src_object_id =
 224                                object_id_from_bios_object_id(0x1100);
 225                                /* break; */
 226                        }
 227                }
 228                bp_result = BP_RESULT_OK;
 229                break;
 230        case OBJECT_TYPE_CONNECTOR:
 231                for (i = 0; i < tbl->v1_4->number_of_path; i++) {
 232                        obj_id = object_id_from_bios_object_id(
 233                                tbl->v1_4->display_path[i].display_objid);
 234
 235                        if (object_id.type == obj_id.type &&
 236                                object_id.id == obj_id.id &&
 237                                        object_id.enum_id == obj_id.enum_id) {
 238                                *src_object_id =
 239                                object_id_from_bios_object_id(
 240                                tbl->v1_4->display_path[i].encoderobjid);
 241                                /* break; */
 242                        }
 243                }
 244                bp_result = BP_RESULT_OK;
 245                break;
 246        default:
 247                break;
 248        }
 249
 250        return bp_result;
 251}
 252
 253/* from graphics_object_id, find display path which includes the object_id */
 254static struct atom_display_object_path_v2 *get_bios_object(
 255                struct bios_parser *bp,
 256                struct graphics_object_id id)
 257{
 258        unsigned int i;
 259        struct graphics_object_id obj_id = {0};
 260
 261        switch (id.type) {
 262        case OBJECT_TYPE_ENCODER:
 263                for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
 264                        obj_id = object_id_from_bios_object_id(
 265                                        bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
 266                        if (id.type == obj_id.type && id.id == obj_id.id
 267                                        && id.enum_id == obj_id.enum_id)
 268                                return &bp->object_info_tbl.v1_4->display_path[i];
 269                }
 270                fallthrough;
 271        case OBJECT_TYPE_CONNECTOR:
 272        case OBJECT_TYPE_GENERIC:
 273                /* Both Generic and Connector Object ID
 274                 * will be stored on display_objid
 275                 */
 276                for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
 277                        obj_id = object_id_from_bios_object_id(
 278                                        bp->object_info_tbl.v1_4->display_path[i].display_objid);
 279                        if (id.type == obj_id.type && id.id == obj_id.id
 280                                        && id.enum_id == obj_id.enum_id)
 281                                return &bp->object_info_tbl.v1_4->display_path[i];
 282                }
 283                fallthrough;
 284        default:
 285                return NULL;
 286        }
 287}
 288
 289static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
 290        struct graphics_object_id id,
 291        struct graphics_object_i2c_info *info)
 292{
 293        uint32_t offset;
 294        struct atom_display_object_path_v2 *object;
 295        struct atom_common_record_header *header;
 296        struct atom_i2c_record *record;
 297        struct atom_i2c_record dummy_record = {0};
 298        struct bios_parser *bp = BP_FROM_DCB(dcb);
 299
 300        if (!info)
 301                return BP_RESULT_BADINPUT;
 302
 303        if (id.type == OBJECT_TYPE_GENERIC) {
 304                dummy_record.i2c_id = id.id;
 305
 306                if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
 307                        return BP_RESULT_OK;
 308                else
 309                        return BP_RESULT_NORECORD;
 310        }
 311
 312        object = get_bios_object(bp, id);
 313
 314        if (!object)
 315                return BP_RESULT_BADINPUT;
 316
 317        offset = object->disp_recordoffset + bp->object_info_tbl_offset;
 318
 319        for (;;) {
 320                header = GET_IMAGE(struct atom_common_record_header, offset);
 321
 322                if (!header)
 323                        return BP_RESULT_BADBIOSTABLE;
 324
 325                if (header->record_type == LAST_RECORD_TYPE ||
 326                        !header->record_size)
 327                        break;
 328
 329                if (header->record_type == ATOM_I2C_RECORD_TYPE
 330                        && sizeof(struct atom_i2c_record) <=
 331                                                        header->record_size) {
 332                        /* get the I2C info */
 333                        record = (struct atom_i2c_record *) header;
 334
 335                        if (get_gpio_i2c_info(bp, record, info) ==
 336                                                                BP_RESULT_OK)
 337                                return BP_RESULT_OK;
 338                }
 339
 340                offset += header->record_size;
 341        }
 342
 343        return BP_RESULT_NORECORD;
 344}
 345
 346static enum bp_result get_gpio_i2c_info(
 347        struct bios_parser *bp,
 348        struct atom_i2c_record *record,
 349        struct graphics_object_i2c_info *info)
 350{
 351        struct atom_gpio_pin_lut_v2_1 *header;
 352        uint32_t count = 0;
 353        unsigned int table_index = 0;
 354        bool find_valid = false;
 355
 356        if (!info)
 357                return BP_RESULT_BADINPUT;
 358
 359        /* get the GPIO_I2C info */
 360        if (!DATA_TABLES(gpio_pin_lut))
 361                return BP_RESULT_BADBIOSTABLE;
 362
 363        header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
 364                                        DATA_TABLES(gpio_pin_lut));
 365        if (!header)
 366                return BP_RESULT_BADBIOSTABLE;
 367
 368        if (sizeof(struct atom_common_table_header) +
 369                        sizeof(struct atom_gpio_pin_assignment) >
 370                        le16_to_cpu(header->table_header.structuresize))
 371                return BP_RESULT_BADBIOSTABLE;
 372
 373        /* TODO: is version change? */
 374        if (header->table_header.content_revision != 1)
 375                return BP_RESULT_UNSUPPORTED;
 376
 377        /* get data count */
 378        count = (le16_to_cpu(header->table_header.structuresize)
 379                        - sizeof(struct atom_common_table_header))
 380                                / sizeof(struct atom_gpio_pin_assignment);
 381
 382        for (table_index = 0; table_index < count; table_index++) {
 383                if (((record->i2c_id & I2C_HW_CAP) == (
 384                header->gpio_pin[table_index].gpio_id &
 385                                                I2C_HW_CAP)) &&
 386                ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==
 387                (header->gpio_pin[table_index].gpio_id &
 388                                        I2C_HW_ENGINE_ID_MASK)) &&
 389                ((record->i2c_id & I2C_HW_LANE_MUX) ==
 390                (header->gpio_pin[table_index].gpio_id &
 391                                                I2C_HW_LANE_MUX))) {
 392                        /* still valid */
 393                        find_valid = true;
 394                        break;
 395                }
 396        }
 397
 398        /* If we don't find the entry that we are looking for then
 399         *  we will return BP_Result_BadBiosTable.
 400         */
 401        if (find_valid == false)
 402                return BP_RESULT_BADBIOSTABLE;
 403
 404        /* get the GPIO_I2C_INFO */
 405        info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
 406        info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
 407        info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
 408        info->i2c_slave_address = record->i2c_slave_addr;
 409
 410        /* TODO: check how to get register offset for en, Y, etc. */
 411        info->gpio_info.clk_a_register_index =
 412                        le16_to_cpu(
 413                        header->gpio_pin[table_index].data_a_reg_index);
 414        info->gpio_info.clk_a_shift =
 415                        header->gpio_pin[table_index].gpio_bitshift;
 416
 417        return BP_RESULT_OK;
 418}
 419
 420static enum bp_result bios_parser_get_hpd_info(
 421        struct dc_bios *dcb,
 422        struct graphics_object_id id,
 423        struct graphics_object_hpd_info *info)
 424{
 425        struct bios_parser *bp = BP_FROM_DCB(dcb);
 426        struct atom_display_object_path_v2 *object;
 427        struct atom_hpd_int_record *record = NULL;
 428
 429        if (!info)
 430                return BP_RESULT_BADINPUT;
 431
 432        object = get_bios_object(bp, id);
 433
 434        if (!object)
 435                return BP_RESULT_BADINPUT;
 436
 437        record = get_hpd_record(bp, object);
 438
 439        if (record != NULL) {
 440                info->hpd_int_gpio_uid = record->pin_id;
 441                info->hpd_active = record->plugin_pin_state;
 442                return BP_RESULT_OK;
 443        }
 444
 445        return BP_RESULT_NORECORD;
 446}
 447
 448static struct atom_hpd_int_record *get_hpd_record(
 449        struct bios_parser *bp,
 450        struct atom_display_object_path_v2 *object)
 451{
 452        struct atom_common_record_header *header;
 453        uint32_t offset;
 454
 455        if (!object) {
 456                BREAK_TO_DEBUGGER(); /* Invalid object */
 457                return NULL;
 458        }
 459
 460        offset = le16_to_cpu(object->disp_recordoffset)
 461                        + bp->object_info_tbl_offset;
 462
 463        for (;;) {
 464                header = GET_IMAGE(struct atom_common_record_header, offset);
 465
 466                if (!header)
 467                        return NULL;
 468
 469                if (header->record_type == LAST_RECORD_TYPE ||
 470                        !header->record_size)
 471                        break;
 472
 473                if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
 474                        && sizeof(struct atom_hpd_int_record) <=
 475                                                        header->record_size)
 476                        return (struct atom_hpd_int_record *) header;
 477
 478                offset += header->record_size;
 479        }
 480
 481        return NULL;
 482}
 483
 484/**
 485 * bios_parser_get_gpio_pin_info
 486 * Get GpioPin information of input gpio id
 487 *
 488 * @param gpio_id, GPIO ID
 489 * @param info, GpioPin information structure
 490 * @return Bios parser result code
 491 * @note
 492 *  to get the GPIO PIN INFO, we need:
 493 *  1. get the GPIO_ID from other object table, see GetHPDInfo()
 494 *  2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
 495 *      to get the registerA  offset/mask
 496 */
 497static enum bp_result bios_parser_get_gpio_pin_info(
 498        struct dc_bios *dcb,
 499        uint32_t gpio_id,
 500        struct gpio_pin_info *info)
 501{
 502        struct bios_parser *bp = BP_FROM_DCB(dcb);
 503        struct atom_gpio_pin_lut_v2_1 *header;
 504        uint32_t count = 0;
 505        uint32_t i = 0;
 506
 507        if (!DATA_TABLES(gpio_pin_lut))
 508                return BP_RESULT_BADBIOSTABLE;
 509
 510        header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
 511                                                DATA_TABLES(gpio_pin_lut));
 512        if (!header)
 513                return BP_RESULT_BADBIOSTABLE;
 514
 515        if (sizeof(struct atom_common_table_header) +
 516                        sizeof(struct atom_gpio_pin_assignment)
 517                        > le16_to_cpu(header->table_header.structuresize))
 518                return BP_RESULT_BADBIOSTABLE;
 519
 520        if (header->table_header.content_revision != 1)
 521                return BP_RESULT_UNSUPPORTED;
 522
 523        /* Temporary hard code gpio pin info */
 524#if defined(FOR_SIMNOW_BOOT)
 525        {
 526                struct  atom_gpio_pin_assignment  gpio_pin[8] = {
 527                                {0x5db5, 0, 0, 1, 0},
 528                                {0x5db5, 8, 8, 2, 0},
 529                                {0x5db5, 0x10, 0x10, 3, 0},
 530                                {0x5db5, 0x18, 0x14, 4, 0},
 531                                {0x5db5, 0x1A, 0x18, 5, 0},
 532                                {0x5db5, 0x1C, 0x1C, 6, 0},
 533                };
 534
 535                count = 6;
 536                memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
 537        }
 538#else
 539        count = (le16_to_cpu(header->table_header.structuresize)
 540                        - sizeof(struct atom_common_table_header))
 541                                / sizeof(struct atom_gpio_pin_assignment);
 542#endif
 543        for (i = 0; i < count; ++i) {
 544                if (header->gpio_pin[i].gpio_id != gpio_id)
 545                        continue;
 546
 547                info->offset =
 548                        (uint32_t) le16_to_cpu(
 549                                        header->gpio_pin[i].data_a_reg_index);
 550                info->offset_y = info->offset + 2;
 551                info->offset_en = info->offset + 1;
 552                info->offset_mask = info->offset - 1;
 553
 554                info->mask = (uint32_t) (1 <<
 555                        header->gpio_pin[i].gpio_bitshift);
 556                info->mask_y = info->mask + 2;
 557                info->mask_en = info->mask + 1;
 558                info->mask_mask = info->mask - 1;
 559
 560                return BP_RESULT_OK;
 561        }
 562
 563        return BP_RESULT_NORECORD;
 564}
 565
 566static struct device_id device_type_from_device_id(uint16_t device_id)
 567{
 568
 569        struct device_id result_device_id;
 570
 571        result_device_id.raw_device_tag = device_id;
 572
 573        switch (device_id) {
 574        case ATOM_DISPLAY_LCD1_SUPPORT:
 575                result_device_id.device_type = DEVICE_TYPE_LCD;
 576                result_device_id.enum_id = 1;
 577                break;
 578
 579        case ATOM_DISPLAY_DFP1_SUPPORT:
 580                result_device_id.device_type = DEVICE_TYPE_DFP;
 581                result_device_id.enum_id = 1;
 582                break;
 583
 584        case ATOM_DISPLAY_DFP2_SUPPORT:
 585                result_device_id.device_type = DEVICE_TYPE_DFP;
 586                result_device_id.enum_id = 2;
 587                break;
 588
 589        case ATOM_DISPLAY_DFP3_SUPPORT:
 590                result_device_id.device_type = DEVICE_TYPE_DFP;
 591                result_device_id.enum_id = 3;
 592                break;
 593
 594        case ATOM_DISPLAY_DFP4_SUPPORT:
 595                result_device_id.device_type = DEVICE_TYPE_DFP;
 596                result_device_id.enum_id = 4;
 597                break;
 598
 599        case ATOM_DISPLAY_DFP5_SUPPORT:
 600                result_device_id.device_type = DEVICE_TYPE_DFP;
 601                result_device_id.enum_id = 5;
 602                break;
 603
 604        case ATOM_DISPLAY_DFP6_SUPPORT:
 605                result_device_id.device_type = DEVICE_TYPE_DFP;
 606                result_device_id.enum_id = 6;
 607                break;
 608
 609        default:
 610                BREAK_TO_DEBUGGER(); /* Invalid device Id */
 611                result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
 612                result_device_id.enum_id = 0;
 613        }
 614        return result_device_id;
 615}
 616
 617static enum bp_result bios_parser_get_device_tag(
 618        struct dc_bios *dcb,
 619        struct graphics_object_id connector_object_id,
 620        uint32_t device_tag_index,
 621        struct connector_device_tag_info *info)
 622{
 623        struct bios_parser *bp = BP_FROM_DCB(dcb);
 624        struct atom_display_object_path_v2 *object;
 625
 626        if (!info)
 627                return BP_RESULT_BADINPUT;
 628
 629        /* getBiosObject will return MXM object */
 630        object = get_bios_object(bp, connector_object_id);
 631
 632        if (!object) {
 633                BREAK_TO_DEBUGGER(); /* Invalid object id */
 634                return BP_RESULT_BADINPUT;
 635        }
 636
 637        info->acpi_device = 0; /* BIOS no longer provides this */
 638        info->dev_id = device_type_from_device_id(object->device_tag);
 639
 640        return BP_RESULT_OK;
 641}
 642
 643static enum bp_result get_ss_info_v4_1(
 644        struct bios_parser *bp,
 645        uint32_t id,
 646        uint32_t index,
 647        struct spread_spectrum_info *ss_info)
 648{
 649        enum bp_result result = BP_RESULT_OK;
 650        struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
 651        struct atom_smu_info_v3_3 *smu_info = NULL;
 652
 653        if (!ss_info)
 654                return BP_RESULT_BADINPUT;
 655
 656        if (!DATA_TABLES(dce_info))
 657                return BP_RESULT_BADBIOSTABLE;
 658
 659        disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_1,
 660                                                        DATA_TABLES(dce_info));
 661        if (!disp_cntl_tbl)
 662                return BP_RESULT_BADBIOSTABLE;
 663
 664
 665        ss_info->type.STEP_AND_DELAY_INFO = false;
 666        ss_info->spread_percentage_divider = 1000;
 667        /* BIOS no longer uses target clock.  Always enable for now */
 668        ss_info->target_clock_range = 0xffffffff;
 669
 670        switch (id) {
 671        case AS_SIGNAL_TYPE_DVI:
 672                ss_info->spread_spectrum_percentage =
 673                                disp_cntl_tbl->dvi_ss_percentage;
 674                ss_info->spread_spectrum_range =
 675                                disp_cntl_tbl->dvi_ss_rate_10hz * 10;
 676                if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 677                        ss_info->type.CENTER_MODE = true;
 678                break;
 679        case AS_SIGNAL_TYPE_HDMI:
 680                ss_info->spread_spectrum_percentage =
 681                                disp_cntl_tbl->hdmi_ss_percentage;
 682                ss_info->spread_spectrum_range =
 683                                disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
 684                if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 685                        ss_info->type.CENTER_MODE = true;
 686                break;
 687        /* TODO LVDS not support anymore? */
 688        case AS_SIGNAL_TYPE_DISPLAY_PORT:
 689                ss_info->spread_spectrum_percentage =
 690                                disp_cntl_tbl->dp_ss_percentage;
 691                ss_info->spread_spectrum_range =
 692                                disp_cntl_tbl->dp_ss_rate_10hz * 10;
 693                if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 694                        ss_info->type.CENTER_MODE = true;
 695                break;
 696        case AS_SIGNAL_TYPE_GPU_PLL:
 697                /* atom_firmware: DAL only get data from dce_info table.
 698                 * if data within smu_info is needed for DAL, VBIOS should
 699                 * copy it into dce_info
 700                 */
 701                result = BP_RESULT_UNSUPPORTED;
 702                break;
 703        case AS_SIGNAL_TYPE_XGMI:
 704                smu_info =  GET_IMAGE(struct atom_smu_info_v3_3,
 705                                      DATA_TABLES(smu_info));
 706                if (!smu_info)
 707                        return BP_RESULT_BADBIOSTABLE;
 708
 709                ss_info->spread_spectrum_percentage =
 710                                smu_info->waflclk_ss_percentage;
 711                ss_info->spread_spectrum_range =
 712                                smu_info->gpuclk_ss_rate_10hz * 10;
 713                if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 714                        ss_info->type.CENTER_MODE = true;
 715                break;
 716        default:
 717                result = BP_RESULT_UNSUPPORTED;
 718        }
 719
 720        return result;
 721}
 722
 723static enum bp_result get_ss_info_v4_2(
 724        struct bios_parser *bp,
 725        uint32_t id,
 726        uint32_t index,
 727        struct spread_spectrum_info *ss_info)
 728{
 729        enum bp_result result = BP_RESULT_OK;
 730        struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
 731        struct atom_smu_info_v3_1 *smu_info = NULL;
 732
 733        if (!ss_info)
 734                return BP_RESULT_BADINPUT;
 735
 736        if (!DATA_TABLES(dce_info))
 737                return BP_RESULT_BADBIOSTABLE;
 738
 739        if (!DATA_TABLES(smu_info))
 740                return BP_RESULT_BADBIOSTABLE;
 741
 742        disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_2,
 743                                                        DATA_TABLES(dce_info));
 744        if (!disp_cntl_tbl)
 745                return BP_RESULT_BADBIOSTABLE;
 746
 747        smu_info =  GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
 748        if (!smu_info)
 749                return BP_RESULT_BADBIOSTABLE;
 750
 751        ss_info->type.STEP_AND_DELAY_INFO = false;
 752        ss_info->spread_percentage_divider = 1000;
 753        /* BIOS no longer uses target clock.  Always enable for now */
 754        ss_info->target_clock_range = 0xffffffff;
 755
 756        switch (id) {
 757        case AS_SIGNAL_TYPE_DVI:
 758                ss_info->spread_spectrum_percentage =
 759                                disp_cntl_tbl->dvi_ss_percentage;
 760                ss_info->spread_spectrum_range =
 761                                disp_cntl_tbl->dvi_ss_rate_10hz * 10;
 762                if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 763                        ss_info->type.CENTER_MODE = true;
 764                break;
 765        case AS_SIGNAL_TYPE_HDMI:
 766                ss_info->spread_spectrum_percentage =
 767                                disp_cntl_tbl->hdmi_ss_percentage;
 768                ss_info->spread_spectrum_range =
 769                                disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
 770                if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 771                        ss_info->type.CENTER_MODE = true;
 772                break;
 773        /* TODO LVDS not support anymore? */
 774        case AS_SIGNAL_TYPE_DISPLAY_PORT:
 775                ss_info->spread_spectrum_percentage =
 776                                smu_info->gpuclk_ss_percentage;
 777                ss_info->spread_spectrum_range =
 778                                smu_info->gpuclk_ss_rate_10hz * 10;
 779                if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
 780                        ss_info->type.CENTER_MODE = true;
 781                break;
 782        case AS_SIGNAL_TYPE_GPU_PLL:
 783                /* atom_firmware: DAL only get data from dce_info table.
 784                 * if data within smu_info is needed for DAL, VBIOS should
 785                 * copy it into dce_info
 786                 */
 787                result = BP_RESULT_UNSUPPORTED;
 788                break;
 789        default:
 790                result = BP_RESULT_UNSUPPORTED;
 791        }
 792
 793        return result;
 794}
 795
 796/**
 797 * bios_parser_get_spread_spectrum_info
 798 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
 799 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
 800 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
 801 * ver 3.1,
 802 * there is only one entry for each signal /ss id.  However, there is
 803 * no planning of supporting multiple spread Sprectum entry for EverGreen
 804 * @param [in] this
 805 * @param [in] signal, ASSignalType to be converted to info index
 806 * @param [in] index, number of entries that match the converted info index
 807 * @param [out] ss_info, sprectrum information structure,
 808 * @return Bios parser result code
 809 */
 810static enum bp_result bios_parser_get_spread_spectrum_info(
 811        struct dc_bios *dcb,
 812        enum as_signal_type signal,
 813        uint32_t index,
 814        struct spread_spectrum_info *ss_info)
 815{
 816        struct bios_parser *bp = BP_FROM_DCB(dcb);
 817        enum bp_result result = BP_RESULT_UNSUPPORTED;
 818        struct atom_common_table_header *header;
 819        struct atom_data_revision tbl_revision;
 820
 821        if (!ss_info) /* check for bad input */
 822                return BP_RESULT_BADINPUT;
 823
 824        if (!DATA_TABLES(dce_info))
 825                return BP_RESULT_UNSUPPORTED;
 826
 827        header = GET_IMAGE(struct atom_common_table_header,
 828                                                DATA_TABLES(dce_info));
 829        get_atom_data_table_revision(header, &tbl_revision);
 830
 831        switch (tbl_revision.major) {
 832        case 4:
 833                switch (tbl_revision.minor) {
 834                case 1:
 835                        return get_ss_info_v4_1(bp, signal, index, ss_info);
 836                case 2:
 837                case 3:
 838                        return get_ss_info_v4_2(bp, signal, index, ss_info);
 839                default:
 840                        break;
 841                }
 842                break;
 843        default:
 844                break;
 845        }
 846        /* there can not be more then one entry for SS Info table */
 847        return result;
 848}
 849
 850static enum bp_result get_embedded_panel_info_v2_1(
 851                struct bios_parser *bp,
 852                struct embedded_panel_info *info)
 853{
 854        struct lcd_info_v2_1 *lvds;
 855
 856        if (!info)
 857                return BP_RESULT_BADINPUT;
 858
 859        if (!DATA_TABLES(lcd_info))
 860                return BP_RESULT_UNSUPPORTED;
 861
 862        lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
 863
 864        if (!lvds)
 865                return BP_RESULT_BADBIOSTABLE;
 866
 867        /* TODO: previous vv1_3, should v2_1 */
 868        if (!((lvds->table_header.format_revision == 2)
 869                        && (lvds->table_header.content_revision >= 1)))
 870                return BP_RESULT_UNSUPPORTED;
 871
 872        memset(info, 0, sizeof(struct embedded_panel_info));
 873
 874        /* We need to convert from 10KHz units into KHz units */
 875        info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
 876        /* usHActive does not include borders, according to VBIOS team */
 877        info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
 878        /* usHBlanking_Time includes borders, so we should really be
 879         * subtractingborders duing this translation, but LVDS generally
 880         * doesn't have borders, so we should be okay leaving this as is for
 881         * now.  May need to revisit if we ever have LVDS with borders
 882         */
 883        info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
 884        /* usVActive does not include borders, according to VBIOS team*/
 885        info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
 886        /* usVBlanking_Time includes borders, so we should really be
 887         * subtracting borders duing this translation, but LVDS generally
 888         * doesn't have borders, so we should be okay leaving this as is for
 889         * now. May need to revisit if we ever have LVDS with borders
 890         */
 891        info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time);
 892        info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset);
 893        info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width);
 894        info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset);
 895        info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth);
 896        info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
 897        info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
 898
 899        /* not provided by VBIOS */
 900        info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
 901
 902        info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
 903                        & ATOM_HSYNC_POLARITY);
 904        info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
 905                        & ATOM_VSYNC_POLARITY);
 906
 907        /* not provided by VBIOS */
 908        info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
 909
 910        info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
 911                        & ATOM_H_REPLICATIONBY2);
 912        info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
 913                        & ATOM_V_REPLICATIONBY2);
 914        info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo
 915                        & ATOM_COMPOSITESYNC);
 916        info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
 917
 918        /* not provided by VBIOS*/
 919        info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
 920        /* not provided by VBIOS*/
 921        info->ss_id = 0;
 922
 923        info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
 924
 925        return BP_RESULT_OK;
 926}
 927
 928static enum bp_result bios_parser_get_embedded_panel_info(
 929                struct dc_bios *dcb,
 930                struct embedded_panel_info *info)
 931{
 932        struct bios_parser
 933        *bp = BP_FROM_DCB(dcb);
 934        struct atom_common_table_header *header;
 935        struct atom_data_revision tbl_revision;
 936
 937        if (!DATA_TABLES(lcd_info))
 938                return BP_RESULT_FAILURE;
 939
 940        header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
 941
 942        if (!header)
 943                return BP_RESULT_BADBIOSTABLE;
 944
 945        get_atom_data_table_revision(header, &tbl_revision);
 946
 947        switch (tbl_revision.major) {
 948        case 2:
 949                switch (tbl_revision.minor) {
 950                case 1:
 951                        return get_embedded_panel_info_v2_1(bp, info);
 952                default:
 953                        break;
 954                }
 955        default:
 956                break;
 957        }
 958
 959        return BP_RESULT_FAILURE;
 960}
 961
 962static uint32_t get_support_mask_for_device_id(struct device_id device_id)
 963{
 964        enum dal_device_type device_type = device_id.device_type;
 965        uint32_t enum_id = device_id.enum_id;
 966
 967        switch (device_type) {
 968        case DEVICE_TYPE_LCD:
 969                switch (enum_id) {
 970                case 1:
 971                        return ATOM_DISPLAY_LCD1_SUPPORT;
 972                default:
 973                        break;
 974                }
 975                break;
 976        case DEVICE_TYPE_DFP:
 977                switch (enum_id) {
 978                case 1:
 979                        return ATOM_DISPLAY_DFP1_SUPPORT;
 980                case 2:
 981                        return ATOM_DISPLAY_DFP2_SUPPORT;
 982                case 3:
 983                        return ATOM_DISPLAY_DFP3_SUPPORT;
 984                case 4:
 985                        return ATOM_DISPLAY_DFP4_SUPPORT;
 986                case 5:
 987                        return ATOM_DISPLAY_DFP5_SUPPORT;
 988                case 6:
 989                        return ATOM_DISPLAY_DFP6_SUPPORT;
 990                default:
 991                        break;
 992                }
 993                break;
 994        default:
 995                break;
 996        }
 997
 998        /* Unidentified device ID, return empty support mask. */
 999        return 0;
1000}
1001
1002static bool bios_parser_is_device_id_supported(
1003        struct dc_bios *dcb,
1004        struct device_id id)
1005{
1006        struct bios_parser *bp = BP_FROM_DCB(dcb);
1007
1008        uint32_t mask = get_support_mask_for_device_id(id);
1009
1010        return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
1011                                                                mask) != 0;
1012}
1013
1014static uint32_t bios_parser_get_ss_entry_number(
1015        struct dc_bios *dcb,
1016        enum as_signal_type signal)
1017{
1018        /* TODO: DAL2 atomfirmware implementation does not need this.
1019         * why DAL3 need this?
1020         */
1021        return 1;
1022}
1023
1024static enum bp_result bios_parser_transmitter_control(
1025        struct dc_bios *dcb,
1026        struct bp_transmitter_control *cntl)
1027{
1028        struct bios_parser *bp = BP_FROM_DCB(dcb);
1029
1030        if (!bp->cmd_tbl.transmitter_control)
1031                return BP_RESULT_FAILURE;
1032
1033        return bp->cmd_tbl.transmitter_control(bp, cntl);
1034}
1035
1036static enum bp_result bios_parser_encoder_control(
1037        struct dc_bios *dcb,
1038        struct bp_encoder_control *cntl)
1039{
1040        struct bios_parser *bp = BP_FROM_DCB(dcb);
1041
1042        if (!bp->cmd_tbl.dig_encoder_control)
1043                return BP_RESULT_FAILURE;
1044
1045        return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1046}
1047
1048static enum bp_result bios_parser_set_pixel_clock(
1049        struct dc_bios *dcb,
1050        struct bp_pixel_clock_parameters *bp_params)
1051{
1052        struct bios_parser *bp = BP_FROM_DCB(dcb);
1053
1054        if (!bp->cmd_tbl.set_pixel_clock)
1055                return BP_RESULT_FAILURE;
1056
1057        return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1058}
1059
1060static enum bp_result bios_parser_set_dce_clock(
1061        struct dc_bios *dcb,
1062        struct bp_set_dce_clock_parameters *bp_params)
1063{
1064        struct bios_parser *bp = BP_FROM_DCB(dcb);
1065
1066        if (!bp->cmd_tbl.set_dce_clock)
1067                return BP_RESULT_FAILURE;
1068
1069        return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1070}
1071
1072static enum bp_result bios_parser_program_crtc_timing(
1073        struct dc_bios *dcb,
1074        struct bp_hw_crtc_timing_parameters *bp_params)
1075{
1076        struct bios_parser *bp = BP_FROM_DCB(dcb);
1077
1078        if (!bp->cmd_tbl.set_crtc_timing)
1079                return BP_RESULT_FAILURE;
1080
1081        return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1082}
1083
1084static enum bp_result bios_parser_enable_crtc(
1085        struct dc_bios *dcb,
1086        enum controller_id id,
1087        bool enable)
1088{
1089        struct bios_parser *bp = BP_FROM_DCB(dcb);
1090
1091        if (!bp->cmd_tbl.enable_crtc)
1092                return BP_RESULT_FAILURE;
1093
1094        return bp->cmd_tbl.enable_crtc(bp, id, enable);
1095}
1096
1097static enum bp_result bios_parser_enable_disp_power_gating(
1098        struct dc_bios *dcb,
1099        enum controller_id controller_id,
1100        enum bp_pipe_control_action action)
1101{
1102        struct bios_parser *bp = BP_FROM_DCB(dcb);
1103
1104        if (!bp->cmd_tbl.enable_disp_power_gating)
1105                return BP_RESULT_FAILURE;
1106
1107        return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1108                action);
1109}
1110
1111static enum bp_result bios_parser_enable_lvtma_control(
1112        struct dc_bios *dcb,
1113        uint8_t uc_pwr_on)
1114{
1115        struct bios_parser *bp = BP_FROM_DCB(dcb);
1116
1117        if (!bp->cmd_tbl.enable_lvtma_control)
1118                return BP_RESULT_FAILURE;
1119
1120        return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on);
1121}
1122
1123static bool bios_parser_is_accelerated_mode(
1124        struct dc_bios *dcb)
1125{
1126        return bios_is_accelerated_mode(dcb);
1127}
1128
1129/**
1130 * bios_parser_set_scratch_critical_state
1131 *
1132 * @brief
1133 *  update critical state bit in VBIOS scratch register
1134 *
1135 * @param
1136 *  bool - to set or reset state
1137 */
1138static void bios_parser_set_scratch_critical_state(
1139        struct dc_bios *dcb,
1140        bool state)
1141{
1142        bios_set_scratch_critical_state(dcb, state);
1143}
1144
1145static enum bp_result bios_parser_get_firmware_info(
1146        struct dc_bios *dcb,
1147        struct dc_firmware_info *info)
1148{
1149        struct bios_parser *bp = BP_FROM_DCB(dcb);
1150        enum bp_result result = BP_RESULT_BADBIOSTABLE;
1151        struct atom_common_table_header *header;
1152
1153        struct atom_data_revision revision;
1154
1155        if (info && DATA_TABLES(firmwareinfo)) {
1156                header = GET_IMAGE(struct atom_common_table_header,
1157                                DATA_TABLES(firmwareinfo));
1158                get_atom_data_table_revision(header, &revision);
1159                switch (revision.major) {
1160                case 3:
1161                        switch (revision.minor) {
1162                        case 1:
1163                                result = get_firmware_info_v3_1(bp, info);
1164                                break;
1165                        case 2:
1166                                result = get_firmware_info_v3_2(bp, info);
1167                                break;
1168                        case 3:
1169#ifdef CONFIG_DRM_AMD_DC_DCN3_0
1170                        case 4:
1171#endif
1172                                result = get_firmware_info_v3_2(bp, info);
1173                                break;
1174                        default:
1175                                break;
1176                        }
1177                        break;
1178                default:
1179                        break;
1180                }
1181        }
1182
1183        return result;
1184}
1185
1186static enum bp_result get_firmware_info_v3_1(
1187        struct bios_parser *bp,
1188        struct dc_firmware_info *info)
1189{
1190        struct atom_firmware_info_v3_1 *firmware_info;
1191        struct atom_display_controller_info_v4_1 *dce_info = NULL;
1192
1193        if (!info)
1194                return BP_RESULT_BADINPUT;
1195
1196        firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1197                        DATA_TABLES(firmwareinfo));
1198
1199        dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1200                        DATA_TABLES(dce_info));
1201
1202        if (!firmware_info || !dce_info)
1203                return BP_RESULT_BADBIOSTABLE;
1204
1205        memset(info, 0, sizeof(*info));
1206
1207        /* Pixel clock pll information. */
1208         /* We need to convert from 10KHz units into KHz units */
1209        info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1210        info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1211
1212         /* 27MHz for Vega10: */
1213        info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1214
1215        /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1216        if (info->pll_info.crystal_frequency == 0)
1217                info->pll_info.crystal_frequency = 27000;
1218        /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1219        info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1220        info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1221
1222        /* Get GPU PLL VCO Clock */
1223
1224        if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1225                /* VBIOS gives in 10KHz */
1226                info->smu_gpu_pll_output_freq =
1227                                bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1228        }
1229
1230        info->oem_i2c_present = false;
1231
1232        return BP_RESULT_OK;
1233}
1234
1235static enum bp_result get_firmware_info_v3_2(
1236        struct bios_parser *bp,
1237        struct dc_firmware_info *info)
1238{
1239        struct atom_firmware_info_v3_2 *firmware_info;
1240        struct atom_display_controller_info_v4_1 *dce_info = NULL;
1241        struct atom_common_table_header *header;
1242        struct atom_data_revision revision;
1243        struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1244        struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1245
1246        if (!info)
1247                return BP_RESULT_BADINPUT;
1248
1249        firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1250                        DATA_TABLES(firmwareinfo));
1251
1252        dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1253                        DATA_TABLES(dce_info));
1254
1255        if (!firmware_info || !dce_info)
1256                return BP_RESULT_BADBIOSTABLE;
1257
1258        memset(info, 0, sizeof(*info));
1259
1260        header = GET_IMAGE(struct atom_common_table_header,
1261                                        DATA_TABLES(smu_info));
1262        get_atom_data_table_revision(header, &revision);
1263
1264        if (revision.minor == 2) {
1265                /* Vega12 */
1266                smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1267                                                        DATA_TABLES(smu_info));
1268
1269                if (!smu_info_v3_2)
1270                        return BP_RESULT_BADBIOSTABLE;
1271
1272                info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1273        } else if (revision.minor == 3) {
1274                /* Vega20 */
1275                smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1276                                                        DATA_TABLES(smu_info));
1277
1278                if (!smu_info_v3_3)
1279                        return BP_RESULT_BADBIOSTABLE;
1280
1281                info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1282        }
1283
1284         // We need to convert from 10KHz units into KHz units.
1285        info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1286
1287         /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1288        info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1289        /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1290        if (info->pll_info.crystal_frequency == 0) {
1291                if (revision.minor == 2)
1292                        info->pll_info.crystal_frequency = 27000;
1293                else if (revision.minor == 3)
1294                        info->pll_info.crystal_frequency = 100000;
1295        }
1296        /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1297        info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1298        info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1299
1300        /* Get GPU PLL VCO Clock */
1301        if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1302                if (revision.minor == 2)
1303                        info->smu_gpu_pll_output_freq =
1304                                        bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1305                else if (revision.minor == 3)
1306                        info->smu_gpu_pll_output_freq =
1307                                        bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1308        }
1309
1310        if (firmware_info->board_i2c_feature_id == 0x2) {
1311                info->oem_i2c_present = true;
1312                info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
1313        } else {
1314                info->oem_i2c_present = false;
1315        }
1316
1317        return BP_RESULT_OK;
1318}
1319
1320static enum bp_result bios_parser_get_encoder_cap_info(
1321        struct dc_bios *dcb,
1322        struct graphics_object_id object_id,
1323        struct bp_encoder_cap_info *info)
1324{
1325        struct bios_parser *bp = BP_FROM_DCB(dcb);
1326        struct atom_display_object_path_v2 *object;
1327        struct atom_encoder_caps_record *record = NULL;
1328
1329        if (!info)
1330                return BP_RESULT_BADINPUT;
1331
1332        object = get_bios_object(bp, object_id);
1333
1334        if (!object)
1335                return BP_RESULT_BADINPUT;
1336
1337        record = get_encoder_cap_record(bp, object);
1338        if (!record)
1339                return BP_RESULT_NORECORD;
1340
1341        info->DP_HBR2_CAP = (record->encodercaps &
1342                        ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
1343        info->DP_HBR2_EN = (record->encodercaps &
1344                        ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
1345        info->DP_HBR3_EN = (record->encodercaps &
1346                        ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
1347        info->HDMI_6GB_EN = (record->encodercaps &
1348                        ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
1349        info->DP_IS_USB_C = (record->encodercaps &
1350                        ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
1351
1352        return BP_RESULT_OK;
1353}
1354
1355
1356static struct atom_encoder_caps_record *get_encoder_cap_record(
1357        struct bios_parser *bp,
1358        struct atom_display_object_path_v2 *object)
1359{
1360        struct atom_common_record_header *header;
1361        uint32_t offset;
1362
1363        if (!object) {
1364                BREAK_TO_DEBUGGER(); /* Invalid object */
1365                return NULL;
1366        }
1367
1368        offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
1369
1370        for (;;) {
1371                header = GET_IMAGE(struct atom_common_record_header, offset);
1372
1373                if (!header)
1374                        return NULL;
1375
1376                offset += header->record_size;
1377
1378                if (header->record_type == LAST_RECORD_TYPE ||
1379                                !header->record_size)
1380                        break;
1381
1382                if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
1383                        continue;
1384
1385                if (sizeof(struct atom_encoder_caps_record) <=
1386                                                        header->record_size)
1387                        return (struct atom_encoder_caps_record *)header;
1388        }
1389
1390        return NULL;
1391}
1392
1393static enum bp_result get_vram_info_v23(
1394        struct bios_parser *bp,
1395        struct dc_vram_info *info)
1396{
1397        struct atom_vram_info_header_v2_3 *info_v23;
1398        enum bp_result result = BP_RESULT_OK;
1399
1400        info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
1401                                                DATA_TABLES(vram_info));
1402
1403        if (info_v23 == NULL)
1404                return BP_RESULT_BADBIOSTABLE;
1405
1406        info->num_chans = info_v23->vram_module[0].channel_num;
1407        info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8;
1408
1409        return result;
1410}
1411
1412static enum bp_result get_vram_info_v24(
1413        struct bios_parser *bp,
1414        struct dc_vram_info *info)
1415{
1416        struct atom_vram_info_header_v2_4 *info_v24;
1417        enum bp_result result = BP_RESULT_OK;
1418
1419        info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
1420                                                DATA_TABLES(vram_info));
1421
1422        if (info_v24 == NULL)
1423                return BP_RESULT_BADBIOSTABLE;
1424
1425        info->num_chans = info_v24->vram_module[0].channel_num;
1426        info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8;
1427
1428        return result;
1429}
1430
1431static enum bp_result get_vram_info_v25(
1432        struct bios_parser *bp,
1433        struct dc_vram_info *info)
1434{
1435        struct atom_vram_info_header_v2_5 *info_v25;
1436        enum bp_result result = BP_RESULT_OK;
1437
1438        info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
1439                                                DATA_TABLES(vram_info));
1440
1441        if (info_v25 == NULL)
1442                return BP_RESULT_BADBIOSTABLE;
1443
1444        info->num_chans = info_v25->vram_module[0].channel_num;
1445        info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8;
1446
1447        return result;
1448}
1449
1450/*
1451 * get_integrated_info_v11
1452 *
1453 * @brief
1454 * Get V8 integrated BIOS information
1455 *
1456 * @param
1457 * bios_parser *bp - [in]BIOS parser handler to get master data table
1458 * integrated_info *info - [out] store and output integrated info
1459 *
1460 * @return
1461 * enum bp_result - BP_RESULT_OK if information is available,
1462 *                  BP_RESULT_BADBIOSTABLE otherwise.
1463 */
1464static enum bp_result get_integrated_info_v11(
1465        struct bios_parser *bp,
1466        struct integrated_info *info)
1467{
1468        struct atom_integrated_system_info_v1_11 *info_v11;
1469        uint32_t i;
1470
1471        info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
1472                                        DATA_TABLES(integratedsysteminfo));
1473
1474        if (info_v11 == NULL)
1475                return BP_RESULT_BADBIOSTABLE;
1476
1477        info->gpu_cap_info =
1478        le32_to_cpu(info_v11->gpucapinfo);
1479        /*
1480        * system_config: Bit[0] = 0 : PCIE power gating disabled
1481        *                       = 1 : PCIE power gating enabled
1482        *                Bit[1] = 0 : DDR-PLL shut down disabled
1483        *                       = 1 : DDR-PLL shut down enabled
1484        *                Bit[2] = 0 : DDR-PLL power down disabled
1485        *                       = 1 : DDR-PLL power down enabled
1486        */
1487        info->system_config = le32_to_cpu(info_v11->system_config);
1488        info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
1489        info->memory_type = info_v11->memorytype;
1490        info->ma_channel_number = info_v11->umachannelnumber;
1491        info->lvds_ss_percentage =
1492        le16_to_cpu(info_v11->lvds_ss_percentage);
1493        info->dp_ss_control =
1494        le16_to_cpu(info_v11->reserved1);
1495        info->lvds_sspread_rate_in_10hz =
1496        le16_to_cpu(info_v11->lvds_ss_rate_10hz);
1497        info->hdmi_ss_percentage =
1498        le16_to_cpu(info_v11->hdmi_ss_percentage);
1499        info->hdmi_sspread_rate_in_10hz =
1500        le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
1501        info->dvi_ss_percentage =
1502        le16_to_cpu(info_v11->dvi_ss_percentage);
1503        info->dvi_sspread_rate_in_10_hz =
1504        le16_to_cpu(info_v11->dvi_ss_rate_10hz);
1505        info->lvds_misc = info_v11->lvds_misc;
1506        for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
1507                info->ext_disp_conn_info.gu_id[i] =
1508                                info_v11->extdispconninfo.guid[i];
1509        }
1510
1511        for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
1512                info->ext_disp_conn_info.path[i].device_connector_id =
1513                object_id_from_bios_object_id(
1514                le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
1515
1516                info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
1517                object_id_from_bios_object_id(
1518                        le16_to_cpu(
1519                        info_v11->extdispconninfo.path[i].ext_encoder_objid));
1520
1521                info->ext_disp_conn_info.path[i].device_tag =
1522                        le16_to_cpu(
1523                                info_v11->extdispconninfo.path[i].device_tag);
1524                info->ext_disp_conn_info.path[i].device_acpi_enum =
1525                le16_to_cpu(
1526                        info_v11->extdispconninfo.path[i].device_acpi_enum);
1527                info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
1528                        info_v11->extdispconninfo.path[i].auxddclut_index;
1529                info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
1530                        info_v11->extdispconninfo.path[i].hpdlut_index;
1531                info->ext_disp_conn_info.path[i].channel_mapping.raw =
1532                        info_v11->extdispconninfo.path[i].channelmapping;
1533                info->ext_disp_conn_info.path[i].caps =
1534                                le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
1535        }
1536        info->ext_disp_conn_info.checksum =
1537        info_v11->extdispconninfo.checksum;
1538
1539        info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
1540        info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
1541        for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
1542                info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
1543                                info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1544                info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
1545                                info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1546        }
1547        info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
1548        for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
1549                info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1550                                info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1551                info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1552                                info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1553        }
1554
1555        info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
1556        info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
1557        for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
1558                info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
1559                                info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1560                info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
1561                                info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1562        }
1563        info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
1564        for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
1565                info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1566                                info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1567                info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1568                                info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1569        }
1570
1571        info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
1572        info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
1573        for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
1574                info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
1575                                info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1576                info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
1577                                info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1578        }
1579        info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
1580        for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
1581                info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1582                                info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1583                info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1584                                info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1585        }
1586
1587        info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
1588        info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
1589        for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
1590                info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
1591                                info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1592                info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
1593                                info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1594        }
1595        info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
1596        for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
1597                info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1598                                info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1599                info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1600                                info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1601        }
1602
1603
1604        /** TODO - review **/
1605        #if 0
1606        info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
1607                                                                        * 10;
1608        info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
1609        info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
1610
1611        for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1612                /* Convert [10KHz] into [KHz] */
1613                info->disp_clk_voltage[i].max_supported_clk =
1614                le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
1615                        ulMaximumSupportedCLK) * 10;
1616                info->disp_clk_voltage[i].voltage_index =
1617                le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
1618        }
1619
1620        info->boot_up_req_display_vector =
1621                        le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
1622        info->boot_up_nb_voltage =
1623                        le16_to_cpu(info_v11->usBootUpNBVoltage);
1624        info->ext_disp_conn_info_offset =
1625                        le16_to_cpu(info_v11->usExtDispConnInfoOffset);
1626        info->gmc_restore_reset_time =
1627                        le32_to_cpu(info_v11->ulGMCRestoreResetTime);
1628        info->minimum_n_clk =
1629                        le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
1630        for (i = 1; i < 4; ++i)
1631                info->minimum_n_clk =
1632                                info->minimum_n_clk <
1633                                le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
1634                                info->minimum_n_clk : le32_to_cpu(
1635                                        info_v11->ulNbpStateNClkFreq[i]);
1636
1637        info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
1638        info->ddr_dll_power_up_time =
1639            le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
1640        info->ddr_pll_power_up_time =
1641                le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
1642        info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
1643        info->max_lvds_pclk_freq_in_single_link =
1644                le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1645        info->max_lvds_pclk_freq_in_single_link =
1646                le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1647        info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
1648                info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
1649        info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
1650                info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
1651        info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
1652                info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
1653        info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
1654                info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
1655        info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
1656                info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
1657        info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
1658                info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
1659        info->lvds_off_to_on_delay_in_4ms =
1660                info_v11->ucLVDSOffToOnDelay_in4Ms;
1661        info->lvds_bit_depth_control_val =
1662                le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
1663
1664        for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
1665                /* Convert [10KHz] into [KHz] */
1666                info->avail_s_clk[i].supported_s_clk =
1667                        le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
1668                                                                        * 10;
1669                info->avail_s_clk[i].voltage_index =
1670                        le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
1671                info->avail_s_clk[i].voltage_id =
1672                        le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
1673        }
1674        #endif /* TODO*/
1675
1676        return BP_RESULT_OK;
1677}
1678
1679
1680/*
1681 * construct_integrated_info
1682 *
1683 * @brief
1684 * Get integrated BIOS information based on table revision
1685 *
1686 * @param
1687 * bios_parser *bp - [in]BIOS parser handler to get master data table
1688 * integrated_info *info - [out] store and output integrated info
1689 *
1690 * @return
1691 * enum bp_result - BP_RESULT_OK if information is available,
1692 *                  BP_RESULT_BADBIOSTABLE otherwise.
1693 */
1694static enum bp_result construct_integrated_info(
1695        struct bios_parser *bp,
1696        struct integrated_info *info)
1697{
1698        enum bp_result result = BP_RESULT_BADBIOSTABLE;
1699
1700        struct atom_common_table_header *header;
1701        struct atom_data_revision revision;
1702        uint32_t i;
1703        uint32_t j;
1704
1705        if (info && DATA_TABLES(integratedsysteminfo)) {
1706                header = GET_IMAGE(struct atom_common_table_header,
1707                                        DATA_TABLES(integratedsysteminfo));
1708
1709                get_atom_data_table_revision(header, &revision);
1710
1711                /* Don't need to check major revision as they are all 1 */
1712                switch (revision.minor) {
1713                case 11:
1714                case 12:
1715                        result = get_integrated_info_v11(bp, info);
1716                        break;
1717                default:
1718                        return result;
1719                }
1720        }
1721
1722        if (result != BP_RESULT_OK)
1723                return result;
1724
1725        /* Sort voltage table from low to high*/
1726        for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1727                for (j = i; j > 0; --j) {
1728                        if (info->disp_clk_voltage[j].max_supported_clk <
1729                                info->disp_clk_voltage[j-1].max_supported_clk
1730                                ) {
1731                                /* swap j and j - 1*/
1732                                swap(info->disp_clk_voltage[j - 1],
1733                                     info->disp_clk_voltage[j]);
1734                        }
1735                }
1736        }
1737
1738        return result;
1739}
1740
1741static enum bp_result bios_parser_get_vram_info(
1742                struct dc_bios *dcb,
1743                struct dc_vram_info *info)
1744{
1745        struct bios_parser *bp = BP_FROM_DCB(dcb);
1746        enum bp_result result = BP_RESULT_BADBIOSTABLE;
1747        struct atom_common_table_header *header;
1748        struct atom_data_revision revision;
1749
1750        if (info && DATA_TABLES(vram_info)) {
1751                header = GET_IMAGE(struct atom_common_table_header,
1752                                        DATA_TABLES(vram_info));
1753
1754                get_atom_data_table_revision(header, &revision);
1755
1756                switch (revision.major) {
1757                case 2:
1758                        switch (revision.minor) {
1759                        case 3:
1760                                result = get_vram_info_v23(bp, info);
1761                                break;
1762                        case 4:
1763                                result = get_vram_info_v24(bp, info);
1764                                break;
1765                        case 5:
1766                                result = get_vram_info_v25(bp, info);
1767                                break;
1768                        default:
1769                                break;
1770                        }
1771                        break;
1772
1773                default:
1774                        return result;
1775                }
1776
1777        }
1778        return result;
1779}
1780
1781static struct integrated_info *bios_parser_create_integrated_info(
1782        struct dc_bios *dcb)
1783{
1784        struct bios_parser *bp = BP_FROM_DCB(dcb);
1785        struct integrated_info *info = NULL;
1786
1787        info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
1788
1789        if (info == NULL) {
1790                ASSERT_CRITICAL(0);
1791                return NULL;
1792        }
1793
1794        if (construct_integrated_info(bp, info) == BP_RESULT_OK)
1795                return info;
1796
1797        kfree(info);
1798
1799        return NULL;
1800}
1801
1802static enum bp_result update_slot_layout_info(
1803        struct dc_bios *dcb,
1804        unsigned int i,
1805        struct slot_layout_info *slot_layout_info)
1806{
1807        unsigned int record_offset;
1808        unsigned int j;
1809        struct atom_display_object_path_v2 *object;
1810        struct atom_bracket_layout_record *record;
1811        struct atom_common_record_header *record_header;
1812        enum bp_result result;
1813        struct bios_parser *bp;
1814        struct object_info_table *tbl;
1815        struct display_object_info_table_v1_4 *v1_4;
1816
1817        record = NULL;
1818        record_header = NULL;
1819        result = BP_RESULT_NORECORD;
1820
1821        bp = BP_FROM_DCB(dcb);
1822        tbl = &bp->object_info_tbl;
1823        v1_4 = tbl->v1_4;
1824
1825        object = &v1_4->display_path[i];
1826        record_offset = (unsigned int)
1827                (object->disp_recordoffset) +
1828                (unsigned int)(bp->object_info_tbl_offset);
1829
1830        for (;;) {
1831
1832                record_header = (struct atom_common_record_header *)
1833                        GET_IMAGE(struct atom_common_record_header,
1834                        record_offset);
1835                if (record_header == NULL) {
1836                        result = BP_RESULT_BADBIOSTABLE;
1837                        break;
1838                }
1839
1840                /* the end of the list */
1841                if (record_header->record_type == 0xff ||
1842                        record_header->record_size == 0)        {
1843                        break;
1844                }
1845
1846                if (record_header->record_type ==
1847                        ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
1848                        sizeof(struct atom_bracket_layout_record)
1849                        <= record_header->record_size) {
1850                        record = (struct atom_bracket_layout_record *)
1851                                (record_header);
1852                        result = BP_RESULT_OK;
1853                        break;
1854                }
1855
1856                record_offset += record_header->record_size;
1857        }
1858
1859        /* return if the record not found */
1860        if (result != BP_RESULT_OK)
1861                return result;
1862
1863        /* get slot sizes */
1864        slot_layout_info->length = record->bracketlen;
1865        slot_layout_info->width = record->bracketwidth;
1866
1867        /* get info for each connector in the slot */
1868        slot_layout_info->num_of_connectors = record->conn_num;
1869        for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
1870                slot_layout_info->connectors[j].connector_type =
1871                        (enum connector_layout_type)
1872                        (record->conn_info[j].connector_type);
1873                switch (record->conn_info[j].connector_type) {
1874                case CONNECTOR_TYPE_DVI_D:
1875                        slot_layout_info->connectors[j].connector_type =
1876                                CONNECTOR_LAYOUT_TYPE_DVI_D;
1877                        slot_layout_info->connectors[j].length =
1878                                CONNECTOR_SIZE_DVI;
1879                        break;
1880
1881                case CONNECTOR_TYPE_HDMI:
1882                        slot_layout_info->connectors[j].connector_type =
1883                                CONNECTOR_LAYOUT_TYPE_HDMI;
1884                        slot_layout_info->connectors[j].length =
1885                                CONNECTOR_SIZE_HDMI;
1886                        break;
1887
1888                case CONNECTOR_TYPE_DISPLAY_PORT:
1889                        slot_layout_info->connectors[j].connector_type =
1890                                CONNECTOR_LAYOUT_TYPE_DP;
1891                        slot_layout_info->connectors[j].length =
1892                                CONNECTOR_SIZE_DP;
1893                        break;
1894
1895                case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
1896                        slot_layout_info->connectors[j].connector_type =
1897                                CONNECTOR_LAYOUT_TYPE_MINI_DP;
1898                        slot_layout_info->connectors[j].length =
1899                                CONNECTOR_SIZE_MINI_DP;
1900                        break;
1901
1902                default:
1903                        slot_layout_info->connectors[j].connector_type =
1904                                CONNECTOR_LAYOUT_TYPE_UNKNOWN;
1905                        slot_layout_info->connectors[j].length =
1906                                CONNECTOR_SIZE_UNKNOWN;
1907                }
1908
1909                slot_layout_info->connectors[j].position =
1910                        record->conn_info[j].position;
1911                slot_layout_info->connectors[j].connector_id =
1912                        object_id_from_bios_object_id(
1913                                record->conn_info[j].connectorobjid);
1914        }
1915        return result;
1916}
1917
1918
1919static enum bp_result get_bracket_layout_record(
1920        struct dc_bios *dcb,
1921        unsigned int bracket_layout_id,
1922        struct slot_layout_info *slot_layout_info)
1923{
1924        unsigned int i;
1925        struct bios_parser *bp = BP_FROM_DCB(dcb);
1926        enum bp_result result;
1927        struct object_info_table *tbl;
1928        struct display_object_info_table_v1_4 *v1_4;
1929
1930        if (slot_layout_info == NULL) {
1931                DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
1932                return BP_RESULT_BADINPUT;
1933        }
1934        tbl = &bp->object_info_tbl;
1935        v1_4 = tbl->v1_4;
1936
1937        result = BP_RESULT_NORECORD;
1938        for (i = 0; i < v1_4->number_of_path; ++i)      {
1939
1940                if (bracket_layout_id ==
1941                        v1_4->display_path[i].display_objid) {
1942                        result = update_slot_layout_info(dcb, i,
1943                                slot_layout_info);
1944                        break;
1945                }
1946        }
1947        return result;
1948}
1949
1950static enum bp_result bios_get_board_layout_info(
1951        struct dc_bios *dcb,
1952        struct board_layout_info *board_layout_info)
1953{
1954        unsigned int i;
1955        enum bp_result record_result;
1956
1957        const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
1958                GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
1959                GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
1960                0, 0
1961        };
1962
1963        if (board_layout_info == NULL) {
1964                DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
1965                return BP_RESULT_BADINPUT;
1966        }
1967
1968        board_layout_info->num_of_slots = 0;
1969
1970        for (i = 0; i < MAX_BOARD_SLOTS; ++i) {
1971                record_result = get_bracket_layout_record(dcb,
1972                        slot_index_to_vbios_id[i],
1973                        &board_layout_info->slots[i]);
1974
1975                if (record_result == BP_RESULT_NORECORD && i > 0)
1976                        break; /* no more slots present in bios */
1977                else if (record_result != BP_RESULT_OK)
1978                        return record_result;  /* fail */
1979
1980                ++board_layout_info->num_of_slots;
1981        }
1982
1983        /* all data is valid */
1984        board_layout_info->is_number_of_slots_valid = 1;
1985        board_layout_info->is_slots_size_valid = 1;
1986        board_layout_info->is_connector_offsets_valid = 1;
1987        board_layout_info->is_connector_lengths_valid = 1;
1988
1989        return BP_RESULT_OK;
1990}
1991
1992
1993static uint16_t bios_parser_pack_data_tables(
1994        struct dc_bios *dcb,
1995        void *dst)
1996{
1997#ifdef PACK_BIOS_DATA
1998        struct bios_parser *bp = BP_FROM_DCB(dcb);
1999        struct atom_rom_header_v2_2 *rom_header = NULL;
2000        struct atom_rom_header_v2_2 *packed_rom_header = NULL;
2001        struct atom_common_table_header *data_tbl_header = NULL;
2002        struct atom_master_list_of_data_tables_v2_1 *data_tbl_list = NULL;
2003        struct atom_master_data_table_v2_1 *packed_master_data_tbl = NULL;
2004        struct atom_data_revision tbl_rev = {0};
2005        uint16_t *rom_header_offset = NULL;
2006        const uint8_t *bios = bp->base.bios;
2007        uint8_t *bios_dst = (uint8_t *)dst;
2008        uint16_t packed_rom_header_offset;
2009        uint16_t packed_masterdatatable_offset;
2010        uint16_t packed_data_tbl_offset;
2011        uint16_t data_tbl_offset;
2012        unsigned int i;
2013
2014        rom_header_offset =
2015                GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2016
2017        if (!rom_header_offset)
2018                return 0;
2019
2020        rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
2021
2022        if (!rom_header)
2023                return 0;
2024
2025        get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
2026        if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
2027                return 0;
2028
2029        get_atom_data_table_revision(&bp->master_data_tbl->table_header, &tbl_rev);
2030        if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 1))
2031                return 0;
2032
2033        packed_rom_header_offset =
2034                OFFSET_TO_ATOM_ROM_HEADER_POINTER + sizeof(*rom_header_offset);
2035
2036        packed_masterdatatable_offset =
2037                packed_rom_header_offset + rom_header->table_header.structuresize;
2038
2039        packed_data_tbl_offset =
2040                packed_masterdatatable_offset +
2041                bp->master_data_tbl->table_header.structuresize;
2042
2043        packed_rom_header =
2044                (struct atom_rom_header_v2_2 *)(bios_dst + packed_rom_header_offset);
2045
2046        packed_master_data_tbl =
2047                (struct atom_master_data_table_v2_1 *)(bios_dst +
2048                packed_masterdatatable_offset);
2049
2050        memcpy(bios_dst, bios, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2051
2052        *((uint16_t *)(bios_dst + OFFSET_TO_ATOM_ROM_HEADER_POINTER)) =
2053                packed_rom_header_offset;
2054
2055        memcpy(bios_dst + packed_rom_header_offset, rom_header,
2056                rom_header->table_header.structuresize);
2057
2058        packed_rom_header->masterdatatable_offset = packed_masterdatatable_offset;
2059
2060        memcpy(&packed_master_data_tbl->table_header,
2061                &bp->master_data_tbl->table_header,
2062                sizeof(bp->master_data_tbl->table_header));
2063
2064        data_tbl_list = &bp->master_data_tbl->listOfdatatables;
2065
2066        /* Each data table offset in data table list is 2 bytes,
2067         * we can use that to iterate through listOfdatatables
2068         * without knowing the name of each member.
2069         */
2070        for (i = 0; i < sizeof(*data_tbl_list)/sizeof(uint16_t); i++) {
2071                data_tbl_offset = *((uint16_t *)data_tbl_list + i);
2072
2073                if (data_tbl_offset) {
2074                        data_tbl_header =
2075                                (struct atom_common_table_header *)(bios + data_tbl_offset);
2076
2077                        memcpy(bios_dst + packed_data_tbl_offset, data_tbl_header,
2078                                data_tbl_header->structuresize);
2079
2080                        *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) =
2081                                packed_data_tbl_offset;
2082
2083                        packed_data_tbl_offset += data_tbl_header->structuresize;
2084                } else {
2085                        *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) = 0;
2086                }
2087        }
2088        return packed_data_tbl_offset;
2089#endif
2090        // TODO: There is data bytes alignment issue, disable it for now.
2091        return 0;
2092}
2093
2094static struct atom_dc_golden_table_v1 *bios_get_golden_table(
2095                struct bios_parser *bp,
2096                uint32_t rev_major,
2097                uint32_t rev_minor,
2098                uint16_t *dc_golden_table_ver)
2099{
2100        struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL;
2101        uint32_t dc_golden_offset = 0;
2102        *dc_golden_table_ver = 0;
2103
2104        if (!DATA_TABLES(dce_info))
2105                return NULL;
2106
2107        /* ver.4.4 or higher */
2108        switch (rev_major) {
2109        case 4:
2110                switch (rev_minor) {
2111                case 4:
2112                        disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
2113                                                                        DATA_TABLES(dce_info));
2114                        if (!disp_cntl_tbl_4_4)
2115                                return NULL;
2116                        dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset;
2117                        *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
2118                        break;
2119                }
2120                break;
2121        }
2122
2123        if (!dc_golden_offset)
2124                return NULL;
2125
2126        if (*dc_golden_table_ver != 1)
2127                return NULL;
2128
2129        return GET_IMAGE(struct atom_dc_golden_table_v1,
2130                        dc_golden_offset);
2131}
2132
2133static enum bp_result bios_get_atom_dc_golden_table(
2134        struct dc_bios *dcb)
2135{
2136        struct bios_parser *bp = BP_FROM_DCB(dcb);
2137        enum bp_result result = BP_RESULT_OK;
2138        struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL;
2139        struct atom_common_table_header *header;
2140        struct atom_data_revision tbl_revision;
2141        uint16_t dc_golden_table_ver = 0;
2142
2143        header = GET_IMAGE(struct atom_common_table_header,
2144                                                        DATA_TABLES(dce_info));
2145        if (!header)
2146                return BP_RESULT_UNSUPPORTED;
2147
2148        get_atom_data_table_revision(header, &tbl_revision);
2149
2150        atom_dc_golden_table = bios_get_golden_table(bp,
2151                        tbl_revision.major,
2152                        tbl_revision.minor,
2153                        &dc_golden_table_ver);
2154
2155        if (!atom_dc_golden_table)
2156                return BP_RESULT_UNSUPPORTED;
2157
2158        dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver;
2159        dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val;
2160        dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val;
2161        dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val;
2162        dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val;
2163        dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val;
2164        dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val;
2165        dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val;
2166        dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val;
2167        dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val;
2168
2169        return result;
2170}
2171
2172
2173static const struct dc_vbios_funcs vbios_funcs = {
2174        .get_connectors_number = bios_parser_get_connectors_number,
2175
2176        .get_connector_id = bios_parser_get_connector_id,
2177
2178        .get_src_obj = bios_parser_get_src_obj,
2179
2180        .get_i2c_info = bios_parser_get_i2c_info,
2181
2182        .get_hpd_info = bios_parser_get_hpd_info,
2183
2184        .get_device_tag = bios_parser_get_device_tag,
2185
2186        .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
2187
2188        .get_ss_entry_number = bios_parser_get_ss_entry_number,
2189
2190        .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
2191
2192        .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
2193
2194        .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
2195
2196        .is_device_id_supported = bios_parser_is_device_id_supported,
2197
2198        .is_accelerated_mode = bios_parser_is_accelerated_mode,
2199
2200        .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
2201
2202
2203/*       COMMANDS */
2204        .encoder_control = bios_parser_encoder_control,
2205
2206        .transmitter_control = bios_parser_transmitter_control,
2207
2208        .enable_crtc = bios_parser_enable_crtc,
2209
2210        .set_pixel_clock = bios_parser_set_pixel_clock,
2211
2212        .set_dce_clock = bios_parser_set_dce_clock,
2213
2214        .program_crtc_timing = bios_parser_program_crtc_timing,
2215
2216        .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
2217
2218        .bios_parser_destroy = firmware_parser_destroy,
2219
2220        .get_board_layout_info = bios_get_board_layout_info,
2221        .pack_data_tables = bios_parser_pack_data_tables,
2222
2223        .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
2224
2225        .enable_lvtma_control = bios_parser_enable_lvtma_control
2226};
2227
2228static bool bios_parser2_construct(
2229        struct bios_parser *bp,
2230        struct bp_init_data *init,
2231        enum dce_version dce_version)
2232{
2233        uint16_t *rom_header_offset = NULL;
2234        struct atom_rom_header_v2_2 *rom_header = NULL;
2235        struct display_object_info_table_v1_4 *object_info_tbl;
2236        struct atom_data_revision tbl_rev = {0};
2237
2238        if (!init)
2239                return false;
2240
2241        if (!init->bios)
2242                return false;
2243
2244        bp->base.funcs = &vbios_funcs;
2245        bp->base.bios = init->bios;
2246        bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
2247
2248        bp->base.ctx = init->ctx;
2249
2250        bp->base.bios_local_image = NULL;
2251
2252        rom_header_offset =
2253                        GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2254
2255        if (!rom_header_offset)
2256                return false;
2257
2258        rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
2259
2260        if (!rom_header)
2261                return false;
2262
2263        get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
2264        if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
2265                return false;
2266
2267        bp->master_data_tbl =
2268                GET_IMAGE(struct atom_master_data_table_v2_1,
2269                                rom_header->masterdatatable_offset);
2270
2271        if (!bp->master_data_tbl)
2272                return false;
2273
2274        bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
2275
2276        if (!bp->object_info_tbl_offset)
2277                return false;
2278
2279        object_info_tbl =
2280                        GET_IMAGE(struct display_object_info_table_v1_4,
2281                                                bp->object_info_tbl_offset);
2282
2283        if (!object_info_tbl)
2284                return false;
2285
2286        get_atom_data_table_revision(&object_info_tbl->table_header,
2287                &bp->object_info_tbl.revision);
2288
2289        if (bp->object_info_tbl.revision.major == 1
2290                && bp->object_info_tbl.revision.minor >= 4) {
2291                struct display_object_info_table_v1_4 *tbl_v1_4;
2292
2293                tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
2294                        bp->object_info_tbl_offset);
2295                if (!tbl_v1_4)
2296                        return false;
2297
2298                bp->object_info_tbl.v1_4 = tbl_v1_4;
2299        } else
2300                return false;
2301
2302        dal_firmware_parser_init_cmd_tbl(bp);
2303        dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
2304
2305        bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
2306        bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
2307        bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);
2308
2309        return true;
2310}
2311
2312struct dc_bios *firmware_parser_create(
2313        struct bp_init_data *init,
2314        enum dce_version dce_version)
2315{
2316        struct bios_parser *bp = NULL;
2317
2318        bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
2319        if (!bp)
2320                return NULL;
2321
2322        if (bios_parser2_construct(bp, init, dce_version))
2323                return &bp->base;
2324
2325        kfree(bp);
2326        return NULL;
2327}
2328
2329
2330