command_table2.c 25 KB

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