dcn10_hubp.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  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 "dce_calcs.h"
  27. #include "reg_helper.h"
  28. #include "basics/conversion.h"
  29. #include "dcn10_hubp.h"
  30. #define REG(reg)\
  31. hubp1->hubp_regs->reg
  32. #define CTX \
  33. hubp1->base.ctx
  34. #undef FN
  35. #define FN(reg_name, field_name) \
  36. hubp1->hubp_shift->field_name, hubp1->hubp_mask->field_name
  37. void hubp1_set_blank(struct hubp *hubp, bool blank)
  38. {
  39. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  40. uint32_t blank_en = blank ? 1 : 0;
  41. REG_UPDATE_2(DCHUBP_CNTL,
  42. HUBP_BLANK_EN, blank_en,
  43. HUBP_TTU_DISABLE, blank_en);
  44. if (blank) {
  45. uint32_t reg_val = REG_READ(DCHUBP_CNTL);
  46. if (reg_val) {
  47. /* init sequence workaround: in case HUBP is
  48. * power gated, this wait would timeout.
  49. *
  50. * we just wrote reg_val to non-0, if it stay 0
  51. * it means HUBP is gated
  52. */
  53. REG_WAIT(DCHUBP_CNTL,
  54. HUBP_NO_OUTSTANDING_REQ, 1,
  55. 1, 200);
  56. }
  57. hubp->mpcc_id = 0xf;
  58. hubp->opp_id = 0xf;
  59. }
  60. }
  61. static void hubp1_disconnect(struct hubp *hubp)
  62. {
  63. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  64. REG_UPDATE(DCHUBP_CNTL,
  65. HUBP_TTU_DISABLE, 1);
  66. REG_UPDATE(CURSOR_CONTROL,
  67. CURSOR_ENABLE, 0);
  68. }
  69. static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
  70. {
  71. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  72. uint32_t blank_en = blank ? 1 : 0;
  73. REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
  74. }
  75. static void hubp1_vready_workaround(struct hubp *hubp,
  76. struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
  77. {
  78. uint32_t value = 0;
  79. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  80. /* set HBUBREQ_DEBUG_DB[12] = 1 */
  81. value = REG_READ(HUBPREQ_DEBUG_DB);
  82. /* hack mode disable */
  83. value |= 0x100;
  84. value &= ~0x1000;
  85. if ((pipe_dest->vstartup_start - 2*(pipe_dest->vready_offset+pipe_dest->vupdate_width
  86. + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) {
  87. /* if (eco_fix_needed(otg_global_sync_timing)
  88. * set HBUBREQ_DEBUG_DB[12] = 1 */
  89. value |= 0x1000;
  90. }
  91. REG_WRITE(HUBPREQ_DEBUG_DB, value);
  92. }
  93. void hubp1_program_tiling(
  94. struct hubp *hubp,
  95. const union dc_tiling_info *info,
  96. const enum surface_pixel_format pixel_format)
  97. {
  98. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  99. REG_UPDATE_6(DCSURF_ADDR_CONFIG,
  100. NUM_PIPES, log_2(info->gfx9.num_pipes),
  101. NUM_BANKS, log_2(info->gfx9.num_banks),
  102. PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
  103. NUM_SE, log_2(info->gfx9.num_shader_engines),
  104. NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se),
  105. MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags));
  106. REG_UPDATE_4(DCSURF_TILING_CONFIG,
  107. SW_MODE, info->gfx9.swizzle,
  108. META_LINEAR, info->gfx9.meta_linear,
  109. RB_ALIGNED, info->gfx9.rb_aligned,
  110. PIPE_ALIGNED, info->gfx9.pipe_aligned);
  111. }
  112. void hubp1_program_size_and_rotation(
  113. struct hubp *hubp,
  114. enum dc_rotation_angle rotation,
  115. enum surface_pixel_format format,
  116. const union plane_size *plane_size,
  117. struct dc_plane_dcc_param *dcc,
  118. bool horizontal_mirror)
  119. {
  120. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  121. uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror;
  122. /* Program data and meta surface pitch (calculation from addrlib)
  123. * 444 or 420 luma
  124. */
  125. if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
  126. pitch = plane_size->video.luma_pitch - 1;
  127. meta_pitch = dcc->video.meta_pitch_l - 1;
  128. pitch_c = plane_size->video.chroma_pitch - 1;
  129. meta_pitch_c = dcc->video.meta_pitch_c - 1;
  130. } else {
  131. pitch = plane_size->grph.surface_pitch - 1;
  132. meta_pitch = dcc->grph.meta_pitch - 1;
  133. pitch_c = 0;
  134. meta_pitch_c = 0;
  135. }
  136. if (!dcc->enable) {
  137. meta_pitch = 0;
  138. meta_pitch_c = 0;
  139. }
  140. REG_UPDATE_2(DCSURF_SURFACE_PITCH,
  141. PITCH, pitch, META_PITCH, meta_pitch);
  142. if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
  143. REG_UPDATE_2(DCSURF_SURFACE_PITCH_C,
  144. PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c);
  145. if (horizontal_mirror)
  146. mirror = 1;
  147. else
  148. mirror = 0;
  149. /* Program rotation angle and horz mirror - no mirror */
  150. if (rotation == ROTATION_ANGLE_0)
  151. REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
  152. ROTATION_ANGLE, 0,
  153. H_MIRROR_EN, mirror);
  154. else if (rotation == ROTATION_ANGLE_90)
  155. REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
  156. ROTATION_ANGLE, 1,
  157. H_MIRROR_EN, mirror);
  158. else if (rotation == ROTATION_ANGLE_180)
  159. REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
  160. ROTATION_ANGLE, 2,
  161. H_MIRROR_EN, mirror);
  162. else if (rotation == ROTATION_ANGLE_270)
  163. REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
  164. ROTATION_ANGLE, 3,
  165. H_MIRROR_EN, mirror);
  166. }
  167. void hubp1_program_pixel_format(
  168. struct hubp *hubp,
  169. enum surface_pixel_format format)
  170. {
  171. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  172. uint32_t red_bar = 3;
  173. uint32_t blue_bar = 2;
  174. /* swap for ABGR format */
  175. if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
  176. || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
  177. || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
  178. || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
  179. red_bar = 2;
  180. blue_bar = 3;
  181. }
  182. REG_UPDATE_2(HUBPRET_CONTROL,
  183. CROSSBAR_SRC_CB_B, blue_bar,
  184. CROSSBAR_SRC_CR_R, red_bar);
  185. /* Mapping is same as ipp programming (cnvc) */
  186. switch (format) {
  187. case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
  188. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  189. SURFACE_PIXEL_FORMAT, 1);
  190. break;
  191. case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
  192. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  193. SURFACE_PIXEL_FORMAT, 3);
  194. break;
  195. case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
  196. case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
  197. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  198. SURFACE_PIXEL_FORMAT, 8);
  199. break;
  200. case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
  201. case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
  202. case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
  203. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  204. SURFACE_PIXEL_FORMAT, 10);
  205. break;
  206. case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
  207. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  208. SURFACE_PIXEL_FORMAT, 22);
  209. break;
  210. case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
  211. case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
  212. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  213. SURFACE_PIXEL_FORMAT, 24);
  214. break;
  215. case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
  216. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  217. SURFACE_PIXEL_FORMAT, 65);
  218. break;
  219. case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
  220. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  221. SURFACE_PIXEL_FORMAT, 64);
  222. break;
  223. case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
  224. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  225. SURFACE_PIXEL_FORMAT, 67);
  226. break;
  227. case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
  228. REG_UPDATE(DCSURF_SURFACE_CONFIG,
  229. SURFACE_PIXEL_FORMAT, 66);
  230. break;
  231. default:
  232. BREAK_TO_DEBUGGER();
  233. break;
  234. }
  235. /* don't see the need of program the xbar in DCN 1.0 */
  236. }
  237. bool hubp1_program_surface_flip_and_addr(
  238. struct hubp *hubp,
  239. const struct dc_plane_address *address,
  240. bool flip_immediate)
  241. {
  242. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  243. /* program flip type */
  244. REG_SET(DCSURF_FLIP_CONTROL, 0,
  245. SURFACE_FLIP_TYPE, flip_immediate);
  246. /* HW automatically latch rest of address register on write to
  247. * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
  248. *
  249. * program high first and then the low addr, order matters!
  250. */
  251. switch (address->type) {
  252. case PLN_ADDR_TYPE_GRAPHICS:
  253. /* DCN1.0 does not support const color
  254. * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1
  255. * base on address->grph.dcc_const_color
  256. * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma
  257. * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma
  258. */
  259. if (address->grph.addr.quad_part == 0)
  260. break;
  261. REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
  262. PRIMARY_SURFACE_TMZ, address->tmz_surface,
  263. PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
  264. if (address->grph.meta_addr.quad_part != 0) {
  265. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
  266. PRIMARY_META_SURFACE_ADDRESS_HIGH,
  267. address->grph.meta_addr.high_part);
  268. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
  269. PRIMARY_META_SURFACE_ADDRESS,
  270. address->grph.meta_addr.low_part);
  271. }
  272. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
  273. PRIMARY_SURFACE_ADDRESS_HIGH,
  274. address->grph.addr.high_part);
  275. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
  276. PRIMARY_SURFACE_ADDRESS,
  277. address->grph.addr.low_part);
  278. break;
  279. case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
  280. if (address->video_progressive.luma_addr.quad_part == 0
  281. || address->video_progressive.chroma_addr.quad_part == 0)
  282. break;
  283. REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
  284. PRIMARY_SURFACE_TMZ, address->tmz_surface,
  285. PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
  286. PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
  287. PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
  288. if (address->video_progressive.luma_meta_addr.quad_part != 0) {
  289. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
  290. PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
  291. address->video_progressive.chroma_meta_addr.high_part);
  292. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
  293. PRIMARY_META_SURFACE_ADDRESS_C,
  294. address->video_progressive.chroma_meta_addr.low_part);
  295. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
  296. PRIMARY_META_SURFACE_ADDRESS_HIGH,
  297. address->video_progressive.luma_meta_addr.high_part);
  298. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
  299. PRIMARY_META_SURFACE_ADDRESS,
  300. address->video_progressive.luma_meta_addr.low_part);
  301. }
  302. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
  303. PRIMARY_SURFACE_ADDRESS_HIGH_C,
  304. address->video_progressive.chroma_addr.high_part);
  305. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
  306. PRIMARY_SURFACE_ADDRESS_C,
  307. address->video_progressive.chroma_addr.low_part);
  308. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
  309. PRIMARY_SURFACE_ADDRESS_HIGH,
  310. address->video_progressive.luma_addr.high_part);
  311. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
  312. PRIMARY_SURFACE_ADDRESS,
  313. address->video_progressive.luma_addr.low_part);
  314. break;
  315. case PLN_ADDR_TYPE_GRPH_STEREO:
  316. if (address->grph_stereo.left_addr.quad_part == 0)
  317. break;
  318. if (address->grph_stereo.right_addr.quad_part == 0)
  319. break;
  320. REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
  321. PRIMARY_SURFACE_TMZ, address->tmz_surface,
  322. PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
  323. PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
  324. PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
  325. if (address->grph_stereo.right_meta_addr.quad_part != 0) {
  326. REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
  327. SECONDARY_META_SURFACE_ADDRESS_HIGH,
  328. address->grph_stereo.right_meta_addr.high_part);
  329. REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
  330. SECONDARY_META_SURFACE_ADDRESS,
  331. address->grph_stereo.right_meta_addr.low_part);
  332. }
  333. if (address->grph_stereo.left_meta_addr.quad_part != 0) {
  334. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
  335. PRIMARY_META_SURFACE_ADDRESS_HIGH,
  336. address->grph_stereo.left_meta_addr.high_part);
  337. REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
  338. PRIMARY_META_SURFACE_ADDRESS,
  339. address->grph_stereo.left_meta_addr.low_part);
  340. }
  341. REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
  342. SECONDARY_SURFACE_ADDRESS_HIGH,
  343. address->grph_stereo.right_addr.high_part);
  344. REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
  345. SECONDARY_SURFACE_ADDRESS,
  346. address->grph_stereo.right_addr.low_part);
  347. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
  348. PRIMARY_SURFACE_ADDRESS_HIGH,
  349. address->grph_stereo.left_addr.high_part);
  350. REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
  351. PRIMARY_SURFACE_ADDRESS,
  352. address->grph_stereo.left_addr.low_part);
  353. break;
  354. default:
  355. BREAK_TO_DEBUGGER();
  356. break;
  357. }
  358. hubp->request_address = *address;
  359. if (flip_immediate)
  360. hubp->current_address = *address;
  361. return true;
  362. }
  363. void hubp1_dcc_control(struct hubp *hubp, bool enable,
  364. bool independent_64b_blks)
  365. {
  366. uint32_t dcc_en = enable ? 1 : 0;
  367. uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
  368. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  369. REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
  370. PRIMARY_SURFACE_DCC_EN, dcc_en,
  371. PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
  372. }
  373. void hubp1_program_surface_config(
  374. struct hubp *hubp,
  375. enum surface_pixel_format format,
  376. union dc_tiling_info *tiling_info,
  377. union plane_size *plane_size,
  378. enum dc_rotation_angle rotation,
  379. struct dc_plane_dcc_param *dcc,
  380. bool horizontal_mirror)
  381. {
  382. hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
  383. hubp1_program_tiling(hubp, tiling_info, format);
  384. hubp1_program_size_and_rotation(
  385. hubp, rotation, format, plane_size, dcc, horizontal_mirror);
  386. hubp1_program_pixel_format(hubp, format);
  387. }
  388. void hubp1_program_requestor(
  389. struct hubp *hubp,
  390. struct _vcs_dpi_display_rq_regs_st *rq_regs)
  391. {
  392. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  393. REG_UPDATE(HUBPRET_CONTROL,
  394. DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
  395. REG_SET_4(DCN_EXPANSION_MODE, 0,
  396. DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
  397. PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
  398. MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
  399. CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
  400. REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
  401. CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
  402. MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
  403. META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
  404. MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
  405. DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
  406. MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
  407. SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
  408. PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
  409. REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0,
  410. CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
  411. MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
  412. META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
  413. MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
  414. DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
  415. MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size,
  416. SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
  417. PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
  418. }
  419. void hubp1_program_deadline(
  420. struct hubp *hubp,
  421. struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
  422. struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
  423. {
  424. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  425. /* DLG - Per hubp */
  426. REG_SET_2(BLANK_OFFSET_0, 0,
  427. REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
  428. DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
  429. REG_SET(BLANK_OFFSET_1, 0,
  430. MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
  431. REG_SET(DST_DIMENSIONS, 0,
  432. REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
  433. REG_SET_2(DST_AFTER_SCALER, 0,
  434. REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
  435. DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
  436. if (REG(PREFETCH_SETTINS))
  437. REG_SET_2(PREFETCH_SETTINS, 0,
  438. DST_Y_PREFETCH, dlg_attr->dst_y_prefetch,
  439. VRATIO_PREFETCH, dlg_attr->vratio_prefetch);
  440. else
  441. REG_SET_2(PREFETCH_SETTINGS, 0,
  442. DST_Y_PREFETCH, dlg_attr->dst_y_prefetch,
  443. VRATIO_PREFETCH, dlg_attr->vratio_prefetch);
  444. REG_SET_2(VBLANK_PARAMETERS_0, 0,
  445. DST_Y_PER_VM_VBLANK, dlg_attr->dst_y_per_vm_vblank,
  446. DST_Y_PER_ROW_VBLANK, dlg_attr->dst_y_per_row_vblank);
  447. REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
  448. REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
  449. /* DLG - Per luma/chroma */
  450. REG_SET(VBLANK_PARAMETERS_1, 0,
  451. REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
  452. REG_SET(VBLANK_PARAMETERS_3, 0,
  453. REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l);
  454. REG_SET(NOM_PARAMETERS_0, 0,
  455. DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
  456. REG_SET(NOM_PARAMETERS_1, 0,
  457. REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
  458. REG_SET(NOM_PARAMETERS_4, 0,
  459. DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
  460. REG_SET(NOM_PARAMETERS_5, 0,
  461. REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
  462. REG_SET_2(PER_LINE_DELIVERY_PRE, 0,
  463. REFCYC_PER_LINE_DELIVERY_PRE_L, dlg_attr->refcyc_per_line_delivery_pre_l,
  464. REFCYC_PER_LINE_DELIVERY_PRE_C, dlg_attr->refcyc_per_line_delivery_pre_c);
  465. REG_SET_2(PER_LINE_DELIVERY, 0,
  466. REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
  467. REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
  468. if (REG(PREFETCH_SETTINS_C))
  469. REG_SET(PREFETCH_SETTINS_C, 0,
  470. VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c);
  471. else
  472. REG_SET(PREFETCH_SETTINGS_C, 0,
  473. VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c);
  474. REG_SET(VBLANK_PARAMETERS_2, 0,
  475. REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
  476. REG_SET(VBLANK_PARAMETERS_4, 0,
  477. REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c);
  478. REG_SET(NOM_PARAMETERS_2, 0,
  479. DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
  480. REG_SET(NOM_PARAMETERS_3, 0,
  481. REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
  482. REG_SET(NOM_PARAMETERS_6, 0,
  483. DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
  484. REG_SET(NOM_PARAMETERS_7, 0,
  485. REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
  486. /* TTU - per hubp */
  487. REG_SET_2(DCN_TTU_QOS_WM, 0,
  488. QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
  489. QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
  490. REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0,
  491. MIN_TTU_VBLANK, ttu_attr->min_ttu_vblank,
  492. QoS_LEVEL_FLIP, ttu_attr->qos_level_flip);
  493. /* TTU - per luma/chroma */
  494. /* Assumed surf0 is luma and 1 is chroma */
  495. REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
  496. REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
  497. QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
  498. QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
  499. REG_SET(DCN_SURF0_TTU_CNTL1, 0,
  500. REFCYC_PER_REQ_DELIVERY_PRE,
  501. ttu_attr->refcyc_per_req_delivery_pre_l);
  502. REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
  503. REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
  504. QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
  505. QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
  506. REG_SET(DCN_SURF1_TTU_CNTL1, 0,
  507. REFCYC_PER_REQ_DELIVERY_PRE,
  508. ttu_attr->refcyc_per_req_delivery_pre_c);
  509. }
  510. static void hubp1_setup(
  511. struct hubp *hubp,
  512. struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
  513. struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
  514. struct _vcs_dpi_display_rq_regs_st *rq_regs,
  515. struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
  516. {
  517. /* otg is locked when this func is called. Register are double buffered.
  518. * disable the requestors is not needed
  519. */
  520. hubp1_program_requestor(hubp, rq_regs);
  521. hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
  522. hubp1_vready_workaround(hubp, pipe_dest);
  523. }
  524. bool hubp1_is_flip_pending(struct hubp *hubp)
  525. {
  526. uint32_t flip_pending = 0;
  527. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  528. struct dc_plane_address earliest_inuse_address;
  529. REG_GET(DCSURF_FLIP_CONTROL,
  530. SURFACE_FLIP_PENDING, &flip_pending);
  531. REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
  532. SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part);
  533. REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
  534. SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part);
  535. if (flip_pending)
  536. return true;
  537. if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
  538. return true;
  539. hubp->current_address = hubp->request_address;
  540. return false;
  541. }
  542. uint32_t aperture_default_system = 1;
  543. uint32_t context0_default_system; /* = 0;*/
  544. static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
  545. struct vm_system_aperture_param *apt)
  546. {
  547. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  548. PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
  549. PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
  550. PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
  551. mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12;
  552. mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 12;
  553. mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
  554. REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
  555. MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */
  556. MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
  557. REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
  558. MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
  559. REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0,
  560. MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mc_vm_apt_low.high_part);
  561. REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0,
  562. MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mc_vm_apt_low.low_part);
  563. REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0,
  564. MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mc_vm_apt_high.high_part);
  565. REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0,
  566. MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
  567. }
  568. static void hubp1_set_vm_context0_settings(struct hubp *hubp,
  569. const struct vm_context0_param *vm0)
  570. {
  571. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  572. /* pte base */
  573. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
  574. VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
  575. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, 0,
  576. VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, vm0->pte_base.low_part);
  577. /* pte start */
  578. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, 0,
  579. VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, vm0->pte_start.high_part);
  580. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, 0,
  581. VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, vm0->pte_start.low_part);
  582. /* pte end */
  583. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, 0,
  584. VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->pte_end.high_part);
  585. REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, 0,
  586. VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
  587. /* fault handling */
  588. REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
  589. VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
  590. VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
  591. REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
  592. VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
  593. /* control: enable VM PTE*/
  594. REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0,
  595. ENABLE_L1_TLB, 1,
  596. SYSTEM_ACCESS_MODE, 3);
  597. }
  598. void min_set_viewport(
  599. struct hubp *hubp,
  600. const struct rect *viewport,
  601. const struct rect *viewport_c)
  602. {
  603. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  604. REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
  605. PRI_VIEWPORT_WIDTH, viewport->width,
  606. PRI_VIEWPORT_HEIGHT, viewport->height);
  607. REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0,
  608. PRI_VIEWPORT_X_START, viewport->x,
  609. PRI_VIEWPORT_Y_START, viewport->y);
  610. /*for stereo*/
  611. REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0,
  612. SEC_VIEWPORT_WIDTH, viewport->width,
  613. SEC_VIEWPORT_HEIGHT, viewport->height);
  614. REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0,
  615. SEC_VIEWPORT_X_START, viewport->x,
  616. SEC_VIEWPORT_Y_START, viewport->y);
  617. /* DC supports NV12 only at the moment */
  618. REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0,
  619. PRI_VIEWPORT_WIDTH_C, viewport_c->width,
  620. PRI_VIEWPORT_HEIGHT_C, viewport_c->height);
  621. REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
  622. PRI_VIEWPORT_X_START_C, viewport_c->x,
  623. PRI_VIEWPORT_Y_START_C, viewport_c->y);
  624. }
  625. void hubp1_read_state(struct dcn10_hubp *hubp1,
  626. struct dcn_hubp_state *s)
  627. {
  628. REG_GET(DCSURF_SURFACE_CONFIG,
  629. SURFACE_PIXEL_FORMAT, &s->pixel_format);
  630. REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
  631. SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi);
  632. REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION,
  633. PRI_VIEWPORT_WIDTH, &s->viewport_width,
  634. PRI_VIEWPORT_HEIGHT, &s->viewport_height);
  635. REG_GET_2(DCSURF_SURFACE_CONFIG,
  636. ROTATION_ANGLE, &s->rotation_angle,
  637. H_MIRROR_EN, &s->h_mirror_en);
  638. REG_GET(DCSURF_TILING_CONFIG,
  639. SW_MODE, &s->sw_mode);
  640. REG_GET(DCSURF_SURFACE_CONTROL,
  641. PRIMARY_SURFACE_DCC_EN, &s->dcc_en);
  642. REG_GET_3(DCHUBP_CNTL,
  643. HUBP_BLANK_EN, &s->blank_en,
  644. HUBP_TTU_DISABLE, &s->ttu_disable,
  645. HUBP_UNDERFLOW_STATUS, &s->underflow_status);
  646. REG_GET(DCN_GLOBAL_TTU_CNTL,
  647. MIN_TTU_VBLANK, &s->min_ttu_vblank);
  648. REG_GET_2(DCN_TTU_QOS_WM,
  649. QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
  650. QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
  651. }
  652. enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
  653. {
  654. enum cursor_pitch hw_pitch;
  655. switch (pitch) {
  656. case 64:
  657. hw_pitch = CURSOR_PITCH_64_PIXELS;
  658. break;
  659. case 128:
  660. hw_pitch = CURSOR_PITCH_128_PIXELS;
  661. break;
  662. case 256:
  663. hw_pitch = CURSOR_PITCH_256_PIXELS;
  664. break;
  665. default:
  666. DC_ERR("Invalid cursor pitch of %d. "
  667. "Only 64/128/256 is supported on DCN.\n", pitch);
  668. hw_pitch = CURSOR_PITCH_64_PIXELS;
  669. break;
  670. }
  671. return hw_pitch;
  672. }
  673. static enum cursor_lines_per_chunk hubp1_get_lines_per_chunk(
  674. unsigned int cur_width,
  675. enum dc_cursor_color_format format)
  676. {
  677. enum cursor_lines_per_chunk line_per_chunk;
  678. if (format == CURSOR_MODE_MONO)
  679. /* impl B. expansion in CUR Buffer reader */
  680. line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
  681. else if (cur_width <= 32)
  682. line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
  683. else if (cur_width <= 64)
  684. line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
  685. else if (cur_width <= 128)
  686. line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
  687. else
  688. line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
  689. return line_per_chunk;
  690. }
  691. void hubp1_cursor_set_attributes(
  692. struct hubp *hubp,
  693. const struct dc_cursor_attributes *attr)
  694. {
  695. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  696. enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch);
  697. enum cursor_lines_per_chunk lpc = hubp1_get_lines_per_chunk(
  698. attr->width, attr->color_format);
  699. hubp->curs_attr = *attr;
  700. REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
  701. CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
  702. REG_UPDATE(CURSOR_SURFACE_ADDRESS,
  703. CURSOR_SURFACE_ADDRESS, attr->address.low_part);
  704. REG_UPDATE_2(CURSOR_SIZE,
  705. CURSOR_WIDTH, attr->width,
  706. CURSOR_HEIGHT, attr->height);
  707. REG_UPDATE_3(CURSOR_CONTROL,
  708. CURSOR_MODE, attr->color_format,
  709. CURSOR_PITCH, hw_pitch,
  710. CURSOR_LINES_PER_CHUNK, lpc);
  711. REG_SET_2(CURSOR_SETTINS, 0,
  712. /* no shift of the cursor HDL schedule */
  713. CURSOR0_DST_Y_OFFSET, 0,
  714. /* used to shift the cursor chunk request deadline */
  715. CURSOR0_CHUNK_HDL_ADJUST, 3);
  716. }
  717. void hubp1_cursor_set_position(
  718. struct hubp *hubp,
  719. const struct dc_cursor_position *pos,
  720. const struct dc_cursor_mi_param *param)
  721. {
  722. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  723. int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
  724. uint32_t cur_en = pos->enable ? 1 : 0;
  725. uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
  726. /*
  727. * Guard aganst cursor_set_position() from being called with invalid
  728. * attributes
  729. *
  730. * TODO: Look at combining cursor_set_position() and
  731. * cursor_set_attributes() into cursor_update()
  732. */
  733. if (hubp->curs_attr.address.quad_part == 0)
  734. return;
  735. dst_x_offset *= param->ref_clk_khz;
  736. dst_x_offset /= param->pixel_clk_khz;
  737. ASSERT(param->h_scale_ratio.value);
  738. if (param->h_scale_ratio.value)
  739. dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
  740. dal_fixed31_32_from_int(dst_x_offset),
  741. param->h_scale_ratio));
  742. if (src_x_offset >= (int)param->viewport_width)
  743. cur_en = 0; /* not visible beyond right edge*/
  744. if (src_x_offset + (int)hubp->curs_attr.width < 0)
  745. cur_en = 0; /* not visible beyond left edge*/
  746. if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
  747. hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
  748. REG_UPDATE(CURSOR_CONTROL,
  749. CURSOR_ENABLE, cur_en);
  750. REG_SET_2(CURSOR_POSITION, 0,
  751. CURSOR_X_POSITION, pos->x,
  752. CURSOR_Y_POSITION, pos->y);
  753. REG_SET_2(CURSOR_HOT_SPOT, 0,
  754. CURSOR_HOT_SPOT_X, pos->x_hotspot,
  755. CURSOR_HOT_SPOT_Y, pos->y_hotspot);
  756. REG_SET(CURSOR_DST_OFFSET, 0,
  757. CURSOR_DST_X_OFFSET, dst_x_offset);
  758. /* TODO Handle surface pixel formats other than 4:4:4 */
  759. }
  760. void hubp1_clk_cntl(struct hubp *hubp, bool enable)
  761. {
  762. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  763. uint32_t clk_enable = enable ? 1 : 0;
  764. REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
  765. }
  766. void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
  767. {
  768. struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
  769. REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
  770. }
  771. static struct hubp_funcs dcn10_hubp_funcs = {
  772. .hubp_program_surface_flip_and_addr =
  773. hubp1_program_surface_flip_and_addr,
  774. .hubp_program_surface_config =
  775. hubp1_program_surface_config,
  776. .hubp_is_flip_pending = hubp1_is_flip_pending,
  777. .hubp_setup = hubp1_setup,
  778. .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
  779. .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
  780. .set_blank = hubp1_set_blank,
  781. .dcc_control = hubp1_dcc_control,
  782. .mem_program_viewport = min_set_viewport,
  783. .set_hubp_blank_en = hubp1_set_hubp_blank_en,
  784. .set_cursor_attributes = hubp1_cursor_set_attributes,
  785. .set_cursor_position = hubp1_cursor_set_position,
  786. .hubp_disconnect = hubp1_disconnect,
  787. .hubp_clk_cntl = hubp1_clk_cntl,
  788. .hubp_vtg_sel = hubp1_vtg_sel,
  789. };
  790. /*****************************************/
  791. /* Constructor, Destructor */
  792. /*****************************************/
  793. void dcn10_hubp_construct(
  794. struct dcn10_hubp *hubp1,
  795. struct dc_context *ctx,
  796. uint32_t inst,
  797. const struct dcn_mi_registers *hubp_regs,
  798. const struct dcn_mi_shift *hubp_shift,
  799. const struct dcn_mi_mask *hubp_mask)
  800. {
  801. hubp1->base.funcs = &dcn10_hubp_funcs;
  802. hubp1->base.ctx = ctx;
  803. hubp1->hubp_regs = hubp_regs;
  804. hubp1->hubp_shift = hubp_shift;
  805. hubp1->hubp_mask = hubp_mask;
  806. hubp1->base.inst = inst;
  807. hubp1->base.opp_id = 0xf;
  808. hubp1->base.mpcc_id = 0xf;
  809. }