command_table.c 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445
  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. #include "dm_services.h"
  26. #include "atom.h"
  27. #include "include/bios_parser_interface.h"
  28. #include "command_table.h"
  29. #include "command_table_helper.h"
  30. #include "bios_parser_helper.h"
  31. #include "bios_parser_types_internal.h"
  32. #define EXEC_BIOS_CMD_TABLE(command, params)\
  33. (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
  34. GetIndexIntoMasterTable(COMMAND, command), \
  35. &params) == 0)
  36. #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
  37. cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
  38. GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
  39. #define BIOS_CMD_TABLE_PARA_REVISION(command)\
  40. bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
  41. GetIndexIntoMasterTable(COMMAND, command))
  42. static void init_dig_encoder_control(struct bios_parser *bp);
  43. static void init_transmitter_control(struct bios_parser *bp);
  44. static void init_set_pixel_clock(struct bios_parser *bp);
  45. static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
  46. static void init_adjust_display_pll(struct bios_parser *bp);
  47. static void init_dac_encoder_control(struct bios_parser *bp);
  48. static void init_dac_output_control(struct bios_parser *bp);
  49. static void init_set_crtc_timing(struct bios_parser *bp);
  50. static void init_select_crtc_source(struct bios_parser *bp);
  51. static void init_enable_crtc(struct bios_parser *bp);
  52. static void init_enable_crtc_mem_req(struct bios_parser *bp);
  53. static void init_external_encoder_control(struct bios_parser *bp);
  54. static void init_enable_disp_power_gating(struct bios_parser *bp);
  55. static void init_program_clock(struct bios_parser *bp);
  56. static void init_set_dce_clock(struct bios_parser *bp);
  57. void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
  58. {
  59. init_dig_encoder_control(bp);
  60. init_transmitter_control(bp);
  61. init_set_pixel_clock(bp);
  62. init_enable_spread_spectrum_on_ppll(bp);
  63. init_adjust_display_pll(bp);
  64. init_dac_encoder_control(bp);
  65. init_dac_output_control(bp);
  66. init_set_crtc_timing(bp);
  67. init_select_crtc_source(bp);
  68. init_enable_crtc(bp);
  69. init_enable_crtc_mem_req(bp);
  70. init_program_clock(bp);
  71. init_external_encoder_control(bp);
  72. init_enable_disp_power_gating(bp);
  73. init_set_dce_clock(bp);
  74. }
  75. static uint32_t bios_cmd_table_para_revision(void *cgs_device,
  76. uint32_t index)
  77. {
  78. uint8_t frev, crev;
  79. if (cgs_atom_get_cmd_table_revs(cgs_device,
  80. index,
  81. &frev, &crev) != 0)
  82. return 0;
  83. return crev;
  84. }
  85. /*******************************************************************************
  86. ********************************************************************************
  87. **
  88. ** D I G E N C O D E R C O N T R O L
  89. **
  90. ********************************************************************************
  91. *******************************************************************************/
  92. static enum bp_result encoder_control_digx_v3(
  93. struct bios_parser *bp,
  94. struct bp_encoder_control *cntl);
  95. static enum bp_result encoder_control_digx_v4(
  96. struct bios_parser *bp,
  97. struct bp_encoder_control *cntl);
  98. static enum bp_result encoder_control_digx_v5(
  99. struct bios_parser *bp,
  100. struct bp_encoder_control *cntl);
  101. static void init_encoder_control_dig_v1(struct bios_parser *bp);
  102. static void init_dig_encoder_control(struct bios_parser *bp)
  103. {
  104. uint32_t version =
  105. BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
  106. switch (version) {
  107. case 2:
  108. bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
  109. break;
  110. case 4:
  111. bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
  112. break;
  113. case 5:
  114. bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
  115. break;
  116. default:
  117. init_encoder_control_dig_v1(bp);
  118. break;
  119. }
  120. }
  121. static enum bp_result encoder_control_dig_v1(
  122. struct bios_parser *bp,
  123. struct bp_encoder_control *cntl);
  124. static enum bp_result encoder_control_dig1_v1(
  125. struct bios_parser *bp,
  126. struct bp_encoder_control *cntl);
  127. static enum bp_result encoder_control_dig2_v1(
  128. struct bios_parser *bp,
  129. struct bp_encoder_control *cntl);
  130. static void init_encoder_control_dig_v1(struct bios_parser *bp)
  131. {
  132. struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
  133. if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
  134. cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
  135. else
  136. cmd_tbl->encoder_control_dig1 = NULL;
  137. if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
  138. cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
  139. else
  140. cmd_tbl->encoder_control_dig2 = NULL;
  141. cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
  142. }
  143. static enum bp_result encoder_control_dig_v1(
  144. struct bios_parser *bp,
  145. struct bp_encoder_control *cntl)
  146. {
  147. enum bp_result result = BP_RESULT_FAILURE;
  148. struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
  149. if (cntl != NULL)
  150. switch (cntl->engine_id) {
  151. case ENGINE_ID_DIGA:
  152. if (cmd_tbl->encoder_control_dig1 != NULL)
  153. result =
  154. cmd_tbl->encoder_control_dig1(bp, cntl);
  155. break;
  156. case ENGINE_ID_DIGB:
  157. if (cmd_tbl->encoder_control_dig2 != NULL)
  158. result =
  159. cmd_tbl->encoder_control_dig2(bp, cntl);
  160. break;
  161. default:
  162. break;
  163. }
  164. return result;
  165. }
  166. static enum bp_result encoder_control_dig1_v1(
  167. struct bios_parser *bp,
  168. struct bp_encoder_control *cntl)
  169. {
  170. enum bp_result result = BP_RESULT_FAILURE;
  171. DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
  172. bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
  173. if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
  174. result = BP_RESULT_OK;
  175. return result;
  176. }
  177. static enum bp_result encoder_control_dig2_v1(
  178. struct bios_parser *bp,
  179. struct bp_encoder_control *cntl)
  180. {
  181. enum bp_result result = BP_RESULT_FAILURE;
  182. DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
  183. bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
  184. if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
  185. result = BP_RESULT_OK;
  186. return result;
  187. }
  188. static enum bp_result encoder_control_digx_v3(
  189. struct bios_parser *bp,
  190. struct bp_encoder_control *cntl)
  191. {
  192. enum bp_result result = BP_RESULT_FAILURE;
  193. DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
  194. if (LANE_COUNT_FOUR < cntl->lanes_number)
  195. params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
  196. else
  197. params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
  198. params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
  199. /* We need to convert from KHz units into 10KHz units */
  200. params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
  201. params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  202. params.ucEncoderMode =
  203. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  204. cntl->signal,
  205. cntl->enable_dp_audio);
  206. params.ucLaneNum = (uint8_t)(cntl->lanes_number);
  207. if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
  208. result = BP_RESULT_OK;
  209. return result;
  210. }
  211. static enum bp_result encoder_control_digx_v4(
  212. struct bios_parser *bp,
  213. struct bp_encoder_control *cntl)
  214. {
  215. enum bp_result result = BP_RESULT_FAILURE;
  216. DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
  217. if (LANE_COUNT_FOUR < cntl->lanes_number)
  218. params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
  219. else
  220. params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
  221. params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
  222. /* We need to convert from KHz units into 10KHz units */
  223. params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
  224. params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  225. params.ucEncoderMode =
  226. (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
  227. cntl->signal,
  228. cntl->enable_dp_audio));
  229. params.ucLaneNum = (uint8_t)(cntl->lanes_number);
  230. if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
  231. result = BP_RESULT_OK;
  232. return result;
  233. }
  234. static enum bp_result encoder_control_digx_v5(
  235. struct bios_parser *bp,
  236. struct bp_encoder_control *cntl)
  237. {
  238. enum bp_result result = BP_RESULT_FAILURE;
  239. ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
  240. params.ucDigId = (uint8_t)(cntl->engine_id);
  241. params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
  242. params.ulPixelClock = cntl->pixel_clock / 10;
  243. params.ucDigMode =
  244. (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
  245. cntl->signal,
  246. cntl->enable_dp_audio));
  247. params.ucLaneNum = (uint8_t)(cntl->lanes_number);
  248. switch (cntl->color_depth) {
  249. case COLOR_DEPTH_888:
  250. params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
  251. break;
  252. case COLOR_DEPTH_101010:
  253. params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
  254. break;
  255. case COLOR_DEPTH_121212:
  256. params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
  257. break;
  258. case COLOR_DEPTH_161616:
  259. params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
  260. break;
  261. default:
  262. break;
  263. }
  264. if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
  265. switch (cntl->color_depth) {
  266. case COLOR_DEPTH_101010:
  267. params.ulPixelClock =
  268. (params.ulPixelClock * 30) / 24;
  269. break;
  270. case COLOR_DEPTH_121212:
  271. params.ulPixelClock =
  272. (params.ulPixelClock * 36) / 24;
  273. break;
  274. case COLOR_DEPTH_161616:
  275. params.ulPixelClock =
  276. (params.ulPixelClock * 48) / 24;
  277. break;
  278. default:
  279. break;
  280. }
  281. if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
  282. result = BP_RESULT_OK;
  283. return result;
  284. }
  285. /*******************************************************************************
  286. ********************************************************************************
  287. **
  288. ** TRANSMITTER CONTROL
  289. **
  290. ********************************************************************************
  291. *******************************************************************************/
  292. static enum bp_result transmitter_control_v2(
  293. struct bios_parser *bp,
  294. struct bp_transmitter_control *cntl);
  295. static enum bp_result transmitter_control_v3(
  296. struct bios_parser *bp,
  297. struct bp_transmitter_control *cntl);
  298. static enum bp_result transmitter_control_v4(
  299. struct bios_parser *bp,
  300. struct bp_transmitter_control *cntl);
  301. static enum bp_result transmitter_control_v1_5(
  302. struct bios_parser *bp,
  303. struct bp_transmitter_control *cntl);
  304. static enum bp_result transmitter_control_v1_6(
  305. struct bios_parser *bp,
  306. struct bp_transmitter_control *cntl);
  307. static void init_transmitter_control(struct bios_parser *bp)
  308. {
  309. uint8_t frev;
  310. uint8_t crev;
  311. if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
  312. frev, crev) != 0)
  313. BREAK_TO_DEBUGGER();
  314. switch (crev) {
  315. case 2:
  316. bp->cmd_tbl.transmitter_control = transmitter_control_v2;
  317. break;
  318. case 3:
  319. bp->cmd_tbl.transmitter_control = transmitter_control_v3;
  320. break;
  321. case 4:
  322. bp->cmd_tbl.transmitter_control = transmitter_control_v4;
  323. break;
  324. case 5:
  325. bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
  326. break;
  327. case 6:
  328. bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
  329. break;
  330. default:
  331. dm_error("Don't have transmitter_control for v%d\n", crev);
  332. bp->cmd_tbl.transmitter_control = NULL;
  333. break;
  334. }
  335. }
  336. static enum bp_result transmitter_control_v2(
  337. struct bios_parser *bp,
  338. struct bp_transmitter_control *cntl)
  339. {
  340. enum bp_result result = BP_RESULT_FAILURE;
  341. DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
  342. enum connector_id connector_id =
  343. dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
  344. memset(&params, 0, sizeof(params));
  345. switch (cntl->transmitter) {
  346. case TRANSMITTER_UNIPHY_A:
  347. case TRANSMITTER_UNIPHY_B:
  348. case TRANSMITTER_UNIPHY_C:
  349. case TRANSMITTER_UNIPHY_D:
  350. case TRANSMITTER_UNIPHY_E:
  351. case TRANSMITTER_UNIPHY_F:
  352. case TRANSMITTER_TRAVIS_LCD:
  353. break;
  354. default:
  355. return BP_RESULT_BADINPUT;
  356. }
  357. switch (cntl->action) {
  358. case TRANSMITTER_CONTROL_INIT:
  359. if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
  360. (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
  361. /* on INIT this bit should be set according to the
  362. * phisycal connector
  363. * Bit0: dual link connector flag
  364. * =0 connector is single link connector
  365. * =1 connector is dual link connector
  366. */
  367. params.acConfig.fDualLinkConnector = 1;
  368. /* connector object id */
  369. params.usInitInfo =
  370. cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
  371. break;
  372. case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
  373. /* votage swing and pre-emphsis */
  374. params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
  375. params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
  376. break;
  377. default:
  378. /* if dual-link */
  379. if (LANE_COUNT_FOUR < cntl->lanes_number) {
  380. /* on ENABLE/DISABLE this bit should be set according to
  381. * actual timing (number of lanes)
  382. * Bit0: dual link connector flag
  383. * =0 connector is single link connector
  384. * =1 connector is dual link connector
  385. */
  386. params.acConfig.fDualLinkConnector = 1;
  387. /* link rate, half for dual link
  388. * We need to convert from KHz units into 20KHz units
  389. */
  390. params.usPixelClock =
  391. cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
  392. } else
  393. /* link rate, half for dual link
  394. * We need to convert from KHz units into 10KHz units
  395. */
  396. params.usPixelClock =
  397. cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  398. break;
  399. }
  400. /* 00 - coherent mode
  401. * 01 - incoherent mode
  402. */
  403. params.acConfig.fCoherentMode = cntl->coherent;
  404. if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
  405. || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
  406. || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
  407. /* Bit2: Transmitter Link selection
  408. * =0 when bit0=0, single link A/C/E, when bit0=1,
  409. * master link A/C/E
  410. * =1 when bit0=0, single link B/D/F, when bit0=1,
  411. * master link B/D/F
  412. */
  413. params.acConfig.ucLinkSel = 1;
  414. if (ENGINE_ID_DIGB == cntl->engine_id)
  415. /* Bit3: Transmitter data source selection
  416. * =0 DIGA is data source.
  417. * =1 DIGB is data source.
  418. * This bit is only useful when ucAction= ATOM_ENABLE
  419. */
  420. params.acConfig.ucEncoderSel = 1;
  421. if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
  422. /* Bit4: DP connector flag
  423. * =0 connector is none-DP connector
  424. * =1 connector is DP connector
  425. */
  426. params.acConfig.fDPConnector = 1;
  427. /* Bit[7:6]: Transmitter selection
  428. * =0 UNIPHY_ENCODER: UNIPHYA/B
  429. * =1 UNIPHY1_ENCODER: UNIPHYC/D
  430. * =2 UNIPHY2_ENCODER: UNIPHYE/F
  431. * =3 reserved
  432. */
  433. params.acConfig.ucTransmitterSel =
  434. (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
  435. cntl->transmitter);
  436. params.ucAction = (uint8_t)cntl->action;
  437. if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
  438. result = BP_RESULT_OK;
  439. return result;
  440. }
  441. static enum bp_result transmitter_control_v3(
  442. struct bios_parser *bp,
  443. struct bp_transmitter_control *cntl)
  444. {
  445. enum bp_result result = BP_RESULT_FAILURE;
  446. DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
  447. uint32_t pll_id;
  448. enum connector_id conn_id =
  449. dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
  450. const struct command_table_helper *cmd = bp->cmd_helper;
  451. bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
  452. || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
  453. memset(&params, 0, sizeof(params));
  454. switch (cntl->transmitter) {
  455. case TRANSMITTER_UNIPHY_A:
  456. case TRANSMITTER_UNIPHY_B:
  457. case TRANSMITTER_UNIPHY_C:
  458. case TRANSMITTER_UNIPHY_D:
  459. case TRANSMITTER_UNIPHY_E:
  460. case TRANSMITTER_UNIPHY_F:
  461. case TRANSMITTER_TRAVIS_LCD:
  462. break;
  463. default:
  464. return BP_RESULT_BADINPUT;
  465. }
  466. if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
  467. return BP_RESULT_BADINPUT;
  468. /* fill information based on the action */
  469. switch (cntl->action) {
  470. case TRANSMITTER_CONTROL_INIT:
  471. if (dual_link_conn) {
  472. /* on INIT this bit should be set according to the
  473. * phisycal connector
  474. * Bit0: dual link connector flag
  475. * =0 connector is single link connector
  476. * =1 connector is dual link connector
  477. */
  478. params.acConfig.fDualLinkConnector = 1;
  479. }
  480. /* connector object id */
  481. params.usInitInfo =
  482. cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
  483. break;
  484. case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
  485. /* votage swing and pre-emphsis */
  486. params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
  487. params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
  488. break;
  489. default:
  490. if (dual_link_conn && cntl->multi_path)
  491. /* on ENABLE/DISABLE this bit should be set according to
  492. * actual timing (number of lanes)
  493. * Bit0: dual link connector flag
  494. * =0 connector is single link connector
  495. * =1 connector is dual link connector
  496. */
  497. params.acConfig.fDualLinkConnector = 1;
  498. /* if dual-link */
  499. if (LANE_COUNT_FOUR < cntl->lanes_number) {
  500. /* on ENABLE/DISABLE this bit should be set according to
  501. * actual timing (number of lanes)
  502. * Bit0: dual link connector flag
  503. * =0 connector is single link connector
  504. * =1 connector is dual link connector
  505. */
  506. params.acConfig.fDualLinkConnector = 1;
  507. /* link rate, half for dual link
  508. * We need to convert from KHz units into 20KHz units
  509. */
  510. params.usPixelClock =
  511. cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
  512. } else {
  513. /* link rate, half for dual link
  514. * We need to convert from KHz units into 10KHz units
  515. */
  516. params.usPixelClock =
  517. cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  518. }
  519. break;
  520. }
  521. /* 00 - coherent mode
  522. * 01 - incoherent mode
  523. */
  524. params.acConfig.fCoherentMode = cntl->coherent;
  525. if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
  526. || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
  527. || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
  528. /* Bit2: Transmitter Link selection
  529. * =0 when bit0=0, single link A/C/E, when bit0=1,
  530. * master link A/C/E
  531. * =1 when bit0=0, single link B/D/F, when bit0=1,
  532. * master link B/D/F
  533. */
  534. params.acConfig.ucLinkSel = 1;
  535. if (ENGINE_ID_DIGB == cntl->engine_id)
  536. /* Bit3: Transmitter data source selection
  537. * =0 DIGA is data source.
  538. * =1 DIGB is data source.
  539. * This bit is only useful when ucAction= ATOM_ENABLE
  540. */
  541. params.acConfig.ucEncoderSel = 1;
  542. /* Bit[7:6]: Transmitter selection
  543. * =0 UNIPHY_ENCODER: UNIPHYA/B
  544. * =1 UNIPHY1_ENCODER: UNIPHYC/D
  545. * =2 UNIPHY2_ENCODER: UNIPHYE/F
  546. * =3 reserved
  547. */
  548. params.acConfig.ucTransmitterSel =
  549. (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
  550. params.ucLaneNum = (uint8_t)cntl->lanes_number;
  551. params.acConfig.ucRefClkSource = (uint8_t)pll_id;
  552. params.ucAction = (uint8_t)cntl->action;
  553. if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
  554. result = BP_RESULT_OK;
  555. return result;
  556. }
  557. static enum bp_result transmitter_control_v4(
  558. struct bios_parser *bp,
  559. struct bp_transmitter_control *cntl)
  560. {
  561. enum bp_result result = BP_RESULT_FAILURE;
  562. DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
  563. uint32_t ref_clk_src_id;
  564. enum connector_id conn_id =
  565. dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
  566. const struct command_table_helper *cmd = bp->cmd_helper;
  567. memset(&params, 0, sizeof(params));
  568. switch (cntl->transmitter) {
  569. case TRANSMITTER_UNIPHY_A:
  570. case TRANSMITTER_UNIPHY_B:
  571. case TRANSMITTER_UNIPHY_C:
  572. case TRANSMITTER_UNIPHY_D:
  573. case TRANSMITTER_UNIPHY_E:
  574. case TRANSMITTER_UNIPHY_F:
  575. case TRANSMITTER_TRAVIS_LCD:
  576. break;
  577. default:
  578. return BP_RESULT_BADINPUT;
  579. }
  580. if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
  581. return BP_RESULT_BADINPUT;
  582. switch (cntl->action) {
  583. case TRANSMITTER_CONTROL_INIT:
  584. {
  585. if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
  586. (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
  587. /* on INIT this bit should be set according to the
  588. * phisycal connector
  589. * Bit0: dual link connector flag
  590. * =0 connector is single link connector
  591. * =1 connector is dual link connector
  592. */
  593. params.acConfig.fDualLinkConnector = 1;
  594. /* connector object id */
  595. params.usInitInfo =
  596. cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
  597. }
  598. break;
  599. case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
  600. /* votage swing and pre-emphsis */
  601. params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
  602. params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
  603. break;
  604. default:
  605. if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
  606. (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
  607. /* on ENABLE/DISABLE this bit should be set according to
  608. * actual timing (number of lanes)
  609. * Bit0: dual link connector flag
  610. * =0 connector is single link connector
  611. * =1 connector is dual link connector
  612. */
  613. params.acConfig.fDualLinkConnector = 1;
  614. /* if dual-link */
  615. if (LANE_COUNT_FOUR < cntl->lanes_number)
  616. /* link rate, half for dual link
  617. * We need to convert from KHz units into 20KHz units
  618. */
  619. params.usPixelClock =
  620. cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
  621. else {
  622. /* link rate, half for dual link
  623. * We need to convert from KHz units into 10KHz units
  624. */
  625. params.usPixelClock =
  626. cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  627. }
  628. break;
  629. }
  630. /* 00 - coherent mode
  631. * 01 - incoherent mode
  632. */
  633. params.acConfig.fCoherentMode = cntl->coherent;
  634. if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
  635. || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
  636. || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
  637. /* Bit2: Transmitter Link selection
  638. * =0 when bit0=0, single link A/C/E, when bit0=1,
  639. * master link A/C/E
  640. * =1 when bit0=0, single link B/D/F, when bit0=1,
  641. * master link B/D/F
  642. */
  643. params.acConfig.ucLinkSel = 1;
  644. if (ENGINE_ID_DIGB == cntl->engine_id)
  645. /* Bit3: Transmitter data source selection
  646. * =0 DIGA is data source.
  647. * =1 DIGB is data source.
  648. * This bit is only useful when ucAction= ATOM_ENABLE
  649. */
  650. params.acConfig.ucEncoderSel = 1;
  651. /* Bit[7:6]: Transmitter selection
  652. * =0 UNIPHY_ENCODER: UNIPHYA/B
  653. * =1 UNIPHY1_ENCODER: UNIPHYC/D
  654. * =2 UNIPHY2_ENCODER: UNIPHYE/F
  655. * =3 reserved
  656. */
  657. params.acConfig.ucTransmitterSel =
  658. (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
  659. params.ucLaneNum = (uint8_t)(cntl->lanes_number);
  660. params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
  661. params.ucAction = (uint8_t)(cntl->action);
  662. if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
  663. result = BP_RESULT_OK;
  664. return result;
  665. }
  666. static enum bp_result transmitter_control_v1_5(
  667. struct bios_parser *bp,
  668. struct bp_transmitter_control *cntl)
  669. {
  670. enum bp_result result = BP_RESULT_FAILURE;
  671. const struct command_table_helper *cmd = bp->cmd_helper;
  672. DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
  673. memset(&params, 0, sizeof(params));
  674. params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
  675. params.ucAction = (uint8_t)cntl->action;
  676. params.ucLaneNum = (uint8_t)cntl->lanes_number;
  677. params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
  678. params.ucDigMode =
  679. cmd->signal_type_to_atom_dig_mode(cntl->signal);
  680. params.asConfig.ucPhyClkSrcId =
  681. cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
  682. /* 00 - coherent mode */
  683. params.asConfig.ucCoherentMode = cntl->coherent;
  684. params.asConfig.ucHPDSel =
  685. cmd->hpd_sel_to_atom(cntl->hpd_sel);
  686. params.ucDigEncoderSel =
  687. cmd->dig_encoder_sel_to_atom(cntl->engine_id);
  688. params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
  689. params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
  690. /*
  691. * In SI/TN case, caller have to set usPixelClock as following:
  692. * DP mode: usPixelClock = DP_LINK_CLOCK/10
  693. * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
  694. * DVI single link mode: usPixelClock = pixel clock
  695. * DVI dual link mode: usPixelClock = pixel clock
  696. * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
  697. * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
  698. * LVDS mode: usPixelClock = pixel clock
  699. */
  700. if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
  701. result = BP_RESULT_OK;
  702. return result;
  703. }
  704. static enum bp_result transmitter_control_v1_6(
  705. struct bios_parser *bp,
  706. struct bp_transmitter_control *cntl)
  707. {
  708. enum bp_result result = BP_RESULT_FAILURE;
  709. const struct command_table_helper *cmd = bp->cmd_helper;
  710. DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
  711. memset(&params, 0, sizeof(params));
  712. params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
  713. params.ucAction = (uint8_t)cntl->action;
  714. if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
  715. params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
  716. else
  717. params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
  718. params.ucLaneNum = (uint8_t)cntl->lanes_number;
  719. params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
  720. params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
  721. params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
  722. params.ulSymClock = cntl->pixel_clock/10;
  723. /*
  724. * In SI/TN case, caller have to set usPixelClock as following:
  725. * DP mode: usPixelClock = DP_LINK_CLOCK/10
  726. * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
  727. * DVI single link mode: usPixelClock = pixel clock
  728. * DVI dual link mode: usPixelClock = pixel clock
  729. * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
  730. * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
  731. * LVDS mode: usPixelClock = pixel clock
  732. */
  733. switch (cntl->signal) {
  734. case SIGNAL_TYPE_HDMI_TYPE_A:
  735. switch (cntl->color_depth) {
  736. case COLOR_DEPTH_101010:
  737. params.ulSymClock =
  738. cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
  739. break;
  740. case COLOR_DEPTH_121212:
  741. params.ulSymClock =
  742. cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
  743. break;
  744. case COLOR_DEPTH_161616:
  745. params.ulSymClock =
  746. cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
  747. break;
  748. default:
  749. break;
  750. }
  751. break;
  752. default:
  753. break;
  754. }
  755. if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
  756. result = BP_RESULT_OK;
  757. return result;
  758. }
  759. /*******************************************************************************
  760. ********************************************************************************
  761. **
  762. ** SET PIXEL CLOCK
  763. **
  764. ********************************************************************************
  765. *******************************************************************************/
  766. static enum bp_result set_pixel_clock_v3(
  767. struct bios_parser *bp,
  768. struct bp_pixel_clock_parameters *bp_params);
  769. static enum bp_result set_pixel_clock_v5(
  770. struct bios_parser *bp,
  771. struct bp_pixel_clock_parameters *bp_params);
  772. static enum bp_result set_pixel_clock_v6(
  773. struct bios_parser *bp,
  774. struct bp_pixel_clock_parameters *bp_params);
  775. static enum bp_result set_pixel_clock_v7(
  776. struct bios_parser *bp,
  777. struct bp_pixel_clock_parameters *bp_params);
  778. static void init_set_pixel_clock(struct bios_parser *bp)
  779. {
  780. switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
  781. case 3:
  782. bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
  783. break;
  784. case 5:
  785. bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
  786. break;
  787. case 6:
  788. bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
  789. break;
  790. case 7:
  791. bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
  792. break;
  793. default:
  794. dm_error("Don't have set_pixel_clock for v%d\n",
  795. BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
  796. bp->cmd_tbl.set_pixel_clock = NULL;
  797. break;
  798. }
  799. }
  800. static enum bp_result set_pixel_clock_v3(
  801. struct bios_parser *bp,
  802. struct bp_pixel_clock_parameters *bp_params)
  803. {
  804. enum bp_result result = BP_RESULT_FAILURE;
  805. PIXEL_CLOCK_PARAMETERS_V3 *params;
  806. SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
  807. memset(&allocation, 0, sizeof(allocation));
  808. if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
  809. allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
  810. else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
  811. allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
  812. else
  813. return BP_RESULT_BADINPUT;
  814. allocation.sPCLKInput.usRefDiv =
  815. cpu_to_le16((uint16_t)bp_params->reference_divider);
  816. allocation.sPCLKInput.usFbDiv =
  817. cpu_to_le16((uint16_t)bp_params->feedback_divider);
  818. allocation.sPCLKInput.ucFracFbDiv =
  819. (uint8_t)bp_params->fractional_feedback_divider;
  820. allocation.sPCLKInput.ucPostDiv =
  821. (uint8_t)bp_params->pixel_clock_post_divider;
  822. /* We need to convert from KHz units into 10KHz units */
  823. allocation.sPCLKInput.usPixelClock =
  824. cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
  825. params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
  826. params->ucTransmitterId =
  827. bp->cmd_helper->encoder_id_to_atom(
  828. dal_graphics_object_id_get_encoder_id(
  829. bp_params->encoder_object_id));
  830. params->ucEncoderMode =
  831. (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
  832. bp_params->signal_type, false));
  833. if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
  834. params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
  835. if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
  836. params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
  837. if (CONTROLLER_ID_D1 != bp_params->controller_id)
  838. params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
  839. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
  840. result = BP_RESULT_OK;
  841. return result;
  842. }
  843. #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
  844. /* video bios did not define this: */
  845. typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
  846. PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
  847. /* Caller doesn't need to init this portion */
  848. ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
  849. } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
  850. #endif
  851. #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
  852. /* video bios did not define this: */
  853. typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
  854. PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
  855. /* Caller doesn't need to init this portion */
  856. ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
  857. } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
  858. #endif
  859. static enum bp_result set_pixel_clock_v5(
  860. struct bios_parser *bp,
  861. struct bp_pixel_clock_parameters *bp_params)
  862. {
  863. enum bp_result result = BP_RESULT_FAILURE;
  864. SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
  865. uint8_t controller_id;
  866. uint32_t pll_id;
  867. memset(&clk, 0, sizeof(clk));
  868. if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
  869. && bp->cmd_helper->controller_id_to_atom(
  870. bp_params->controller_id, &controller_id)) {
  871. clk.sPCLKInput.ucCRTC = controller_id;
  872. clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
  873. clk.sPCLKInput.ucRefDiv =
  874. (uint8_t)(bp_params->reference_divider);
  875. clk.sPCLKInput.usFbDiv =
  876. cpu_to_le16((uint16_t)(bp_params->feedback_divider));
  877. clk.sPCLKInput.ulFbDivDecFrac =
  878. cpu_to_le32(bp_params->fractional_feedback_divider);
  879. clk.sPCLKInput.ucPostDiv =
  880. (uint8_t)(bp_params->pixel_clock_post_divider);
  881. clk.sPCLKInput.ucTransmitterID =
  882. bp->cmd_helper->encoder_id_to_atom(
  883. dal_graphics_object_id_get_encoder_id(
  884. bp_params->encoder_object_id));
  885. clk.sPCLKInput.ucEncoderMode =
  886. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  887. bp_params->signal_type, false);
  888. /* We need to convert from KHz units into 10KHz units */
  889. clk.sPCLKInput.usPixelClock =
  890. cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
  891. if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
  892. clk.sPCLKInput.ucMiscInfo |=
  893. PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
  894. if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
  895. clk.sPCLKInput.ucMiscInfo |=
  896. PIXEL_CLOCK_MISC_REF_DIV_SRC;
  897. /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
  898. * =1:30bpp, =2:32bpp
  899. * driver choose program it itself, i.e. here we program it
  900. * to 888 by default.
  901. */
  902. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
  903. result = BP_RESULT_OK;
  904. }
  905. return result;
  906. }
  907. static enum bp_result set_pixel_clock_v6(
  908. struct bios_parser *bp,
  909. struct bp_pixel_clock_parameters *bp_params)
  910. {
  911. enum bp_result result = BP_RESULT_FAILURE;
  912. SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
  913. uint8_t controller_id;
  914. uint32_t pll_id;
  915. memset(&clk, 0, sizeof(clk));
  916. if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
  917. && bp->cmd_helper->controller_id_to_atom(
  918. bp_params->controller_id, &controller_id)) {
  919. /* Note: VBIOS still wants to use ucCRTC name which is now
  920. * 1 byte in ULONG
  921. *typedef struct _CRTC_PIXEL_CLOCK_FREQ
  922. *{
  923. * target the pixel clock to drive the CRTC timing.
  924. * ULONG ulPixelClock:24;
  925. * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
  926. * previous version.
  927. * ATOM_CRTC1~6, indicate the CRTC controller to
  928. * ULONG ucCRTC:8;
  929. * drive the pixel clock. not used for DCPLL case.
  930. *}CRTC_PIXEL_CLOCK_FREQ;
  931. *union
  932. *{
  933. * pixel clock and CRTC id frequency
  934. * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
  935. * ULONG ulDispEngClkFreq; dispclk frequency
  936. *};
  937. */
  938. clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
  939. clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
  940. clk.sPCLKInput.ucRefDiv =
  941. (uint8_t) bp_params->reference_divider;
  942. clk.sPCLKInput.usFbDiv =
  943. cpu_to_le16((uint16_t) bp_params->feedback_divider);
  944. clk.sPCLKInput.ulFbDivDecFrac =
  945. cpu_to_le32(bp_params->fractional_feedback_divider);
  946. clk.sPCLKInput.ucPostDiv =
  947. (uint8_t) bp_params->pixel_clock_post_divider;
  948. clk.sPCLKInput.ucTransmitterID =
  949. bp->cmd_helper->encoder_id_to_atom(
  950. dal_graphics_object_id_get_encoder_id(
  951. bp_params->encoder_object_id));
  952. clk.sPCLKInput.ucEncoderMode =
  953. (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
  954. bp_params->signal_type, false);
  955. /* We need to convert from KHz units into 10KHz units */
  956. clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
  957. cpu_to_le32(bp_params->target_pixel_clock / 10);
  958. if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
  959. clk.sPCLKInput.ucMiscInfo |=
  960. PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
  961. }
  962. if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
  963. clk.sPCLKInput.ucMiscInfo |=
  964. PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
  965. }
  966. /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
  967. * 24bpp =1:30bpp, =2:32bpp
  968. * driver choose program it itself, i.e. here we pass required
  969. * target rate that includes deep color.
  970. */
  971. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
  972. result = BP_RESULT_OK;
  973. }
  974. return result;
  975. }
  976. static enum bp_result set_pixel_clock_v7(
  977. struct bios_parser *bp,
  978. struct bp_pixel_clock_parameters *bp_params)
  979. {
  980. enum bp_result result = BP_RESULT_FAILURE;
  981. PIXEL_CLOCK_PARAMETERS_V7 clk;
  982. uint8_t controller_id;
  983. uint32_t pll_id;
  984. memset(&clk, 0, sizeof(clk));
  985. if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
  986. && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
  987. /* Note: VBIOS still wants to use ucCRTC name which is now
  988. * 1 byte in ULONG
  989. *typedef struct _CRTC_PIXEL_CLOCK_FREQ
  990. *{
  991. * target the pixel clock to drive the CRTC timing.
  992. * ULONG ulPixelClock:24;
  993. * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
  994. * previous version.
  995. * ATOM_CRTC1~6, indicate the CRTC controller to
  996. * ULONG ucCRTC:8;
  997. * drive the pixel clock. not used for DCPLL case.
  998. *}CRTC_PIXEL_CLOCK_FREQ;
  999. *union
  1000. *{
  1001. * pixel clock and CRTC id frequency
  1002. * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
  1003. * ULONG ulDispEngClkFreq; dispclk frequency
  1004. *};
  1005. */
  1006. clk.ucCRTC = controller_id;
  1007. clk.ucPpll = (uint8_t) pll_id;
  1008. clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
  1009. clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
  1010. /* We need to convert from KHz units into 10KHz units */
  1011. clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock * 10);
  1012. clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
  1013. if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
  1014. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
  1015. if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
  1016. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
  1017. if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
  1018. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
  1019. if (bp_params->flags.SUPPORT_YUV_420)
  1020. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
  1021. if (bp_params->flags.SET_XTALIN_REF_SRC)
  1022. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
  1023. if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
  1024. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
  1025. if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
  1026. clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
  1027. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
  1028. result = BP_RESULT_OK;
  1029. }
  1030. return result;
  1031. }
  1032. /*******************************************************************************
  1033. ********************************************************************************
  1034. **
  1035. ** ENABLE PIXEL CLOCK SS
  1036. **
  1037. ********************************************************************************
  1038. *******************************************************************************/
  1039. static enum bp_result enable_spread_spectrum_on_ppll_v1(
  1040. struct bios_parser *bp,
  1041. struct bp_spread_spectrum_parameters *bp_params,
  1042. bool enable);
  1043. static enum bp_result enable_spread_spectrum_on_ppll_v2(
  1044. struct bios_parser *bp,
  1045. struct bp_spread_spectrum_parameters *bp_params,
  1046. bool enable);
  1047. static enum bp_result enable_spread_spectrum_on_ppll_v3(
  1048. struct bios_parser *bp,
  1049. struct bp_spread_spectrum_parameters *bp_params,
  1050. bool enable);
  1051. static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
  1052. {
  1053. switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
  1054. case 1:
  1055. bp->cmd_tbl.enable_spread_spectrum_on_ppll =
  1056. enable_spread_spectrum_on_ppll_v1;
  1057. break;
  1058. case 2:
  1059. bp->cmd_tbl.enable_spread_spectrum_on_ppll =
  1060. enable_spread_spectrum_on_ppll_v2;
  1061. break;
  1062. case 3:
  1063. bp->cmd_tbl.enable_spread_spectrum_on_ppll =
  1064. enable_spread_spectrum_on_ppll_v3;
  1065. break;
  1066. default:
  1067. dm_error("Don't have enable_spread_spectrum_on_ppll for v%d\n",
  1068. BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
  1069. bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
  1070. break;
  1071. }
  1072. }
  1073. static enum bp_result enable_spread_spectrum_on_ppll_v1(
  1074. struct bios_parser *bp,
  1075. struct bp_spread_spectrum_parameters *bp_params,
  1076. bool enable)
  1077. {
  1078. enum bp_result result = BP_RESULT_FAILURE;
  1079. ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
  1080. memset(&params, 0, sizeof(params));
  1081. if ((enable == true) && (bp_params->percentage > 0))
  1082. params.ucEnable = ATOM_ENABLE;
  1083. else
  1084. params.ucEnable = ATOM_DISABLE;
  1085. params.usSpreadSpectrumPercentage =
  1086. cpu_to_le16((uint16_t)bp_params->percentage);
  1087. params.ucSpreadSpectrumStep =
  1088. (uint8_t)bp_params->ver1.step;
  1089. params.ucSpreadSpectrumDelay =
  1090. (uint8_t)bp_params->ver1.delay;
  1091. /* convert back to unit of 10KHz */
  1092. params.ucSpreadSpectrumRange =
  1093. (uint8_t)(bp_params->ver1.range / 10000);
  1094. if (bp_params->flags.EXTERNAL_SS)
  1095. params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
  1096. if (bp_params->flags.CENTER_SPREAD)
  1097. params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
  1098. if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
  1099. params.ucPpll = ATOM_PPLL1;
  1100. else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
  1101. params.ucPpll = ATOM_PPLL2;
  1102. else
  1103. BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
  1104. if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
  1105. result = BP_RESULT_OK;
  1106. return result;
  1107. }
  1108. static enum bp_result enable_spread_spectrum_on_ppll_v2(
  1109. struct bios_parser *bp,
  1110. struct bp_spread_spectrum_parameters *bp_params,
  1111. bool enable)
  1112. {
  1113. enum bp_result result = BP_RESULT_FAILURE;
  1114. ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
  1115. memset(&params, 0, sizeof(params));
  1116. if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
  1117. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
  1118. else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
  1119. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
  1120. else
  1121. BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
  1122. if ((enable == true) && (bp_params->percentage > 0)) {
  1123. params.ucEnable = ATOM_ENABLE;
  1124. params.usSpreadSpectrumPercentage =
  1125. cpu_to_le16((uint16_t)(bp_params->percentage));
  1126. params.usSpreadSpectrumStep =
  1127. cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
  1128. if (bp_params->flags.EXTERNAL_SS)
  1129. params.ucSpreadSpectrumType |=
  1130. ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
  1131. if (bp_params->flags.CENTER_SPREAD)
  1132. params.ucSpreadSpectrumType |=
  1133. ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
  1134. /* Both amounts need to be left shifted first before bit
  1135. * comparison. Otherwise, the result will always be zero here
  1136. */
  1137. params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
  1138. ((bp_params->ds.feedback_amount <<
  1139. ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
  1140. ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
  1141. ((bp_params->ds.nfrac_amount <<
  1142. ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
  1143. ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
  1144. } else
  1145. params.ucEnable = ATOM_DISABLE;
  1146. if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
  1147. result = BP_RESULT_OK;
  1148. return result;
  1149. }
  1150. static enum bp_result enable_spread_spectrum_on_ppll_v3(
  1151. struct bios_parser *bp,
  1152. struct bp_spread_spectrum_parameters *bp_params,
  1153. bool enable)
  1154. {
  1155. enum bp_result result = BP_RESULT_FAILURE;
  1156. ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
  1157. memset(&params, 0, sizeof(params));
  1158. switch (bp_params->pll_id) {
  1159. case CLOCK_SOURCE_ID_PLL0:
  1160. /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
  1161. * not for SI display clock.
  1162. */
  1163. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
  1164. break;
  1165. case CLOCK_SOURCE_ID_PLL1:
  1166. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
  1167. break;
  1168. case CLOCK_SOURCE_ID_PLL2:
  1169. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
  1170. break;
  1171. case CLOCK_SOURCE_ID_DCPLL:
  1172. params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
  1173. break;
  1174. default:
  1175. BREAK_TO_DEBUGGER();
  1176. /* Unexpected PLL value!! */
  1177. return result;
  1178. }
  1179. if (enable == true) {
  1180. params.ucEnable = ATOM_ENABLE;
  1181. params.usSpreadSpectrumAmountFrac =
  1182. cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
  1183. params.usSpreadSpectrumStep =
  1184. cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
  1185. if (bp_params->flags.EXTERNAL_SS)
  1186. params.ucSpreadSpectrumType |=
  1187. ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
  1188. if (bp_params->flags.CENTER_SPREAD)
  1189. params.ucSpreadSpectrumType |=
  1190. ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
  1191. /* Both amounts need to be left shifted first before bit
  1192. * comparison. Otherwise, the result will always be zero here
  1193. */
  1194. params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
  1195. ((bp_params->ds.feedback_amount <<
  1196. ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
  1197. ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
  1198. ((bp_params->ds.nfrac_amount <<
  1199. ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
  1200. ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
  1201. } else
  1202. params.ucEnable = ATOM_DISABLE;
  1203. if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
  1204. result = BP_RESULT_OK;
  1205. return result;
  1206. }
  1207. /*******************************************************************************
  1208. ********************************************************************************
  1209. **
  1210. ** ADJUST DISPLAY PLL
  1211. **
  1212. ********************************************************************************
  1213. *******************************************************************************/
  1214. static enum bp_result adjust_display_pll_v2(
  1215. struct bios_parser *bp,
  1216. struct bp_adjust_pixel_clock_parameters *bp_params);
  1217. static enum bp_result adjust_display_pll_v3(
  1218. struct bios_parser *bp,
  1219. struct bp_adjust_pixel_clock_parameters *bp_params);
  1220. static void init_adjust_display_pll(struct bios_parser *bp)
  1221. {
  1222. switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
  1223. case 2:
  1224. bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
  1225. break;
  1226. case 3:
  1227. bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
  1228. break;
  1229. default:
  1230. dm_error("Don't have adjust_display_pll for v%d\n",
  1231. BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
  1232. bp->cmd_tbl.adjust_display_pll = NULL;
  1233. break;
  1234. }
  1235. }
  1236. static enum bp_result adjust_display_pll_v2(
  1237. struct bios_parser *bp,
  1238. struct bp_adjust_pixel_clock_parameters *bp_params)
  1239. {
  1240. enum bp_result result = BP_RESULT_FAILURE;
  1241. ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
  1242. /* We need to convert from KHz units into 10KHz units and then convert
  1243. * output pixel clock back 10KHz-->KHz */
  1244. uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
  1245. params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
  1246. params.ucTransmitterID =
  1247. bp->cmd_helper->encoder_id_to_atom(
  1248. dal_graphics_object_id_get_encoder_id(
  1249. bp_params->encoder_object_id));
  1250. params.ucEncodeMode =
  1251. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  1252. bp_params->signal_type, false);
  1253. return result;
  1254. }
  1255. static enum bp_result adjust_display_pll_v3(
  1256. struct bios_parser *bp,
  1257. struct bp_adjust_pixel_clock_parameters *bp_params)
  1258. {
  1259. enum bp_result result = BP_RESULT_FAILURE;
  1260. ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
  1261. uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
  1262. memset(&params, 0, sizeof(params));
  1263. /* We need to convert from KHz units into 10KHz units and then convert
  1264. * output pixel clock back 10KHz-->KHz */
  1265. params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
  1266. params.sInput.ucTransmitterID =
  1267. bp->cmd_helper->encoder_id_to_atom(
  1268. dal_graphics_object_id_get_encoder_id(
  1269. bp_params->encoder_object_id));
  1270. params.sInput.ucEncodeMode =
  1271. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  1272. bp_params->signal_type, false);
  1273. if (bp_params->ss_enable == true)
  1274. params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
  1275. if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
  1276. params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
  1277. if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
  1278. /* Convert output pixel clock back 10KHz-->KHz: multiply
  1279. * original pixel clock in KHz by ratio
  1280. * [output pxlClk/input pxlClk] */
  1281. uint64_t pixel_clk_10_khz_out =
  1282. (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
  1283. uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
  1284. if (pixel_clk_10_kHz_in != 0) {
  1285. bp_params->adjusted_pixel_clock =
  1286. div_u64(pixel_clk * pixel_clk_10_khz_out,
  1287. pixel_clk_10_kHz_in);
  1288. } else {
  1289. bp_params->adjusted_pixel_clock = 0;
  1290. BREAK_TO_DEBUGGER();
  1291. }
  1292. bp_params->reference_divider = params.sOutput.ucRefDiv;
  1293. bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
  1294. result = BP_RESULT_OK;
  1295. }
  1296. return result;
  1297. }
  1298. /*******************************************************************************
  1299. ********************************************************************************
  1300. **
  1301. ** DAC ENCODER CONTROL
  1302. **
  1303. ********************************************************************************
  1304. *******************************************************************************/
  1305. static enum bp_result dac1_encoder_control_v1(
  1306. struct bios_parser *bp,
  1307. bool enable,
  1308. uint32_t pixel_clock,
  1309. uint8_t dac_standard);
  1310. static enum bp_result dac2_encoder_control_v1(
  1311. struct bios_parser *bp,
  1312. bool enable,
  1313. uint32_t pixel_clock,
  1314. uint8_t dac_standard);
  1315. static void init_dac_encoder_control(struct bios_parser *bp)
  1316. {
  1317. switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
  1318. case 1:
  1319. bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
  1320. break;
  1321. default:
  1322. bp->cmd_tbl.dac1_encoder_control = NULL;
  1323. break;
  1324. }
  1325. switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
  1326. case 1:
  1327. bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
  1328. break;
  1329. default:
  1330. bp->cmd_tbl.dac2_encoder_control = NULL;
  1331. break;
  1332. }
  1333. }
  1334. static void dac_encoder_control_prepare_params(
  1335. DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
  1336. bool enable,
  1337. uint32_t pixel_clock,
  1338. uint8_t dac_standard)
  1339. {
  1340. params->ucDacStandard = dac_standard;
  1341. if (enable)
  1342. params->ucAction = ATOM_ENABLE;
  1343. else
  1344. params->ucAction = ATOM_DISABLE;
  1345. /* We need to convert from KHz units into 10KHz units
  1346. * it looks as if the TvControl do not care about pixel clock
  1347. */
  1348. params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
  1349. }
  1350. static enum bp_result dac1_encoder_control_v1(
  1351. struct bios_parser *bp,
  1352. bool enable,
  1353. uint32_t pixel_clock,
  1354. uint8_t dac_standard)
  1355. {
  1356. enum bp_result result = BP_RESULT_FAILURE;
  1357. DAC_ENCODER_CONTROL_PS_ALLOCATION params;
  1358. dac_encoder_control_prepare_params(
  1359. &params,
  1360. enable,
  1361. pixel_clock,
  1362. dac_standard);
  1363. if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
  1364. result = BP_RESULT_OK;
  1365. return result;
  1366. }
  1367. static enum bp_result dac2_encoder_control_v1(
  1368. struct bios_parser *bp,
  1369. bool enable,
  1370. uint32_t pixel_clock,
  1371. uint8_t dac_standard)
  1372. {
  1373. enum bp_result result = BP_RESULT_FAILURE;
  1374. DAC_ENCODER_CONTROL_PS_ALLOCATION params;
  1375. dac_encoder_control_prepare_params(
  1376. &params,
  1377. enable,
  1378. pixel_clock,
  1379. dac_standard);
  1380. if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
  1381. result = BP_RESULT_OK;
  1382. return result;
  1383. }
  1384. /*******************************************************************************
  1385. ********************************************************************************
  1386. **
  1387. ** DAC OUTPUT CONTROL
  1388. **
  1389. ********************************************************************************
  1390. *******************************************************************************/
  1391. static enum bp_result dac1_output_control_v1(
  1392. struct bios_parser *bp,
  1393. bool enable);
  1394. static enum bp_result dac2_output_control_v1(
  1395. struct bios_parser *bp,
  1396. bool enable);
  1397. static void init_dac_output_control(struct bios_parser *bp)
  1398. {
  1399. switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
  1400. case 1:
  1401. bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
  1402. break;
  1403. default:
  1404. bp->cmd_tbl.dac1_output_control = NULL;
  1405. break;
  1406. }
  1407. switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
  1408. case 1:
  1409. bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
  1410. break;
  1411. default:
  1412. bp->cmd_tbl.dac2_output_control = NULL;
  1413. break;
  1414. }
  1415. }
  1416. static enum bp_result dac1_output_control_v1(
  1417. struct bios_parser *bp, bool enable)
  1418. {
  1419. enum bp_result result = BP_RESULT_FAILURE;
  1420. DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
  1421. if (enable)
  1422. params.ucAction = ATOM_ENABLE;
  1423. else
  1424. params.ucAction = ATOM_DISABLE;
  1425. if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
  1426. result = BP_RESULT_OK;
  1427. return result;
  1428. }
  1429. static enum bp_result dac2_output_control_v1(
  1430. struct bios_parser *bp, bool enable)
  1431. {
  1432. enum bp_result result = BP_RESULT_FAILURE;
  1433. DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
  1434. if (enable)
  1435. params.ucAction = ATOM_ENABLE;
  1436. else
  1437. params.ucAction = ATOM_DISABLE;
  1438. if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
  1439. result = BP_RESULT_OK;
  1440. return result;
  1441. }
  1442. /*******************************************************************************
  1443. ********************************************************************************
  1444. **
  1445. ** SET CRTC TIMING
  1446. **
  1447. ********************************************************************************
  1448. *******************************************************************************/
  1449. static enum bp_result set_crtc_using_dtd_timing_v3(
  1450. struct bios_parser *bp,
  1451. struct bp_hw_crtc_timing_parameters *bp_params);
  1452. static enum bp_result set_crtc_timing_v1(
  1453. struct bios_parser *bp,
  1454. struct bp_hw_crtc_timing_parameters *bp_params);
  1455. static void init_set_crtc_timing(struct bios_parser *bp)
  1456. {
  1457. uint32_t dtd_version =
  1458. BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
  1459. if (dtd_version > 2)
  1460. switch (dtd_version) {
  1461. case 3:
  1462. bp->cmd_tbl.set_crtc_timing =
  1463. set_crtc_using_dtd_timing_v3;
  1464. break;
  1465. default:
  1466. dm_error("Don't have set_crtc_timing for dtd v%d\n",
  1467. dtd_version);
  1468. bp->cmd_tbl.set_crtc_timing = NULL;
  1469. break;
  1470. }
  1471. else
  1472. switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
  1473. case 1:
  1474. bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
  1475. break;
  1476. default:
  1477. dm_error("Don't have set_crtc_timing for v%d\n",
  1478. BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
  1479. bp->cmd_tbl.set_crtc_timing = NULL;
  1480. break;
  1481. }
  1482. }
  1483. static enum bp_result set_crtc_timing_v1(
  1484. struct bios_parser *bp,
  1485. struct bp_hw_crtc_timing_parameters *bp_params)
  1486. {
  1487. enum bp_result result = BP_RESULT_FAILURE;
  1488. SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
  1489. uint8_t atom_controller_id;
  1490. if (bp->cmd_helper->controller_id_to_atom(
  1491. bp_params->controller_id, &atom_controller_id))
  1492. params.ucCRTC = atom_controller_id;
  1493. params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
  1494. params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
  1495. params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
  1496. params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
  1497. params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
  1498. params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
  1499. params.usV_SyncStart =
  1500. cpu_to_le16((uint16_t)(bp_params->v_sync_start));
  1501. params.usV_SyncWidth =
  1502. cpu_to_le16((uint16_t)(bp_params->v_sync_width));
  1503. /* VBIOS does not expect any value except zero into this call, for
  1504. * underscan use another entry ProgramOverscan call but when mode
  1505. * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
  1506. * but when same ,but 60 Hz there is corruption
  1507. * DAL1 does not allow the mode 1776x1000@60
  1508. */
  1509. params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
  1510. params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
  1511. params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
  1512. params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
  1513. if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
  1514. params.susModeMiscInfo.usAccess =
  1515. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
  1516. if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
  1517. params.susModeMiscInfo.usAccess =
  1518. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
  1519. if (bp_params->flags.INTERLACE) {
  1520. params.susModeMiscInfo.usAccess =
  1521. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
  1522. /* original DAL code has this condition to apply tis for
  1523. * non-TV/CV only due to complex MV testing for possible
  1524. * impact
  1525. * if (pACParameters->signal != SignalType_YPbPr &&
  1526. * pACParameters->signal != SignalType_Composite &&
  1527. * pACParameters->signal != SignalType_SVideo)
  1528. */
  1529. /* HW will deduct 0.5 line from 2nd feild.
  1530. * i.e. for 1080i, it is 2 lines for 1st field, 2.5
  1531. * lines for the 2nd feild. we need input as 5 instead
  1532. * of 4, but it is 4 either from Edid data
  1533. * (spec CEA 861) or CEA timing table.
  1534. */
  1535. params.usV_SyncStart =
  1536. cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
  1537. }
  1538. if (bp_params->flags.HORZ_COUNT_BY_TWO)
  1539. params.susModeMiscInfo.usAccess =
  1540. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
  1541. if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
  1542. result = BP_RESULT_OK;
  1543. return result;
  1544. }
  1545. static enum bp_result set_crtc_using_dtd_timing_v3(
  1546. struct bios_parser *bp,
  1547. struct bp_hw_crtc_timing_parameters *bp_params)
  1548. {
  1549. enum bp_result result = BP_RESULT_FAILURE;
  1550. SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
  1551. uint8_t atom_controller_id;
  1552. if (bp->cmd_helper->controller_id_to_atom(
  1553. bp_params->controller_id, &atom_controller_id))
  1554. params.ucCRTC = atom_controller_id;
  1555. /* bios usH_Size wants h addressable size */
  1556. params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
  1557. /* bios usH_Blanking_Time wants borders included in blanking */
  1558. params.usH_Blanking_Time =
  1559. cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
  1560. /* bios usV_Size wants v addressable size */
  1561. params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
  1562. /* bios usV_Blanking_Time wants borders included in blanking */
  1563. params.usV_Blanking_Time =
  1564. cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
  1565. /* bios usHSyncOffset is the offset from the end of h addressable,
  1566. * our horizontalSyncStart is the offset from the beginning
  1567. * of h addressable */
  1568. params.usH_SyncOffset =
  1569. cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
  1570. params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
  1571. /* bios usHSyncOffset is the offset from the end of v addressable,
  1572. * our verticalSyncStart is the offset from the beginning of
  1573. * v addressable */
  1574. params.usV_SyncOffset =
  1575. cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
  1576. params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
  1577. /* we assume that overscan from original timing does not get bigger
  1578. * than 255
  1579. * we will program all the borders in the Set CRTC Overscan call below
  1580. */
  1581. if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
  1582. params.susModeMiscInfo.usAccess =
  1583. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
  1584. if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
  1585. params.susModeMiscInfo.usAccess =
  1586. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
  1587. if (bp_params->flags.INTERLACE) {
  1588. params.susModeMiscInfo.usAccess =
  1589. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
  1590. /* original DAL code has this condition to apply this
  1591. * for non-TV/CV only
  1592. * due to complex MV testing for possible impact
  1593. * if ( pACParameters->signal != SignalType_YPbPr &&
  1594. * pACParameters->signal != SignalType_Composite &&
  1595. * pACParameters->signal != SignalType_SVideo)
  1596. */
  1597. {
  1598. /* HW will deduct 0.5 line from 2nd feild.
  1599. * i.e. for 1080i, it is 2 lines for 1st field,
  1600. * 2.5 lines for the 2nd feild. we need input as 5
  1601. * instead of 4.
  1602. * but it is 4 either from Edid data (spec CEA 861)
  1603. * or CEA timing table.
  1604. */
  1605. params.usV_SyncOffset =
  1606. cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
  1607. }
  1608. }
  1609. if (bp_params->flags.HORZ_COUNT_BY_TWO)
  1610. params.susModeMiscInfo.usAccess =
  1611. cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
  1612. if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
  1613. result = BP_RESULT_OK;
  1614. return result;
  1615. }
  1616. /*******************************************************************************
  1617. ********************************************************************************
  1618. **
  1619. ** SELECT CRTC SOURCE
  1620. **
  1621. ********************************************************************************
  1622. *******************************************************************************/
  1623. static enum bp_result select_crtc_source_v2(
  1624. struct bios_parser *bp,
  1625. struct bp_crtc_source_select *bp_params);
  1626. static enum bp_result select_crtc_source_v3(
  1627. struct bios_parser *bp,
  1628. struct bp_crtc_source_select *bp_params);
  1629. static void init_select_crtc_source(struct bios_parser *bp)
  1630. {
  1631. switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
  1632. case 2:
  1633. bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
  1634. break;
  1635. case 3:
  1636. bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
  1637. break;
  1638. default:
  1639. dm_error("Don't select_crtc_source enable_crtc for v%d\n",
  1640. BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source));
  1641. bp->cmd_tbl.select_crtc_source = NULL;
  1642. break;
  1643. }
  1644. }
  1645. static enum bp_result select_crtc_source_v2(
  1646. struct bios_parser *bp,
  1647. struct bp_crtc_source_select *bp_params)
  1648. {
  1649. enum bp_result result = BP_RESULT_FAILURE;
  1650. SELECT_CRTC_SOURCE_PARAMETERS_V2 params;
  1651. uint8_t atom_controller_id;
  1652. uint32_t atom_engine_id;
  1653. enum signal_type s = bp_params->signal;
  1654. memset(&params, 0, sizeof(params));
  1655. /* set controller id */
  1656. if (bp->cmd_helper->controller_id_to_atom(
  1657. bp_params->controller_id, &atom_controller_id))
  1658. params.ucCRTC = atom_controller_id;
  1659. else
  1660. return BP_RESULT_FAILURE;
  1661. /* set encoder id */
  1662. if (bp->cmd_helper->engine_bp_to_atom(
  1663. bp_params->engine_id, &atom_engine_id))
  1664. params.ucEncoderID = (uint8_t)atom_engine_id;
  1665. else
  1666. return BP_RESULT_FAILURE;
  1667. if (SIGNAL_TYPE_EDP == s ||
  1668. (SIGNAL_TYPE_DISPLAY_PORT == s &&
  1669. SIGNAL_TYPE_LVDS == bp_params->sink_signal))
  1670. s = SIGNAL_TYPE_LVDS;
  1671. params.ucEncodeMode =
  1672. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  1673. s, bp_params->enable_dp_audio);
  1674. if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
  1675. result = BP_RESULT_OK;
  1676. return result;
  1677. }
  1678. static enum bp_result select_crtc_source_v3(
  1679. struct bios_parser *bp,
  1680. struct bp_crtc_source_select *bp_params)
  1681. {
  1682. bool result = BP_RESULT_FAILURE;
  1683. SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
  1684. uint8_t atom_controller_id;
  1685. uint32_t atom_engine_id;
  1686. enum signal_type s = bp_params->signal;
  1687. memset(&params, 0, sizeof(params));
  1688. if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
  1689. &atom_controller_id))
  1690. params.ucCRTC = atom_controller_id;
  1691. else
  1692. return result;
  1693. if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
  1694. &atom_engine_id))
  1695. params.ucEncoderID = (uint8_t)atom_engine_id;
  1696. else
  1697. return result;
  1698. if (SIGNAL_TYPE_EDP == s ||
  1699. (SIGNAL_TYPE_DISPLAY_PORT == s &&
  1700. SIGNAL_TYPE_LVDS == bp_params->sink_signal))
  1701. s = SIGNAL_TYPE_LVDS;
  1702. params.ucEncodeMode =
  1703. bp->cmd_helper->encoder_mode_bp_to_atom(
  1704. s, bp_params->enable_dp_audio);
  1705. /* Needed for VBIOS Random Spatial Dithering feature */
  1706. params.ucDstBpc = (uint8_t)(bp_params->display_output_bit_depth);
  1707. if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
  1708. result = BP_RESULT_OK;
  1709. return result;
  1710. }
  1711. /*******************************************************************************
  1712. ********************************************************************************
  1713. **
  1714. ** ENABLE CRTC
  1715. **
  1716. ********************************************************************************
  1717. *******************************************************************************/
  1718. static enum bp_result enable_crtc_v1(
  1719. struct bios_parser *bp,
  1720. enum controller_id controller_id,
  1721. bool enable);
  1722. static void init_enable_crtc(struct bios_parser *bp)
  1723. {
  1724. switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
  1725. case 1:
  1726. bp->cmd_tbl.enable_crtc = enable_crtc_v1;
  1727. break;
  1728. default:
  1729. dm_error("Don't have enable_crtc for v%d\n",
  1730. BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
  1731. bp->cmd_tbl.enable_crtc = NULL;
  1732. break;
  1733. }
  1734. }
  1735. static enum bp_result enable_crtc_v1(
  1736. struct bios_parser *bp,
  1737. enum controller_id controller_id,
  1738. bool enable)
  1739. {
  1740. bool result = BP_RESULT_FAILURE;
  1741. ENABLE_CRTC_PARAMETERS params = {0};
  1742. uint8_t id;
  1743. if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
  1744. params.ucCRTC = id;
  1745. else
  1746. return BP_RESULT_BADINPUT;
  1747. if (enable)
  1748. params.ucEnable = ATOM_ENABLE;
  1749. else
  1750. params.ucEnable = ATOM_DISABLE;
  1751. if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
  1752. result = BP_RESULT_OK;
  1753. return result;
  1754. }
  1755. /*******************************************************************************
  1756. ********************************************************************************
  1757. **
  1758. ** ENABLE CRTC MEM REQ
  1759. **
  1760. ********************************************************************************
  1761. *******************************************************************************/
  1762. static enum bp_result enable_crtc_mem_req_v1(
  1763. struct bios_parser *bp,
  1764. enum controller_id controller_id,
  1765. bool enable);
  1766. static void init_enable_crtc_mem_req(struct bios_parser *bp)
  1767. {
  1768. switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
  1769. case 1:
  1770. bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
  1771. break;
  1772. default:
  1773. bp->cmd_tbl.enable_crtc_mem_req = NULL;
  1774. break;
  1775. }
  1776. }
  1777. static enum bp_result enable_crtc_mem_req_v1(
  1778. struct bios_parser *bp,
  1779. enum controller_id controller_id,
  1780. bool enable)
  1781. {
  1782. bool result = BP_RESULT_BADINPUT;
  1783. ENABLE_CRTC_PARAMETERS params = {0};
  1784. uint8_t id;
  1785. if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
  1786. params.ucCRTC = id;
  1787. if (enable)
  1788. params.ucEnable = ATOM_ENABLE;
  1789. else
  1790. params.ucEnable = ATOM_DISABLE;
  1791. if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
  1792. result = BP_RESULT_OK;
  1793. else
  1794. result = BP_RESULT_FAILURE;
  1795. }
  1796. return result;
  1797. }
  1798. /*******************************************************************************
  1799. ********************************************************************************
  1800. **
  1801. ** DISPLAY PLL
  1802. **
  1803. ********************************************************************************
  1804. *******************************************************************************/
  1805. static enum bp_result program_clock_v5(
  1806. struct bios_parser *bp,
  1807. struct bp_pixel_clock_parameters *bp_params);
  1808. static enum bp_result program_clock_v6(
  1809. struct bios_parser *bp,
  1810. struct bp_pixel_clock_parameters *bp_params);
  1811. static void init_program_clock(struct bios_parser *bp)
  1812. {
  1813. switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
  1814. case 5:
  1815. bp->cmd_tbl.program_clock = program_clock_v5;
  1816. break;
  1817. case 6:
  1818. bp->cmd_tbl.program_clock = program_clock_v6;
  1819. break;
  1820. default:
  1821. dm_error("Don't have program_clock for v%d\n",
  1822. BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
  1823. bp->cmd_tbl.program_clock = NULL;
  1824. break;
  1825. }
  1826. }
  1827. static enum bp_result program_clock_v5(
  1828. struct bios_parser *bp,
  1829. struct bp_pixel_clock_parameters *bp_params)
  1830. {
  1831. enum bp_result result = BP_RESULT_FAILURE;
  1832. SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
  1833. uint32_t atom_pll_id;
  1834. memset(&params, 0, sizeof(params));
  1835. if (!bp->cmd_helper->clock_source_id_to_atom(
  1836. bp_params->pll_id, &atom_pll_id)) {
  1837. BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
  1838. return BP_RESULT_BADINPUT;
  1839. }
  1840. /* We need to convert from KHz units into 10KHz units */
  1841. params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
  1842. params.sPCLKInput.usPixelClock =
  1843. cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
  1844. params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
  1845. if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
  1846. params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
  1847. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
  1848. result = BP_RESULT_OK;
  1849. return result;
  1850. }
  1851. static enum bp_result program_clock_v6(
  1852. struct bios_parser *bp,
  1853. struct bp_pixel_clock_parameters *bp_params)
  1854. {
  1855. enum bp_result result = BP_RESULT_FAILURE;
  1856. SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
  1857. uint32_t atom_pll_id;
  1858. memset(&params, 0, sizeof(params));
  1859. if (!bp->cmd_helper->clock_source_id_to_atom(
  1860. bp_params->pll_id, &atom_pll_id)) {
  1861. BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
  1862. return BP_RESULT_BADINPUT;
  1863. }
  1864. /* We need to convert from KHz units into 10KHz units */
  1865. params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
  1866. params.sPCLKInput.ulDispEngClkFreq =
  1867. cpu_to_le32(bp_params->target_pixel_clock / 10);
  1868. if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
  1869. params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
  1870. if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
  1871. /* True display clock is returned by VBIOS if DFS bypass
  1872. * is enabled. */
  1873. bp_params->dfs_bypass_display_clock =
  1874. (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
  1875. result = BP_RESULT_OK;
  1876. }
  1877. return result;
  1878. }
  1879. /*******************************************************************************
  1880. ********************************************************************************
  1881. **
  1882. ** EXTERNAL ENCODER CONTROL
  1883. **
  1884. ********************************************************************************
  1885. *******************************************************************************/
  1886. static enum bp_result external_encoder_control_v3(
  1887. struct bios_parser *bp,
  1888. struct bp_external_encoder_control *cntl);
  1889. static void init_external_encoder_control(
  1890. struct bios_parser *bp)
  1891. {
  1892. switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
  1893. case 3:
  1894. bp->cmd_tbl.external_encoder_control =
  1895. external_encoder_control_v3;
  1896. break;
  1897. default:
  1898. bp->cmd_tbl.external_encoder_control = NULL;
  1899. break;
  1900. }
  1901. }
  1902. static enum bp_result external_encoder_control_v3(
  1903. struct bios_parser *bp,
  1904. struct bp_external_encoder_control *cntl)
  1905. {
  1906. enum bp_result result = BP_RESULT_FAILURE;
  1907. /* we need use _PS_Alloc struct */
  1908. EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
  1909. EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
  1910. struct graphics_object_id encoder;
  1911. bool is_input_signal_dp = false;
  1912. memset(&params, 0, sizeof(params));
  1913. cntl_params = &params.sExtEncoder;
  1914. encoder = cntl->encoder_id;
  1915. /* check if encoder supports external encoder control table */
  1916. switch (dal_graphics_object_id_get_encoder_id(encoder)) {
  1917. case ENCODER_ID_EXTERNAL_NUTMEG:
  1918. case ENCODER_ID_EXTERNAL_TRAVIS:
  1919. is_input_signal_dp = true;
  1920. break;
  1921. default:
  1922. BREAK_TO_DEBUGGER();
  1923. return BP_RESULT_BADINPUT;
  1924. }
  1925. /* Fill information based on the action
  1926. *
  1927. * Bit[6:4]: indicate external encoder, applied to all functions.
  1928. * =0: external encoder1, mapped to external encoder enum id1
  1929. * =1: external encoder2, mapped to external encoder enum id2
  1930. *
  1931. * enum ObjectEnumId
  1932. * {
  1933. * EnumId_Unknown = 0,
  1934. * EnumId_1,
  1935. * EnumId_2,
  1936. * };
  1937. */
  1938. cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
  1939. switch (cntl->action) {
  1940. case EXTERNAL_ENCODER_CONTROL_INIT:
  1941. /* output display connector type. Only valid in encoder
  1942. * initialization */
  1943. cntl_params->usConnectorId =
  1944. cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
  1945. break;
  1946. case EXTERNAL_ENCODER_CONTROL_SETUP:
  1947. /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
  1948. * 10KHz
  1949. * output display device pixel clock frequency in unit of 10KHz.
  1950. * Only valid in setup and enableoutput
  1951. */
  1952. cntl_params->usPixelClock =
  1953. cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  1954. /* Indicate display output signal type drive by external
  1955. * encoder, only valid in setup and enableoutput */
  1956. cntl_params->ucEncoderMode =
  1957. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  1958. cntl->signal, false);
  1959. if (is_input_signal_dp) {
  1960. /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
  1961. * only valid in encoder setup with DP mode. */
  1962. if (LINK_RATE_HIGH == cntl->link_rate)
  1963. cntl_params->ucConfig |= 1;
  1964. /* output color depth Indicate encoder data bpc format
  1965. * in DP mode, only valid in encoder setup in DP mode.
  1966. */
  1967. cntl_params->ucBitPerColor =
  1968. (uint8_t)(cntl->color_depth);
  1969. }
  1970. /* Indicate how many lanes used by external encoder, only valid
  1971. * in encoder setup and enableoutput. */
  1972. cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
  1973. break;
  1974. case EXTERNAL_ENCODER_CONTROL_ENABLE:
  1975. cntl_params->usPixelClock =
  1976. cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
  1977. cntl_params->ucEncoderMode =
  1978. (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
  1979. cntl->signal, false);
  1980. cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
  1981. break;
  1982. default:
  1983. break;
  1984. }
  1985. cntl_params->ucAction = (uint8_t)cntl->action;
  1986. if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
  1987. result = BP_RESULT_OK;
  1988. return result;
  1989. }
  1990. /*******************************************************************************
  1991. ********************************************************************************
  1992. **
  1993. ** ENABLE DISPLAY POWER GATING
  1994. **
  1995. ********************************************************************************
  1996. *******************************************************************************/
  1997. static enum bp_result enable_disp_power_gating_v2_1(
  1998. struct bios_parser *bp,
  1999. enum controller_id crtc_id,
  2000. enum bp_pipe_control_action action);
  2001. static void init_enable_disp_power_gating(
  2002. struct bios_parser *bp)
  2003. {
  2004. switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
  2005. case 1:
  2006. bp->cmd_tbl.enable_disp_power_gating =
  2007. enable_disp_power_gating_v2_1;
  2008. break;
  2009. default:
  2010. dm_error("Don't enable_disp_power_gating enable_crtc for v%d\n",
  2011. BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
  2012. bp->cmd_tbl.enable_disp_power_gating = NULL;
  2013. break;
  2014. }
  2015. }
  2016. static enum bp_result enable_disp_power_gating_v2_1(
  2017. struct bios_parser *bp,
  2018. enum controller_id crtc_id,
  2019. enum bp_pipe_control_action action)
  2020. {
  2021. enum bp_result result = BP_RESULT_FAILURE;
  2022. ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
  2023. uint8_t atom_crtc_id;
  2024. if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
  2025. params.ucDispPipeId = atom_crtc_id;
  2026. else
  2027. return BP_RESULT_BADINPUT;
  2028. params.ucEnable =
  2029. bp->cmd_helper->disp_power_gating_action_to_atom(action);
  2030. if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
  2031. result = BP_RESULT_OK;
  2032. return result;
  2033. }
  2034. /*******************************************************************************
  2035. ********************************************************************************
  2036. **
  2037. ** SET DCE CLOCK
  2038. **
  2039. ********************************************************************************
  2040. *******************************************************************************/
  2041. static enum bp_result set_dce_clock_v2_1(
  2042. struct bios_parser *bp,
  2043. struct bp_set_dce_clock_parameters *bp_params);
  2044. static void init_set_dce_clock(struct bios_parser *bp)
  2045. {
  2046. switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
  2047. case 1:
  2048. bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
  2049. break;
  2050. default:
  2051. dm_error("Don't have set_dce_clock for v%d\n",
  2052. BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
  2053. bp->cmd_tbl.set_dce_clock = NULL;
  2054. break;
  2055. }
  2056. }
  2057. static enum bp_result set_dce_clock_v2_1(
  2058. struct bios_parser *bp,
  2059. struct bp_set_dce_clock_parameters *bp_params)
  2060. {
  2061. enum bp_result result = BP_RESULT_FAILURE;
  2062. SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
  2063. uint32_t atom_pll_id;
  2064. uint32_t atom_clock_type;
  2065. const struct command_table_helper *cmd = bp->cmd_helper;
  2066. memset(&params, 0, sizeof(params));
  2067. if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
  2068. !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
  2069. return BP_RESULT_BADINPUT;
  2070. params.asParam.ucDCEClkSrc = atom_pll_id;
  2071. params.asParam.ucDCEClkType = atom_clock_type;
  2072. if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
  2073. if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
  2074. params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
  2075. if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
  2076. params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
  2077. if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
  2078. params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
  2079. if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
  2080. params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
  2081. }
  2082. else
  2083. /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
  2084. /* We need to convert from KHz units into 10KHz units */
  2085. params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
  2086. if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
  2087. /* Convert from 10KHz units back to KHz */
  2088. bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
  2089. result = BP_RESULT_OK;
  2090. }
  2091. return result;
  2092. }