/*
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "dce_mem_input.h"
#include "reg_helper.h"
#include "basics/conversion.h"

#define CTX \
	dce_mi->base.ctx
#define REG(reg)\
	dce_mi->regs->reg

#undef FN
#define FN(reg_name, field_name) \
	dce_mi->shifts->field_name, dce_mi->masks->field_name

struct pte_setting {
	unsigned int bpp;
	unsigned int page_width;
	unsigned int page_height;
	unsigned char min_pte_before_flip_horiz_scan;
	unsigned char min_pte_before_flip_vert_scan;
	unsigned char pte_req_per_chunk;
	unsigned char param_6;
	unsigned char param_7;
	unsigned char param_8;
};

enum mi_bits_per_pixel {
	mi_bpp_8 = 0,
	mi_bpp_16,
	mi_bpp_32,
	mi_bpp_64,
	mi_bpp_count,
};

enum mi_tiling_format {
	mi_tiling_linear = 0,
	mi_tiling_1D,
	mi_tiling_2D,
	mi_tiling_count,
};

static const struct pte_setting pte_settings[mi_tiling_count][mi_bpp_count] = {
	[mi_tiling_linear] = {
		{  8, 4096, 1, 8, 0, 1, 0, 0, 0},
		{ 16, 2048, 1, 8, 0, 1, 0, 0, 0},
		{ 32, 1024, 1, 8, 0, 1, 0, 0, 0},
		{ 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
	},
	[mi_tiling_1D] = {
		{  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
		{ 16, 256, 8, 2, 0, 1, 0, 0, 0},
		{ 32, 128, 8, 4, 0, 1, 0, 0, 0},
		{ 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
	},
	[mi_tiling_2D] = {
		{  8, 64, 64,  8,  8, 1, 4, 0, 0},
		{ 16, 64, 32,  8, 16, 1, 8, 0, 0},
		{ 32, 32, 32, 16, 16, 1, 8, 0, 0},
		{ 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
	},
};

static enum mi_bits_per_pixel get_mi_bpp(
		enum surface_pixel_format format)
{
	if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616)
		return mi_bpp_64;
	else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888)
		return mi_bpp_32;
	else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB1555)
		return mi_bpp_16;
	else
		return mi_bpp_8;
}

static enum mi_tiling_format get_mi_tiling(
		union dc_tiling_info *tiling_info)
{
	switch (tiling_info->gfx8.array_mode) {
	case DC_ARRAY_1D_TILED_THIN1:
	case DC_ARRAY_1D_TILED_THICK:
	case DC_ARRAY_PRT_TILED_THIN1:
		return mi_tiling_1D;
	case DC_ARRAY_2D_TILED_THIN1:
	case DC_ARRAY_2D_TILED_THICK:
	case DC_ARRAY_2D_TILED_X_THICK:
	case DC_ARRAY_PRT_2D_TILED_THIN1:
	case DC_ARRAY_PRT_2D_TILED_THICK:
		return mi_tiling_2D;
	case DC_ARRAY_LINEAR_GENERAL:
	case DC_ARRAY_LINEAR_ALLIGNED:
		return mi_tiling_linear;
	default:
		return mi_tiling_2D;
	}
}

static bool is_vert_scan(enum dc_rotation_angle rotation)
{
	switch (rotation) {
	case ROTATION_ANGLE_90:
	case ROTATION_ANGLE_270:
		return true;
	default:
		return false;
	}
}

static void dce_mi_program_pte_vm(
		struct mem_input *mi,
		enum surface_pixel_format format,
		union dc_tiling_info *tiling_info,
		enum dc_rotation_angle rotation)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	enum mi_bits_per_pixel mi_bpp = get_mi_bpp(format);
	enum mi_tiling_format mi_tiling = get_mi_tiling(tiling_info);
	const struct pte_setting *pte = &pte_settings[mi_tiling][mi_bpp];

	unsigned int page_width = log_2(pte->page_width);
	unsigned int page_height = log_2(pte->page_height);
	unsigned int min_pte_before_flip = is_vert_scan(rotation) ?
			pte->min_pte_before_flip_vert_scan :
			pte->min_pte_before_flip_horiz_scan;

	REG_UPDATE(GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT,
			GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0x7f);

	REG_UPDATE_3(DVMM_PTE_CONTROL,
			DVMM_PAGE_WIDTH, page_width,
			DVMM_PAGE_HEIGHT, page_height,
			DVMM_MIN_PTE_BEFORE_FLIP, min_pte_before_flip);

	REG_UPDATE_2(DVMM_PTE_ARB_CONTROL,
			DVMM_PTE_REQ_PER_CHUNK, pte->pte_req_per_chunk,
			DVMM_MAX_PTE_REQ_OUTSTANDING, 0x7f);
}

static void program_urgency_watermark(
	struct dce_mem_input *dce_mi,
	uint32_t wm_select,
	uint32_t urgency_low_wm,
	uint32_t urgency_high_wm)
{
	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
		URGENCY_WATERMARK_MASK, wm_select);

	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
		URGENCY_LOW_WATERMARK, urgency_low_wm,
		URGENCY_HIGH_WATERMARK, urgency_high_wm);
}

static void dce120_program_urgency_watermark(
	struct dce_mem_input *dce_mi,
	uint32_t wm_select,
	uint32_t urgency_low_wm,
	uint32_t urgency_high_wm)
{
	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
		URGENCY_WATERMARK_MASK, wm_select);

	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
		URGENCY_LOW_WATERMARK, urgency_low_wm,
		URGENCY_HIGH_WATERMARK, urgency_high_wm);

	REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0,
		URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm,
		URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm);

}

static void program_nbp_watermark(
	struct dce_mem_input *dce_mi,
	uint32_t wm_select,
	uint32_t nbp_wm)
{
	if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
		REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
				NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);

		REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
				NB_PSTATE_CHANGE_ENABLE, 1,
				NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
				NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);

		REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
				NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
	}

	if (REG(DPG_PIPE_LOW_POWER_CONTROL)) {
		REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
				PSTATE_CHANGE_WATERMARK_MASK, wm_select);

		REG_UPDATE_3(DPG_PIPE_LOW_POWER_CONTROL,
				PSTATE_CHANGE_ENABLE, 1,
				PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
				PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);

		REG_UPDATE(DPG_PIPE_LOW_POWER_CONTROL,
				PSTATE_CHANGE_WATERMARK, nbp_wm);
	}
}

static void dce120_program_stutter_watermark(
	struct dce_mem_input *dce_mi,
	uint32_t wm_select,
	uint32_t stutter_mark,
	uint32_t stutter_entry)
{
	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);

	if (REG(DPG_PIPE_STUTTER_CONTROL2))
		REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2,
				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
				STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
	else
		REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
				STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
}

static void program_stutter_watermark(
	struct dce_mem_input *dce_mi,
	uint32_t wm_select,
	uint32_t stutter_mark)
{
	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);

	if (REG(DPG_PIPE_STUTTER_CONTROL2))
		REG_UPDATE(DPG_PIPE_STUTTER_CONTROL2,
				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
	else
		REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
}

static void dce_mi_program_display_marks(
	struct mem_input *mi,
	struct dce_watermarks nbp,
	struct dce_watermarks stutter_exit,
	struct dce_watermarks stutter_enter,
	struct dce_watermarks urgent,
	uint32_t total_dest_line_time_ns)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;

	program_urgency_watermark(dce_mi, 2, /* set a */
			urgent.a_mark, total_dest_line_time_ns);
	program_urgency_watermark(dce_mi, 1, /* set d */
			urgent.d_mark, total_dest_line_time_ns);

	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
		STUTTER_ENABLE, stutter_en,
		STUTTER_IGNORE_FBC, 1);
	program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */
	program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */

	program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */
	program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */
}

