command_table.c 72 KB

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