File Index
Files and directories
Sign in
FILE

dce110_mem_input_v.c

File preview with syntax highlighting.

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