static void dce112_mi_program_display_marks(struct mem_input *mi,
	struct dce_watermarks nbp,
	struct dce_watermarks stutter_exit,
	struct dce_watermarks stutter_entry,
	struct dce_watermarks urgent,
	uint32_t total_dest_line_time_ns)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;

	program_urgency_watermark(dce_mi, 0, /* set a */
			urgent.a_mark, total_dest_line_time_ns);
	program_urgency_watermark(dce_mi, 1, /* set b */
			urgent.b_mark, total_dest_line_time_ns);
	program_urgency_watermark(dce_mi, 2, /* set c */
			urgent.c_mark, total_dest_line_time_ns);
	program_urgency_watermark(dce_mi, 3, /* set d */
			urgent.d_mark, total_dest_line_time_ns);

	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
		STUTTER_ENABLE, stutter_en,
		STUTTER_IGNORE_FBC, 1);
	program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
	program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
	program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
	program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */

	program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */
	program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */
	program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */
	program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */
}

static void dce120_mi_program_display_marks(struct mem_input *mi,
	struct dce_watermarks nbp,
	struct dce_watermarks stutter_exit,
	struct dce_watermarks stutter_entry,
	struct dce_watermarks urgent,
	uint32_t total_dest_line_time_ns)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;

	dce120_program_urgency_watermark(dce_mi, 0, /* set a */
			urgent.a_mark, total_dest_line_time_ns);
	dce120_program_urgency_watermark(dce_mi, 1, /* set b */
			urgent.b_mark, total_dest_line_time_ns);
	dce120_program_urgency_watermark(dce_mi, 2, /* set c */
			urgent.c_mark, total_dest_line_time_ns);
	dce120_program_urgency_watermark(dce_mi, 3, /* set d */
			urgent.d_mark, total_dest_line_time_ns);

	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
		STUTTER_ENABLE, stutter_en,
		STUTTER_IGNORE_FBC, 1);
	program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
	program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
	program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
	program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */

	dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */
	dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */
	dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */
	dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */
}

