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