cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dce110_mem_input_v.c (27050B)


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