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