dcn10_optc.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  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 "reg_helper.h"
  26. #include "dcn10_optc.h"
  27. #include "dc.h"
  28. #define REG(reg)\
  29. optc1->tg_regs->reg
  30. #define CTX \
  31. optc1->base.ctx
  32. #undef FN
  33. #define FN(reg_name, field_name) \
  34. optc1->tg_shift->field_name, optc1->tg_mask->field_name
  35. #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
  36. /**
  37. * apply_front_porch_workaround TODO FPGA still need?
  38. *
  39. * This is a workaround for a bug that has existed since R5xx and has not been
  40. * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
  41. */
  42. static void optc1_apply_front_porch_workaround(
  43. struct timing_generator *optc,
  44. struct dc_crtc_timing *timing)
  45. {
  46. if (timing->flags.INTERLACE == 1) {
  47. if (timing->v_front_porch < 2)
  48. timing->v_front_porch = 2;
  49. } else {
  50. if (timing->v_front_porch < 1)
  51. timing->v_front_porch = 1;
  52. }
  53. }
  54. void optc1_program_global_sync(
  55. struct timing_generator *optc)
  56. {
  57. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  58. if (optc->dlg_otg_param.vstartup_start == 0) {
  59. BREAK_TO_DEBUGGER();
  60. return;
  61. }
  62. REG_SET(OTG_VSTARTUP_PARAM, 0,
  63. VSTARTUP_START, optc->dlg_otg_param.vstartup_start);
  64. REG_SET_2(OTG_VUPDATE_PARAM, 0,
  65. VUPDATE_OFFSET, optc->dlg_otg_param.vupdate_offset,
  66. VUPDATE_WIDTH, optc->dlg_otg_param.vupdate_width);
  67. REG_SET(OTG_VREADY_PARAM, 0,
  68. VREADY_OFFSET, optc->dlg_otg_param.vready_offset);
  69. }
  70. static void optc1_disable_stereo(struct timing_generator *optc)
  71. {
  72. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  73. REG_SET(OTG_STEREO_CONTROL, 0,
  74. OTG_STEREO_EN, 0);
  75. REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0,
  76. OTG_3D_STRUCTURE_EN, 0,
  77. OTG_3D_STRUCTURE_V_UPDATE_MODE, 0,
  78. OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
  79. }
  80. /**
  81. * program_timing_generator used by mode timing set
  82. * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
  83. * Including SYNC. Call BIOS command table to program Timings.
  84. */
  85. void optc1_program_timing(
  86. struct timing_generator *optc,
  87. const struct dc_crtc_timing *dc_crtc_timing,
  88. bool use_vbios)
  89. {
  90. struct dc_crtc_timing patched_crtc_timing;
  91. uint32_t vesa_sync_start;
  92. uint32_t asic_blank_end;
  93. uint32_t asic_blank_start;
  94. uint32_t v_total;
  95. uint32_t v_sync_end;
  96. uint32_t v_init, v_fp2;
  97. uint32_t h_sync_polarity, v_sync_polarity;
  98. uint32_t interlace_factor;
  99. uint32_t start_point = 0;
  100. uint32_t field_num = 0;
  101. uint32_t h_div_2;
  102. int32_t vertical_line_start;
  103. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  104. patched_crtc_timing = *dc_crtc_timing;
  105. optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
  106. /* Load horizontal timing */
  107. /* CRTC_H_TOTAL = vesa.h_total - 1 */
  108. REG_SET(OTG_H_TOTAL, 0,
  109. OTG_H_TOTAL, patched_crtc_timing.h_total - 1);
  110. /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
  111. REG_UPDATE_2(OTG_H_SYNC_A,
  112. OTG_H_SYNC_A_START, 0,
  113. OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
  114. /* asic_h_blank_end = HsyncWidth + HbackPorch =
  115. * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
  116. * vesa.h_left_border
  117. */
  118. vesa_sync_start = patched_crtc_timing.h_addressable +
  119. patched_crtc_timing.h_border_right +
  120. patched_crtc_timing.h_front_porch;
  121. asic_blank_end = patched_crtc_timing.h_total -
  122. vesa_sync_start -
  123. patched_crtc_timing.h_border_left;
  124. /* h_blank_start = v_blank_end + v_active */
  125. asic_blank_start = asic_blank_end +
  126. patched_crtc_timing.h_border_left +
  127. patched_crtc_timing.h_addressable +
  128. patched_crtc_timing.h_border_right;
  129. REG_UPDATE_2(OTG_H_BLANK_START_END,
  130. OTG_H_BLANK_START, asic_blank_start,
  131. OTG_H_BLANK_END, asic_blank_end);
  132. /* h_sync polarity */
  133. h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
  134. 0 : 1;
  135. REG_UPDATE(OTG_H_SYNC_A_CNTL,
  136. OTG_H_SYNC_A_POL, h_sync_polarity);
  137. /* Load vertical timing */
  138. /* CRTC_V_TOTAL = v_total - 1 */
  139. if (patched_crtc_timing.flags.INTERLACE) {
  140. interlace_factor = 2;
  141. v_total = 2 * patched_crtc_timing.v_total;
  142. } else {
  143. interlace_factor = 1;
  144. v_total = patched_crtc_timing.v_total - 1;
  145. }
  146. REG_SET(OTG_V_TOTAL, 0,
  147. OTG_V_TOTAL, v_total);
  148. /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
  149. * OTG_V_TOTAL_MIN are equal to V_TOTAL.
  150. */
  151. REG_SET(OTG_V_TOTAL_MAX, 0,
  152. OTG_V_TOTAL_MAX, v_total);
  153. REG_SET(OTG_V_TOTAL_MIN, 0,
  154. OTG_V_TOTAL_MIN, v_total);
  155. /* v_sync_start = 0, v_sync_end = v_sync_width */
  156. v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
  157. REG_UPDATE_2(OTG_V_SYNC_A,
  158. OTG_V_SYNC_A_START, 0,
  159. OTG_V_SYNC_A_END, v_sync_end);
  160. vesa_sync_start = patched_crtc_timing.v_addressable +
  161. patched_crtc_timing.v_border_bottom +
  162. patched_crtc_timing.v_front_porch;
  163. asic_blank_end = (patched_crtc_timing.v_total -
  164. vesa_sync_start -
  165. patched_crtc_timing.v_border_top)
  166. * interlace_factor;
  167. /* v_blank_start = v_blank_end + v_active */
  168. asic_blank_start = asic_blank_end +
  169. (patched_crtc_timing.v_border_top +
  170. patched_crtc_timing.v_addressable +
  171. patched_crtc_timing.v_border_bottom)
  172. * interlace_factor;
  173. REG_UPDATE_2(OTG_V_BLANK_START_END,
  174. OTG_V_BLANK_START, asic_blank_start,
  175. OTG_V_BLANK_END, asic_blank_end);
  176. /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
  177. * program the reg for interrupt postition.
  178. */
  179. vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
  180. if (vertical_line_start < 0) {
  181. ASSERT(0);
  182. vertical_line_start = 0;
  183. }
  184. REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
  185. OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
  186. /* v_sync polarity */
  187. v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
  188. 0 : 1;
  189. REG_UPDATE(OTG_V_SYNC_A_CNTL,
  190. OTG_V_SYNC_A_POL, v_sync_polarity);
  191. v_init = asic_blank_start;
  192. if (optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
  193. optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
  194. optc->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
  195. start_point = 1;
  196. if (patched_crtc_timing.flags.INTERLACE == 1)
  197. field_num = 1;
  198. }
  199. v_fp2 = 0;
  200. if (optc->dlg_otg_param.vstartup_start > asic_blank_end)
  201. v_fp2 = optc->dlg_otg_param.vstartup_start > asic_blank_end;
  202. /* Interlace */
  203. if (patched_crtc_timing.flags.INTERLACE == 1) {
  204. REG_UPDATE(OTG_INTERLACE_CONTROL,
  205. OTG_INTERLACE_ENABLE, 1);
  206. v_init = v_init / 2;
  207. if ((optc->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
  208. v_fp2 = v_fp2 / 2;
  209. } else
  210. REG_UPDATE(OTG_INTERLACE_CONTROL,
  211. OTG_INTERLACE_ENABLE, 0);
  212. /* VTG enable set to 0 first VInit */
  213. REG_UPDATE(CONTROL,
  214. VTG0_ENABLE, 0);
  215. REG_UPDATE_2(CONTROL,
  216. VTG0_FP2, v_fp2,
  217. VTG0_VCOUNT_INIT, v_init);
  218. /* original code is using VTG offset to address OTG reg, seems wrong */
  219. REG_UPDATE_2(OTG_CONTROL,
  220. OTG_START_POINT_CNTL, start_point,
  221. OTG_FIELD_NUMBER_CNTL, field_num);
  222. optc1_program_global_sync(optc);
  223. /* TODO
  224. * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
  225. * program_horz_count_by_2
  226. * for DVI 30bpp mode, 0 otherwise
  227. * program_horz_count_by_2(optc, &patched_crtc_timing);
  228. */
  229. /* Enable stereo - only when we need to pack 3D frame. Other types
  230. * of stereo handled in explicit call
  231. */
  232. h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
  233. 1 : 0;
  234. REG_UPDATE(OTG_H_TIMING_CNTL,
  235. OTG_H_TIMING_DIV_BY2, h_div_2);
  236. }
  237. static void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
  238. {
  239. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  240. uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
  241. REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
  242. OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
  243. }
  244. /**
  245. * unblank_crtc
  246. * Call ASIC Control Object to UnBlank CRTC.
  247. */
  248. static void optc1_unblank_crtc(struct timing_generator *optc)
  249. {
  250. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  251. uint32_t vertical_interrupt_enable = 0;
  252. REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
  253. OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
  254. /* temporary work around for vertical interrupt, once vertical interrupt enabled,
  255. * this check will be removed.
  256. */
  257. if (vertical_interrupt_enable)
  258. optc1_set_blank_data_double_buffer(optc, true);
  259. REG_UPDATE_2(OTG_BLANK_CONTROL,
  260. OTG_BLANK_DATA_EN, 0,
  261. OTG_BLANK_DE_MODE, 0);
  262. }
  263. /**
  264. * blank_crtc
  265. * Call ASIC Control Object to Blank CRTC.
  266. */
  267. static void optc1_blank_crtc(struct timing_generator *optc)
  268. {
  269. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  270. REG_UPDATE_2(OTG_BLANK_CONTROL,
  271. OTG_BLANK_DATA_EN, 1,
  272. OTG_BLANK_DE_MODE, 0);
  273. optc1_set_blank_data_double_buffer(optc, false);
  274. }
  275. void optc1_set_blank(struct timing_generator *optc,
  276. bool enable_blanking)
  277. {
  278. if (enable_blanking)
  279. optc1_blank_crtc(optc);
  280. else
  281. optc1_unblank_crtc(optc);
  282. }
  283. bool optc1_is_blanked(struct timing_generator *optc)
  284. {
  285. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  286. uint32_t blank_en;
  287. uint32_t blank_state;
  288. REG_GET_2(OTG_BLANK_CONTROL,
  289. OTG_BLANK_DATA_EN, &blank_en,
  290. OTG_CURRENT_BLANK_STATE, &blank_state);
  291. return blank_en && blank_state;
  292. }
  293. void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
  294. {
  295. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  296. if (enable) {
  297. REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
  298. OPTC_INPUT_CLK_EN, 1,
  299. OPTC_INPUT_CLK_GATE_DIS, 1);
  300. REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
  301. OPTC_INPUT_CLK_ON, 1,
  302. 1, 1000);
  303. /* Enable clock */
  304. REG_UPDATE_2(OTG_CLOCK_CONTROL,
  305. OTG_CLOCK_EN, 1,
  306. OTG_CLOCK_GATE_DIS, 1);
  307. REG_WAIT(OTG_CLOCK_CONTROL,
  308. OTG_CLOCK_ON, 1,
  309. 1, 1000);
  310. } else {
  311. REG_UPDATE_2(OTG_CLOCK_CONTROL,
  312. OTG_CLOCK_GATE_DIS, 0,
  313. OTG_CLOCK_EN, 0);
  314. REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
  315. OPTC_INPUT_CLK_GATE_DIS, 0,
  316. OPTC_INPUT_CLK_EN, 0);
  317. }
  318. }
  319. /**
  320. * Enable CRTC
  321. * Enable CRTC - call ASIC Control Object to enable Timing generator.
  322. */
  323. static bool optc1_enable_crtc(struct timing_generator *optc)
  324. {
  325. /* TODO FPGA wait for answer
  326. * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
  327. * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
  328. */
  329. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  330. /* opp instance for OTG. For DCN1.0, ODM is remoed.
  331. * OPP and OPTC should 1:1 mapping
  332. */
  333. REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
  334. OPTC_SRC_SEL, optc->inst);
  335. /* VTG enable first is for HW workaround */
  336. REG_UPDATE(CONTROL,
  337. VTG0_ENABLE, 1);
  338. /* Enable CRTC */
  339. REG_UPDATE_2(OTG_CONTROL,
  340. OTG_DISABLE_POINT_CNTL, 3,
  341. OTG_MASTER_EN, 1);
  342. return true;
  343. }
  344. /* disable_crtc - call ASIC Control Object to disable Timing generator. */
  345. bool optc1_disable_crtc(struct timing_generator *optc)
  346. {
  347. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  348. /* disable otg request until end of the first line
  349. * in the vertical blank region
  350. */
  351. REG_UPDATE_2(OTG_CONTROL,
  352. OTG_DISABLE_POINT_CNTL, 3,
  353. OTG_MASTER_EN, 0);
  354. REG_UPDATE(CONTROL,
  355. VTG0_ENABLE, 0);
  356. /* CRTC disabled, so disable clock. */
  357. REG_WAIT(OTG_CLOCK_CONTROL,
  358. OTG_BUSY, 0,
  359. 1, 100000);
  360. return true;
  361. }
  362. void optc1_program_blank_color(
  363. struct timing_generator *optc,
  364. const struct tg_color *black_color)
  365. {
  366. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  367. REG_SET_3(OTG_BLACK_COLOR, 0,
  368. OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
  369. OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
  370. OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
  371. }
  372. bool optc1_validate_timing(
  373. struct timing_generator *optc,
  374. const struct dc_crtc_timing *timing)
  375. {
  376. uint32_t interlace_factor;
  377. uint32_t v_blank;
  378. uint32_t h_blank;
  379. uint32_t min_v_blank;
  380. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  381. ASSERT(timing != NULL);
  382. interlace_factor = timing->flags.INTERLACE ? 2 : 1;
  383. v_blank = (timing->v_total - timing->v_addressable -
  384. timing->v_border_top - timing->v_border_bottom) *
  385. interlace_factor;
  386. h_blank = (timing->h_total - timing->h_addressable -
  387. timing->h_border_right -
  388. timing->h_border_left);
  389. if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
  390. timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
  391. timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
  392. timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
  393. timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
  394. timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
  395. return false;
  396. /* Temporarily blocking interlacing mode until it's supported */
  397. if (timing->flags.INTERLACE == 1)
  398. return false;
  399. /* Check maximum number of pixels supported by Timing Generator
  400. * (Currently will never fail, in order to fail needs display which
  401. * needs more than 8192 horizontal and
  402. * more than 8192 vertical total pixels)
  403. */
  404. if (timing->h_total > optc1->max_h_total ||
  405. timing->v_total > optc1->max_v_total)
  406. return false;
  407. if (h_blank < optc1->min_h_blank)
  408. return false;
  409. if (timing->h_sync_width < optc1->min_h_sync_width ||
  410. timing->v_sync_width < optc1->min_v_sync_width)
  411. return false;
  412. min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank;
  413. if (v_blank < min_v_blank)
  414. return false;
  415. return true;
  416. }
  417. /*
  418. * get_vblank_counter
  419. *
  420. * @brief
  421. * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
  422. * holds the counter of frames.
  423. *
  424. * @param
  425. * struct timing_generator *optc - [in] timing generator which controls the
  426. * desired CRTC
  427. *
  428. * @return
  429. * Counter of frames, which should equal to number of vblanks.
  430. */
  431. uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
  432. {
  433. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  434. uint32_t frame_count;
  435. REG_GET(OTG_STATUS_FRAME_COUNT,
  436. OTG_FRAME_COUNT, &frame_count);
  437. return frame_count;
  438. }
  439. void optc1_lock(struct timing_generator *optc)
  440. {
  441. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  442. REG_SET(OTG_GLOBAL_CONTROL0, 0,
  443. OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
  444. REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
  445. OTG_MASTER_UPDATE_LOCK, 1);
  446. /* Should be fast, status does not update on maximus */
  447. if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
  448. REG_WAIT(OTG_MASTER_UPDATE_LOCK,
  449. UPDATE_LOCK_STATUS, 1,
  450. 1, 10);
  451. }
  452. void optc1_unlock(struct timing_generator *optc)
  453. {
  454. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  455. REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
  456. OTG_MASTER_UPDATE_LOCK, 0);
  457. }
  458. void optc1_get_position(struct timing_generator *optc,
  459. struct crtc_position *position)
  460. {
  461. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  462. REG_GET_2(OTG_STATUS_POSITION,
  463. OTG_HORZ_COUNT, &position->horizontal_count,
  464. OTG_VERT_COUNT, &position->vertical_count);
  465. REG_GET(OTG_NOM_VERT_POSITION,
  466. OTG_VERT_COUNT_NOM, &position->nominal_vcount);
  467. }
  468. bool optc1_is_counter_moving(struct timing_generator *optc)
  469. {
  470. struct crtc_position position1, position2;
  471. optc->funcs->get_position(optc, &position1);
  472. optc->funcs->get_position(optc, &position2);
  473. if (position1.horizontal_count == position2.horizontal_count &&
  474. position1.vertical_count == position2.vertical_count)
  475. return false;
  476. else
  477. return true;
  478. }
  479. bool optc1_did_triggered_reset_occur(
  480. struct timing_generator *optc)
  481. {
  482. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  483. uint32_t occurred_force, occurred_vsync;
  484. REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
  485. OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
  486. REG_GET(OTG_VERT_SYNC_CONTROL,
  487. OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
  488. return occurred_vsync != 0 || occurred_force != 0;
  489. }
  490. void optc1_disable_reset_trigger(struct timing_generator *optc)
  491. {
  492. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  493. REG_WRITE(OTG_TRIGA_CNTL, 0);
  494. REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
  495. OTG_FORCE_COUNT_NOW_CLEAR, 1);
  496. REG_SET(OTG_VERT_SYNC_CONTROL, 0,
  497. OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
  498. }
  499. void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst)
  500. {
  501. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  502. uint32_t falling_edge;
  503. REG_GET(OTG_V_SYNC_A_CNTL,
  504. OTG_V_SYNC_A_POL, &falling_edge);
  505. if (falling_edge)
  506. REG_SET_3(OTG_TRIGA_CNTL, 0,
  507. /* vsync signal from selected OTG pipe based
  508. * on OTG_TRIG_SOURCE_PIPE_SELECT setting
  509. */
  510. OTG_TRIGA_SOURCE_SELECT, 20,
  511. OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
  512. /* always detect falling edge */
  513. OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
  514. else
  515. REG_SET_3(OTG_TRIGA_CNTL, 0,
  516. /* vsync signal from selected OTG pipe based
  517. * on OTG_TRIG_SOURCE_PIPE_SELECT setting
  518. */
  519. OTG_TRIGA_SOURCE_SELECT, 20,
  520. OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
  521. /* always detect rising edge */
  522. OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
  523. REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
  524. /* force H count to H_TOTAL and V count to V_TOTAL in
  525. * progressive mode and V_TOTAL-1 in interlaced mode
  526. */
  527. OTG_FORCE_COUNT_NOW_MODE, 2);
  528. }
  529. void optc1_enable_crtc_reset(
  530. struct timing_generator *optc,
  531. int source_tg_inst,
  532. struct crtc_trigger_info *crtc_tp)
  533. {
  534. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  535. uint32_t falling_edge = 0;
  536. uint32_t rising_edge = 0;
  537. switch (crtc_tp->event) {
  538. case CRTC_EVENT_VSYNC_RISING:
  539. rising_edge = 1;
  540. break;
  541. case CRTC_EVENT_VSYNC_FALLING:
  542. falling_edge = 1;
  543. break;
  544. }
  545. REG_SET_4(OTG_TRIGA_CNTL, 0,
  546. /* vsync signal from selected OTG pipe based
  547. * on OTG_TRIG_SOURCE_PIPE_SELECT setting
  548. */
  549. OTG_TRIGA_SOURCE_SELECT, 20,
  550. OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
  551. /* always detect falling edge */
  552. OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge,
  553. OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge);
  554. switch (crtc_tp->delay) {
  555. case TRIGGER_DELAY_NEXT_LINE:
  556. REG_SET(OTG_VERT_SYNC_CONTROL, 0,
  557. OTG_AUTO_FORCE_VSYNC_MODE, 1);
  558. break;
  559. case TRIGGER_DELAY_NEXT_PIXEL:
  560. REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
  561. /* force H count to H_TOTAL and V count to V_TOTAL in
  562. * progressive mode and V_TOTAL-1 in interlaced mode
  563. */
  564. OTG_FORCE_COUNT_NOW_MODE, 2);
  565. break;
  566. }
  567. }
  568. void optc1_wait_for_state(struct timing_generator *optc,
  569. enum crtc_state state)
  570. {
  571. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  572. switch (state) {
  573. case CRTC_STATE_VBLANK:
  574. REG_WAIT(OTG_STATUS,
  575. OTG_V_BLANK, 1,
  576. 1, 100000); /* 1 vupdate at 10hz */
  577. break;
  578. case CRTC_STATE_VACTIVE:
  579. REG_WAIT(OTG_STATUS,
  580. OTG_V_ACTIVE_DISP, 1,
  581. 1, 100000); /* 1 vupdate at 10hz */
  582. break;
  583. default:
  584. break;
  585. }
  586. }
  587. void optc1_set_early_control(
  588. struct timing_generator *optc,
  589. uint32_t early_cntl)
  590. {
  591. /* asic design change, do not need this control
  592. * empty for share caller logic
  593. */
  594. }
  595. void optc1_set_static_screen_control(
  596. struct timing_generator *optc,
  597. uint32_t value)
  598. {
  599. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  600. /* Bit 8 is no longer applicable in RV for PSR case,
  601. * set bit 8 to 0 if given
  602. */
  603. if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
  604. != 0)
  605. value = value &
  606. ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
  607. REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
  608. OTG_STATIC_SCREEN_EVENT_MASK, value,
  609. OTG_STATIC_SCREEN_FRAME_COUNT, 2);
  610. }
  611. /**
  612. *****************************************************************************
  613. * Function: set_drr
  614. *
  615. * @brief
  616. * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
  617. *
  618. *****************************************************************************
  619. */
  620. void optc1_set_drr(
  621. struct timing_generator *optc,
  622. const struct drr_params *params)
  623. {
  624. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  625. if (params != NULL &&
  626. params->vertical_total_max > 0 &&
  627. params->vertical_total_min > 0) {
  628. REG_SET(OTG_V_TOTAL_MAX, 0,
  629. OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
  630. REG_SET(OTG_V_TOTAL_MIN, 0,
  631. OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
  632. REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
  633. OTG_V_TOTAL_MIN_SEL, 1,
  634. OTG_V_TOTAL_MAX_SEL, 1,
  635. OTG_FORCE_LOCK_ON_EVENT, 0,
  636. OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
  637. OTG_SET_V_TOTAL_MIN_MASK, 0);
  638. } else {
  639. REG_SET(OTG_V_TOTAL_MIN, 0,
  640. OTG_V_TOTAL_MIN, 0);
  641. REG_SET(OTG_V_TOTAL_MAX, 0,
  642. OTG_V_TOTAL_MAX, 0);
  643. REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
  644. OTG_SET_V_TOTAL_MIN_MASK, 0,
  645. OTG_V_TOTAL_MIN_SEL, 0,
  646. OTG_V_TOTAL_MAX_SEL, 0,
  647. OTG_FORCE_LOCK_ON_EVENT, 0);
  648. }
  649. }
  650. static void optc1_set_test_pattern(
  651. struct timing_generator *optc,
  652. /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
  653. * because this is not DP-specific (which is probably somewhere in DP
  654. * encoder) */
  655. enum controller_dp_test_pattern test_pattern,
  656. enum dc_color_depth color_depth)
  657. {
  658. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  659. enum test_pattern_color_format bit_depth;
  660. enum test_pattern_dyn_range dyn_range;
  661. enum test_pattern_mode mode;
  662. uint32_t pattern_mask;
  663. uint32_t pattern_data;
  664. /* color ramp generator mixes 16-bits color */
  665. uint32_t src_bpc = 16;
  666. /* requested bpc */
  667. uint32_t dst_bpc;
  668. uint32_t index;
  669. /* RGB values of the color bars.
  670. * Produce two RGB colors: RGB0 - white (all Fs)
  671. * and RGB1 - black (all 0s)
  672. * (three RGB components for two colors)
  673. */
  674. uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
  675. 0x0000, 0x0000};
  676. /* dest color (converted to the specified color format) */
  677. uint16_t dst_color[6];
  678. uint32_t inc_base;
  679. /* translate to bit depth */
  680. switch (color_depth) {
  681. case COLOR_DEPTH_666:
  682. bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
  683. break;
  684. case COLOR_DEPTH_888:
  685. bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  686. break;
  687. case COLOR_DEPTH_101010:
  688. bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
  689. break;
  690. case COLOR_DEPTH_121212:
  691. bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
  692. break;
  693. default:
  694. bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  695. break;
  696. }
  697. switch (test_pattern) {
  698. case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
  699. case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
  700. {
  701. dyn_range = (test_pattern ==
  702. CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
  703. TEST_PATTERN_DYN_RANGE_CEA :
  704. TEST_PATTERN_DYN_RANGE_VESA);
  705. mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
  706. REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
  707. OTG_TEST_PATTERN_VRES, 6,
  708. OTG_TEST_PATTERN_HRES, 6);
  709. REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
  710. OTG_TEST_PATTERN_EN, 1,
  711. OTG_TEST_PATTERN_MODE, mode,
  712. OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
  713. OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
  714. }
  715. break;
  716. case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
  717. case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
  718. {
  719. mode = (test_pattern ==
  720. CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
  721. TEST_PATTERN_MODE_VERTICALBARS :
  722. TEST_PATTERN_MODE_HORIZONTALBARS);
  723. switch (bit_depth) {
  724. case TEST_PATTERN_COLOR_FORMAT_BPC_6:
  725. dst_bpc = 6;
  726. break;
  727. case TEST_PATTERN_COLOR_FORMAT_BPC_8:
  728. dst_bpc = 8;
  729. break;
  730. case TEST_PATTERN_COLOR_FORMAT_BPC_10:
  731. dst_bpc = 10;
  732. break;
  733. default:
  734. dst_bpc = 8;
  735. break;
  736. }
  737. /* adjust color to the required colorFormat */
  738. for (index = 0; index < 6; index++) {
  739. /* dst = 2^dstBpc * src / 2^srcBpc = src >>
  740. * (srcBpc - dstBpc);
  741. */
  742. dst_color[index] =
  743. src_color[index] >> (src_bpc - dst_bpc);
  744. /* CRTC_TEST_PATTERN_DATA has 16 bits,
  745. * lowest 6 are hardwired to ZERO
  746. * color bits should be left aligned aligned to MSB
  747. * XXXXXXXXXX000000 for 10 bit,
  748. * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
  749. */
  750. dst_color[index] <<= (16 - dst_bpc);
  751. }
  752. REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
  753. /* We have to write the mask before data, similar to pipeline.
  754. * For example, for 8 bpc, if we want RGB0 to be magenta,
  755. * and RGB1 to be cyan,
  756. * we need to make 7 writes:
  757. * MASK DATA
  758. * 000001 00000000 00000000 set mask to R0
  759. * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0
  760. * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0
  761. * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1
  762. * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1
  763. * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1
  764. * 100000 11111111 00000000 B1 255, 0xFF00
  765. *
  766. * we will make a loop of 6 in which we prepare the mask,
  767. * then write, then prepare the color for next write.
  768. * first iteration will write mask only,
  769. * but each next iteration color prepared in
  770. * previous iteration will be written within new mask,
  771. * the last component will written separately,
  772. * mask is not changing between 6th and 7th write
  773. * and color will be prepared by last iteration
  774. */
  775. /* write color, color values mask in CRTC_TEST_PATTERN_MASK
  776. * is B1, G1, R1, B0, G0, R0
  777. */
  778. pattern_data = 0;
  779. for (index = 0; index < 6; index++) {
  780. /* prepare color mask, first write PATTERN_DATA
  781. * will have all zeros
  782. */
  783. pattern_mask = (1 << index);
  784. /* write color component */
  785. REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
  786. OTG_TEST_PATTERN_MASK, pattern_mask,
  787. OTG_TEST_PATTERN_DATA, pattern_data);
  788. /* prepare next color component,
  789. * will be written in the next iteration
  790. */
  791. pattern_data = dst_color[index];
  792. }
  793. /* write last color component,
  794. * it's been already prepared in the loop
  795. */
  796. REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
  797. OTG_TEST_PATTERN_MASK, pattern_mask,
  798. OTG_TEST_PATTERN_DATA, pattern_data);
  799. /* enable test pattern */
  800. REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
  801. OTG_TEST_PATTERN_EN, 1,
  802. OTG_TEST_PATTERN_MODE, mode,
  803. OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
  804. OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
  805. }
  806. break;
  807. case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
  808. {
  809. mode = (bit_depth ==
  810. TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
  811. TEST_PATTERN_MODE_DUALRAMP_RGB :
  812. TEST_PATTERN_MODE_SINGLERAMP_RGB);
  813. switch (bit_depth) {
  814. case TEST_PATTERN_COLOR_FORMAT_BPC_6:
  815. dst_bpc = 6;
  816. break;
  817. case TEST_PATTERN_COLOR_FORMAT_BPC_8:
  818. dst_bpc = 8;
  819. break;
  820. case TEST_PATTERN_COLOR_FORMAT_BPC_10:
  821. dst_bpc = 10;
  822. break;
  823. default:
  824. dst_bpc = 8;
  825. break;
  826. }
  827. /* increment for the first ramp for one color gradation
  828. * 1 gradation for 6-bit color is 2^10
  829. * gradations in 16-bit color
  830. */
  831. inc_base = (src_bpc - dst_bpc);
  832. switch (bit_depth) {
  833. case TEST_PATTERN_COLOR_FORMAT_BPC_6:
  834. {
  835. REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
  836. OTG_TEST_PATTERN_INC0, inc_base,
  837. OTG_TEST_PATTERN_INC1, 0,
  838. OTG_TEST_PATTERN_HRES, 6,
  839. OTG_TEST_PATTERN_VRES, 6,
  840. OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
  841. }
  842. break;
  843. case TEST_PATTERN_COLOR_FORMAT_BPC_8:
  844. {
  845. REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
  846. OTG_TEST_PATTERN_INC0, inc_base,
  847. OTG_TEST_PATTERN_INC1, 0,
  848. OTG_TEST_PATTERN_HRES, 8,
  849. OTG_TEST_PATTERN_VRES, 6,
  850. OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
  851. }
  852. break;
  853. case TEST_PATTERN_COLOR_FORMAT_BPC_10:
  854. {
  855. REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
  856. OTG_TEST_PATTERN_INC0, inc_base,
  857. OTG_TEST_PATTERN_INC1, inc_base + 2,
  858. OTG_TEST_PATTERN_HRES, 8,
  859. OTG_TEST_PATTERN_VRES, 5,
  860. OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
  861. }
  862. break;
  863. default:
  864. break;
  865. }
  866. REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
  867. /* enable test pattern */
  868. REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
  869. REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
  870. OTG_TEST_PATTERN_EN, 1,
  871. OTG_TEST_PATTERN_MODE, mode,
  872. OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
  873. OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
  874. }
  875. break;
  876. case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
  877. {
  878. REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
  879. REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
  880. REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
  881. }
  882. break;
  883. default:
  884. break;
  885. }
  886. }
  887. void optc1_get_crtc_scanoutpos(
  888. struct timing_generator *optc,
  889. uint32_t *v_blank_start,
  890. uint32_t *v_blank_end,
  891. uint32_t *h_position,
  892. uint32_t *v_position)
  893. {
  894. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  895. struct crtc_position position;
  896. REG_GET_2(OTG_V_BLANK_START_END,
  897. OTG_V_BLANK_START, v_blank_start,
  898. OTG_V_BLANK_END, v_blank_end);
  899. optc1_get_position(optc, &position);
  900. *h_position = position.horizontal_count;
  901. *v_position = position.vertical_count;
  902. }
  903. static void optc1_enable_stereo(struct timing_generator *optc,
  904. const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
  905. {
  906. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  907. if (flags) {
  908. uint32_t stereo_en;
  909. stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
  910. if (flags->PROGRAM_STEREO)
  911. REG_UPDATE_3(OTG_STEREO_CONTROL,
  912. OTG_STEREO_EN, stereo_en,
  913. OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
  914. OTG_STEREO_SYNC_OUTPUT_POLARITY, 0);
  915. if (flags->PROGRAM_POLARITY)
  916. REG_UPDATE(OTG_STEREO_CONTROL,
  917. OTG_STEREO_EYE_FLAG_POLARITY,
  918. flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
  919. if (flags->DISABLE_STEREO_DP_SYNC)
  920. REG_UPDATE(OTG_STEREO_CONTROL,
  921. OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
  922. if (flags->PROGRAM_STEREO)
  923. REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL,
  924. OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
  925. OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED,
  926. OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
  927. }
  928. }
  929. void optc1_program_stereo(struct timing_generator *optc,
  930. const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
  931. {
  932. if (flags->PROGRAM_STEREO)
  933. optc1_enable_stereo(optc, timing, flags);
  934. else
  935. optc1_disable_stereo(optc);
  936. }
  937. bool optc1_is_stereo_left_eye(struct timing_generator *optc)
  938. {
  939. bool ret = false;
  940. uint32_t left_eye = 0;
  941. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  942. REG_GET(OTG_STEREO_STATUS,
  943. OTG_STEREO_CURRENT_EYE, &left_eye);
  944. if (left_eye == 1)
  945. ret = true;
  946. else
  947. ret = false;
  948. return ret;
  949. }
  950. void optc1_read_otg_state(struct optc *optc1,
  951. struct dcn_otg_state *s)
  952. {
  953. REG_GET(OTG_CONTROL,
  954. OTG_MASTER_EN, &s->otg_enabled);
  955. REG_GET_2(OTG_V_BLANK_START_END,
  956. OTG_V_BLANK_START, &s->v_blank_start,
  957. OTG_V_BLANK_END, &s->v_blank_end);
  958. REG_GET(OTG_V_SYNC_A_CNTL,
  959. OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
  960. REG_GET(OTG_V_TOTAL,
  961. OTG_V_TOTAL, &s->v_total);
  962. REG_GET(OTG_V_TOTAL_MAX,
  963. OTG_V_TOTAL_MAX, &s->v_total_max);
  964. REG_GET(OTG_V_TOTAL_MIN,
  965. OTG_V_TOTAL_MIN, &s->v_total_min);
  966. REG_GET_2(OTG_V_SYNC_A,
  967. OTG_V_SYNC_A_START, &s->v_sync_a_start,
  968. OTG_V_SYNC_A_END, &s->v_sync_a_end);
  969. REG_GET_2(OTG_H_BLANK_START_END,
  970. OTG_H_BLANK_START, &s->h_blank_start,
  971. OTG_H_BLANK_END, &s->h_blank_end);
  972. REG_GET_2(OTG_H_SYNC_A,
  973. OTG_H_SYNC_A_START, &s->h_sync_a_start,
  974. OTG_H_SYNC_A_END, &s->h_sync_a_end);
  975. REG_GET(OTG_H_SYNC_A_CNTL,
  976. OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
  977. REG_GET(OTG_H_TOTAL,
  978. OTG_H_TOTAL, &s->h_total);
  979. REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
  980. OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
  981. }
  982. static void optc1_clear_optc_underflow(struct timing_generator *optc)
  983. {
  984. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  985. REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
  986. }
  987. static void optc1_tg_init(struct timing_generator *optc)
  988. {
  989. optc1_set_blank_data_double_buffer(optc, true);
  990. optc1_clear_optc_underflow(optc);
  991. }
  992. static bool optc1_is_tg_enabled(struct timing_generator *optc)
  993. {
  994. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  995. uint32_t otg_enabled = 0;
  996. REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
  997. return (otg_enabled != 0);
  998. }
  999. static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
  1000. {
  1001. struct optc *optc1 = DCN10TG_FROM_TG(optc);
  1002. uint32_t underflow_occurred = 0;
  1003. REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
  1004. OPTC_UNDERFLOW_OCCURRED_STATUS,
  1005. &underflow_occurred);
  1006. return (underflow_occurred == 1);
  1007. }
  1008. static const struct timing_generator_funcs dcn10_tg_funcs = {
  1009. .validate_timing = optc1_validate_timing,
  1010. .program_timing = optc1_program_timing,
  1011. .program_global_sync = optc1_program_global_sync,
  1012. .enable_crtc = optc1_enable_crtc,
  1013. .disable_crtc = optc1_disable_crtc,
  1014. /* used by enable_timing_synchronization. Not need for FPGA */
  1015. .is_counter_moving = optc1_is_counter_moving,
  1016. .get_position = optc1_get_position,
  1017. .get_frame_count = optc1_get_vblank_counter,
  1018. .get_scanoutpos = optc1_get_crtc_scanoutpos,
  1019. .set_early_control = optc1_set_early_control,
  1020. /* used by enable_timing_synchronization. Not need for FPGA */
  1021. .wait_for_state = optc1_wait_for_state,
  1022. .set_blank = optc1_set_blank,
  1023. .is_blanked = optc1_is_blanked,
  1024. .set_blank_color = optc1_program_blank_color,
  1025. .did_triggered_reset_occur = optc1_did_triggered_reset_occur,
  1026. .enable_reset_trigger = optc1_enable_reset_trigger,
  1027. .enable_crtc_reset = optc1_enable_crtc_reset,
  1028. .disable_reset_trigger = optc1_disable_reset_trigger,
  1029. .lock = optc1_lock,
  1030. .unlock = optc1_unlock,
  1031. .enable_optc_clock = optc1_enable_optc_clock,
  1032. .set_drr = optc1_set_drr,
  1033. .set_static_screen_control = optc1_set_static_screen_control,
  1034. .set_test_pattern = optc1_set_test_pattern,
  1035. .program_stereo = optc1_program_stereo,
  1036. .is_stereo_left_eye = optc1_is_stereo_left_eye,
  1037. .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer,
  1038. .tg_init = optc1_tg_init,
  1039. .is_tg_enabled = optc1_is_tg_enabled,
  1040. .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
  1041. .clear_optc_underflow = optc1_clear_optc_underflow,
  1042. };
  1043. void dcn10_timing_generator_init(struct optc *optc1)
  1044. {
  1045. optc1->base.funcs = &dcn10_tg_funcs;
  1046. optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
  1047. optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
  1048. optc1->min_h_blank = 32;
  1049. optc1->min_v_blank = 3;
  1050. optc1->min_v_blank_interlace = 5;
  1051. optc1->min_h_sync_width = 8;
  1052. optc1->min_v_sync_width = 1;
  1053. }