command_table2.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  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 "ObjectID.h"
  27. #include "atomfirmware.h"
  28. #include "include/bios_parser_interface.h"
  29. #include "command_table2.h"
  30. #include "command_table_helper2.h"
  31. #include "bios_parser_helper.h"
  32. #include "bios_parser_types_internal2.h"
  33. #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
  34. (((char *)(&((\
  35. struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\
  36. ->FieldName)-(char *)0)/sizeof(uint16_t))
  37. #define EXEC_BIOS_CMD_TABLE(fname, params)\
  38. (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
  39. GET_INDEX_INTO_MASTER_TABLE(command, fname), \
  40. &params) == 0)
  41. #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
  42. cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
  43. GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
  44. #define BIOS_CMD_TABLE_PARA_REVISION(fname)\
  45. bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
  46. GET_INDEX_INTO_MASTER_TABLE(command, fname))
  47. static void init_dig_encoder_control(struct bios_parser *bp);
  48. static void init_transmitter_control(struct bios_parser *bp);
  49. static void init_set_pixel_clock(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_external_encoder_control(struct bios_parser *bp);
  54. static void init_enable_disp_power_gating(struct bios_parser *bp);
  55. static void init_set_dce_clock(struct bios_parser *bp);
  56. static void init_get_smu_clock_info(struct bios_parser *bp);
  57. void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
  58. {
  59. init_dig_encoder_control(bp);
  60. init_transmitter_control(bp);
  61. init_set_pixel_clock(bp);
  62. init_set_crtc_timing(bp);
  63. init_select_crtc_source(bp);
  64. init_enable_crtc(bp);
  65. init_external_encoder_control(bp);
  66. init_enable_disp_power_gating(bp);
  67. init_set_dce_clock(bp);
  68. init_get_smu_clock_info(bp);
  69. }
  70. static uint32_t bios_cmd_table_para_revision(void *cgs_device,
  71. uint32_t index)
  72. {
  73. uint8_t frev, crev;
  74. if (cgs_atom_get_cmd_table_revs(cgs_device,
  75. index,
  76. &frev, &crev) != 0)
  77. return 0;
  78. return crev;
  79. }
  80. /******************************************************************************
  81. ******************************************************************************
  82. **
  83. ** D I G E N C O D E R C O N T R O L
  84. **
  85. ******************************************************************************
  86. *****************************************************************************/
  87. static enum bp_result encoder_control_digx_v1_5(
  88. struct bios_parser *bp,
  89. struct bp_encoder_control *cntl);
  90. static void init_dig_encoder_control(struct bios_parser *bp)
  91. {
  92. uint32_t version =
  93. BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
  94. switch (version) {
  95. case 5:
  96. bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
  97. break;
  98. default:
  99. bp->cmd_tbl.dig_encoder_control = NULL;
  100. break;
  101. }
  102. }
  103. static enum bp_result encoder_control_digx_v1_5(
  104. struct bios_parser *bp,
  105. struct bp_encoder_control *cntl)
  106. {
  107. enum bp_result result = BP_RESULT_FAILURE;
  108. struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
  109. params.digid = (uint8_t)(cntl->engine_id);
  110. params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
  111. params.pclk_10khz = cntl->pixel_clock / 10;
  112. params.digmode =
  113. (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
  114. cntl->signal,
  115. cntl->enable_dp_audio));
  116. params.lanenum = (uint8_t)(cntl->lanes_number);
  117. switch (cntl->color_depth) {
  118. case COLOR_DEPTH_888:
  119. params.bitpercolor = PANEL_8BIT_PER_COLOR;
  120. break;
  121. case COLOR_DEPTH_101010:
  122. params.bitpercolor = PANEL_10BIT_PER_COLOR;
  123. break;
  124. case COLOR_DEPTH_121212:
  125. params.bitpercolor = PANEL_12BIT_PER_COLOR;
  126. break;
  127. case COLOR_DEPTH_161616:
  128. params.bitpercolor = PANEL_16BIT_PER_COLOR;
  129. break;
  130. default:
  131. break;
  132. }
  133. if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
  134. switch (cntl->color_depth) {
  135. case COLOR_DEPTH_101010:
  136. params.pclk_10khz =
  137. (params.pclk_10khz * 30) / 24;
  138. break;
  139. case COLOR_DEPTH_121212:
  140. params.pclk_10khz =
  141. (params.pclk_10khz * 36) / 24;
  142. break;
  143. case COLOR_DEPTH_161616:
  144. params.pclk_10khz =
  145. (params.pclk_10khz * 48) / 24;
  146. break;
  147. default:
  148. break;
  149. }
  150. if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
  151. result = BP_RESULT_OK;
  152. return result;
  153. }
  154. /*****************************************************************************
  155. ******************************************************************************
  156. **
  157. ** TRANSMITTER CONTROL
  158. **
  159. ******************************************************************************
  160. *****************************************************************************/
  161. static enum bp_result transmitter_control_v1_6(
  162. struct bios_parser *bp,
  163. struct bp_transmitter_control *cntl);
  164. static void init_transmitter_control(struct bios_parser *bp)
  165. {
  166. uint8_t frev;
  167. uint8_t crev;
  168. if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0)
  169. BREAK_TO_DEBUGGER();
  170. switch (crev) {
  171. case 6:
  172. bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
  173. break;
  174. default:
  175. bp->cmd_tbl.transmitter_control = NULL;
  176. break;
  177. }
  178. }
  179. static enum bp_result transmitter_control_v1_6(
  180. struct bios_parser *bp,
  181. struct bp_transmitter_control *cntl)
  182. {
  183. enum bp_result result = BP_RESULT_FAILURE;
  184. const struct command_table_helper *cmd = bp->cmd_helper;
  185. struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
  186. ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
  187. ps.param.action = (uint8_t)cntl->action;
  188. if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
  189. ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
  190. else
  191. ps.param.mode_laneset.digmode =
  192. cmd->signal_type_to_atom_dig_mode(cntl->signal);
  193. ps.param.lanenum = (uint8_t)cntl->lanes_number;
  194. ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
  195. ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
  196. ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
  197. ps.param.symclk_10khz = cntl->pixel_clock/10;
  198. if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
  199. cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
  200. cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
  201. dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\
  202. "%s:ps.param.symclk_10khz = %d\n",\
  203. __func__, ps.param.symclk_10khz);
  204. }
  205. /*color_depth not used any more, driver has deep color factor in the Phyclk*/
  206. if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
  207. result = BP_RESULT_OK;
  208. return result;
  209. }
  210. /******************************************************************************
  211. ******************************************************************************
  212. **
  213. ** SET PIXEL CLOCK
  214. **
  215. ******************************************************************************
  216. *****************************************************************************/
  217. static enum bp_result set_pixel_clock_v7(
  218. struct bios_parser *bp,
  219. struct bp_pixel_clock_parameters *bp_params);
  220. static void init_set_pixel_clock(struct bios_parser *bp)
  221. {
  222. switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
  223. case 7:
  224. bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
  225. break;
  226. default:
  227. bp->cmd_tbl.set_pixel_clock = NULL;
  228. break;
  229. }
  230. }
  231. static enum bp_result set_pixel_clock_v7(
  232. struct bios_parser *bp,
  233. struct bp_pixel_clock_parameters *bp_params)
  234. {
  235. enum bp_result result = BP_RESULT_FAILURE;
  236. struct set_pixel_clock_parameter_v1_7 clk;
  237. uint8_t controller_id;
  238. uint32_t pll_id;
  239. memset(&clk, 0, sizeof(clk));
  240. if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
  241. && bp->cmd_helper->controller_id_to_atom(bp_params->
  242. controller_id, &controller_id)) {
  243. /* Note: VBIOS still wants to use ucCRTC name which is now
  244. * 1 byte in ULONG
  245. *typedef struct _CRTC_PIXEL_CLOCK_FREQ
  246. *{
  247. * target the pixel clock to drive the CRTC timing.
  248. * ULONG ulPixelClock:24;
  249. * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
  250. * previous version.
  251. * ATOM_CRTC1~6, indicate the CRTC controller to
  252. * ULONG ucCRTC:8;
  253. * drive the pixel clock. not used for DCPLL case.
  254. *}CRTC_PIXEL_CLOCK_FREQ;
  255. *union
  256. *{
  257. * pixel clock and CRTC id frequency
  258. * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
  259. * ULONG ulDispEngClkFreq; dispclk frequency
  260. *};
  261. */
  262. clk.crtc_id = controller_id;
  263. clk.pll_id = (uint8_t) pll_id;
  264. clk.encoderobjid =
  265. bp->cmd_helper->encoder_id_to_atom(
  266. dal_graphics_object_id_get_encoder_id(
  267. bp_params->encoder_object_id));
  268. clk.encoder_mode = (uint8_t) bp->
  269. cmd_helper->encoder_mode_bp_to_atom(
  270. bp_params->signal_type, false);
  271. /* We need to convert from KHz units into 10KHz units */
  272. clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock *
  273. 10);
  274. clk.deep_color_ratio =
  275. (uint8_t) bp->cmd_helper->
  276. transmitter_color_depth_to_atom(
  277. bp_params->color_depth);
  278. dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\
  279. "%s:program display clock = %d"\
  280. "colorDepth = %d\n", __func__,\
  281. bp_params->target_pixel_clock, bp_params->color_depth);
  282. if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
  283. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
  284. if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
  285. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
  286. if (bp_params->flags.SUPPORT_YUV_420)
  287. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
  288. if (bp_params->flags.SET_XTALIN_REF_SRC)
  289. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
  290. if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
  291. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
  292. if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
  293. clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
  294. if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
  295. result = BP_RESULT_OK;
  296. }
  297. return result;
  298. }
  299. /******************************************************************************
  300. ******************************************************************************
  301. **
  302. ** SET CRTC TIMING
  303. **
  304. ******************************************************************************
  305. *****************************************************************************/
  306. static enum bp_result set_crtc_using_dtd_timing_v3(
  307. struct bios_parser *bp,
  308. struct bp_hw_crtc_timing_parameters *bp_params);
  309. static void init_set_crtc_timing(struct bios_parser *bp)
  310. {
  311. uint32_t dtd_version =
  312. BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
  313. switch (dtd_version) {
  314. case 3:
  315. bp->cmd_tbl.set_crtc_timing =
  316. set_crtc_using_dtd_timing_v3;
  317. break;
  318. default:
  319. bp->cmd_tbl.set_crtc_timing = NULL;
  320. break;
  321. }
  322. }
  323. static enum bp_result set_crtc_using_dtd_timing_v3(
  324. struct bios_parser *bp,
  325. struct bp_hw_crtc_timing_parameters *bp_params)
  326. {
  327. enum bp_result result = BP_RESULT_FAILURE;
  328. struct set_crtc_using_dtd_timing_parameters params = {0};
  329. uint8_t atom_controller_id;
  330. if (bp->cmd_helper->controller_id_to_atom(
  331. bp_params->controller_id, &atom_controller_id))
  332. params.crtc_id = atom_controller_id;
  333. /* bios usH_Size wants h addressable size */
  334. params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
  335. /* bios usH_Blanking_Time wants borders included in blanking */
  336. params.h_blanking_time =
  337. cpu_to_le16((uint16_t)(bp_params->h_total -
  338. bp_params->h_addressable));
  339. /* bios usV_Size wants v addressable size */
  340. params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
  341. /* bios usV_Blanking_Time wants borders included in blanking */
  342. params.v_blanking_time =
  343. cpu_to_le16((uint16_t)(bp_params->v_total -
  344. bp_params->v_addressable));
  345. /* bios usHSyncOffset is the offset from the end of h addressable,
  346. * our horizontalSyncStart is the offset from the beginning
  347. * of h addressable
  348. */
  349. params.h_syncoffset =
  350. cpu_to_le16((uint16_t)(bp_params->h_sync_start -
  351. bp_params->h_addressable));
  352. params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
  353. /* bios usHSyncOffset is the offset from the end of v addressable,
  354. * our verticalSyncStart is the offset from the beginning of
  355. * v addressable
  356. */
  357. params.v_syncoffset =
  358. cpu_to_le16((uint16_t)(bp_params->v_sync_start -
  359. bp_params->v_addressable));
  360. params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
  361. /* we assume that overscan from original timing does not get bigger
  362. * than 255
  363. * we will program all the borders in the Set CRTC Overscan call below
  364. */
  365. if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
  366. params.modemiscinfo =
  367. cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
  368. ATOM_HSYNC_POLARITY);
  369. if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
  370. params.modemiscinfo =
  371. cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
  372. ATOM_VSYNC_POLARITY);
  373. if (bp_params->flags.INTERLACE) {
  374. params.modemiscinfo =
  375. cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
  376. ATOM_INTERLACE);
  377. /* original DAL code has this condition to apply this
  378. * for non-TV/CV only
  379. * due to complex MV testing for possible impact
  380. * if ( pACParameters->signal != SignalType_YPbPr &&
  381. * pACParameters->signal != SignalType_Composite &&
  382. * pACParameters->signal != SignalType_SVideo)
  383. */
  384. {
  385. /* HW will deduct 0.5 line from 2nd feild.
  386. * i.e. for 1080i, it is 2 lines for 1st field,
  387. * 2.5 lines for the 2nd feild. we need input as 5
  388. * instead of 4.
  389. * but it is 4 either from Edid data (spec CEA 861)
  390. * or CEA timing table.
  391. */
  392. params.v_syncoffset =
  393. cpu_to_le16(le16_to_cpu(params.v_syncoffset) +
  394. 1);
  395. }
  396. }
  397. if (bp_params->flags.HORZ_COUNT_BY_TWO)
  398. params.modemiscinfo =
  399. cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
  400. 0x100); /* ATOM_DOUBLE_CLOCK_MODE */
  401. if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
  402. result = BP_RESULT_OK;
  403. return result;
  404. }
  405. /******************************************************************************
  406. ******************************************************************************
  407. **
  408. ** SELECT CRTC SOURCE
  409. **
  410. ******************************************************************************
  411. *****************************************************************************/
  412. static enum bp_result select_crtc_source_v3(
  413. struct bios_parser *bp,
  414. struct bp_crtc_source_select *bp_params);
  415. static void init_select_crtc_source(struct bios_parser *bp)
  416. {
  417. switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) {
  418. case 3:
  419. bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
  420. break;
  421. default:
  422. bp->cmd_tbl.select_crtc_source = NULL;
  423. break;
  424. }
  425. }
  426. static enum bp_result select_crtc_source_v3(
  427. struct bios_parser *bp,
  428. struct bp_crtc_source_select *bp_params)
  429. {
  430. bool result = BP_RESULT_FAILURE;
  431. struct select_crtc_source_parameters_v2_3 params;
  432. uint8_t atom_controller_id;
  433. uint32_t atom_engine_id;
  434. enum signal_type s = bp_params->signal;
  435. memset(&params, 0, sizeof(params));
  436. if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
  437. &atom_controller_id))
  438. params.crtc_id = atom_controller_id;
  439. else
  440. return result;
  441. if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
  442. &atom_engine_id))
  443. params.encoder_id = (uint8_t)atom_engine_id;
  444. else
  445. return result;
  446. if (s == SIGNAL_TYPE_EDP ||
  447. (s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal ==
  448. SIGNAL_TYPE_LVDS))
  449. s = SIGNAL_TYPE_LVDS;
  450. params.encode_mode =
  451. bp->cmd_helper->encoder_mode_bp_to_atom(
  452. s, bp_params->enable_dp_audio);
  453. /* Needed for VBIOS Random Spatial Dithering feature */
  454. params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth);
  455. if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params))
  456. result = BP_RESULT_OK;
  457. return result;
  458. }
  459. /******************************************************************************
  460. ******************************************************************************
  461. **
  462. ** ENABLE CRTC
  463. **
  464. ******************************************************************************
  465. *****************************************************************************/
  466. static enum bp_result enable_crtc_v1(
  467. struct bios_parser *bp,
  468. enum controller_id controller_id,
  469. bool enable);
  470. static void init_enable_crtc(struct bios_parser *bp)
  471. {
  472. switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
  473. case 1:
  474. bp->cmd_tbl.enable_crtc = enable_crtc_v1;
  475. break;
  476. default:
  477. bp->cmd_tbl.enable_crtc = NULL;
  478. break;
  479. }
  480. }
  481. static enum bp_result enable_crtc_v1(
  482. struct bios_parser *bp,
  483. enum controller_id controller_id,
  484. bool enable)
  485. {
  486. bool result = BP_RESULT_FAILURE;
  487. struct enable_crtc_parameters params = {0};
  488. uint8_t id;
  489. if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
  490. params.crtc_id = id;
  491. else
  492. return BP_RESULT_BADINPUT;
  493. if (enable)
  494. params.enable = ATOM_ENABLE;
  495. else
  496. params.enable = ATOM_DISABLE;
  497. if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
  498. result = BP_RESULT_OK;
  499. return result;
  500. }
  501. /******************************************************************************
  502. ******************************************************************************
  503. **
  504. ** DISPLAY PLL
  505. **
  506. ******************************************************************************
  507. *****************************************************************************/
  508. /******************************************************************************
  509. ******************************************************************************
  510. **
  511. ** EXTERNAL ENCODER CONTROL
  512. **
  513. ******************************************************************************
  514. *****************************************************************************/
  515. static enum bp_result external_encoder_control_v3(
  516. struct bios_parser *bp,
  517. struct bp_external_encoder_control *cntl);
  518. static void init_external_encoder_control(
  519. struct bios_parser *bp)
  520. {
  521. switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
  522. case 3:
  523. bp->cmd_tbl.external_encoder_control =
  524. external_encoder_control_v3;
  525. break;
  526. default:
  527. bp->cmd_tbl.external_encoder_control = NULL;
  528. break;
  529. }
  530. }
  531. static enum bp_result external_encoder_control_v3(
  532. struct bios_parser *bp,
  533. struct bp_external_encoder_control *cntl)
  534. {
  535. /* TODO */
  536. return BP_RESULT_OK;
  537. }
  538. /******************************************************************************
  539. ******************************************************************************
  540. **
  541. ** ENABLE DISPLAY POWER GATING
  542. **
  543. ******************************************************************************
  544. *****************************************************************************/
  545. static enum bp_result enable_disp_power_gating_v2_1(
  546. struct bios_parser *bp,
  547. enum controller_id crtc_id,
  548. enum bp_pipe_control_action action);
  549. static void init_enable_disp_power_gating(
  550. struct bios_parser *bp)
  551. {
  552. switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
  553. case 1:
  554. bp->cmd_tbl.enable_disp_power_gating =
  555. enable_disp_power_gating_v2_1;
  556. break;
  557. default:
  558. bp->cmd_tbl.enable_disp_power_gating = NULL;
  559. break;
  560. }
  561. }
  562. static enum bp_result enable_disp_power_gating_v2_1(
  563. struct bios_parser *bp,
  564. enum controller_id crtc_id,
  565. enum bp_pipe_control_action action)
  566. {
  567. enum bp_result result = BP_RESULT_FAILURE;
  568. struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
  569. uint8_t atom_crtc_id;
  570. if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
  571. ps.param.disp_pipe_id = atom_crtc_id;
  572. else
  573. return BP_RESULT_BADINPUT;
  574. ps.param.enable =
  575. bp->cmd_helper->disp_power_gating_action_to_atom(action);
  576. if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
  577. result = BP_RESULT_OK;
  578. return result;
  579. }
  580. /******************************************************************************
  581. *******************************************************************************
  582. **
  583. ** SET DCE CLOCK
  584. **
  585. *******************************************************************************
  586. *******************************************************************************/
  587. static enum bp_result set_dce_clock_v2_1(
  588. struct bios_parser *bp,
  589. struct bp_set_dce_clock_parameters *bp_params);
  590. static void init_set_dce_clock(struct bios_parser *bp)
  591. {
  592. switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
  593. case 1:
  594. bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
  595. break;
  596. default:
  597. bp->cmd_tbl.set_dce_clock = NULL;
  598. break;
  599. }
  600. }
  601. static enum bp_result set_dce_clock_v2_1(
  602. struct bios_parser *bp,
  603. struct bp_set_dce_clock_parameters *bp_params)
  604. {
  605. enum bp_result result = BP_RESULT_FAILURE;
  606. struct set_dce_clock_ps_allocation_v2_1 params;
  607. uint32_t atom_pll_id;
  608. uint32_t atom_clock_type;
  609. const struct command_table_helper *cmd = bp->cmd_helper;
  610. memset(&params, 0, sizeof(params));
  611. if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
  612. !cmd->dc_clock_type_to_atom(bp_params->clock_type,
  613. &atom_clock_type))
  614. return BP_RESULT_BADINPUT;
  615. params.param.dceclksrc = atom_pll_id;
  616. params.param.dceclktype = atom_clock_type;
  617. if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
  618. if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
  619. params.param.dceclkflag |=
  620. DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
  621. if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
  622. params.param.dceclkflag |=
  623. DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
  624. if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
  625. params.param.dceclkflag |=
  626. DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
  627. if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
  628. params.param.dceclkflag |=
  629. DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
  630. } else
  631. /* only program clock frequency if display clock is used;
  632. * VBIOS will program DPREFCLK
  633. * We need to convert from KHz units into 10KHz units
  634. */
  635. params.param.dceclk_10khz = cpu_to_le32(
  636. bp_params->target_clock_frequency / 10);
  637. dm_logger_write(bp->base.ctx->logger, LOG_BIOS,
  638. "%s:target_clock_frequency = %d"\
  639. "clock_type = %d \n", __func__,\
  640. bp_params->target_clock_frequency,\
  641. bp_params->clock_type);
  642. if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
  643. /* Convert from 10KHz units back to KHz */
  644. bp_params->target_clock_frequency = le32_to_cpu(
  645. params.param.dceclk_10khz) * 10;
  646. result = BP_RESULT_OK;
  647. }
  648. return result;
  649. }
  650. /******************************************************************************
  651. ******************************************************************************
  652. **
  653. ** GET SMU CLOCK INFO
  654. **
  655. ******************************************************************************
  656. *****************************************************************************/
  657. static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp);
  658. static void init_get_smu_clock_info(struct bios_parser *bp)
  659. {
  660. /* TODO add switch for table vrsion */
  661. bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
  662. }
  663. static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp)
  664. {
  665. struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
  666. struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
  667. smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
  668. /* Get Specific Clock */
  669. if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
  670. memmove(&smu_output, &smu_input, sizeof(
  671. struct atom_get_smu_clock_info_parameters_v3_1));
  672. return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
  673. }
  674. return 0;
  675. }