command_table.c 73 KB

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