]>
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 | ||
75c2dec3 | 46 | REG_UPDATE_2(DCHUBP_CNTL, |
70ccab60 HW |
47 | HUBP_BLANK_EN, blank_en, |
48 | HUBP_TTU_DISABLE, blank_en); | |
d65359d5 | 49 | |
cc408d72 | 50 | if (blank) { |
75c2dec3 TC |
51 | uint32_t reg_val = REG_READ(DCHUBP_CNTL); |
52 | ||
cc55b1f5 TC |
53 | if (reg_val) { |
54 | /* init sequence workaround: in case HUBP is | |
55 | * power gated, this wait would timeout. | |
56 | * | |
57 | * we just wrote reg_val to non-0, if it stay 0 | |
58 | * it means HUBP is gated | |
59 | */ | |
60 | REG_WAIT(DCHUBP_CNTL, | |
61 | HUBP_NO_OUTSTANDING_REQ, 1, | |
62 | 1, 200); | |
63 | } | |
64 | ||
8feabd03 | 65 | hubp->mpcc_id = 0xf; |
043f5bb6 | 66 | hubp->opp_id = OPP_ID_INVALID; |
cc408d72 | 67 | } |
70ccab60 HW |
68 | } |
69 | ||
1dbac201 YS |
70 | static void hubp1_disconnect(struct hubp *hubp) |
71 | { | |
72 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
73 | ||
74 | REG_UPDATE(DCHUBP_CNTL, | |
75 | HUBP_TTU_DISABLE, 1); | |
5af9d013 EY |
76 | |
77 | REG_UPDATE(CURSOR_CONTROL, | |
78 | CURSOR_ENABLE, 0); | |
1dbac201 YS |
79 | } |
80 | ||
3ba43a59 CL |
81 | static void hubp1_disable_control(struct hubp *hubp, bool disable_hubp) |
82 | { | |
83 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
84 | uint32_t disable = disable_hubp ? 1 : 0; | |
85 | ||
86 | REG_UPDATE(DCHUBP_CNTL, | |
87 | HUBP_DISABLE, disable); | |
88 | } | |
89 | ||
90 | static unsigned int hubp1_get_underflow_status(struct hubp *hubp) | |
91 | { | |
92 | uint32_t hubp_underflow = 0; | |
93 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
94 | ||
95 | REG_GET(DCHUBP_CNTL, | |
96 | HUBP_UNDERFLOW_STATUS, | |
97 | &hubp_underflow); | |
98 | ||
99 | return hubp_underflow; | |
100 | } | |
101 | ||
eb6b29d6 JL |
102 | |
103 | void hubp1_clear_underflow(struct hubp *hubp) | |
104 | { | |
105 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
106 | ||
107 | REG_UPDATE(DCHUBP_CNTL, HUBP_UNDERFLOW_CLEAR, 1); | |
108 | } | |
109 | ||
8feabd03 | 110 | static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank) |
41f97c07 | 111 | { |
8feabd03 | 112 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
41f97c07 HW |
113 | uint32_t blank_en = blank ? 1 : 0; |
114 | ||
115 | REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en); | |
116 | } | |
117 | ||
60a804c8 | 118 | void hubp1_vready_workaround(struct hubp *hubp, |
70ccab60 HW |
119 | struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) |
120 | { | |
121 | uint32_t value = 0; | |
8feabd03 | 122 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
123 | |
124 | /* set HBUBREQ_DEBUG_DB[12] = 1 */ | |
125 | value = REG_READ(HUBPREQ_DEBUG_DB); | |
126 | ||
127 | /* hack mode disable */ | |
128 | value |= 0x100; | |
129 | value &= ~0x1000; | |
130 | ||
131 | if ((pipe_dest->vstartup_start - 2*(pipe_dest->vready_offset+pipe_dest->vupdate_width | |
132 | + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) { | |
133 | /* if (eco_fix_needed(otg_global_sync_timing) | |
134 | * set HBUBREQ_DEBUG_DB[12] = 1 */ | |
135 | value |= 0x1000; | |
136 | } | |
137 | ||
138 | REG_WRITE(HUBPREQ_DEBUG_DB, value); | |
139 | } | |
140 | ||
b7901be0 | 141 | void hubp1_program_tiling( |
4b8240bf | 142 | struct hubp *hubp, |
70ccab60 HW |
143 | const union dc_tiling_info *info, |
144 | const enum surface_pixel_format pixel_format) | |
145 | { | |
4b8240bf YHL |
146 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
147 | ||
70ccab60 HW |
148 | REG_UPDATE_6(DCSURF_ADDR_CONFIG, |
149 | NUM_PIPES, log_2(info->gfx9.num_pipes), | |
150 | NUM_BANKS, log_2(info->gfx9.num_banks), | |
151 | PIPE_INTERLEAVE, info->gfx9.pipe_interleave, | |
152 | NUM_SE, log_2(info->gfx9.num_shader_engines), | |
153 | NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se), | |
154 | MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); | |
155 | ||
156 | REG_UPDATE_4(DCSURF_TILING_CONFIG, | |
157 | SW_MODE, info->gfx9.swizzle, | |
158 | META_LINEAR, info->gfx9.meta_linear, | |
159 | RB_ALIGNED, info->gfx9.rb_aligned, | |
160 | PIPE_ALIGNED, info->gfx9.pipe_aligned); | |
161 | } | |
162 | ||
a9962fb8 | 163 | void hubp1_program_size( |
4b8240bf | 164 | struct hubp *hubp, |
70ccab60 | 165 | enum surface_pixel_format format, |
12e2b2d4 | 166 | const struct plane_size *plane_size, |
a9962fb8 | 167 | struct dc_plane_dcc_param *dcc) |
70ccab60 | 168 | { |
4b8240bf | 169 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
a9962fb8 | 170 | uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c; |
70ccab60 HW |
171 | |
172 | /* Program data and meta surface pitch (calculation from addrlib) | |
173 | * 444 or 420 luma | |
174 | */ | |
836758ff | 175 | if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) { |
12e2b2d4 | 176 | ASSERT(plane_size->chroma_pitch != 0); |
8ec06a17 JP |
177 | /* Chroma pitch zero can cause system hang! */ |
178 | ||
12e2b2d4 DL |
179 | pitch = plane_size->surface_pitch - 1; |
180 | meta_pitch = dcc->meta_pitch - 1; | |
181 | pitch_c = plane_size->chroma_pitch - 1; | |
182 | meta_pitch_c = dcc->meta_pitch_c - 1; | |
70ccab60 | 183 | } else { |
12e2b2d4 DL |
184 | pitch = plane_size->surface_pitch - 1; |
185 | meta_pitch = dcc->meta_pitch - 1; | |
70ccab60 HW |
186 | pitch_c = 0; |
187 | meta_pitch_c = 0; | |
188 | } | |
189 | ||
190 | if (!dcc->enable) { | |
191 | meta_pitch = 0; | |
192 | meta_pitch_c = 0; | |
193 | } | |
194 | ||
195 | REG_UPDATE_2(DCSURF_SURFACE_PITCH, | |
196 | PITCH, pitch, META_PITCH, meta_pitch); | |
197 | ||
198 | if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) | |
199 | REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, | |
200 | PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); | |
a9962fb8 EB |
201 | } |
202 | ||
203 | void hubp1_program_rotation( | |
204 | struct hubp *hubp, | |
205 | enum dc_rotation_angle rotation, | |
206 | bool horizontal_mirror) | |
207 | { | |
208 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
209 | uint32_t mirror; | |
210 | ||
70ccab60 HW |
211 | |
212 | if (horizontal_mirror) | |
213 | mirror = 1; | |
214 | else | |
215 | mirror = 0; | |
216 | ||
70ccab60 HW |
217 | /* Program rotation angle and horz mirror - no mirror */ |
218 | if (rotation == ROTATION_ANGLE_0) | |
219 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
220 | ROTATION_ANGLE, 0, | |
221 | H_MIRROR_EN, mirror); | |
222 | else if (rotation == ROTATION_ANGLE_90) | |
223 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
224 | ROTATION_ANGLE, 1, | |
225 | H_MIRROR_EN, mirror); | |
226 | else if (rotation == ROTATION_ANGLE_180) | |
227 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
228 | ROTATION_ANGLE, 2, | |
229 | H_MIRROR_EN, mirror); | |
230 | else if (rotation == ROTATION_ANGLE_270) | |
231 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
232 | ROTATION_ANGLE, 3, | |
233 | H_MIRROR_EN, mirror); | |
234 | } | |
235 | ||
b7901be0 | 236 | void hubp1_program_pixel_format( |
4b8240bf | 237 | struct hubp *hubp, |
70ccab60 HW |
238 | enum surface_pixel_format format) |
239 | { | |
4b8240bf | 240 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
241 | uint32_t red_bar = 3; |
242 | uint32_t blue_bar = 2; | |
243 | ||
244 | /* swap for ABGR format */ | |
245 | if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 | |
246 | || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 | |
247 | || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS | |
050cd3d6 | 248 | || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 |
70ccab60 HW |
249 | || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) { |
250 | red_bar = 2; | |
251 | blue_bar = 3; | |
252 | } | |
253 | ||
254 | REG_UPDATE_2(HUBPRET_CONTROL, | |
255 | CROSSBAR_SRC_CB_B, blue_bar, | |
256 | CROSSBAR_SRC_CR_R, red_bar); | |
257 | ||
258 | /* Mapping is same as ipp programming (cnvc) */ | |
259 | ||
260 | switch (format) { | |
261 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: | |
262 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
263 | SURFACE_PIXEL_FORMAT, 1); | |
264 | break; | |
265 | case SURFACE_PIXEL_FORMAT_GRPH_RGB565: | |
266 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
267 | SURFACE_PIXEL_FORMAT, 3); | |
268 | break; | |
269 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: | |
270 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: | |
271 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
272 | SURFACE_PIXEL_FORMAT, 8); | |
273 | break; | |
274 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: | |
275 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: | |
276 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: | |
277 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
278 | SURFACE_PIXEL_FORMAT, 10); | |
279 | break; | |
280 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: | |
050cd3d6 | 281 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/ |
70ccab60 | 282 | REG_UPDATE(DCSURF_SURFACE_CONFIG, |
050cd3d6 | 283 | SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */ |
70ccab60 HW |
284 | break; |
285 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: | |
286 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/ | |
287 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
288 | SURFACE_PIXEL_FORMAT, 24); | |
289 | break; | |
290 | ||
291 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: | |
292 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
293 | SURFACE_PIXEL_FORMAT, 65); | |
294 | break; | |
295 | case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: | |
296 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
297 | SURFACE_PIXEL_FORMAT, 64); | |
298 | break; | |
299 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: | |
300 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
301 | SURFACE_PIXEL_FORMAT, 67); | |
302 | break; | |
303 | case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: | |
304 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
305 | SURFACE_PIXEL_FORMAT, 66); | |
306 | break; | |
3fc9fc4c | 307 | case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888: |
308 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
309 | SURFACE_PIXEL_FORMAT, 12); | |
310 | break; | |
bbeb64d0 HW |
311 | case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: |
312 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
313 | SURFACE_PIXEL_FORMAT, 112); | |
314 | break; | |
315 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: | |
316 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
317 | SURFACE_PIXEL_FORMAT, 113); | |
318 | break; | |
319 | case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: | |
320 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
321 | SURFACE_PIXEL_FORMAT, 114); | |
322 | break; | |
323 | case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: | |
324 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
325 | SURFACE_PIXEL_FORMAT, 118); | |
326 | break; | |
327 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: | |
328 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | |
329 | SURFACE_PIXEL_FORMAT, 119); | |
330 | break; | |
db7b0216 BL |
331 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
332 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
333 | SURFACE_PIXEL_FORMAT, 116, | |
334 | ALPHA_PLANE_EN, 0); | |
335 | break; | |
336 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: | |
337 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | |
338 | SURFACE_PIXEL_FORMAT, 116, | |
339 | ALPHA_PLANE_EN, 1); | |
340 | break; | |
70ccab60 HW |
341 | default: |
342 | BREAK_TO_DEBUGGER(); | |
343 | break; | |
344 | } | |
345 | ||
346 | /* don't see the need of program the xbar in DCN 1.0 */ | |
347 | } | |
348 | ||
b7901be0 | 349 | bool hubp1_program_surface_flip_and_addr( |
8feabd03 | 350 | struct hubp *hubp, |
70ccab60 | 351 | const struct dc_plane_address *address, |
bda9afda | 352 | bool flip_immediate) |
70ccab60 | 353 | { |
8feabd03 | 354 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 | 355 | |
1336926f A |
356 | |
357 | //program flip type | |
358 | REG_UPDATE(DCSURF_FLIP_CONTROL, | |
70ccab60 HW |
359 | SURFACE_FLIP_TYPE, flip_immediate); |
360 | ||
1336926f A |
361 | |
362 | if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) { | |
363 | REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1); | |
364 | REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1); | |
365 | ||
366 | } else { | |
367 | // turn off stereo if not in stereo | |
368 | REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0); | |
369 | REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0); | |
370 | } | |
371 | ||
372 | ||
373 | ||
89c872e5 TC |
374 | /* HW automatically latch rest of address register on write to |
375 | * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used | |
376 | * | |
377 | * program high first and then the low addr, order matters! | |
378 | */ | |
70ccab60 HW |
379 | switch (address->type) { |
380 | case PLN_ADDR_TYPE_GRAPHICS: | |
89c872e5 TC |
381 | /* DCN1.0 does not support const color |
382 | * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1 | |
383 | * base on address->grph.dcc_const_color | |
384 | * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma | |
385 | * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma | |
386 | */ | |
387 | ||
70ccab60 HW |
388 | if (address->grph.addr.quad_part == 0) |
389 | break; | |
390 | ||
cf8c19a3 YS |
391 | REG_UPDATE_2(DCSURF_SURFACE_CONTROL, |
392 | PRIMARY_SURFACE_TMZ, address->tmz_surface, | |
393 | PRIMARY_META_SURFACE_TMZ, address->tmz_surface); | |
9ee20ee6 | 394 | |
70ccab60 | 395 | if (address->grph.meta_addr.quad_part != 0) { |
d9e88878 | 396 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
397 | PRIMARY_META_SURFACE_ADDRESS_HIGH, |
398 | address->grph.meta_addr.high_part); | |
399 | ||
d9e88878 | 400 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, |
70ccab60 HW |
401 | PRIMARY_META_SURFACE_ADDRESS, |
402 | address->grph.meta_addr.low_part); | |
403 | } | |
404 | ||
d9e88878 | 405 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
406 | PRIMARY_SURFACE_ADDRESS_HIGH, |
407 | address->grph.addr.high_part); | |
408 | ||
d9e88878 | 409 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, |
70ccab60 HW |
410 | PRIMARY_SURFACE_ADDRESS, |
411 | address->grph.addr.low_part); | |
70ccab60 HW |
412 | break; |
413 | case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: | |
414 | if (address->video_progressive.luma_addr.quad_part == 0 | |
415 | || address->video_progressive.chroma_addr.quad_part == 0) | |
416 | break; | |
417 | ||
cf8c19a3 YS |
418 | REG_UPDATE_4(DCSURF_SURFACE_CONTROL, |
419 | PRIMARY_SURFACE_TMZ, address->tmz_surface, | |
420 | PRIMARY_SURFACE_TMZ_C, address->tmz_surface, | |
421 | PRIMARY_META_SURFACE_TMZ, address->tmz_surface, | |
422 | PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface); | |
9ee20ee6 | 423 | |
70ccab60 | 424 | if (address->video_progressive.luma_meta_addr.quad_part != 0) { |
d9e88878 DL |
425 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0, |
426 | PRIMARY_META_SURFACE_ADDRESS_HIGH_C, | |
427 | address->video_progressive.chroma_meta_addr.high_part); | |
70ccab60 | 428 | |
d9e88878 DL |
429 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0, |
430 | PRIMARY_META_SURFACE_ADDRESS_C, | |
431 | address->video_progressive.chroma_meta_addr.low_part); | |
432 | ||
433 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, | |
70ccab60 HW |
434 | PRIMARY_META_SURFACE_ADDRESS_HIGH, |
435 | address->video_progressive.luma_meta_addr.high_part); | |
436 | ||
d9e88878 | 437 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, |
70ccab60 HW |
438 | PRIMARY_META_SURFACE_ADDRESS, |
439 | address->video_progressive.luma_meta_addr.low_part); | |
70ccab60 HW |
440 | } |
441 | ||
d9e88878 | 442 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, |
70ccab60 HW |
443 | PRIMARY_SURFACE_ADDRESS_HIGH_C, |
444 | address->video_progressive.chroma_addr.high_part); | |
445 | ||
d9e88878 | 446 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, |
70ccab60 HW |
447 | PRIMARY_SURFACE_ADDRESS_C, |
448 | address->video_progressive.chroma_addr.low_part); | |
449 | ||
d9e88878 | 450 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, |
89c872e5 TC |
451 | PRIMARY_SURFACE_ADDRESS_HIGH, |
452 | address->video_progressive.luma_addr.high_part); | |
453 | ||
d9e88878 | 454 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, |
89c872e5 TC |
455 | PRIMARY_SURFACE_ADDRESS, |
456 | address->video_progressive.luma_addr.low_part); | |
70ccab60 HW |
457 | break; |
458 | case PLN_ADDR_TYPE_GRPH_STEREO: | |
459 | if (address->grph_stereo.left_addr.quad_part == 0) | |
460 | break; | |
461 | if (address->grph_stereo.right_addr.quad_part == 0) | |
462 | break; | |
9ee20ee6 | 463 | |
aa6d4a59 | 464 | REG_UPDATE_8(DCSURF_SURFACE_CONTROL, |
cf8c19a3 YS |
465 | PRIMARY_SURFACE_TMZ, address->tmz_surface, |
466 | PRIMARY_SURFACE_TMZ_C, address->tmz_surface, | |
467 | PRIMARY_META_SURFACE_TMZ, address->tmz_surface, | |
aa6d4a59 EB |
468 | PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface, |
469 | SECONDARY_SURFACE_TMZ, address->tmz_surface, | |
470 | SECONDARY_SURFACE_TMZ_C, address->tmz_surface, | |
471 | SECONDARY_META_SURFACE_TMZ, address->tmz_surface, | |
472 | SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface); | |
9ee20ee6 | 473 | |
70ccab60 HW |
474 | if (address->grph_stereo.right_meta_addr.quad_part != 0) { |
475 | ||
d9e88878 | 476 | REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
477 | SECONDARY_META_SURFACE_ADDRESS_HIGH, |
478 | address->grph_stereo.right_meta_addr.high_part); | |
479 | ||
d9e88878 | 480 | REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0, |
70ccab60 HW |
481 | SECONDARY_META_SURFACE_ADDRESS, |
482 | address->grph_stereo.right_meta_addr.low_part); | |
483 | } | |
484 | if (address->grph_stereo.left_meta_addr.quad_part != 0) { | |
485 | ||
d9e88878 | 486 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
487 | PRIMARY_META_SURFACE_ADDRESS_HIGH, |
488 | address->grph_stereo.left_meta_addr.high_part); | |
489 | ||
d9e88878 | 490 | REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, |
70ccab60 HW |
491 | PRIMARY_META_SURFACE_ADDRESS, |
492 | address->grph_stereo.left_meta_addr.low_part); | |
493 | } | |
494 | ||
d9e88878 | 495 | REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
496 | SECONDARY_SURFACE_ADDRESS_HIGH, |
497 | address->grph_stereo.right_addr.high_part); | |
498 | ||
d9e88878 | 499 | REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0, |
70ccab60 HW |
500 | SECONDARY_SURFACE_ADDRESS, |
501 | address->grph_stereo.right_addr.low_part); | |
502 | ||
d9e88878 | 503 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, |
70ccab60 HW |
504 | PRIMARY_SURFACE_ADDRESS_HIGH, |
505 | address->grph_stereo.left_addr.high_part); | |
506 | ||
d9e88878 | 507 | REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, |
70ccab60 HW |
508 | PRIMARY_SURFACE_ADDRESS, |
509 | address->grph_stereo.left_addr.low_part); | |
510 | break; | |
511 | default: | |
512 | BREAK_TO_DEBUGGER(); | |
513 | break; | |
514 | } | |
70ccab60 | 515 | |
8feabd03 | 516 | hubp->request_address = *address; |
70ccab60 | 517 | |
70ccab60 HW |
518 | return true; |
519 | } | |
520 | ||
8feabd03 | 521 | void hubp1_dcc_control(struct hubp *hubp, bool enable, |
2c58cc6d | 522 | enum hubp_ind_block_size independent_64b_blks) |
70ccab60 | 523 | { |
4c6e7598 YS |
524 | uint32_t dcc_en = enable ? 1 : 0; |
525 | uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; | |
8feabd03 | 526 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 | 527 | |
aa6d4a59 | 528 | REG_UPDATE_4(DCSURF_SURFACE_CONTROL, |
70ccab60 | 529 | PRIMARY_SURFACE_DCC_EN, dcc_en, |
aa6d4a59 EB |
530 | PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk, |
531 | SECONDARY_SURFACE_DCC_EN, dcc_en, | |
532 | SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); | |
4c6e7598 | 533 | } |
70ccab60 | 534 | |
e4b3b5cc | 535 | void hubp1_program_surface_config( |
8feabd03 | 536 | struct hubp *hubp, |
70ccab60 HW |
537 | enum surface_pixel_format format, |
538 | union dc_tiling_info *tiling_info, | |
12e2b2d4 | 539 | struct plane_size *plane_size, |
70ccab60 HW |
540 | enum dc_rotation_angle rotation, |
541 | struct dc_plane_dcc_param *dcc, | |
a465feae CL |
542 | bool horizontal_mirror, |
543 | unsigned int compat_level) | |
70ccab60 | 544 | { |
12e2b2d4 | 545 | hubp1_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks); |
4b8240bf | 546 | hubp1_program_tiling(hubp, tiling_info, format); |
a9962fb8 EB |
547 | hubp1_program_size(hubp, format, plane_size, dcc); |
548 | hubp1_program_rotation(hubp, rotation, horizontal_mirror); | |
4b8240bf | 549 | hubp1_program_pixel_format(hubp, format); |
70ccab60 HW |
550 | } |
551 | ||
b7901be0 | 552 | void hubp1_program_requestor( |
8feabd03 | 553 | struct hubp *hubp, |
70ccab60 HW |
554 | struct _vcs_dpi_display_rq_regs_st *rq_regs) |
555 | { | |
8feabd03 | 556 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
557 | |
558 | REG_UPDATE(HUBPRET_CONTROL, | |
559 | DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); | |
560 | REG_SET_4(DCN_EXPANSION_MODE, 0, | |
561 | DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, | |
562 | PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode, | |
563 | MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode, | |
564 | CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode); | |
565 | REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0, | |
566 | CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size, | |
567 | MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size, | |
568 | META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size, | |
569 | MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size, | |
570 | DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size, | |
571 | MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size, | |
572 | SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height, | |
573 | PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear); | |
574 | REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0, | |
575 | CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size, | |
576 | MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size, | |
577 | META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size, | |
578 | MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size, | |
579 | DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size, | |
580 | MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size, | |
581 | SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height, | |
582 | PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear); | |
583 | } | |
584 | ||
585 | ||
b7901be0 | 586 | void hubp1_program_deadline( |
8feabd03 | 587 | struct hubp *hubp, |
70ccab60 HW |
588 | struct _vcs_dpi_display_dlg_regs_st *dlg_attr, |
589 | struct _vcs_dpi_display_ttu_regs_st *ttu_attr) | |
590 | { | |
8feabd03 | 591 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
592 | |
593 | /* DLG - Per hubp */ | |
594 | REG_SET_2(BLANK_OFFSET_0, 0, | |
595 | REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end, | |
596 | DLG_V_BLANK_END, dlg_attr->dlg_vblank_end); | |
597 | ||
598 | REG_SET(BLANK_OFFSET_1, 0, | |
599 | MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start); | |
600 | ||
601 | REG_SET(DST_DIMENSIONS, 0, | |
602 | REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal); | |
603 | ||
604 | REG_SET_2(DST_AFTER_SCALER, 0, | |
605 | REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler, | |
606 | DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler); | |
607 | ||
70ccab60 HW |
608 | REG_SET(REF_FREQ_TO_PIX_FREQ, 0, |
609 | REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq); | |
610 | ||
611 | /* DLG - Per luma/chroma */ | |
612 | REG_SET(VBLANK_PARAMETERS_1, 0, | |
613 | REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l); | |
614 | ||
b552204b NC |
615 | if (REG(NOM_PARAMETERS_0)) |
616 | REG_SET(NOM_PARAMETERS_0, 0, | |
617 | DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l); | |
70ccab60 | 618 | |
b552204b NC |
619 | if (REG(NOM_PARAMETERS_1)) |
620 | REG_SET(NOM_PARAMETERS_1, 0, | |
621 | REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l); | |
70ccab60 HW |
622 | |
623 | REG_SET(NOM_PARAMETERS_4, 0, | |
624 | DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l); | |
625 | ||
626 | REG_SET(NOM_PARAMETERS_5, 0, | |
627 | REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l); | |
628 | ||
70ccab60 HW |
629 | REG_SET_2(PER_LINE_DELIVERY, 0, |
630 | REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l, | |
631 | REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c); | |
632 | ||
70ccab60 HW |
633 | REG_SET(VBLANK_PARAMETERS_2, 0, |
634 | REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c); | |
635 | ||
b552204b NC |
636 | if (REG(NOM_PARAMETERS_2)) |
637 | REG_SET(NOM_PARAMETERS_2, 0, | |
638 | DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c); | |
70ccab60 | 639 | |
b552204b NC |
640 | if (REG(NOM_PARAMETERS_3)) |
641 | REG_SET(NOM_PARAMETERS_3, 0, | |
642 | REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c); | |
70ccab60 HW |
643 | |
644 | REG_SET(NOM_PARAMETERS_6, 0, | |
645 | DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c); | |
646 | ||
647 | REG_SET(NOM_PARAMETERS_7, 0, | |
648 | REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c); | |
649 | ||
650 | /* TTU - per hubp */ | |
651 | REG_SET_2(DCN_TTU_QOS_WM, 0, | |
652 | QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm, | |
653 | QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm); | |
654 | ||
70ccab60 HW |
655 | /* TTU - per luma/chroma */ |
656 | /* Assumed surf0 is luma and 1 is chroma */ | |
657 | ||
658 | REG_SET_3(DCN_SURF0_TTU_CNTL0, 0, | |
659 | REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l, | |
660 | QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l, | |
661 | QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l); | |
662 | ||
70ccab60 HW |
663 | REG_SET_3(DCN_SURF1_TTU_CNTL0, 0, |
664 | REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c, | |
665 | QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c, | |
666 | QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c); | |
667 | ||
c0aceb7d CL |
668 | REG_SET_3(DCN_CUR0_TTU_CNTL0, 0, |
669 | REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0, | |
670 | QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0, | |
671 | QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0); | |
70ccab60 HW |
672 | } |
673 | ||
b7901be0 | 674 | static void hubp1_setup( |
8feabd03 | 675 | struct hubp *hubp, |
70ccab60 HW |
676 | struct _vcs_dpi_display_dlg_regs_st *dlg_attr, |
677 | struct _vcs_dpi_display_ttu_regs_st *ttu_attr, | |
678 | struct _vcs_dpi_display_rq_regs_st *rq_regs, | |
679 | struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) | |
680 | { | |
681 | /* otg is locked when this func is called. Register are double buffered. | |
682 | * disable the requestors is not needed | |
683 | */ | |
8feabd03 YHL |
684 | hubp1_program_requestor(hubp, rq_regs); |
685 | hubp1_program_deadline(hubp, dlg_attr, ttu_attr); | |
686 | hubp1_vready_workaround(hubp, pipe_dest); | |
70ccab60 HW |
687 | } |
688 | ||
1a1adf17 DL |
689 | static void hubp1_setup_interdependent( |
690 | struct hubp *hubp, | |
691 | struct _vcs_dpi_display_dlg_regs_st *dlg_attr, | |
692 | struct _vcs_dpi_display_ttu_regs_st *ttu_attr) | |
693 | { | |
694 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
695 | ||
696 | REG_SET_2(PREFETCH_SETTINS, 0, | |
697 | DST_Y_PREFETCH, dlg_attr->dst_y_prefetch, | |
698 | VRATIO_PREFETCH, dlg_attr->vratio_prefetch); | |
699 | ||
700 | REG_SET(PREFETCH_SETTINS_C, 0, | |
701 | VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c); | |
702 | ||
703 | REG_SET_2(VBLANK_PARAMETERS_0, 0, | |
704 | DST_Y_PER_VM_VBLANK, dlg_attr->dst_y_per_vm_vblank, | |
705 | DST_Y_PER_ROW_VBLANK, dlg_attr->dst_y_per_row_vblank); | |
706 | ||
707 | REG_SET(VBLANK_PARAMETERS_3, 0, | |
708 | REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l); | |
709 | ||
710 | REG_SET(VBLANK_PARAMETERS_4, 0, | |
711 | REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c); | |
712 | ||
713 | REG_SET_2(PER_LINE_DELIVERY_PRE, 0, | |
714 | REFCYC_PER_LINE_DELIVERY_PRE_L, dlg_attr->refcyc_per_line_delivery_pre_l, | |
715 | REFCYC_PER_LINE_DELIVERY_PRE_C, dlg_attr->refcyc_per_line_delivery_pre_c); | |
716 | ||
717 | REG_SET(DCN_SURF0_TTU_CNTL1, 0, | |
718 | REFCYC_PER_REQ_DELIVERY_PRE, | |
719 | ttu_attr->refcyc_per_req_delivery_pre_l); | |
720 | REG_SET(DCN_SURF1_TTU_CNTL1, 0, | |
721 | REFCYC_PER_REQ_DELIVERY_PRE, | |
722 | ttu_attr->refcyc_per_req_delivery_pre_c); | |
723 | REG_SET(DCN_CUR0_TTU_CNTL1, 0, | |
724 | REFCYC_PER_REQ_DELIVERY_PRE, ttu_attr->refcyc_per_req_delivery_pre_cur0); | |
725 | ||
726 | REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0, | |
727 | MIN_TTU_VBLANK, ttu_attr->min_ttu_vblank, | |
728 | QoS_LEVEL_FLIP, ttu_attr->qos_level_flip); | |
729 | } | |
730 | ||
8feabd03 | 731 | bool hubp1_is_flip_pending(struct hubp *hubp) |
70ccab60 | 732 | { |
db3bc050 | 733 | uint32_t flip_pending = 0; |
8feabd03 | 734 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
2f1e8efd | 735 | struct dc_plane_address earliest_inuse_address; |
70ccab60 | 736 | |
e8cb7a4d AC |
737 | if (hubp && hubp->power_gated) |
738 | return false; | |
739 | ||
70ccab60 | 740 | REG_GET(DCSURF_FLIP_CONTROL, |
db3bc050 | 741 | SURFACE_FLIP_PENDING, &flip_pending); |
70ccab60 | 742 | |
2f1e8efd YS |
743 | REG_GET(DCSURF_SURFACE_EARLIEST_INUSE, |
744 | SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part); | |
745 | ||
746 | REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, | |
747 | SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part); | |
748 | ||
db3bc050 | 749 | if (flip_pending) |
70ccab60 HW |
750 | return true; |
751 | ||
8feabd03 | 752 | if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part) |
2f1e8efd YS |
753 | return true; |
754 | ||
70ccab60 HW |
755 | return false; |
756 | } | |
757 | ||
6a2b691f TC |
758 | uint32_t aperture_default_system = 1; |
759 | uint32_t context0_default_system; /* = 0;*/ | |
760 | ||
8feabd03 | 761 | static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp, |
70ccab60 HW |
762 | struct vm_system_aperture_param *apt) |
763 | { | |
8feabd03 | 764 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
765 | PHYSICAL_ADDRESS_LOC mc_vm_apt_default; |
766 | PHYSICAL_ADDRESS_LOC mc_vm_apt_low; | |
767 | PHYSICAL_ADDRESS_LOC mc_vm_apt_high; | |
768 | ||
769 | mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12; | |
770 | mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 12; | |
771 | mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12; | |
772 | ||
773 | REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, | |
6a2b691f | 774 | MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */ |
70ccab60 HW |
775 | MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part); |
776 | REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, | |
777 | MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part); | |
778 | ||
779 | REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, | |
780 | MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mc_vm_apt_low.high_part); | |
781 | REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, | |
782 | MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mc_vm_apt_low.low_part); | |
783 | ||
784 | REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, | |
785 | MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mc_vm_apt_high.high_part); | |
786 | REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, | |
787 | MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part); | |
788 | } | |
789 | ||
8feabd03 | 790 | static void hubp1_set_vm_context0_settings(struct hubp *hubp, |
70ccab60 HW |
791 | const struct vm_context0_param *vm0) |
792 | { | |
8feabd03 | 793 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
70ccab60 HW |
794 | /* pte base */ |
795 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0, | |
796 | VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part); | |
797 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, 0, | |
798 | VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, vm0->pte_base.low_part); | |
799 | ||
800 | /* pte start */ | |
801 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, 0, | |
802 | VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, vm0->pte_start.high_part); | |
803 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, 0, | |
804 | VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, vm0->pte_start.low_part); | |
805 | ||
806 | /* pte end */ | |
807 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, 0, | |
808 | VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->pte_end.high_part); | |
809 | REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, 0, | |
810 | VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part); | |
811 | ||
812 | /* fault handling */ | |
6a2b691f TC |
813 | REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0, |
814 | VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part, | |
815 | VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system); | |
70ccab60 HW |
816 | REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0, |
817 | VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part); | |
70ccab60 HW |
818 | |
819 | /* control: enable VM PTE*/ | |
820 | REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0, | |
821 | ENABLE_L1_TLB, 1, | |
822 | SYSTEM_ACCESS_MODE, 3); | |
823 | } | |
824 | ||
c73b046f | 825 | void min_set_viewport( |
8feabd03 | 826 | struct hubp *hubp, |
5667ff5c | 827 | const struct rect *viewport, |
cf27a6d1 | 828 | const struct rect *viewport_c) |
4bd3ae5f | 829 | { |
8feabd03 | 830 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
4bd3ae5f | 831 | |
5667ff5c DA |
832 | REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0, |
833 | PRI_VIEWPORT_WIDTH, viewport->width, | |
834 | PRI_VIEWPORT_HEIGHT, viewport->height); | |
4bd3ae5f | 835 | |
5667ff5c DA |
836 | REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0, |
837 | PRI_VIEWPORT_X_START, viewport->x, | |
838 | PRI_VIEWPORT_Y_START, viewport->y); | |
4bd3ae5f | 839 | |
5667ff5c DA |
840 | /*for stereo*/ |
841 | REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0, | |
842 | SEC_VIEWPORT_WIDTH, viewport->width, | |
843 | SEC_VIEWPORT_HEIGHT, viewport->height); | |
4bd3ae5f | 844 | |
5667ff5c DA |
845 | REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0, |
846 | SEC_VIEWPORT_X_START, viewport->x, | |
847 | SEC_VIEWPORT_Y_START, viewport->y); | |
4bd3ae5f | 848 | |
5667ff5c DA |
849 | /* DC supports NV12 only at the moment */ |
850 | REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0, | |
851 | PRI_VIEWPORT_WIDTH_C, viewport_c->width, | |
852 | PRI_VIEWPORT_HEIGHT_C, viewport_c->height); | |
4bd3ae5f | 853 | |
5667ff5c DA |
854 | REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0, |
855 | PRI_VIEWPORT_X_START_C, viewport_c->x, | |
856 | PRI_VIEWPORT_Y_START_C, viewport_c->y); | |
132dade1 IB |
857 | |
858 | REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0, | |
859 | SEC_VIEWPORT_WIDTH_C, viewport_c->width, | |
860 | SEC_VIEWPORT_HEIGHT_C, viewport_c->height); | |
861 | ||
862 | REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0, | |
863 | SEC_VIEWPORT_X_START_C, viewport_c->x, | |
864 | SEC_VIEWPORT_Y_START_C, viewport_c->y); | |
4bd3ae5f VP |
865 | } |
866 | ||
c70b4016 | 867 | void hubp1_read_state_common(struct hubp *hubp) |
2248eb6b | 868 | { |
0a93dc7f | 869 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
34cb6b38 | 870 | struct dcn_hubp_state *s = &hubp1->state; |
0a93dc7f DL |
871 | struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr; |
872 | struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr; | |
873 | struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; | |
98e95e4f JP |
874 | uint32_t aperture_low_msb, aperture_low_lsb; |
875 | uint32_t aperture_high_msb, aperture_high_lsb; | |
0a93dc7f DL |
876 | |
877 | /* Requester */ | |
878 | REG_GET(HUBPRET_CONTROL, | |
879 | DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address); | |
880 | REG_GET_4(DCN_EXPANSION_MODE, | |
881 | DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode, | |
882 | PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode, | |
883 | MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode, | |
884 | CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode); | |
0a93dc7f | 885 | |
98e95e4f JP |
886 | REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, |
887 | MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, &aperture_low_msb); | |
888 | ||
889 | REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, | |
890 | MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, &aperture_low_lsb); | |
891 | ||
892 | REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, | |
893 | MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, &aperture_high_msb); | |
894 | ||
895 | REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, | |
896 | MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, &aperture_high_lsb); | |
897 | ||
898 | // On DCN1, aperture is broken down into MSB and LSB; only keep bits [47:18] to match later DCN format | |
899 | rq_regs->aperture_low_addr = (aperture_low_msb << 26) | (aperture_low_lsb >> 6); | |
900 | rq_regs->aperture_high_addr = (aperture_high_msb << 26) | (aperture_high_lsb >> 6); | |
901 | ||
0a93dc7f DL |
902 | /* DLG - Per hubp */ |
903 | REG_GET_2(BLANK_OFFSET_0, | |
904 | REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end, | |
905 | DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end); | |
906 | ||
907 | REG_GET(BLANK_OFFSET_1, | |
908 | MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start); | |
909 | ||
910 | REG_GET(DST_DIMENSIONS, | |
911 | REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal); | |
912 | ||
913 | REG_GET_2(DST_AFTER_SCALER, | |
914 | REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler, | |
915 | DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler); | |
916 | ||
917 | if (REG(PREFETCH_SETTINS)) | |
918 | REG_GET_2(PREFETCH_SETTINS, | |
919 | DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch, | |
920 | VRATIO_PREFETCH, &dlg_attr->vratio_prefetch); | |
921 | else | |
922 | REG_GET_2(PREFETCH_SETTINGS, | |
923 | DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch, | |
924 | VRATIO_PREFETCH, &dlg_attr->vratio_prefetch); | |
925 | ||
926 | REG_GET_2(VBLANK_PARAMETERS_0, | |
927 | DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank, | |
928 | DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank); | |
929 | ||
930 | REG_GET(REF_FREQ_TO_PIX_FREQ, | |
931 | REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq); | |
932 | ||
933 | /* DLG - Per luma/chroma */ | |
934 | REG_GET(VBLANK_PARAMETERS_1, | |
935 | REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l); | |
936 | ||
937 | REG_GET(VBLANK_PARAMETERS_3, | |
938 | REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l); | |
939 | ||
940 | if (REG(NOM_PARAMETERS_0)) | |
941 | REG_GET(NOM_PARAMETERS_0, | |
942 | DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l); | |
943 | ||
944 | if (REG(NOM_PARAMETERS_1)) | |
945 | REG_GET(NOM_PARAMETERS_1, | |
946 | REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l); | |
947 | ||
948 | REG_GET(NOM_PARAMETERS_4, | |
949 | DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l); | |
950 | ||
951 | REG_GET(NOM_PARAMETERS_5, | |
952 | REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l); | |
953 | ||
954 | REG_GET_2(PER_LINE_DELIVERY_PRE, | |
955 | REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l, | |
956 | REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c); | |
957 | ||
958 | REG_GET_2(PER_LINE_DELIVERY, | |
959 | REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l, | |
960 | REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c); | |
961 | ||
962 | if (REG(PREFETCH_SETTINS_C)) | |
963 | REG_GET(PREFETCH_SETTINS_C, | |
964 | VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c); | |
965 | else | |
966 | REG_GET(PREFETCH_SETTINGS_C, | |
967 | VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c); | |
968 | ||
969 | REG_GET(VBLANK_PARAMETERS_2, | |
970 | REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c); | |
971 | ||
972 | REG_GET(VBLANK_PARAMETERS_4, | |
973 | REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c); | |
974 | ||
975 | if (REG(NOM_PARAMETERS_2)) | |
976 | REG_GET(NOM_PARAMETERS_2, | |
977 | DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c); | |
978 | ||
979 | if (REG(NOM_PARAMETERS_3)) | |
980 | REG_GET(NOM_PARAMETERS_3, | |
981 | REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c); | |
982 | ||
983 | REG_GET(NOM_PARAMETERS_6, | |
984 | DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c); | |
985 | ||
986 | REG_GET(NOM_PARAMETERS_7, | |
987 | REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c); | |
988 | ||
989 | /* TTU - per hubp */ | |
990 | REG_GET_2(DCN_TTU_QOS_WM, | |
991 | QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm, | |
992 | QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm); | |
993 | ||
994 | REG_GET_2(DCN_GLOBAL_TTU_CNTL, | |
995 | MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank, | |
996 | QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip); | |
997 | ||
998 | /* TTU - per luma/chroma */ | |
999 | /* Assumed surf0 is luma and 1 is chroma */ | |
1000 | ||
1001 | REG_GET_3(DCN_SURF0_TTU_CNTL0, | |
1002 | REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l, | |
1003 | QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l, | |
1004 | QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l); | |
1005 | ||
1006 | REG_GET(DCN_SURF0_TTU_CNTL1, | |
1007 | REFCYC_PER_REQ_DELIVERY_PRE, | |
1008 | &ttu_attr->refcyc_per_req_delivery_pre_l); | |
1009 | ||
1010 | REG_GET_3(DCN_SURF1_TTU_CNTL0, | |
1011 | REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c, | |
1012 | QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c, | |
1013 | QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c); | |
1014 | ||
1015 | REG_GET(DCN_SURF1_TTU_CNTL1, | |
1016 | REFCYC_PER_REQ_DELIVERY_PRE, | |
1017 | &ttu_attr->refcyc_per_req_delivery_pre_c); | |
1018 | ||
1019 | /* Rest of hubp */ | |
2248eb6b TC |
1020 | REG_GET(DCSURF_SURFACE_CONFIG, |
1021 | SURFACE_PIXEL_FORMAT, &s->pixel_format); | |
1022 | ||
1023 | REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, | |
1024 | SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi); | |
1025 | ||
afd0384c JL |
1026 | REG_GET(DCSURF_SURFACE_EARLIEST_INUSE, |
1027 | SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo); | |
1028 | ||
2248eb6b TC |
1029 | REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION, |
1030 | PRI_VIEWPORT_WIDTH, &s->viewport_width, | |
1031 | PRI_VIEWPORT_HEIGHT, &s->viewport_height); | |
1032 | ||
1033 | REG_GET_2(DCSURF_SURFACE_CONFIG, | |
1034 | ROTATION_ANGLE, &s->rotation_angle, | |
1035 | H_MIRROR_EN, &s->h_mirror_en); | |
1036 | ||
1037 | REG_GET(DCSURF_TILING_CONFIG, | |
1038 | SW_MODE, &s->sw_mode); | |
1039 | ||
1040 | REG_GET(DCSURF_SURFACE_CONTROL, | |
1041 | PRIMARY_SURFACE_DCC_EN, &s->dcc_en); | |
1042 | ||
eb4e33b7 | 1043 | REG_GET_3(DCHUBP_CNTL, |
2248eb6b | 1044 | HUBP_BLANK_EN, &s->blank_en, |
eb4e33b7 TC |
1045 | HUBP_TTU_DISABLE, &s->ttu_disable, |
1046 | HUBP_UNDERFLOW_STATUS, &s->underflow_status); | |
2248eb6b | 1047 | |
ae8cf977 LHM |
1048 | REG_GET(HUBP_CLK_CNTL, |
1049 | HUBP_CLOCK_ENABLE, &s->clock_en); | |
1050 | ||
2248eb6b TC |
1051 | REG_GET(DCN_GLOBAL_TTU_CNTL, |
1052 | MIN_TTU_VBLANK, &s->min_ttu_vblank); | |
1053 | ||
1054 | REG_GET_2(DCN_TTU_QOS_WM, | |
1055 | QoS_LEVEL_LOW_WM, &s->qos_level_low_wm, | |
1056 | QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm); | |
c70b4016 | 1057 | |
98e95e4f JP |
1058 | REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS, |
1059 | PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_lo); | |
1060 | ||
1061 | REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, | |
1062 | PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_hi); | |
1063 | ||
1064 | REG_GET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, | |
1065 | PRIMARY_META_SURFACE_ADDRESS, &s->primary_meta_addr_lo); | |
1066 | ||
1067 | REG_GET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, | |
1068 | PRIMARY_META_SURFACE_ADDRESS, &s->primary_meta_addr_hi); | |
2248eb6b | 1069 | } |
4bd3ae5f | 1070 | |
c70b4016 CL |
1071 | void hubp1_read_state(struct hubp *hubp) |
1072 | { | |
1073 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1074 | struct dcn_hubp_state *s = &hubp1->state; | |
1075 | struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; | |
1076 | ||
1077 | hubp1_read_state_common(hubp); | |
1078 | ||
1079 | REG_GET_8(DCHUBP_REQ_SIZE_CONFIG, | |
1080 | CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size, | |
1081 | MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size, | |
1082 | META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size, | |
1083 | MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size, | |
1084 | DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size, | |
1085 | MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size, | |
1086 | SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height, | |
1087 | PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear); | |
1088 | ||
1089 | REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C, | |
1090 | CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size, | |
1091 | MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size, | |
1092 | META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size, | |
1093 | MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size, | |
1094 | DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size, | |
1095 | MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size, | |
1096 | SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height, | |
1097 | PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear); | |
1098 | ||
1099 | } | |
36192e7e | 1100 | enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch) |
b87d78d6 YHL |
1101 | { |
1102 | enum cursor_pitch hw_pitch; | |
1103 | ||
1104 | switch (pitch) { | |
1105 | case 64: | |
1106 | hw_pitch = CURSOR_PITCH_64_PIXELS; | |
1107 | break; | |
1108 | case 128: | |
1109 | hw_pitch = CURSOR_PITCH_128_PIXELS; | |
1110 | break; | |
1111 | case 256: | |
1112 | hw_pitch = CURSOR_PITCH_256_PIXELS; | |
1113 | break; | |
1114 | default: | |
1115 | DC_ERR("Invalid cursor pitch of %d. " | |
1116 | "Only 64/128/256 is supported on DCN.\n", pitch); | |
1117 | hw_pitch = CURSOR_PITCH_64_PIXELS; | |
1118 | break; | |
1119 | } | |
1120 | return hw_pitch; | |
1121 | } | |
1122 | ||
36192e7e | 1123 | static enum cursor_lines_per_chunk hubp1_get_lines_per_chunk( |
b87d78d6 YHL |
1124 | unsigned int cur_width, |
1125 | enum dc_cursor_color_format format) | |
1126 | { | |
1127 | enum cursor_lines_per_chunk line_per_chunk; | |
1128 | ||
1129 | if (format == CURSOR_MODE_MONO) | |
1130 | /* impl B. expansion in CUR Buffer reader */ | |
1131 | line_per_chunk = CURSOR_LINE_PER_CHUNK_16; | |
1132 | else if (cur_width <= 32) | |
1133 | line_per_chunk = CURSOR_LINE_PER_CHUNK_16; | |
1134 | else if (cur_width <= 64) | |
1135 | line_per_chunk = CURSOR_LINE_PER_CHUNK_8; | |
1136 | else if (cur_width <= 128) | |
1137 | line_per_chunk = CURSOR_LINE_PER_CHUNK_4; | |
1138 | else | |
1139 | line_per_chunk = CURSOR_LINE_PER_CHUNK_2; | |
1140 | ||
1141 | return line_per_chunk; | |
1142 | } | |
1143 | ||
b7901be0 | 1144 | void hubp1_cursor_set_attributes( |
8feabd03 | 1145 | struct hubp *hubp, |
b87d78d6 YHL |
1146 | const struct dc_cursor_attributes *attr) |
1147 | { | |
8feabd03 | 1148 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
36192e7e EB |
1149 | enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch); |
1150 | enum cursor_lines_per_chunk lpc = hubp1_get_lines_per_chunk( | |
b87d78d6 YHL |
1151 | attr->width, attr->color_format); |
1152 | ||
8feabd03 | 1153 | hubp->curs_attr = *attr; |
b87d78d6 YHL |
1154 | |
1155 | REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, | |
1156 | CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); | |
1157 | REG_UPDATE(CURSOR_SURFACE_ADDRESS, | |
1158 | CURSOR_SURFACE_ADDRESS, attr->address.low_part); | |
1159 | ||
1160 | REG_UPDATE_2(CURSOR_SIZE, | |
1161 | CURSOR_WIDTH, attr->width, | |
1162 | CURSOR_HEIGHT, attr->height); | |
36192e7e | 1163 | |
b87d78d6 YHL |
1164 | REG_UPDATE_3(CURSOR_CONTROL, |
1165 | CURSOR_MODE, attr->color_format, | |
1166 | CURSOR_PITCH, hw_pitch, | |
1167 | CURSOR_LINES_PER_CHUNK, lpc); | |
36192e7e | 1168 | |
e9be38b4 EB |
1169 | REG_SET_2(CURSOR_SETTINS, 0, |
1170 | /* no shift of the cursor HDL schedule */ | |
1171 | CURSOR0_DST_Y_OFFSET, 0, | |
1172 | /* used to shift the cursor chunk request deadline */ | |
1173 | CURSOR0_CHUNK_HDL_ADJUST, 3); | |
b87d78d6 YHL |
1174 | } |
1175 | ||
b7901be0 | 1176 | void hubp1_cursor_set_position( |
8feabd03 | 1177 | struct hubp *hubp, |
b87d78d6 YHL |
1178 | const struct dc_cursor_position *pos, |
1179 | const struct dc_cursor_mi_param *param) | |
1180 | { | |
8feabd03 | 1181 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
39a9f4d8 | 1182 | int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; |
94a4ffd1 | 1183 | int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; |
08ed681c DL |
1184 | int x_hotspot = pos->x_hotspot; |
1185 | int y_hotspot = pos->y_hotspot; | |
e9e7123a JC |
1186 | int cursor_height = (int)hubp->curs_attr.height; |
1187 | int cursor_width = (int)hubp->curs_attr.width; | |
08ed681c | 1188 | uint32_t dst_x_offset; |
b87d78d6 | 1189 | uint32_t cur_en = pos->enable ? 1 : 0; |
b87d78d6 YHL |
1190 | |
1191 | /* | |
1192 | * Guard aganst cursor_set_position() from being called with invalid | |
1193 | * attributes | |
1194 | * | |
1195 | * TODO: Look at combining cursor_set_position() and | |
1196 | * cursor_set_attributes() into cursor_update() | |
1197 | */ | |
8feabd03 | 1198 | if (hubp->curs_attr.address.quad_part == 0) |
b87d78d6 YHL |
1199 | return; |
1200 | ||
e9e7123a | 1201 | // Rotated cursor width/height and hotspots tweaks for offset calculation |
08ed681c | 1202 | if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { |
e9e7123a JC |
1203 | swap(cursor_height, cursor_width); |
1204 | if (param->rotation == ROTATION_ANGLE_90) { | |
1205 | src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; | |
1206 | src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; | |
1207 | } | |
1208 | } else if (param->rotation == ROTATION_ANGLE_180) { | |
1209 | src_x_offset = pos->x - param->viewport.x; | |
1210 | src_y_offset = pos->y - param->viewport.y; | |
08ed681c DL |
1211 | } |
1212 | ||
1213 | if (param->mirror) { | |
1214 | x_hotspot = param->viewport.width - x_hotspot; | |
1215 | src_x_offset = param->viewport.x + param->viewport.width - src_x_offset; | |
1216 | } | |
1217 | ||
1218 | dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; | |
b87d78d6 YHL |
1219 | dst_x_offset *= param->ref_clk_khz; |
1220 | dst_x_offset /= param->pixel_clk_khz; | |
1221 | ||
1222 | ASSERT(param->h_scale_ratio.value); | |
1223 | ||
1224 | if (param->h_scale_ratio.value) | |
eb0e5154 DL |
1225 | dst_x_offset = dc_fixpt_floor(dc_fixpt_div( |
1226 | dc_fixpt_from_int(dst_x_offset), | |
b87d78d6 YHL |
1227 | param->h_scale_ratio)); |
1228 | ||
39a9f4d8 | 1229 | if (src_x_offset >= (int)param->viewport.width) |
b87d78d6 YHL |
1230 | cur_en = 0; /* not visible beyond right edge*/ |
1231 | ||
e9e7123a | 1232 | if (src_x_offset + cursor_width <= 0) |
b87d78d6 YHL |
1233 | cur_en = 0; /* not visible beyond left edge*/ |
1234 | ||
94a4ffd1 GL |
1235 | if (src_y_offset >= (int)param->viewport.height) |
1236 | cur_en = 0; /* not visible beyond bottom edge*/ | |
1237 | ||
e9e7123a | 1238 | if (src_y_offset + cursor_height <= 0) |
94a4ffd1 GL |
1239 | cur_en = 0; /* not visible beyond top edge*/ |
1240 | ||
b87d78d6 | 1241 | if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) |
36192e7e EB |
1242 | hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); |
1243 | ||
b87d78d6 YHL |
1244 | REG_UPDATE(CURSOR_CONTROL, |
1245 | CURSOR_ENABLE, cur_en); | |
1246 | ||
bd13b2b8 | 1247 | REG_SET_2(CURSOR_POSITION, 0, |
e6d24213 | 1248 | CURSOR_X_POSITION, pos->x, |
bd13b2b8 | 1249 | CURSOR_Y_POSITION, pos->y); |
b87d78d6 YHL |
1250 | |
1251 | REG_SET_2(CURSOR_HOT_SPOT, 0, | |
08ed681c DL |
1252 | CURSOR_HOT_SPOT_X, x_hotspot, |
1253 | CURSOR_HOT_SPOT_Y, y_hotspot); | |
b87d78d6 YHL |
1254 | |
1255 | REG_SET(CURSOR_DST_OFFSET, 0, | |
1256 | CURSOR_DST_X_OFFSET, dst_x_offset); | |
1257 | /* TODO Handle surface pixel formats other than 4:4:4 */ | |
1258 | } | |
1259 | ||
568bb205 RS |
1260 | /** |
1261 | * hubp1_clk_cntl - Disable or enable clocks for DCHUBP | |
1262 | * | |
1263 | * @hubp: hubp struct reference. | |
1264 | * @enable: Set true for enabling gate clock. | |
1265 | * | |
1266 | * When enabling/disabling DCHUBP clock, we affect dcfclk/dppclk. | |
1267 | */ | |
c8242b98 YS |
1268 | void hubp1_clk_cntl(struct hubp *hubp, bool enable) |
1269 | { | |
1270 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1271 | uint32_t clk_enable = enable ? 1 : 0; | |
1272 | ||
1273 | REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable); | |
1274 | } | |
1275 | ||
1276 | void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst) | |
1277 | { | |
1278 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1279 | ||
1280 | REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst); | |
1281 | } | |
1282 | ||
2da94e28 WC |
1283 | bool hubp1_in_blank(struct hubp *hubp) |
1284 | { | |
1285 | uint32_t in_blank; | |
1286 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1287 | ||
1288 | REG_GET(DCHUBP_CNTL, HUBP_IN_BLANK, &in_blank); | |
1289 | return in_blank ? true : false; | |
1290 | } | |
1291 | ||
1292 | void hubp1_soft_reset(struct hubp *hubp, bool reset) | |
1293 | { | |
1294 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1295 | ||
1296 | REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0); | |
1297 | } | |
1298 | ||
568bb205 RS |
1299 | /** |
1300 | * hubp1_set_flip_int - Enable surface flip interrupt | |
1301 | * | |
1302 | * @hubp: hubp struct reference. | |
1303 | */ | |
7afa0033 QZ |
1304 | void hubp1_set_flip_int(struct hubp *hubp) |
1305 | { | |
1306 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | |
1307 | ||
1308 | REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT, | |
1309 | SURFACE_FLIP_INT_MASK, 1); | |
1310 | ||
1311 | return; | |
1312 | } | |
1313 | ||
cc8d8413 CL |
1314 | void hubp1_init(struct hubp *hubp) |
1315 | { | |
1316 | //do nothing | |
1317 | } | |
bd4e7250 | 1318 | static const struct hubp_funcs dcn10_hubp_funcs = { |
8feabd03 | 1319 | .hubp_program_surface_flip_and_addr = |
b7901be0 | 1320 | hubp1_program_surface_flip_and_addr, |
8feabd03 | 1321 | .hubp_program_surface_config = |
b7901be0 | 1322 | hubp1_program_surface_config, |
8feabd03 YHL |
1323 | .hubp_is_flip_pending = hubp1_is_flip_pending, |
1324 | .hubp_setup = hubp1_setup, | |
1a1adf17 | 1325 | .hubp_setup_interdependent = hubp1_setup_interdependent, |
8feabd03 YHL |
1326 | .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings, |
1327 | .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings, | |
b7901be0 YHL |
1328 | .set_blank = hubp1_set_blank, |
1329 | .dcc_control = hubp1_dcc_control, | |
4bd3ae5f | 1330 | .mem_program_viewport = min_set_viewport, |
b7901be0 YHL |
1331 | .set_hubp_blank_en = hubp1_set_hubp_blank_en, |
1332 | .set_cursor_attributes = hubp1_cursor_set_attributes, | |
1333 | .set_cursor_position = hubp1_cursor_set_position, | |
1dbac201 | 1334 | .hubp_disconnect = hubp1_disconnect, |
c8242b98 YS |
1335 | .hubp_clk_cntl = hubp1_clk_cntl, |
1336 | .hubp_vtg_sel = hubp1_vtg_sel, | |
0a93dc7f | 1337 | .hubp_read_state = hubp1_read_state, |
eb6b29d6 | 1338 | .hubp_clear_underflow = hubp1_clear_underflow, |
3ba43a59 CL |
1339 | .hubp_disable_control = hubp1_disable_control, |
1340 | .hubp_get_underflow_status = hubp1_get_underflow_status, | |
cc8d8413 | 1341 | .hubp_init = hubp1_init, |
bbeb64d0 | 1342 | |
bbeb64d0 HW |
1343 | .dmdata_set_attributes = NULL, |
1344 | .dmdata_load = NULL, | |
2da94e28 WC |
1345 | .hubp_soft_reset = hubp1_soft_reset, |
1346 | .hubp_in_blank = hubp1_in_blank, | |
7afa0033 | 1347 | .hubp_set_flip_int = hubp1_set_flip_int, |
70ccab60 HW |
1348 | }; |
1349 | ||
70ccab60 HW |
1350 | /*****************************************/ |
1351 | /* Constructor, Destructor */ | |
1352 | /*****************************************/ | |
1353 | ||
8feabd03 YHL |
1354 | void dcn10_hubp_construct( |
1355 | struct dcn10_hubp *hubp1, | |
70ccab60 HW |
1356 | struct dc_context *ctx, |
1357 | uint32_t inst, | |
c42c275c YHL |
1358 | const struct dcn_mi_registers *hubp_regs, |
1359 | const struct dcn_mi_shift *hubp_shift, | |
1360 | const struct dcn_mi_mask *hubp_mask) | |
70ccab60 | 1361 | { |
8feabd03 YHL |
1362 | hubp1->base.funcs = &dcn10_hubp_funcs; |
1363 | hubp1->base.ctx = ctx; | |
c42c275c YHL |
1364 | hubp1->hubp_regs = hubp_regs; |
1365 | hubp1->hubp_shift = hubp_shift; | |
1366 | hubp1->hubp_mask = hubp_mask; | |
8feabd03 | 1367 | hubp1->base.inst = inst; |
043f5bb6 | 1368 | hubp1->base.opp_id = OPP_ID_INVALID; |
8feabd03 | 1369 | hubp1->base.mpcc_id = 0xf; |
70ccab60 HW |
1370 | } |
1371 | ||
e4b3b5cc | 1372 |