static void program_tiling(
	struct dce_mem_input *dce_mi, const union dc_tiling_info *info)
{
	if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
		REG_UPDATE_6(GRPH_CONTROL,
				GRPH_SW_MODE, info->gfx9.swizzle,
				GRPH_NUM_BANKS, log_2(info->gfx9.num_banks),
				GRPH_NUM_SHADER_ENGINES, log_2(info->gfx9.num_shader_engines),
				GRPH_NUM_PIPES, log_2(info->gfx9.num_pipes),
				GRPH_COLOR_EXPANSION_MODE, 1,
				GRPH_SE_ENABLE, info->gfx9.shaderEnable);
		/* TODO: DCP0_GRPH_CONTROL__GRPH_SE_ENABLE where to get info
		GRPH_SE_ENABLE, 1,
		GRPH_Z, 0);
		 */
	}

	if (dce_mi->masks->GRPH_ARRAY_MODE) { /* GFX8 */
		REG_UPDATE_9(GRPH_CONTROL,
				GRPH_NUM_BANKS, info->gfx8.num_banks,
				GRPH_BANK_WIDTH, info->gfx8.bank_width,
				GRPH_BANK_HEIGHT, info->gfx8.bank_height,
				GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
				GRPH_TILE_SPLIT, info->gfx8.tile_split,
				GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode,
				GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
				GRPH_ARRAY_MODE, info->gfx8.array_mode,
				GRPH_COLOR_EXPANSION_MODE, 1);
		/* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */
		/*
				GRPH_Z, 0);
				*/
	}
}


static void program_size_and_rotation(
	struct dce_mem_input *dce_mi,
	enum dc_rotation_angle rotation,
	const struct plane_size *plane_size)
{
	const struct rect *in_rect = &plane_size->surface_size;
	struct rect hw_rect = plane_size->surface_size;
	const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
			[ROTATION_ANGLE_0] = 0,
			[ROTATION_ANGLE_90] = 1,
			[ROTATION_ANGLE_180] = 2,
			[ROTATION_ANGLE_270] = 3,
	};

	if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) {
		hw_rect.x = in_rect->y;
		hw_rect.y = in_rect->x;

		hw_rect.height = in_rect->width;
		hw_rect.width = in_rect->height;
	}

	REG_SET(GRPH_X_START, 0,
			GRPH_X_START, hw_rect.x);

	REG_SET(GRPH_Y_START, 0,
			GRPH_Y_START, hw_rect.y);

	REG_SET(GRPH_X_END, 0,
			GRPH_X_END, hw_rect.width);

	REG_SET(GRPH_Y_END, 0,
			GRPH_Y_END, hw_rect.height);

	REG_SET(GRPH_PITCH, 0,
			GRPH_PITCH, plane_size->surface_pitch);

	REG_SET(HW_ROTATION, 0,
			GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
}

static void program_grph_pixel_format(
	struct dce_mem_input *dce_mi,
	enum surface_pixel_format format)
{
	uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
	uint32_t grph_depth = 0, grph_format = 0;
	uint32_t sign = 0, floating = 0;

	if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
			/*todo: doesn't look like we handle BGRA here,
			 *  should problem swap endian*/
		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
		/* ABGR formats */
		red_xbar = 2;
		blue_xbar = 2;
	}

	REG_SET_2(GRPH_SWAP_CNTL, 0,
			GRPH_RED_CROSSBAR, red_xbar,
			GRPH_BLUE_CROSSBAR, blue_xbar);

	switch (format) {
	case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
		grph_depth = 0;
		grph_format = 0;
		break;
	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
		grph_depth = 1;
		grph_format = 0;
		break;
	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
		grph_depth = 1;
		grph_format = 1;
		break;
	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
		grph_depth = 2;
		grph_format = 0;
		break;
	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
		grph_depth = 2;
		grph_format = 1;
		break;
	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
		sign = 1;
		floating = 1;
		/* fall through */
	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
		grph_depth = 3;
		grph_format = 0;
		break;
	default:
		DC_ERR("unsupported grph pixel format");
		break;
	}

	REG_UPDATE_2(GRPH_CONTROL,
			GRPH_DEPTH, grph_depth,
			GRPH_FORMAT, grph_format);

	REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
			GRPH_PRESCALE_SELECT, floating,
			GRPH_PRESCALE_R_SIGN, sign,
			GRPH_PRESCALE_G_SIGN, sign,
			GRPH_PRESCALE_B_SIGN, sign);
}

