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