Home | History | Annotate | Line # | Download | only in dce110
      1 /*	$NetBSD: amdgpu_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2012-16 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_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $");
     29 
     30 #include "dm_services.h"
     31 
     32 #include "dce/dce_11_0_d.h"
     33 #include "dce/dce_11_0_sh_mask.h"
     34 /* TODO: this needs to be looked at, used by Stella's workaround*/
     35 #include "gmc/gmc_8_2_d.h"
     36 #include "gmc/gmc_8_2_sh_mask.h"
     37 
     38 #include "include/logger_interface.h"
     39 #include "inc/dce_calcs.h"
     40 
     41 #include "dce/dce_mem_input.h"
     42 #include "dce110/dce110_mem_input_v.h"
     43 
     44 static void set_flip_control(
     45 	struct dce_mem_input *mem_input110,
     46 	bool immediate)
     47 {
     48 	uint32_t value = 0;
     49 
     50 	value = dm_read_reg(
     51 			mem_input110->base.ctx,
     52 			mmUNP_FLIP_CONTROL);
     53 
     54 	set_reg_field_value(value, 1,
     55 			UNP_FLIP_CONTROL,
     56 			GRPH_SURFACE_UPDATE_PENDING_MODE);
     57 
     58 	dm_write_reg(
     59 			mem_input110->base.ctx,
     60 			mmUNP_FLIP_CONTROL,
     61 			value);
     62 }
     63 
     64 /* chroma part */
     65 static void program_pri_addr_c(
     66 	struct dce_mem_input *mem_input110,
     67 	PHYSICAL_ADDRESS_LOC address)
     68 {
     69 	uint32_t value = 0;
     70 	uint32_t temp = 0;
     71 	/*high register MUST be programmed first*/
     72 	temp = address.high_part &
     73 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
     74 
     75 	set_reg_field_value(value, temp,
     76 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
     77 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
     78 
     79 	dm_write_reg(
     80 		mem_input110->base.ctx,
     81 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
     82 		value);
     83 
     84 	temp = 0;
     85 	value = 0;
     86 	temp = address.low_part >>
     87 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
     88 
     89 	set_reg_field_value(value, temp,
     90 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
     91 		GRPH_PRIMARY_SURFACE_ADDRESS_C);
     92 
     93 	dm_write_reg(
     94 		mem_input110->base.ctx,
     95 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
     96 		value);
     97 }
     98 
     99 /* luma part */
    100 static void program_pri_addr_l(
    101 	struct dce_mem_input *mem_input110,
    102 	PHYSICAL_ADDRESS_LOC address)
    103 {
    104 	uint32_t value = 0;
    105 	uint32_t temp = 0;
    106 
    107 	/*high register MUST be programmed first*/
    108 	temp = address.high_part &
    109 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
    110 
    111 	set_reg_field_value(value, temp,
    112 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
    113 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
    114 
    115 	dm_write_reg(
    116 		mem_input110->base.ctx,
    117 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
    118 		value);
    119 
    120 	temp = 0;
    121 	value = 0;
    122 	temp = address.low_part >>
    123 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
    124 
    125 	set_reg_field_value(value, temp,
    126 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
    127 		GRPH_PRIMARY_SURFACE_ADDRESS_L);
    128 
    129 	dm_write_reg(
    130 		mem_input110->base.ctx,
    131 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
    132 		value);
    133 }
    134 
    135 static void program_addr(
    136 	struct dce_mem_input *mem_input110,
    137 	const struct dc_plane_address *addr)
    138 {
    139 	switch (addr->type) {
    140 	case PLN_ADDR_TYPE_GRAPHICS:
    141 		program_pri_addr_l(
    142 			mem_input110,
    143 			addr->grph.addr);
    144 		break;
    145 	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
    146 		program_pri_addr_c(
    147 			mem_input110,
    148 			addr->video_progressive.chroma_addr);
    149 		program_pri_addr_l(
    150 			mem_input110,
    151 			addr->video_progressive.luma_addr);
    152 		break;
    153 	default:
    154 		/* not supported */
    155 		BREAK_TO_DEBUGGER();
    156 	}
    157 }
    158 
    159 static void enable(struct dce_mem_input *mem_input110)
    160 {
    161 	uint32_t value = 0;
    162 
    163 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
    164 	set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
    165 	dm_write_reg(mem_input110->base.ctx,
    166 		mmUNP_GRPH_ENABLE,
    167 		value);
    168 }
    169 
    170 static void program_tiling(
    171 	struct dce_mem_input *mem_input110,
    172 	const union dc_tiling_info *info,
    173 	const enum surface_pixel_format pixel_format)
    174 {
    175 	uint32_t value = 0;
    176 
    177 	set_reg_field_value(value, info->gfx8.num_banks,
    178 		UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
    179 
    180 	set_reg_field_value(value, info->gfx8.bank_width,
    181 		UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
    182 
    183 	set_reg_field_value(value, info->gfx8.bank_height,
    184 		UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
    185 
    186 	set_reg_field_value(value, info->gfx8.tile_aspect,
    187 		UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
    188 
    189 	set_reg_field_value(value, info->gfx8.tile_split,
    190 		UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
    191 
    192 	set_reg_field_value(value, info->gfx8.tile_mode,
    193 		UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
    194 
    195 	set_reg_field_value(value, info->gfx8.pipe_config,
    196 		UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
    197 
    198 	set_reg_field_value(value, info->gfx8.array_mode,
    199 		UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
    200 
    201 	set_reg_field_value(value, 1,
    202 		UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
    203 
    204 	set_reg_field_value(value, 0,
    205 		UNP_GRPH_CONTROL, GRPH_Z);
    206 
    207 	dm_write_reg(
    208 		mem_input110->base.ctx,
    209 		mmUNP_GRPH_CONTROL,
    210 		value);
    211 
    212 	value = 0;
    213 
    214 	set_reg_field_value(value, info->gfx8.bank_width_c,
    215 		UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
    216 
    217 	set_reg_field_value(value, info->gfx8.bank_height_c,
    218 		UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
    219 
    220 	set_reg_field_value(value, info->gfx8.tile_aspect_c,
    221 		UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
    222 
    223 	set_reg_field_value(value, info->gfx8.tile_split_c,
    224 		UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
    225 
    226 	set_reg_field_value(value, info->gfx8.tile_mode_c,
    227 		UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
    228 
    229 	dm_write_reg(
    230 		mem_input110->base.ctx,
    231 		mmUNP_GRPH_CONTROL_C,
    232 		value);
    233 }
    234 
    235 static void program_size_and_rotation(
    236 	struct dce_mem_input *mem_input110,
    237 	enum dc_rotation_angle rotation,
    238 	const struct plane_size *plane_size)
    239 {
    240 	uint32_t value = 0;
    241 	struct plane_size local_size = *plane_size;
    242 
    243 	if (rotation == ROTATION_ANGLE_90 ||
    244 		rotation == ROTATION_ANGLE_270) {
    245 
    246 		swap(local_size.surface_size.x,
    247 		     local_size.surface_size.y);
    248 		swap(local_size.surface_size.width,
    249 		     local_size.surface_size.height);
    250 		swap(local_size.chroma_size.x,
    251 		     local_size.chroma_size.y);
    252 		swap(local_size.chroma_size.width,
    253 		     local_size.chroma_size.height);
    254 	}
    255 
    256 	value = 0;
    257 	set_reg_field_value(value, local_size.surface_pitch,
    258 			UNP_GRPH_PITCH_L, GRPH_PITCH_L);
    259 
    260 	dm_write_reg(
    261 		mem_input110->base.ctx,
    262 		mmUNP_GRPH_PITCH_L,
    263 		value);
    264 
    265 	value = 0;
    266 	set_reg_field_value(value, local_size.chroma_pitch,
    267 			UNP_GRPH_PITCH_C, GRPH_PITCH_C);
    268 	dm_write_reg(
    269 		mem_input110->base.ctx,
    270 		mmUNP_GRPH_PITCH_C,
    271 		value);
    272 
    273 	value = 0;
    274 	set_reg_field_value(value, 0,
    275 			UNP_GRPH_X_START_L, GRPH_X_START_L);
    276 	dm_write_reg(
    277 		mem_input110->base.ctx,
    278 		mmUNP_GRPH_X_START_L,
    279 		value);
    280 
    281 	value = 0;
    282 	set_reg_field_value(value, 0,
    283 			UNP_GRPH_X_START_C, GRPH_X_START_C);
    284 	dm_write_reg(
    285 		mem_input110->base.ctx,
    286 		mmUNP_GRPH_X_START_C,
    287 		value);
    288 
    289 	value = 0;
    290 	set_reg_field_value(value, 0,
    291 			UNP_GRPH_Y_START_L, GRPH_Y_START_L);
    292 	dm_write_reg(
    293 		mem_input110->base.ctx,
    294 		mmUNP_GRPH_Y_START_L,
    295 		value);
    296 
    297 	value = 0;
    298 	set_reg_field_value(value, 0,
    299 			UNP_GRPH_Y_START_C, GRPH_Y_START_C);
    300 	dm_write_reg(
    301 		mem_input110->base.ctx,
    302 		mmUNP_GRPH_Y_START_C,
    303 		value);
    304 
    305 	value = 0;
    306 	set_reg_field_value(value, local_size.surface_size.x +
    307 			local_size.surface_size.width,
    308 			UNP_GRPH_X_END_L, GRPH_X_END_L);
    309 	dm_write_reg(
    310 		mem_input110->base.ctx,
    311 		mmUNP_GRPH_X_END_L,
    312 		value);
    313 
    314 	value = 0;
    315 	set_reg_field_value(value, local_size.chroma_size.x +
    316 			local_size.chroma_size.width,
    317 			UNP_GRPH_X_END_C, GRPH_X_END_C);
    318 	dm_write_reg(
    319 		mem_input110->base.ctx,
    320 		mmUNP_GRPH_X_END_C,
    321 		value);
    322 
    323 	value = 0;
    324 	set_reg_field_value(value, local_size.surface_size.y +
    325 			local_size.surface_size.height,
    326 			UNP_GRPH_Y_END_L, GRPH_Y_END_L);
    327 	dm_write_reg(
    328 		mem_input110->base.ctx,
    329 		mmUNP_GRPH_Y_END_L,
    330 		value);
    331 
    332 	value = 0;
    333 	set_reg_field_value(value, local_size.chroma_size.y +
    334 			local_size.chroma_size.height,
    335 			UNP_GRPH_Y_END_C, GRPH_Y_END_C);
    336 	dm_write_reg(
    337 		mem_input110->base.ctx,
    338 		mmUNP_GRPH_Y_END_C,
    339 		value);
    340 
    341 	value = 0;
    342 	switch (rotation) {
    343 	case ROTATION_ANGLE_90:
    344 		set_reg_field_value(value, 3,
    345 			UNP_HW_ROTATION, ROTATION_ANGLE);
    346 		break;
    347 	case ROTATION_ANGLE_180:
    348 		set_reg_field_value(value, 2,
    349 			UNP_HW_ROTATION, ROTATION_ANGLE);
    350 		break;
    351 	case ROTATION_ANGLE_270:
    352 		set_reg_field_value(value, 1,
    353 			UNP_HW_ROTATION, ROTATION_ANGLE);
    354 		break;
    355 	default:
    356 		set_reg_field_value(value, 0,
    357 			UNP_HW_ROTATION, ROTATION_ANGLE);
    358 		break;
    359 	}
    360 
    361 	dm_write_reg(
    362 		mem_input110->base.ctx,
    363 		mmUNP_HW_ROTATION,
    364 		value);
    365 }
    366 
    367 static void program_pixel_format(
    368 	struct dce_mem_input *mem_input110,
    369 	enum surface_pixel_format format)
    370 {
    371 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
    372 		uint32_t value;
    373 		uint8_t grph_depth;
    374 		uint8_t grph_format;
    375 
    376 		value =	dm_read_reg(
    377 				mem_input110->base.ctx,
    378 				mmUNP_GRPH_CONTROL);
    379 
    380 		switch (format) {
    381 		case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
    382 			grph_depth = 0;
    383 			grph_format = 0;
    384 			break;
    385 		case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
    386 			grph_depth = 1;
    387 			grph_format = 1;
    388 			break;
    389 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
    390 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
    391 			grph_depth = 2;
    392 			grph_format = 0;
    393 			break;
    394 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
    395 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
    396 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
    397 			grph_depth = 2;
    398 			grph_format = 1;
    399 			break;
    400 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
    401 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
    402 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
    403 			grph_depth = 3;
    404 			grph_format = 0;
    405 			break;
    406 		default:
    407 			grph_depth = 2;
    408 			grph_format = 0;
    409 			break;
    410 		}
    411 
    412 		set_reg_field_value(
    413 				value,
    414 				grph_depth,
    415 				UNP_GRPH_CONTROL,
    416 				GRPH_DEPTH);
    417 		set_reg_field_value(
    418 				value,
    419 				grph_format,
    420 				UNP_GRPH_CONTROL,
    421 				GRPH_FORMAT);
    422 
    423 		dm_write_reg(
    424 				mem_input110->base.ctx,
    425 				mmUNP_GRPH_CONTROL,
    426 				value);
    427 
    428 		value =	dm_read_reg(
    429 				mem_input110->base.ctx,
    430 				mmUNP_GRPH_CONTROL_EXP);
    431 
    432 		/* VIDEO FORMAT 0 */
    433 		set_reg_field_value(
    434 				value,
    435 				0,
    436 				UNP_GRPH_CONTROL_EXP,
    437 				VIDEO_FORMAT);
    438 		dm_write_reg(
    439 				mem_input110->base.ctx,
    440 				mmUNP_GRPH_CONTROL_EXP,
    441 				value);
    442 
    443 	} else {
    444 		/* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
    445 		uint32_t value;
    446 		uint8_t video_format;
    447 
    448 		value =	dm_read_reg(
    449 				mem_input110->base.ctx,
    450 				mmUNP_GRPH_CONTROL_EXP);
    451 
    452 		switch (format) {
    453 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
    454 			video_format = 2;
    455 			break;
    456 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
    457 			video_format = 3;
    458 			break;
    459 		default:
    460 			video_format = 0;
    461 			break;
    462 		}
    463 
    464 		set_reg_field_value(
    465 			value,
    466 			video_format,
    467 			UNP_GRPH_CONTROL_EXP,
    468 			VIDEO_FORMAT);
    469 
    470 		dm_write_reg(
    471 			mem_input110->base.ctx,
    472 			mmUNP_GRPH_CONTROL_EXP,
    473 			value);
    474 	}
    475 }
    476 
    477 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
    478 {
    479 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
    480 	uint32_t value;
    481 
    482 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
    483 
    484 	if (get_reg_field_value(value, UNP_GRPH_UPDATE,
    485 			GRPH_SURFACE_UPDATE_PENDING))
    486 		return true;
    487 
    488 	mem_input->current_address = mem_input->request_address;
    489 	return false;
    490 }
    491 
    492 bool dce_mem_input_v_program_surface_flip_and_addr(
    493 	struct mem_input *mem_input,
    494 	const struct dc_plane_address *address,
    495 	bool flip_immediate)
    496 {
    497 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
    498 
    499 	set_flip_control(mem_input110, flip_immediate);
    500 	program_addr(mem_input110,
    501 		address);
    502 
    503 	mem_input->request_address = *address;
    504 
    505 	return true;
    506 }
    507 
    508 /* Scatter Gather param tables */
    509 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
    510 		{  8, 64, 64,  8,  8, 1, 4, 0, 0},
    511 		{ 16, 64, 32,  8, 16, 1, 8, 0, 0},
    512 		{ 32, 32, 32, 16, 16, 1, 8, 0, 0},
    513 		{ 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
    514 };
    515 
    516 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
    517 		{  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
    518 		{ 16, 256, 8, 2, 0, 1, 0, 0, 0},
    519 		{ 32, 128, 8, 4, 0, 1, 0, 0, 0},
    520 		{ 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
    521 };
    522 
    523 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
    524 		{  8, 4096, 1, 8, 0, 1, 0, 0, 0},
    525 		{ 16, 2048, 1, 8, 0, 1, 0, 0, 0},
    526 		{ 32, 1024, 1, 8, 0, 1, 0, 0, 0},
    527 		{ 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
    528 };
    529 
    530 /* Helper to get table entry from surface info */
    531 static const unsigned int *get_dvmm_hw_setting(
    532 		union dc_tiling_info *tiling_info,
    533 		enum surface_pixel_format format,
    534 		bool chroma)
    535 {
    536 	enum bits_per_pixel {
    537 		bpp_8 = 0,
    538 		bpp_16,
    539 		bpp_32,
    540 		bpp_64
    541 	} bpp;
    542 
    543 	if (format >= SURFACE_PIXEL_FORMAT_INVALID)
    544 		bpp = bpp_32;
    545 	else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
    546 		bpp = chroma ? bpp_16 : bpp_8;
    547 	else
    548 		bpp = bpp_8;
    549 
    550 	switch (tiling_info->gfx8.array_mode) {
    551 	case DC_ARRAY_1D_TILED_THIN1:
    552 	case DC_ARRAY_1D_TILED_THICK:
    553 	case DC_ARRAY_PRT_TILED_THIN1:
    554 		return dvmm_Hw_Setting_1DTiling[bpp];
    555 	case DC_ARRAY_2D_TILED_THIN1:
    556 	case DC_ARRAY_2D_TILED_THICK:
    557 	case DC_ARRAY_2D_TILED_X_THICK:
    558 	case DC_ARRAY_PRT_2D_TILED_THIN1:
    559 	case DC_ARRAY_PRT_2D_TILED_THICK:
    560 		return dvmm_Hw_Setting_2DTiling[bpp];
    561 	case DC_ARRAY_LINEAR_GENERAL:
    562 	case DC_ARRAY_LINEAR_ALLIGNED:
    563 		return dvmm_Hw_Setting_Linear[bpp];
    564 	default:
    565 		return dvmm_Hw_Setting_2DTiling[bpp];
    566 	}
    567 }
    568 
    569 void dce_mem_input_v_program_pte_vm(
    570 		struct mem_input *mem_input,
    571 		enum surface_pixel_format format,
    572 		union dc_tiling_info *tiling_info,
    573 		enum dc_rotation_angle rotation)
    574 {
    575 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
    576 	const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
    577 	const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
    578 
    579 	unsigned int page_width = 0;
    580 	unsigned int page_height = 0;
    581 	unsigned int page_width_chroma = 0;
    582 	unsigned int page_height_chroma = 0;
    583 	unsigned int temp_page_width = pte[1];
    584 	unsigned int temp_page_height = pte[2];
    585 	unsigned int min_pte_before_flip = 0;
    586 	unsigned int min_pte_before_flip_chroma = 0;
    587 	uint32_t value = 0;
    588 
    589 	while ((temp_page_width >>= 1) != 0)
    590 		page_width++;
    591 	while ((temp_page_height >>= 1) != 0)
    592 		page_height++;
    593 
    594 	temp_page_width = pte_chroma[1];
    595 	temp_page_height = pte_chroma[2];
    596 	while ((temp_page_width >>= 1) != 0)
    597 		page_width_chroma++;
    598 	while ((temp_page_height >>= 1) != 0)
    599 		page_height_chroma++;
    600 
    601 	switch (rotation) {
    602 	case ROTATION_ANGLE_90:
    603 	case ROTATION_ANGLE_270:
    604 		min_pte_before_flip = pte[4];
    605 		min_pte_before_flip_chroma = pte_chroma[4];
    606 		break;
    607 	default:
    608 		min_pte_before_flip = pte[3];
    609 		min_pte_before_flip_chroma = pte_chroma[3];
    610 		break;
    611 	}
    612 
    613 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
    614 	/* TODO: un-hardcode requestlimit */
    615 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
    616 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
    617 	dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
    618 
    619 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
    620 	set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
    621 	set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
    622 	set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
    623 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
    624 
    625 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
    626 	set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
    627 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
    628 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
    629 
    630 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
    631 	set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
    632 	set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
    633 	set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
    634 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
    635 
    636 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
    637 	set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
    638 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
    639 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
    640 }
    641 
    642 void dce_mem_input_v_program_surface_config(
    643 	struct mem_input *mem_input,
    644 	enum surface_pixel_format format,
    645 	union dc_tiling_info *tiling_info,
    646 	struct plane_size *plane_size,
    647 	enum dc_rotation_angle rotation,
    648 	struct dc_plane_dcc_param *dcc,
    649 	bool horizotal_mirror)
    650 {
    651 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
    652 
    653 	enable(mem_input110);
    654 	program_tiling(mem_input110, tiling_info, format);
    655 	program_size_and_rotation(mem_input110, rotation, plane_size);
    656 	program_pixel_format(mem_input110, format);
    657 }
    658 
    659 static void program_urgency_watermark(
    660 	const struct dc_context *ctx,
    661 	const uint32_t urgency_addr,
    662 	const uint32_t wm_addr,
    663 	struct dce_watermarks marks_low,
    664 	uint32_t total_dest_line_time_ns)
    665 {
    666 	/* register value */
    667 	uint32_t urgency_cntl = 0;
    668 	uint32_t wm_mask_cntl = 0;
    669 
    670 	/*Write mask to enable reading/writing of watermark set A*/
    671 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
    672 	set_reg_field_value(wm_mask_cntl,
    673 			1,
    674 			DPGV0_WATERMARK_MASK_CONTROL,
    675 			URGENCY_WATERMARK_MASK);
    676 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
    677 
    678 	urgency_cntl = dm_read_reg(ctx, urgency_addr);
    679 
    680 	set_reg_field_value(
    681 		urgency_cntl,
    682 		marks_low.a_mark,
    683 		DPGV0_PIPE_URGENCY_CONTROL,
    684 		URGENCY_LOW_WATERMARK);
    685 
    686 	set_reg_field_value(
    687 		urgency_cntl,
    688 		total_dest_line_time_ns,
    689 		DPGV0_PIPE_URGENCY_CONTROL,
    690 		URGENCY_HIGH_WATERMARK);
    691 	dm_write_reg(ctx, urgency_addr, urgency_cntl);
    692 
    693 	/*Write mask to enable reading/writing of watermark set B*/
    694 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
    695 	set_reg_field_value(wm_mask_cntl,
    696 			2,
    697 			DPGV0_WATERMARK_MASK_CONTROL,
    698 			URGENCY_WATERMARK_MASK);
    699 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
    700 
    701 	urgency_cntl = dm_read_reg(ctx, urgency_addr);
    702 
    703 	set_reg_field_value(urgency_cntl,
    704 		marks_low.b_mark,
    705 		DPGV0_PIPE_URGENCY_CONTROL,
    706 		URGENCY_LOW_WATERMARK);
    707 
    708 	set_reg_field_value(urgency_cntl,
    709 		total_dest_line_time_ns,
    710 		DPGV0_PIPE_URGENCY_CONTROL,
    711 		URGENCY_HIGH_WATERMARK);
    712 
    713 	dm_write_reg(ctx, urgency_addr, urgency_cntl);
    714 }
    715 
    716 static void program_urgency_watermark_l(
    717 	const struct dc_context *ctx,
    718 	struct dce_watermarks marks_low,
    719 	uint32_t total_dest_line_time_ns)
    720 {
    721 	program_urgency_watermark(
    722 		ctx,
    723 		mmDPGV0_PIPE_URGENCY_CONTROL,
    724 		mmDPGV0_WATERMARK_MASK_CONTROL,
    725 		marks_low,
    726 		total_dest_line_time_ns);
    727 }
    728 
    729 static void program_urgency_watermark_c(
    730 	const struct dc_context *ctx,
    731 	struct dce_watermarks marks_low,
    732 	uint32_t total_dest_line_time_ns)
    733 {
    734 	program_urgency_watermark(
    735 		ctx,
    736 		mmDPGV1_PIPE_URGENCY_CONTROL,
    737 		mmDPGV1_WATERMARK_MASK_CONTROL,
    738 		marks_low,
    739 		total_dest_line_time_ns);
    740 }
    741 
    742 static void program_stutter_watermark(
    743 	const struct dc_context *ctx,
    744 	const uint32_t stutter_addr,
    745 	const uint32_t wm_addr,
    746 	struct dce_watermarks marks)
    747 {
    748 	/* register value */
    749 	uint32_t stutter_cntl = 0;
    750 	uint32_t wm_mask_cntl = 0;
    751 
    752 	/*Write mask to enable reading/writing of watermark set A*/
    753 
    754 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
    755 	set_reg_field_value(wm_mask_cntl,
    756 		1,
    757 		DPGV0_WATERMARK_MASK_CONTROL,
    758 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
    759 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
    760 
    761 	stutter_cntl = dm_read_reg(ctx, stutter_addr);
    762 
    763 	if (ctx->dc->debug.disable_stutter) {
    764 		set_reg_field_value(stutter_cntl,
    765 			0,
    766 			DPGV0_PIPE_STUTTER_CONTROL,
    767 			STUTTER_ENABLE);
    768 	} else {
    769 		set_reg_field_value(stutter_cntl,
    770 			1,
    771 			DPGV0_PIPE_STUTTER_CONTROL,
    772 			STUTTER_ENABLE);
    773 	}
    774 
    775 	set_reg_field_value(stutter_cntl,
    776 		1,
    777 		DPGV0_PIPE_STUTTER_CONTROL,
    778 		STUTTER_IGNORE_FBC);
    779 
    780 	/*Write watermark set A*/
    781 	set_reg_field_value(stutter_cntl,
    782 		marks.a_mark,
    783 		DPGV0_PIPE_STUTTER_CONTROL,
    784 		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
    785 	dm_write_reg(ctx, stutter_addr, stutter_cntl);
    786 
    787 	/*Write mask to enable reading/writing of watermark set B*/
    788 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
    789 	set_reg_field_value(wm_mask_cntl,
    790 		2,
    791 		DPGV0_WATERMARK_MASK_CONTROL,
    792 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
    793 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
    794 
    795 	stutter_cntl = dm_read_reg(ctx, stutter_addr);
    796 	/*Write watermark set B*/
    797 	set_reg_field_value(stutter_cntl,
    798 		marks.b_mark,
    799 		DPGV0_PIPE_STUTTER_CONTROL,
    800 		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
    801 	dm_write_reg(ctx, stutter_addr, stutter_cntl);
    802 }
    803 
    804 static void program_stutter_watermark_l(
    805 	const struct dc_context *ctx,
    806 	struct dce_watermarks marks)
    807 {
    808 	program_stutter_watermark(ctx,
    809 			mmDPGV0_PIPE_STUTTER_CONTROL,
    810 			mmDPGV0_WATERMARK_MASK_CONTROL,
    811 			marks);
    812 }
    813 
    814 static void program_stutter_watermark_c(
    815 	const struct dc_context *ctx,
    816 	struct dce_watermarks marks)
    817 {
    818 	program_stutter_watermark(ctx,
    819 			mmDPGV1_PIPE_STUTTER_CONTROL,
    820 			mmDPGV1_WATERMARK_MASK_CONTROL,
    821 			marks);
    822 }
    823 
    824 static void program_nbp_watermark(
    825 	const struct dc_context *ctx,
    826 	const uint32_t wm_mask_ctrl_addr,
    827 	const uint32_t nbp_pstate_ctrl_addr,
    828 	struct dce_watermarks marks)
    829 {
    830 	uint32_t value;
    831 
    832 	/* Write mask to enable reading/writing of watermark set A */
    833 
    834 	value = dm_read_reg(ctx, wm_mask_ctrl_addr);
    835 
    836 	set_reg_field_value(
    837 		value,
    838 		1,
    839 		DPGV0_WATERMARK_MASK_CONTROL,
    840 		NB_PSTATE_CHANGE_WATERMARK_MASK);
    841 	dm_write_reg(ctx, wm_mask_ctrl_addr, value);
    842 
    843 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
    844 
    845 	set_reg_field_value(
    846 		value,
    847 		1,
    848 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    849 		NB_PSTATE_CHANGE_ENABLE);
    850 	set_reg_field_value(
    851 		value,
    852 		1,
    853 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    854 		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
    855 	set_reg_field_value(
    856 		value,
    857 		1,
    858 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    859 		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
    860 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
    861 
    862 	/* Write watermark set A */
    863 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
    864 	set_reg_field_value(
    865 		value,
    866 		marks.a_mark,
    867 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    868 		NB_PSTATE_CHANGE_WATERMARK);
    869 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
    870 
    871 	/* Write mask to enable reading/writing of watermark set B */
    872 	value = dm_read_reg(ctx, wm_mask_ctrl_addr);
    873 	set_reg_field_value(
    874 		value,
    875 		2,
    876 		DPGV0_WATERMARK_MASK_CONTROL,
    877 		NB_PSTATE_CHANGE_WATERMARK_MASK);
    878 	dm_write_reg(ctx, wm_mask_ctrl_addr, value);
    879 
    880 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
    881 	set_reg_field_value(
    882 		value,
    883 		1,
    884 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    885 		NB_PSTATE_CHANGE_ENABLE);
    886 	set_reg_field_value(
    887 		value,
    888 		1,
    889 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    890 		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
    891 	set_reg_field_value(
    892 		value,
    893 		1,
    894 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    895 		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
    896 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
    897 
    898 	/* Write watermark set B */
    899 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
    900 	set_reg_field_value(
    901 		value,
    902 		marks.b_mark,
    903 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    904 		NB_PSTATE_CHANGE_WATERMARK);
    905 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
    906 }
    907 
    908 static void program_nbp_watermark_l(
    909 	const struct dc_context *ctx,
    910 	struct dce_watermarks marks)
    911 {
    912 	program_nbp_watermark(ctx,
    913 			mmDPGV0_WATERMARK_MASK_CONTROL,
    914 			mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
    915 			marks);
    916 }
    917 
    918 static void program_nbp_watermark_c(
    919 	const struct dc_context *ctx,
    920 	struct dce_watermarks marks)
    921 {
    922 	program_nbp_watermark(ctx,
    923 			mmDPGV1_WATERMARK_MASK_CONTROL,
    924 			mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL,
    925 			marks);
    926 }
    927 
    928 void dce_mem_input_v_program_display_marks(
    929 	struct mem_input *mem_input,
    930 	struct dce_watermarks nbp,
    931 	struct dce_watermarks stutter,
    932 	struct dce_watermarks stutter_enter,
    933 	struct dce_watermarks urgent,
    934 	uint32_t total_dest_line_time_ns)
    935 {
    936 	program_urgency_watermark_l(
    937 		mem_input->ctx,
    938 		urgent,
    939 		total_dest_line_time_ns);
    940 
    941 	program_nbp_watermark_l(
    942 		mem_input->ctx,
    943 		nbp);
    944 
    945 	program_stutter_watermark_l(
    946 		mem_input->ctx,
    947 		stutter);
    948 
    949 }
    950 
    951 void dce_mem_input_program_chroma_display_marks(
    952 	struct mem_input *mem_input,
    953 	struct dce_watermarks nbp,
    954 	struct dce_watermarks stutter,
    955 	struct dce_watermarks urgent,
    956 	uint32_t total_dest_line_time_ns)
    957 {
    958 	program_urgency_watermark_c(
    959 		mem_input->ctx,
    960 		urgent,
    961 		total_dest_line_time_ns);
    962 
    963 	program_nbp_watermark_c(
    964 		mem_input->ctx,
    965 		nbp);
    966 
    967 	program_stutter_watermark_c(
    968 		mem_input->ctx,
    969 		stutter);
    970 }
    971 
    972 void dce110_allocate_mem_input_v(
    973 	struct mem_input *mi,
    974 	uint32_t h_total,/* for current stream */
    975 	uint32_t v_total,/* for current stream */
    976 	uint32_t pix_clk_khz,/* for current stream */
    977 	uint32_t total_stream_num)
    978 {
    979 	uint32_t addr;
    980 	uint32_t value;
    981 	uint32_t pix_dur;
    982 	if (pix_clk_khz != 0) {
    983 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
    984 		value = dm_read_reg(mi->ctx, addr);
    985 		pix_dur = 1000000000ULL / pix_clk_khz;
    986 		set_reg_field_value(
    987 			value,
    988 			pix_dur,
    989 			DPGV0_PIPE_ARBITRATION_CONTROL1,
    990 			PIXEL_DURATION);
    991 		dm_write_reg(mi->ctx, addr, value);
    992 
    993 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
    994 		value = dm_read_reg(mi->ctx, addr);
    995 		pix_dur = 1000000000ULL / pix_clk_khz;
    996 		set_reg_field_value(
    997 			value,
    998 			pix_dur,
    999 			DPGV1_PIPE_ARBITRATION_CONTROL1,
   1000 			PIXEL_DURATION);
   1001 		dm_write_reg(mi->ctx, addr, value);
   1002 
   1003 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
   1004 		value = 0x4000800;
   1005 		dm_write_reg(mi->ctx, addr, value);
   1006 
   1007 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
   1008 		value = 0x4000800;
   1009 		dm_write_reg(mi->ctx, addr, value);
   1010 	}
   1011 
   1012 }
   1013 
   1014 void dce110_free_mem_input_v(
   1015 	struct mem_input *mi,
   1016 	uint32_t total_stream_num)
   1017 {
   1018 }
   1019 
   1020 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
   1021 	.mem_input_program_display_marks =
   1022 			dce_mem_input_v_program_display_marks,
   1023 	.mem_input_program_chroma_display_marks =
   1024 			dce_mem_input_program_chroma_display_marks,
   1025 	.allocate_mem_input = dce110_allocate_mem_input_v,
   1026 	.free_mem_input = dce110_free_mem_input_v,
   1027 	.mem_input_program_surface_flip_and_addr =
   1028 			dce_mem_input_v_program_surface_flip_and_addr,
   1029 	.mem_input_program_pte_vm =
   1030 			dce_mem_input_v_program_pte_vm,
   1031 	.mem_input_program_surface_config =
   1032 			dce_mem_input_v_program_surface_config,
   1033 	.mem_input_is_flip_pending =
   1034 			dce_mem_input_v_is_surface_pending
   1035 };
   1036 /*****************************************/
   1037 /* Constructor, Destructor               */
   1038 /*****************************************/
   1039 
   1040 void dce110_mem_input_v_construct(
   1041 	struct dce_mem_input *dce_mi,
   1042 	struct dc_context *ctx)
   1043 {
   1044 	dce_mi->base.funcs = &dce110_mem_input_v_funcs;
   1045 	dce_mi->base.ctx = ctx;
   1046 }
   1047 
   1048