123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445 |
- /*
- * Copyright 2012-15 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
- #include "dm_services.h"
- #include "atom.h"
- #include "include/bios_parser_interface.h"
- #include "command_table.h"
- #include "command_table_helper.h"
- #include "bios_parser_helper.h"
- #include "bios_parser_types_internal.h"
- #define EXEC_BIOS_CMD_TABLE(command, params)\
- (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
- GetIndexIntoMasterTable(COMMAND, command), \
- ¶ms) == 0)
- #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
- cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
- GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
- #define BIOS_CMD_TABLE_PARA_REVISION(command)\
- bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
- GetIndexIntoMasterTable(COMMAND, command))
- static void init_dig_encoder_control(struct bios_parser *bp);
- static void init_transmitter_control(struct bios_parser *bp);
- static void init_set_pixel_clock(struct bios_parser *bp);
- static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
- static void init_adjust_display_pll(struct bios_parser *bp);
- static void init_dac_encoder_control(struct bios_parser *bp);
- static void init_dac_output_control(struct bios_parser *bp);
- static void init_set_crtc_timing(struct bios_parser *bp);
- static void init_select_crtc_source(struct bios_parser *bp);
- static void init_enable_crtc(struct bios_parser *bp);
- static void init_enable_crtc_mem_req(struct bios_parser *bp);
- static void init_external_encoder_control(struct bios_parser *bp);
- static void init_enable_disp_power_gating(struct bios_parser *bp);
- static void init_program_clock(struct bios_parser *bp);
- static void init_set_dce_clock(struct bios_parser *bp);
- void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
- {
- init_dig_encoder_control(bp);
- init_transmitter_control(bp);
- init_set_pixel_clock(bp);
- init_enable_spread_spectrum_on_ppll(bp);
- init_adjust_display_pll(bp);
- init_dac_encoder_control(bp);
- init_dac_output_control(bp);
- init_set_crtc_timing(bp);
- init_select_crtc_source(bp);
- init_enable_crtc(bp);
- init_enable_crtc_mem_req(bp);
- init_program_clock(bp);
- init_external_encoder_control(bp);
- init_enable_disp_power_gating(bp);
- init_set_dce_clock(bp);
- }
- static uint32_t bios_cmd_table_para_revision(void *cgs_device,
- uint32_t index)
- {
- uint8_t frev, crev;
- if (cgs_atom_get_cmd_table_revs(cgs_device,
- index,
- &frev, &crev) != 0)
- return 0;
- return crev;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** D I G E N C O D E R C O N T R O L
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result encoder_control_digx_v3(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static enum bp_result encoder_control_digx_v4(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static enum bp_result encoder_control_digx_v5(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static void init_encoder_control_dig_v1(struct bios_parser *bp);
- static void init_dig_encoder_control(struct bios_parser *bp)
- {
- uint32_t version =
- BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
- switch (version) {
- case 2:
- bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
- break;
- case 4:
- bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
- break;
- case 5:
- bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
- break;
- default:
- init_encoder_control_dig_v1(bp);
- break;
- }
- }
- static enum bp_result encoder_control_dig_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static enum bp_result encoder_control_dig1_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static enum bp_result encoder_control_dig2_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
- static void init_encoder_control_dig_v1(struct bios_parser *bp)
- {
- struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
- if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
- cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
- else
- cmd_tbl->encoder_control_dig1 = NULL;
- if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
- cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
- else
- cmd_tbl->encoder_control_dig2 = NULL;
- cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
- }
- static enum bp_result encoder_control_dig_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
- if (cntl != NULL)
- switch (cntl->engine_id) {
- case ENGINE_ID_DIGA:
- if (cmd_tbl->encoder_control_dig1 != NULL)
- result =
- cmd_tbl->encoder_control_dig1(bp, cntl);
- break;
- case ENGINE_ID_DIGB:
- if (cmd_tbl->encoder_control_dig2 != NULL)
- result =
- cmd_tbl->encoder_control_dig2(bp, cntl);
- break;
- default:
- break;
- }
- return result;
- }
- static enum bp_result encoder_control_dig1_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
- bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
- if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result encoder_control_dig2_v1(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
- bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
- if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result encoder_control_digx_v3(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
- if (LANE_COUNT_FOUR < cntl->lanes_number)
- params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
- else
- params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
- params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
- /* We need to convert from KHz units into 10KHz units */
- params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
- params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- params.ucEncoderMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- cntl->signal,
- cntl->enable_dp_audio);
- params.ucLaneNum = (uint8_t)(cntl->lanes_number);
- if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result encoder_control_digx_v4(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
- if (LANE_COUNT_FOUR < cntl->lanes_number)
- params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
- else
- params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
- params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
- /* We need to convert from KHz units into 10KHz units */
- params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
- params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- params.ucEncoderMode =
- (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
- cntl->signal,
- cntl->enable_dp_audio));
- params.ucLaneNum = (uint8_t)(cntl->lanes_number);
- if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result encoder_control_digx_v5(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
- params.ucDigId = (uint8_t)(cntl->engine_id);
- params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
- params.ulPixelClock = cntl->pixel_clock / 10;
- params.ucDigMode =
- (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
- cntl->signal,
- cntl->enable_dp_audio));
- params.ucLaneNum = (uint8_t)(cntl->lanes_number);
- switch (cntl->color_depth) {
- case COLOR_DEPTH_888:
- params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
- break;
- case COLOR_DEPTH_101010:
- params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
- break;
- case COLOR_DEPTH_121212:
- params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
- break;
- case COLOR_DEPTH_161616:
- params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
- break;
- default:
- break;
- }
- if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
- switch (cntl->color_depth) {
- case COLOR_DEPTH_101010:
- params.ulPixelClock =
- (params.ulPixelClock * 30) / 24;
- break;
- case COLOR_DEPTH_121212:
- params.ulPixelClock =
- (params.ulPixelClock * 36) / 24;
- break;
- case COLOR_DEPTH_161616:
- params.ulPixelClock =
- (params.ulPixelClock * 48) / 24;
- break;
- default:
- break;
- }
- if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** TRANSMITTER CONTROL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result transmitter_control_v2(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl);
- static enum bp_result transmitter_control_v3(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl);
- static enum bp_result transmitter_control_v4(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl);
- static enum bp_result transmitter_control_v1_5(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl);
- static enum bp_result transmitter_control_v1_6(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl);
- static void init_transmitter_control(struct bios_parser *bp)
- {
- uint8_t frev;
- uint8_t crev;
- if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
- frev, crev) != 0)
- BREAK_TO_DEBUGGER();
- switch (crev) {
- case 2:
- bp->cmd_tbl.transmitter_control = transmitter_control_v2;
- break;
- case 3:
- bp->cmd_tbl.transmitter_control = transmitter_control_v3;
- break;
- case 4:
- bp->cmd_tbl.transmitter_control = transmitter_control_v4;
- break;
- case 5:
- bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
- break;
- case 6:
- bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
- break;
- default:
- dm_error("Don't have transmitter_control for v%d\n", crev);
- bp->cmd_tbl.transmitter_control = NULL;
- break;
- }
- }
- static enum bp_result transmitter_control_v2(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
- enum connector_id connector_id =
- dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
- memset(¶ms, 0, sizeof(params));
- switch (cntl->transmitter) {
- case TRANSMITTER_UNIPHY_A:
- case TRANSMITTER_UNIPHY_B:
- case TRANSMITTER_UNIPHY_C:
- case TRANSMITTER_UNIPHY_D:
- case TRANSMITTER_UNIPHY_E:
- case TRANSMITTER_UNIPHY_F:
- case TRANSMITTER_TRAVIS_LCD:
- break;
- default:
- return BP_RESULT_BADINPUT;
- }
- switch (cntl->action) {
- case TRANSMITTER_CONTROL_INIT:
- if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
- (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
- /* on INIT this bit should be set according to the
- * phisycal connector
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* connector object id */
- params.usInitInfo =
- cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
- break;
- case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
- /* votage swing and pre-emphsis */
- params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
- params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
- break;
- default:
- /* if dual-link */
- if (LANE_COUNT_FOUR < cntl->lanes_number) {
- /* on ENABLE/DISABLE this bit should be set according to
- * actual timing (number of lanes)
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* link rate, half for dual link
- * We need to convert from KHz units into 20KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
- } else
- /* link rate, half for dual link
- * We need to convert from KHz units into 10KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- break;
- }
- /* 00 - coherent mode
- * 01 - incoherent mode
- */
- params.acConfig.fCoherentMode = cntl->coherent;
- if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
- /* Bit2: Transmitter Link selection
- * =0 when bit0=0, single link A/C/E, when bit0=1,
- * master link A/C/E
- * =1 when bit0=0, single link B/D/F, when bit0=1,
- * master link B/D/F
- */
- params.acConfig.ucLinkSel = 1;
- if (ENGINE_ID_DIGB == cntl->engine_id)
- /* Bit3: Transmitter data source selection
- * =0 DIGA is data source.
- * =1 DIGB is data source.
- * This bit is only useful when ucAction= ATOM_ENABLE
- */
- params.acConfig.ucEncoderSel = 1;
- if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
- /* Bit4: DP connector flag
- * =0 connector is none-DP connector
- * =1 connector is DP connector
- */
- params.acConfig.fDPConnector = 1;
- /* Bit[7:6]: Transmitter selection
- * =0 UNIPHY_ENCODER: UNIPHYA/B
- * =1 UNIPHY1_ENCODER: UNIPHYC/D
- * =2 UNIPHY2_ENCODER: UNIPHYE/F
- * =3 reserved
- */
- params.acConfig.ucTransmitterSel =
- (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
- cntl->transmitter);
- params.ucAction = (uint8_t)cntl->action;
- if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result transmitter_control_v3(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
- uint32_t pll_id;
- enum connector_id conn_id =
- dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
- const struct command_table_helper *cmd = bp->cmd_helper;
- bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
- || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
- memset(¶ms, 0, sizeof(params));
- switch (cntl->transmitter) {
- case TRANSMITTER_UNIPHY_A:
- case TRANSMITTER_UNIPHY_B:
- case TRANSMITTER_UNIPHY_C:
- case TRANSMITTER_UNIPHY_D:
- case TRANSMITTER_UNIPHY_E:
- case TRANSMITTER_UNIPHY_F:
- case TRANSMITTER_TRAVIS_LCD:
- break;
- default:
- return BP_RESULT_BADINPUT;
- }
- if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
- return BP_RESULT_BADINPUT;
- /* fill information based on the action */
- switch (cntl->action) {
- case TRANSMITTER_CONTROL_INIT:
- if (dual_link_conn) {
- /* on INIT this bit should be set according to the
- * phisycal connector
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- }
- /* connector object id */
- params.usInitInfo =
- cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
- break;
- case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
- /* votage swing and pre-emphsis */
- params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
- params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
- break;
- default:
- if (dual_link_conn && cntl->multi_path)
- /* on ENABLE/DISABLE this bit should be set according to
- * actual timing (number of lanes)
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* if dual-link */
- if (LANE_COUNT_FOUR < cntl->lanes_number) {
- /* on ENABLE/DISABLE this bit should be set according to
- * actual timing (number of lanes)
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* link rate, half for dual link
- * We need to convert from KHz units into 20KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
- } else {
- /* link rate, half for dual link
- * We need to convert from KHz units into 10KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- }
- break;
- }
- /* 00 - coherent mode
- * 01 - incoherent mode
- */
- params.acConfig.fCoherentMode = cntl->coherent;
- if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
- /* Bit2: Transmitter Link selection
- * =0 when bit0=0, single link A/C/E, when bit0=1,
- * master link A/C/E
- * =1 when bit0=0, single link B/D/F, when bit0=1,
- * master link B/D/F
- */
- params.acConfig.ucLinkSel = 1;
- if (ENGINE_ID_DIGB == cntl->engine_id)
- /* Bit3: Transmitter data source selection
- * =0 DIGA is data source.
- * =1 DIGB is data source.
- * This bit is only useful when ucAction= ATOM_ENABLE
- */
- params.acConfig.ucEncoderSel = 1;
- /* Bit[7:6]: Transmitter selection
- * =0 UNIPHY_ENCODER: UNIPHYA/B
- * =1 UNIPHY1_ENCODER: UNIPHYC/D
- * =2 UNIPHY2_ENCODER: UNIPHYE/F
- * =3 reserved
- */
- params.acConfig.ucTransmitterSel =
- (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
- params.ucLaneNum = (uint8_t)cntl->lanes_number;
- params.acConfig.ucRefClkSource = (uint8_t)pll_id;
- params.ucAction = (uint8_t)cntl->action;
- if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result transmitter_control_v4(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
- uint32_t ref_clk_src_id;
- enum connector_id conn_id =
- dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
- const struct command_table_helper *cmd = bp->cmd_helper;
- memset(¶ms, 0, sizeof(params));
- switch (cntl->transmitter) {
- case TRANSMITTER_UNIPHY_A:
- case TRANSMITTER_UNIPHY_B:
- case TRANSMITTER_UNIPHY_C:
- case TRANSMITTER_UNIPHY_D:
- case TRANSMITTER_UNIPHY_E:
- case TRANSMITTER_UNIPHY_F:
- case TRANSMITTER_TRAVIS_LCD:
- break;
- default:
- return BP_RESULT_BADINPUT;
- }
- if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
- return BP_RESULT_BADINPUT;
- switch (cntl->action) {
- case TRANSMITTER_CONTROL_INIT:
- {
- if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
- (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
- /* on INIT this bit should be set according to the
- * phisycal connector
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* connector object id */
- params.usInitInfo =
- cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
- }
- break;
- case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
- /* votage swing and pre-emphsis */
- params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
- params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
- break;
- default:
- if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
- (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
- /* on ENABLE/DISABLE this bit should be set according to
- * actual timing (number of lanes)
- * Bit0: dual link connector flag
- * =0 connector is single link connector
- * =1 connector is dual link connector
- */
- params.acConfig.fDualLinkConnector = 1;
- /* if dual-link */
- if (LANE_COUNT_FOUR < cntl->lanes_number)
- /* link rate, half for dual link
- * We need to convert from KHz units into 20KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
- else {
- /* link rate, half for dual link
- * We need to convert from KHz units into 10KHz units
- */
- params.usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- }
- break;
- }
- /* 00 - coherent mode
- * 01 - incoherent mode
- */
- params.acConfig.fCoherentMode = cntl->coherent;
- if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
- || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
- /* Bit2: Transmitter Link selection
- * =0 when bit0=0, single link A/C/E, when bit0=1,
- * master link A/C/E
- * =1 when bit0=0, single link B/D/F, when bit0=1,
- * master link B/D/F
- */
- params.acConfig.ucLinkSel = 1;
- if (ENGINE_ID_DIGB == cntl->engine_id)
- /* Bit3: Transmitter data source selection
- * =0 DIGA is data source.
- * =1 DIGB is data source.
- * This bit is only useful when ucAction= ATOM_ENABLE
- */
- params.acConfig.ucEncoderSel = 1;
- /* Bit[7:6]: Transmitter selection
- * =0 UNIPHY_ENCODER: UNIPHYA/B
- * =1 UNIPHY1_ENCODER: UNIPHYC/D
- * =2 UNIPHY2_ENCODER: UNIPHYE/F
- * =3 reserved
- */
- params.acConfig.ucTransmitterSel =
- (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
- params.ucLaneNum = (uint8_t)(cntl->lanes_number);
- params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
- params.ucAction = (uint8_t)(cntl->action);
- if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result transmitter_control_v1_5(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- const struct command_table_helper *cmd = bp->cmd_helper;
- DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
- memset(¶ms, 0, sizeof(params));
- params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
- params.ucAction = (uint8_t)cntl->action;
- params.ucLaneNum = (uint8_t)cntl->lanes_number;
- params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
- params.ucDigMode =
- cmd->signal_type_to_atom_dig_mode(cntl->signal);
- params.asConfig.ucPhyClkSrcId =
- cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
- /* 00 - coherent mode */
- params.asConfig.ucCoherentMode = cntl->coherent;
- params.asConfig.ucHPDSel =
- cmd->hpd_sel_to_atom(cntl->hpd_sel);
- params.ucDigEncoderSel =
- cmd->dig_encoder_sel_to_atom(cntl->engine_id);
- params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
- params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
- /*
- * In SI/TN case, caller have to set usPixelClock as following:
- * DP mode: usPixelClock = DP_LINK_CLOCK/10
- * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
- * DVI single link mode: usPixelClock = pixel clock
- * DVI dual link mode: usPixelClock = pixel clock
- * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
- * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
- * LVDS mode: usPixelClock = pixel clock
- */
- if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result transmitter_control_v1_6(
- struct bios_parser *bp,
- struct bp_transmitter_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- const struct command_table_helper *cmd = bp->cmd_helper;
- DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
- memset(¶ms, 0, sizeof(params));
- params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
- params.ucAction = (uint8_t)cntl->action;
- if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
- params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
- else
- params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
- params.ucLaneNum = (uint8_t)cntl->lanes_number;
- params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
- params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
- params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
- params.ulSymClock = cntl->pixel_clock/10;
- /*
- * In SI/TN case, caller have to set usPixelClock as following:
- * DP mode: usPixelClock = DP_LINK_CLOCK/10
- * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
- * DVI single link mode: usPixelClock = pixel clock
- * DVI dual link mode: usPixelClock = pixel clock
- * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
- * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
- * LVDS mode: usPixelClock = pixel clock
- */
- switch (cntl->signal) {
- case SIGNAL_TYPE_HDMI_TYPE_A:
- switch (cntl->color_depth) {
- case COLOR_DEPTH_101010:
- params.ulSymClock =
- cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
- break;
- case COLOR_DEPTH_121212:
- params.ulSymClock =
- cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
- break;
- case COLOR_DEPTH_161616:
- params.ulSymClock =
- cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** SET PIXEL CLOCK
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result set_pixel_clock_v3(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static enum bp_result set_pixel_clock_v5(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static enum bp_result set_pixel_clock_v6(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static enum bp_result set_pixel_clock_v7(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static void init_set_pixel_clock(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
- case 3:
- bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
- break;
- case 5:
- bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
- break;
- case 6:
- bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
- break;
- case 7:
- bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
- break;
- default:
- dm_error("Don't have set_pixel_clock for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
- bp->cmd_tbl.set_pixel_clock = NULL;
- break;
- }
- }
- static enum bp_result set_pixel_clock_v3(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- PIXEL_CLOCK_PARAMETERS_V3 *params;
- SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
- memset(&allocation, 0, sizeof(allocation));
- if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
- allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
- else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
- allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
- else
- return BP_RESULT_BADINPUT;
- allocation.sPCLKInput.usRefDiv =
- cpu_to_le16((uint16_t)bp_params->reference_divider);
- allocation.sPCLKInput.usFbDiv =
- cpu_to_le16((uint16_t)bp_params->feedback_divider);
- allocation.sPCLKInput.ucFracFbDiv =
- (uint8_t)bp_params->fractional_feedback_divider;
- allocation.sPCLKInput.ucPostDiv =
- (uint8_t)bp_params->pixel_clock_post_divider;
- /* We need to convert from KHz units into 10KHz units */
- allocation.sPCLKInput.usPixelClock =
- cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
- params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
- params->ucTransmitterId =
- bp->cmd_helper->encoder_id_to_atom(
- dal_graphics_object_id_get_encoder_id(
- bp_params->encoder_object_id));
- params->ucEncoderMode =
- (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
- bp_params->signal_type, false));
- if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
- params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
- if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
- params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
- if (CONTROLLER_ID_D1 != bp_params->controller_id)
- params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
- result = BP_RESULT_OK;
- return result;
- }
- #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
- /* video bios did not define this: */
- typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
- PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
- /* Caller doesn't need to init this portion */
- ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
- } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
- #endif
- #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
- /* video bios did not define this: */
- typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
- PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
- /* Caller doesn't need to init this portion */
- ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
- } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
- #endif
- static enum bp_result set_pixel_clock_v5(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
- uint8_t controller_id;
- uint32_t pll_id;
- memset(&clk, 0, sizeof(clk));
- if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
- && bp->cmd_helper->controller_id_to_atom(
- bp_params->controller_id, &controller_id)) {
- clk.sPCLKInput.ucCRTC = controller_id;
- clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
- clk.sPCLKInput.ucRefDiv =
- (uint8_t)(bp_params->reference_divider);
- clk.sPCLKInput.usFbDiv =
- cpu_to_le16((uint16_t)(bp_params->feedback_divider));
- clk.sPCLKInput.ulFbDivDecFrac =
- cpu_to_le32(bp_params->fractional_feedback_divider);
- clk.sPCLKInput.ucPostDiv =
- (uint8_t)(bp_params->pixel_clock_post_divider);
- clk.sPCLKInput.ucTransmitterID =
- bp->cmd_helper->encoder_id_to_atom(
- dal_graphics_object_id_get_encoder_id(
- bp_params->encoder_object_id));
- clk.sPCLKInput.ucEncoderMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- bp_params->signal_type, false);
- /* We need to convert from KHz units into 10KHz units */
- clk.sPCLKInput.usPixelClock =
- cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
- if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
- clk.sPCLKInput.ucMiscInfo |=
- PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
- if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
- clk.sPCLKInput.ucMiscInfo |=
- PIXEL_CLOCK_MISC_REF_DIV_SRC;
- /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
- * =1:30bpp, =2:32bpp
- * driver choose program it itself, i.e. here we program it
- * to 888 by default.
- */
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
- result = BP_RESULT_OK;
- }
- return result;
- }
- static enum bp_result set_pixel_clock_v6(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
- uint8_t controller_id;
- uint32_t pll_id;
- memset(&clk, 0, sizeof(clk));
- if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
- && bp->cmd_helper->controller_id_to_atom(
- bp_params->controller_id, &controller_id)) {
- /* Note: VBIOS still wants to use ucCRTC name which is now
- * 1 byte in ULONG
- *typedef struct _CRTC_PIXEL_CLOCK_FREQ
- *{
- * target the pixel clock to drive the CRTC timing.
- * ULONG ulPixelClock:24;
- * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
- * previous version.
- * ATOM_CRTC1~6, indicate the CRTC controller to
- * ULONG ucCRTC:8;
- * drive the pixel clock. not used for DCPLL case.
- *}CRTC_PIXEL_CLOCK_FREQ;
- *union
- *{
- * pixel clock and CRTC id frequency
- * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
- * ULONG ulDispEngClkFreq; dispclk frequency
- *};
- */
- clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
- clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
- clk.sPCLKInput.ucRefDiv =
- (uint8_t) bp_params->reference_divider;
- clk.sPCLKInput.usFbDiv =
- cpu_to_le16((uint16_t) bp_params->feedback_divider);
- clk.sPCLKInput.ulFbDivDecFrac =
- cpu_to_le32(bp_params->fractional_feedback_divider);
- clk.sPCLKInput.ucPostDiv =
- (uint8_t) bp_params->pixel_clock_post_divider;
- clk.sPCLKInput.ucTransmitterID =
- bp->cmd_helper->encoder_id_to_atom(
- dal_graphics_object_id_get_encoder_id(
- bp_params->encoder_object_id));
- clk.sPCLKInput.ucEncoderMode =
- (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
- bp_params->signal_type, false);
- /* We need to convert from KHz units into 10KHz units */
- clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
- cpu_to_le32(bp_params->target_pixel_clock / 10);
- if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
- clk.sPCLKInput.ucMiscInfo |=
- PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
- }
- if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
- clk.sPCLKInput.ucMiscInfo |=
- PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
- }
- /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
- * 24bpp =1:30bpp, =2:32bpp
- * driver choose program it itself, i.e. here we pass required
- * target rate that includes deep color.
- */
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
- result = BP_RESULT_OK;
- }
- return result;
- }
- static enum bp_result set_pixel_clock_v7(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- PIXEL_CLOCK_PARAMETERS_V7 clk;
- uint8_t controller_id;
- uint32_t pll_id;
- memset(&clk, 0, sizeof(clk));
- if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
- && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
- /* Note: VBIOS still wants to use ucCRTC name which is now
- * 1 byte in ULONG
- *typedef struct _CRTC_PIXEL_CLOCK_FREQ
- *{
- * target the pixel clock to drive the CRTC timing.
- * ULONG ulPixelClock:24;
- * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
- * previous version.
- * ATOM_CRTC1~6, indicate the CRTC controller to
- * ULONG ucCRTC:8;
- * drive the pixel clock. not used for DCPLL case.
- *}CRTC_PIXEL_CLOCK_FREQ;
- *union
- *{
- * pixel clock and CRTC id frequency
- * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
- * ULONG ulDispEngClkFreq; dispclk frequency
- *};
- */
- clk.ucCRTC = controller_id;
- clk.ucPpll = (uint8_t) pll_id;
- clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
- clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
- /* We need to convert from KHz units into 10KHz units */
- clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock * 10);
- clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
- if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
- if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
- if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
- if (bp_params->flags.SUPPORT_YUV_420)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
- if (bp_params->flags.SET_XTALIN_REF_SRC)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
- if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
- if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
- clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
- result = BP_RESULT_OK;
- }
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** ENABLE PIXEL CLOCK SS
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result enable_spread_spectrum_on_ppll_v1(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable);
- static enum bp_result enable_spread_spectrum_on_ppll_v2(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable);
- static enum bp_result enable_spread_spectrum_on_ppll_v3(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable);
- static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
- case 1:
- bp->cmd_tbl.enable_spread_spectrum_on_ppll =
- enable_spread_spectrum_on_ppll_v1;
- break;
- case 2:
- bp->cmd_tbl.enable_spread_spectrum_on_ppll =
- enable_spread_spectrum_on_ppll_v2;
- break;
- case 3:
- bp->cmd_tbl.enable_spread_spectrum_on_ppll =
- enable_spread_spectrum_on_ppll_v3;
- break;
- default:
- dm_error("Don't have enable_spread_spectrum_on_ppll for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
- bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
- break;
- }
- }
- static enum bp_result enable_spread_spectrum_on_ppll_v1(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
- memset(¶ms, 0, sizeof(params));
- if ((enable == true) && (bp_params->percentage > 0))
- params.ucEnable = ATOM_ENABLE;
- else
- params.ucEnable = ATOM_DISABLE;
- params.usSpreadSpectrumPercentage =
- cpu_to_le16((uint16_t)bp_params->percentage);
- params.ucSpreadSpectrumStep =
- (uint8_t)bp_params->ver1.step;
- params.ucSpreadSpectrumDelay =
- (uint8_t)bp_params->ver1.delay;
- /* convert back to unit of 10KHz */
- params.ucSpreadSpectrumRange =
- (uint8_t)(bp_params->ver1.range / 10000);
- if (bp_params->flags.EXTERNAL_SS)
- params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
- if (bp_params->flags.CENTER_SPREAD)
- params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
- if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
- params.ucPpll = ATOM_PPLL1;
- else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
- params.ucPpll = ATOM_PPLL2;
- else
- BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
- if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result enable_spread_spectrum_on_ppll_v2(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
- memset(¶ms, 0, sizeof(params));
- if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
- else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
- else
- BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
- if ((enable == true) && (bp_params->percentage > 0)) {
- params.ucEnable = ATOM_ENABLE;
- params.usSpreadSpectrumPercentage =
- cpu_to_le16((uint16_t)(bp_params->percentage));
- params.usSpreadSpectrumStep =
- cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
- if (bp_params->flags.EXTERNAL_SS)
- params.ucSpreadSpectrumType |=
- ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
- if (bp_params->flags.CENTER_SPREAD)
- params.ucSpreadSpectrumType |=
- ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
- /* Both amounts need to be left shifted first before bit
- * comparison. Otherwise, the result will always be zero here
- */
- params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
- ((bp_params->ds.feedback_amount <<
- ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
- ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
- ((bp_params->ds.nfrac_amount <<
- ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
- ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
- } else
- params.ucEnable = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result enable_spread_spectrum_on_ppll_v3(
- struct bios_parser *bp,
- struct bp_spread_spectrum_parameters *bp_params,
- bool enable)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
- memset(¶ms, 0, sizeof(params));
- switch (bp_params->pll_id) {
- case CLOCK_SOURCE_ID_PLL0:
- /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
- * not for SI display clock.
- */
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
- break;
- case CLOCK_SOURCE_ID_PLL1:
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
- break;
- case CLOCK_SOURCE_ID_PLL2:
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
- break;
- case CLOCK_SOURCE_ID_DCPLL:
- params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
- break;
- default:
- BREAK_TO_DEBUGGER();
- /* Unexpected PLL value!! */
- return result;
- }
- if (enable == true) {
- params.ucEnable = ATOM_ENABLE;
- params.usSpreadSpectrumAmountFrac =
- cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
- params.usSpreadSpectrumStep =
- cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
- if (bp_params->flags.EXTERNAL_SS)
- params.ucSpreadSpectrumType |=
- ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
- if (bp_params->flags.CENTER_SPREAD)
- params.ucSpreadSpectrumType |=
- ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
- /* Both amounts need to be left shifted first before bit
- * comparison. Otherwise, the result will always be zero here
- */
- params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
- ((bp_params->ds.feedback_amount <<
- ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
- ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
- ((bp_params->ds.nfrac_amount <<
- ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
- ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
- } else
- params.ucEnable = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** ADJUST DISPLAY PLL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result adjust_display_pll_v2(
- struct bios_parser *bp,
- struct bp_adjust_pixel_clock_parameters *bp_params);
- static enum bp_result adjust_display_pll_v3(
- struct bios_parser *bp,
- struct bp_adjust_pixel_clock_parameters *bp_params);
- static void init_adjust_display_pll(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
- case 2:
- bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
- break;
- case 3:
- bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
- break;
- default:
- dm_error("Don't have adjust_display_pll for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
- bp->cmd_tbl.adjust_display_pll = NULL;
- break;
- }
- }
- static enum bp_result adjust_display_pll_v2(
- struct bios_parser *bp,
- struct bp_adjust_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
- /* We need to convert from KHz units into 10KHz units and then convert
- * output pixel clock back 10KHz-->KHz */
- uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
- params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
- params.ucTransmitterID =
- bp->cmd_helper->encoder_id_to_atom(
- dal_graphics_object_id_get_encoder_id(
- bp_params->encoder_object_id));
- params.ucEncodeMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- bp_params->signal_type, false);
- return result;
- }
- static enum bp_result adjust_display_pll_v3(
- struct bios_parser *bp,
- struct bp_adjust_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
- uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
- memset(¶ms, 0, sizeof(params));
- /* We need to convert from KHz units into 10KHz units and then convert
- * output pixel clock back 10KHz-->KHz */
- params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
- params.sInput.ucTransmitterID =
- bp->cmd_helper->encoder_id_to_atom(
- dal_graphics_object_id_get_encoder_id(
- bp_params->encoder_object_id));
- params.sInput.ucEncodeMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- bp_params->signal_type, false);
- if (bp_params->ss_enable == true)
- params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
- if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
- params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
- if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
- /* Convert output pixel clock back 10KHz-->KHz: multiply
- * original pixel clock in KHz by ratio
- * [output pxlClk/input pxlClk] */
- uint64_t pixel_clk_10_khz_out =
- (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
- uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
- if (pixel_clk_10_kHz_in != 0) {
- bp_params->adjusted_pixel_clock =
- div_u64(pixel_clk * pixel_clk_10_khz_out,
- pixel_clk_10_kHz_in);
- } else {
- bp_params->adjusted_pixel_clock = 0;
- BREAK_TO_DEBUGGER();
- }
- bp_params->reference_divider = params.sOutput.ucRefDiv;
- bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
- result = BP_RESULT_OK;
- }
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** DAC ENCODER CONTROL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result dac1_encoder_control_v1(
- struct bios_parser *bp,
- bool enable,
- uint32_t pixel_clock,
- uint8_t dac_standard);
- static enum bp_result dac2_encoder_control_v1(
- struct bios_parser *bp,
- bool enable,
- uint32_t pixel_clock,
- uint8_t dac_standard);
- static void init_dac_encoder_control(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
- case 1:
- bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
- break;
- default:
- bp->cmd_tbl.dac1_encoder_control = NULL;
- break;
- }
- switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
- case 1:
- bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
- break;
- default:
- bp->cmd_tbl.dac2_encoder_control = NULL;
- break;
- }
- }
- static void dac_encoder_control_prepare_params(
- DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
- bool enable,
- uint32_t pixel_clock,
- uint8_t dac_standard)
- {
- params->ucDacStandard = dac_standard;
- if (enable)
- params->ucAction = ATOM_ENABLE;
- else
- params->ucAction = ATOM_DISABLE;
- /* We need to convert from KHz units into 10KHz units
- * it looks as if the TvControl do not care about pixel clock
- */
- params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
- }
- static enum bp_result dac1_encoder_control_v1(
- struct bios_parser *bp,
- bool enable,
- uint32_t pixel_clock,
- uint8_t dac_standard)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DAC_ENCODER_CONTROL_PS_ALLOCATION params;
- dac_encoder_control_prepare_params(
- ¶ms,
- enable,
- pixel_clock,
- dac_standard);
- if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result dac2_encoder_control_v1(
- struct bios_parser *bp,
- bool enable,
- uint32_t pixel_clock,
- uint8_t dac_standard)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DAC_ENCODER_CONTROL_PS_ALLOCATION params;
- dac_encoder_control_prepare_params(
- ¶ms,
- enable,
- pixel_clock,
- dac_standard);
- if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** DAC OUTPUT CONTROL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result dac1_output_control_v1(
- struct bios_parser *bp,
- bool enable);
- static enum bp_result dac2_output_control_v1(
- struct bios_parser *bp,
- bool enable);
- static void init_dac_output_control(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
- case 1:
- bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
- break;
- default:
- bp->cmd_tbl.dac1_output_control = NULL;
- break;
- }
- switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
- case 1:
- bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
- break;
- default:
- bp->cmd_tbl.dac2_output_control = NULL;
- break;
- }
- }
- static enum bp_result dac1_output_control_v1(
- struct bios_parser *bp, bool enable)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
- if (enable)
- params.ucAction = ATOM_ENABLE;
- else
- params.ucAction = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result dac2_output_control_v1(
- struct bios_parser *bp, bool enable)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
- if (enable)
- params.ucAction = ATOM_ENABLE;
- else
- params.ucAction = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** SET CRTC TIMING
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result set_crtc_using_dtd_timing_v3(
- struct bios_parser *bp,
- struct bp_hw_crtc_timing_parameters *bp_params);
- static enum bp_result set_crtc_timing_v1(
- struct bios_parser *bp,
- struct bp_hw_crtc_timing_parameters *bp_params);
- static void init_set_crtc_timing(struct bios_parser *bp)
- {
- uint32_t dtd_version =
- BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
- if (dtd_version > 2)
- switch (dtd_version) {
- case 3:
- bp->cmd_tbl.set_crtc_timing =
- set_crtc_using_dtd_timing_v3;
- break;
- default:
- dm_error("Don't have set_crtc_timing for dtd v%d\n",
- dtd_version);
- bp->cmd_tbl.set_crtc_timing = NULL;
- break;
- }
- else
- switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
- case 1:
- bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
- break;
- default:
- dm_error("Don't have set_crtc_timing for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
- bp->cmd_tbl.set_crtc_timing = NULL;
- break;
- }
- }
- static enum bp_result set_crtc_timing_v1(
- struct bios_parser *bp,
- struct bp_hw_crtc_timing_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
- uint8_t atom_controller_id;
- if (bp->cmd_helper->controller_id_to_atom(
- bp_params->controller_id, &atom_controller_id))
- params.ucCRTC = atom_controller_id;
- params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
- params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
- params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
- params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
- params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
- params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
- params.usV_SyncStart =
- cpu_to_le16((uint16_t)(bp_params->v_sync_start));
- params.usV_SyncWidth =
- cpu_to_le16((uint16_t)(bp_params->v_sync_width));
- /* VBIOS does not expect any value except zero into this call, for
- * underscan use another entry ProgramOverscan call but when mode
- * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
- * but when same ,but 60 Hz there is corruption
- * DAL1 does not allow the mode 1776x1000@60
- */
- params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
- params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
- params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
- params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
- if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
- if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
- if (bp_params->flags.INTERLACE) {
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
- /* original DAL code has this condition to apply tis for
- * non-TV/CV only due to complex MV testing for possible
- * impact
- * if (pACParameters->signal != SignalType_YPbPr &&
- * pACParameters->signal != SignalType_Composite &&
- * pACParameters->signal != SignalType_SVideo)
- */
- /* HW will deduct 0.5 line from 2nd feild.
- * i.e. for 1080i, it is 2 lines for 1st field, 2.5
- * lines for the 2nd feild. we need input as 5 instead
- * of 4, but it is 4 either from Edid data
- * (spec CEA 861) or CEA timing table.
- */
- params.usV_SyncStart =
- cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
- }
- if (bp_params->flags.HORZ_COUNT_BY_TWO)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
- if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result set_crtc_using_dtd_timing_v3(
- struct bios_parser *bp,
- struct bp_hw_crtc_timing_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
- uint8_t atom_controller_id;
- if (bp->cmd_helper->controller_id_to_atom(
- bp_params->controller_id, &atom_controller_id))
- params.ucCRTC = atom_controller_id;
- /* bios usH_Size wants h addressable size */
- params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
- /* bios usH_Blanking_Time wants borders included in blanking */
- params.usH_Blanking_Time =
- cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
- /* bios usV_Size wants v addressable size */
- params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
- /* bios usV_Blanking_Time wants borders included in blanking */
- params.usV_Blanking_Time =
- cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
- /* bios usHSyncOffset is the offset from the end of h addressable,
- * our horizontalSyncStart is the offset from the beginning
- * of h addressable */
- params.usH_SyncOffset =
- cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
- params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
- /* bios usHSyncOffset is the offset from the end of v addressable,
- * our verticalSyncStart is the offset from the beginning of
- * v addressable */
- params.usV_SyncOffset =
- cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
- params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
- /* we assume that overscan from original timing does not get bigger
- * than 255
- * we will program all the borders in the Set CRTC Overscan call below
- */
- if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
- if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
- if (bp_params->flags.INTERLACE) {
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
- /* original DAL code has this condition to apply this
- * for non-TV/CV only
- * due to complex MV testing for possible impact
- * if ( pACParameters->signal != SignalType_YPbPr &&
- * pACParameters->signal != SignalType_Composite &&
- * pACParameters->signal != SignalType_SVideo)
- */
- {
- /* HW will deduct 0.5 line from 2nd feild.
- * i.e. for 1080i, it is 2 lines for 1st field,
- * 2.5 lines for the 2nd feild. we need input as 5
- * instead of 4.
- * but it is 4 either from Edid data (spec CEA 861)
- * or CEA timing table.
- */
- params.usV_SyncOffset =
- cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
- }
- }
- if (bp_params->flags.HORZ_COUNT_BY_TWO)
- params.susModeMiscInfo.usAccess =
- cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
- if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** SELECT CRTC SOURCE
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result select_crtc_source_v2(
- struct bios_parser *bp,
- struct bp_crtc_source_select *bp_params);
- static enum bp_result select_crtc_source_v3(
- struct bios_parser *bp,
- struct bp_crtc_source_select *bp_params);
- static void init_select_crtc_source(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
- case 2:
- bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
- break;
- case 3:
- bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
- break;
- default:
- dm_error("Don't select_crtc_source enable_crtc for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source));
- bp->cmd_tbl.select_crtc_source = NULL;
- break;
- }
- }
- static enum bp_result select_crtc_source_v2(
- struct bios_parser *bp,
- struct bp_crtc_source_select *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SELECT_CRTC_SOURCE_PARAMETERS_V2 params;
- uint8_t atom_controller_id;
- uint32_t atom_engine_id;
- enum signal_type s = bp_params->signal;
- memset(¶ms, 0, sizeof(params));
- /* set controller id */
- if (bp->cmd_helper->controller_id_to_atom(
- bp_params->controller_id, &atom_controller_id))
- params.ucCRTC = atom_controller_id;
- else
- return BP_RESULT_FAILURE;
- /* set encoder id */
- if (bp->cmd_helper->engine_bp_to_atom(
- bp_params->engine_id, &atom_engine_id))
- params.ucEncoderID = (uint8_t)atom_engine_id;
- else
- return BP_RESULT_FAILURE;
- if (SIGNAL_TYPE_EDP == s ||
- (SIGNAL_TYPE_DISPLAY_PORT == s &&
- SIGNAL_TYPE_LVDS == bp_params->sink_signal))
- s = SIGNAL_TYPE_LVDS;
- params.ucEncodeMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- s, bp_params->enable_dp_audio);
- if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result select_crtc_source_v3(
- struct bios_parser *bp,
- struct bp_crtc_source_select *bp_params)
- {
- bool result = BP_RESULT_FAILURE;
- SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
- uint8_t atom_controller_id;
- uint32_t atom_engine_id;
- enum signal_type s = bp_params->signal;
- memset(¶ms, 0, sizeof(params));
- if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
- &atom_controller_id))
- params.ucCRTC = atom_controller_id;
- else
- return result;
- if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
- &atom_engine_id))
- params.ucEncoderID = (uint8_t)atom_engine_id;
- else
- return result;
- if (SIGNAL_TYPE_EDP == s ||
- (SIGNAL_TYPE_DISPLAY_PORT == s &&
- SIGNAL_TYPE_LVDS == bp_params->sink_signal))
- s = SIGNAL_TYPE_LVDS;
- params.ucEncodeMode =
- bp->cmd_helper->encoder_mode_bp_to_atom(
- s, bp_params->enable_dp_audio);
- /* Needed for VBIOS Random Spatial Dithering feature */
- params.ucDstBpc = (uint8_t)(bp_params->display_output_bit_depth);
- if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** ENABLE CRTC
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result enable_crtc_v1(
- struct bios_parser *bp,
- enum controller_id controller_id,
- bool enable);
- static void init_enable_crtc(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
- case 1:
- bp->cmd_tbl.enable_crtc = enable_crtc_v1;
- break;
- default:
- dm_error("Don't have enable_crtc for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
- bp->cmd_tbl.enable_crtc = NULL;
- break;
- }
- }
- static enum bp_result enable_crtc_v1(
- struct bios_parser *bp,
- enum controller_id controller_id,
- bool enable)
- {
- bool result = BP_RESULT_FAILURE;
- ENABLE_CRTC_PARAMETERS params = {0};
- uint8_t id;
- if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
- params.ucCRTC = id;
- else
- return BP_RESULT_BADINPUT;
- if (enable)
- params.ucEnable = ATOM_ENABLE;
- else
- params.ucEnable = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** ENABLE CRTC MEM REQ
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result enable_crtc_mem_req_v1(
- struct bios_parser *bp,
- enum controller_id controller_id,
- bool enable);
- static void init_enable_crtc_mem_req(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
- case 1:
- bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
- break;
- default:
- bp->cmd_tbl.enable_crtc_mem_req = NULL;
- break;
- }
- }
- static enum bp_result enable_crtc_mem_req_v1(
- struct bios_parser *bp,
- enum controller_id controller_id,
- bool enable)
- {
- bool result = BP_RESULT_BADINPUT;
- ENABLE_CRTC_PARAMETERS params = {0};
- uint8_t id;
- if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
- params.ucCRTC = id;
- if (enable)
- params.ucEnable = ATOM_ENABLE;
- else
- params.ucEnable = ATOM_DISABLE;
- if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
- result = BP_RESULT_OK;
- else
- result = BP_RESULT_FAILURE;
- }
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** DISPLAY PLL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result program_clock_v5(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static enum bp_result program_clock_v6(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params);
- static void init_program_clock(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
- case 5:
- bp->cmd_tbl.program_clock = program_clock_v5;
- break;
- case 6:
- bp->cmd_tbl.program_clock = program_clock_v6;
- break;
- default:
- dm_error("Don't have program_clock for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
- bp->cmd_tbl.program_clock = NULL;
- break;
- }
- }
- static enum bp_result program_clock_v5(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
- uint32_t atom_pll_id;
- memset(¶ms, 0, sizeof(params));
- if (!bp->cmd_helper->clock_source_id_to_atom(
- bp_params->pll_id, &atom_pll_id)) {
- BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
- return BP_RESULT_BADINPUT;
- }
- /* We need to convert from KHz units into 10KHz units */
- params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
- params.sPCLKInput.usPixelClock =
- cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
- params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
- if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
- params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
- result = BP_RESULT_OK;
- return result;
- }
- static enum bp_result program_clock_v6(
- struct bios_parser *bp,
- struct bp_pixel_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
- uint32_t atom_pll_id;
- memset(¶ms, 0, sizeof(params));
- if (!bp->cmd_helper->clock_source_id_to_atom(
- bp_params->pll_id, &atom_pll_id)) {
- BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
- return BP_RESULT_BADINPUT;
- }
- /* We need to convert from KHz units into 10KHz units */
- params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
- params.sPCLKInput.ulDispEngClkFreq =
- cpu_to_le32(bp_params->target_pixel_clock / 10);
- if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
- params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
- if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
- /* True display clock is returned by VBIOS if DFS bypass
- * is enabled. */
- bp_params->dfs_bypass_display_clock =
- (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
- result = BP_RESULT_OK;
- }
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** EXTERNAL ENCODER CONTROL
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result external_encoder_control_v3(
- struct bios_parser *bp,
- struct bp_external_encoder_control *cntl);
- static void init_external_encoder_control(
- struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
- case 3:
- bp->cmd_tbl.external_encoder_control =
- external_encoder_control_v3;
- break;
- default:
- bp->cmd_tbl.external_encoder_control = NULL;
- break;
- }
- }
- static enum bp_result external_encoder_control_v3(
- struct bios_parser *bp,
- struct bp_external_encoder_control *cntl)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- /* we need use _PS_Alloc struct */
- EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
- EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
- struct graphics_object_id encoder;
- bool is_input_signal_dp = false;
- memset(¶ms, 0, sizeof(params));
- cntl_params = ¶ms.sExtEncoder;
- encoder = cntl->encoder_id;
- /* check if encoder supports external encoder control table */
- switch (dal_graphics_object_id_get_encoder_id(encoder)) {
- case ENCODER_ID_EXTERNAL_NUTMEG:
- case ENCODER_ID_EXTERNAL_TRAVIS:
- is_input_signal_dp = true;
- break;
- default:
- BREAK_TO_DEBUGGER();
- return BP_RESULT_BADINPUT;
- }
- /* Fill information based on the action
- *
- * Bit[6:4]: indicate external encoder, applied to all functions.
- * =0: external encoder1, mapped to external encoder enum id1
- * =1: external encoder2, mapped to external encoder enum id2
- *
- * enum ObjectEnumId
- * {
- * EnumId_Unknown = 0,
- * EnumId_1,
- * EnumId_2,
- * };
- */
- cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
- switch (cntl->action) {
- case EXTERNAL_ENCODER_CONTROL_INIT:
- /* output display connector type. Only valid in encoder
- * initialization */
- cntl_params->usConnectorId =
- cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
- break;
- case EXTERNAL_ENCODER_CONTROL_SETUP:
- /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
- * 10KHz
- * output display device pixel clock frequency in unit of 10KHz.
- * Only valid in setup and enableoutput
- */
- cntl_params->usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- /* Indicate display output signal type drive by external
- * encoder, only valid in setup and enableoutput */
- cntl_params->ucEncoderMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- cntl->signal, false);
- if (is_input_signal_dp) {
- /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
- * only valid in encoder setup with DP mode. */
- if (LINK_RATE_HIGH == cntl->link_rate)
- cntl_params->ucConfig |= 1;
- /* output color depth Indicate encoder data bpc format
- * in DP mode, only valid in encoder setup in DP mode.
- */
- cntl_params->ucBitPerColor =
- (uint8_t)(cntl->color_depth);
- }
- /* Indicate how many lanes used by external encoder, only valid
- * in encoder setup and enableoutput. */
- cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
- break;
- case EXTERNAL_ENCODER_CONTROL_ENABLE:
- cntl_params->usPixelClock =
- cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
- cntl_params->ucEncoderMode =
- (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
- cntl->signal, false);
- cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
- break;
- default:
- break;
- }
- cntl_params->ucAction = (uint8_t)cntl->action;
- if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** ENABLE DISPLAY POWER GATING
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result enable_disp_power_gating_v2_1(
- struct bios_parser *bp,
- enum controller_id crtc_id,
- enum bp_pipe_control_action action);
- static void init_enable_disp_power_gating(
- struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
- case 1:
- bp->cmd_tbl.enable_disp_power_gating =
- enable_disp_power_gating_v2_1;
- break;
- default:
- dm_error("Don't enable_disp_power_gating enable_crtc for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
- bp->cmd_tbl.enable_disp_power_gating = NULL;
- break;
- }
- }
- static enum bp_result enable_disp_power_gating_v2_1(
- struct bios_parser *bp,
- enum controller_id crtc_id,
- enum bp_pipe_control_action action)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
- uint8_t atom_crtc_id;
- if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
- params.ucDispPipeId = atom_crtc_id;
- else
- return BP_RESULT_BADINPUT;
- params.ucEnable =
- bp->cmd_helper->disp_power_gating_action_to_atom(action);
- if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
- result = BP_RESULT_OK;
- return result;
- }
- /*******************************************************************************
- ********************************************************************************
- **
- ** SET DCE CLOCK
- **
- ********************************************************************************
- *******************************************************************************/
- static enum bp_result set_dce_clock_v2_1(
- struct bios_parser *bp,
- struct bp_set_dce_clock_parameters *bp_params);
- static void init_set_dce_clock(struct bios_parser *bp)
- {
- switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
- case 1:
- bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
- break;
- default:
- dm_error("Don't have set_dce_clock for v%d\n",
- BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
- bp->cmd_tbl.set_dce_clock = NULL;
- break;
- }
- }
- static enum bp_result set_dce_clock_v2_1(
- struct bios_parser *bp,
- struct bp_set_dce_clock_parameters *bp_params)
- {
- enum bp_result result = BP_RESULT_FAILURE;
- SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
- uint32_t atom_pll_id;
- uint32_t atom_clock_type;
- const struct command_table_helper *cmd = bp->cmd_helper;
- memset(¶ms, 0, sizeof(params));
- if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
- !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
- return BP_RESULT_BADINPUT;
- params.asParam.ucDCEClkSrc = atom_pll_id;
- params.asParam.ucDCEClkType = atom_clock_type;
- if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
- if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
- params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
- if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
- params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
- if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
- params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
- if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
- params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
- }
- else
- /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
- /* We need to convert from KHz units into 10KHz units */
- params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
- if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
- /* Convert from 10KHz units back to KHz */
- bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
- result = BP_RESULT_OK;
- }
- return result;
- }
|