static void dce_mi_program_surface_config(
	struct mem_input *mi,
	enum surface_pixel_format format,
	union dc_tiling_info *tiling_info,
	struct plane_size *plane_size,
	enum dc_rotation_angle rotation,
	struct dc_plane_dcc_param *dcc,
	bool horizontal_mirror)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);

	program_tiling(dce_mi, tiling_info);
	program_size_and_rotation(dce_mi, rotation, plane_size);

	if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
		format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
		program_grph_pixel_format(dce_mi, format);
}

static uint32_t get_dmif_switch_time_us(
	uint32_t h_total,
	uint32_t v_total,
	uint32_t pix_clk_khz)
{
	uint32_t frame_time;
	uint32_t pixels_per_second;
	uint32_t pixels_per_frame;
	uint32_t refresh_rate;
	const uint32_t us_in_sec = 1000000;
	const uint32_t min_single_frame_time_us = 30000;
	/*return double of frame time*/
	const uint32_t single_frame_time_multiplier = 2;

	if (!h_total || v_total || !pix_clk_khz)
		return single_frame_time_multiplier * min_single_frame_time_us;

	/*TODO: should we use pixel format normalized pixel clock here?*/
	pixels_per_second = pix_clk_khz * 1000;
	pixels_per_frame = h_total * v_total;

	if (!pixels_per_second || !pixels_per_frame) {
		/* avoid division by zero */
		ASSERT(pixels_per_frame);
		ASSERT(pixels_per_second);
		return single_frame_time_multiplier * min_single_frame_time_us;
	}

	refresh_rate = pixels_per_second / pixels_per_frame;

	if (!refresh_rate) {
		/* avoid division by zero*/
		ASSERT(refresh_rate);
		return single_frame_time_multiplier * min_single_frame_time_us;
	}

	frame_time = us_in_sec / refresh_rate;

	if (frame_time < min_single_frame_time_us)
		frame_time = min_single_frame_time_us;

	frame_time *= single_frame_time_multiplier;

	return frame_time;
}

static void dce_mi_allocate_dmif(
	struct mem_input *mi,
	uint32_t h_total,
	uint32_t v_total,
	uint32_t pix_clk_khz,
	uint32_t total_stream_num)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	const uint32_t retry_delay = 10;
	uint32_t retry_count = get_dmif_switch_time_us(
			h_total,
			v_total,
			pix_clk_khz) / retry_delay;

	uint32_t pix_dur;
	uint32_t buffers_allocated;
	uint32_t dmif_buffer_control;

	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);

	if (buffers_allocated == 2)
		return;

	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
			DMIF_BUFFERS_ALLOCATED, 2);

	REG_WAIT(DMIF_BUFFER_CONTROL,
			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
			retry_delay, retry_count);

	if (pix_clk_khz != 0) {
		pix_dur = 1000000000ULL / pix_clk_khz;

		REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
			PIXEL_DURATION, pix_dur);
	}

	if (dce_mi->wa.single_head_rdreq_dmif_limit) {
		uint32_t eanble =  (total_stream_num > 1) ? 0 :
				dce_mi->wa.single_head_rdreq_dmif_limit;

		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
				ENABLE, eanble);
	}
}

static void dce_mi_free_dmif(
		struct mem_input *mi,
		uint32_t total_stream_num)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
	uint32_t buffers_allocated;
	uint32_t dmif_buffer_control;

	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);

	if (buffers_allocated == 0)
		return;

	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
			DMIF_BUFFERS_ALLOCATED, 0);

	REG_WAIT(DMIF_BUFFER_CONTROL,
			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
			10, 3500);

	if (dce_mi->wa.single_head_rdreq_dmif_limit) {
		uint32_t eanble =  (total_stream_num > 1) ? 0 :
				dce_mi->wa.single_head_rdreq_dmif_limit;

		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
				ENABLE, eanble);
	}
}


static void program_sec_addr(
	struct dce_mem_input *dce_mi,
	PHYSICAL_ADDRESS_LOC address)
{
	/*high register MUST be programmed first*/
	REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
		GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
		address.high_part);

	REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0,
		GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8,
		GRPH_SECONDARY_DFQ_ENABLE, 0);
}

static void program_pri_addr(
	struct dce_mem_input *dce_mi,
	PHYSICAL_ADDRESS_LOC address)
{
	/*high register MUST be programmed first*/
	REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
		address.high_part);

	REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0,
		GRPH_PRIMARY_SURFACE_ADDRESS,
		address.low_part >> 8);
}


static bool dce_mi_is_flip_pending(struct mem_input *mem_input)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
	uint32_t update_pending;

	REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending);
	if (update_pending)
		return true;

	mem_input->current_address = mem_input->request_address;
	return false;
}

static bool dce_mi_program_surface_flip_and_addr(
	struct mem_input *mem_input,
	const struct dc_plane_address *address,
	bool flip_immediate)
{
	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);

	REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);

	REG_UPDATE(
		GRPH_FLIP_CONTROL,
		GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0);

	switch (address->type) {
	case PLN_ADDR_TYPE_GRAPHICS:
		if (address->grph.addr.quad_part == 0)
			break;
		program_pri_addr(dce_mi, address->grph.addr);
		break;
	case PLN_ADDR_TYPE_GRPH_STEREO:
		if (address->grph_stereo.left_addr.quad_part == 0 ||
		    address->grph_stereo.right_addr.quad_part == 0)
			break;
		program_pri_addr(dce_mi, address->grph_stereo.left_addr);
		program_sec_addr(dce_mi, address->grph_stereo.right_addr);
		break;
	default:
		/* not supported */
		BREAK_TO_DEBUGGER();
		break;
	}

	mem_input->request_address = *address;

	if (flip_immediate)
		mem_input->current_address = *address;

	REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);

	return true;
}

static const struct mem_input_funcs dce_mi_funcs = {
	.mem_input_program_display_marks = dce_mi_program_display_marks,
	.allocate_mem_input = dce_mi_allocate_dmif,
	.free_mem_input = dce_mi_free_dmif,
	.mem_input_program_surface_flip_and_addr =
			dce_mi_program_surface_flip_and_addr,
	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
	.mem_input_program_surface_config =
			dce_mi_program_surface_config,
	.mem_input_is_flip_pending = dce_mi_is_flip_pending
};

static const struct mem_input_funcs dce112_mi_funcs = {
	.mem_input_program_display_marks = dce112_mi_program_display_marks,
	.allocate_mem_input = dce_mi_allocate_dmif,
	.free_mem_input = dce_mi_free_dmif,
	.mem_input_program_surface_flip_and_addr =
			dce_mi_program_surface_flip_and_addr,
	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
	.mem_input_program_surface_config =
			dce_mi_program_surface_config,
	.mem_input_is_flip_pending = dce_mi_is_flip_pending
};

static const struct mem_input_funcs dce120_mi_funcs = {
	.mem_input_program_display_marks = dce120_mi_program_display_marks,
	.allocate_mem_input = dce_mi_allocate_dmif,
	.free_mem_input = dce_mi_free_dmif,
	.mem_input_program_surface_flip_and_addr =
			dce_mi_program_surface_flip_and_addr,
	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
	.mem_input_program_surface_config =
			dce_mi_program_surface_config,
	.mem_input_is_flip_pending = dce_mi_is_flip_pending
};

void dce_mem_input_construct(
	struct dce_mem_input *dce_mi,
	struct dc_context *ctx,
	int inst,
	const struct dce_mem_input_registers *regs,
	const struct dce_mem_input_shift *mi_shift,
	const struct dce_mem_input_mask *mi_mask)
{
	dce_mi->base.ctx = ctx;

	dce_mi->base.inst = inst;
	dce_mi->base.funcs = &dce_mi_funcs;

	dce_mi->regs = regs;
	dce_mi->shifts = mi_shift;
	dce_mi->masks = mi_mask;
}

void dce112_mem_input_construct(
	struct dce_mem_input *dce_mi,
	struct dc_context *ctx,
	int inst,
	const struct dce_mem_input_registers *regs,
	const struct dce_mem_input_shift *mi_shift,
	const struct dce_mem_input_mask *mi_mask)
{
	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
	dce_mi->base.funcs = &dce112_mi_funcs;
}

void dce120_mem_input_construct(
	struct dce_mem_input *dce_mi,
	struct dc_context *ctx,
	int inst,
	const struct dce_mem_input_registers *regs,
	const struct dce_mem_input_shift *mi_shift,
	const struct dce_mem_input_mask *mi_mask)
{
	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
	dce_mi->base.funcs = &dce120_mi_funcs;
}
