All of lore.kernel.org
 help / color / mirror / Atom feed
From: cailiwei <cailiwei@hisilicon.com>
To: <linux-fbdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<b.zolnierkie@samsung.com>, <guodong.xu@linaro.org>
Cc: <suzhuangluan@hisilicon.com>, <dengqingshan@hisilicon.com>,
	<xuhongtao8@hisilicon.com>, <zhengwanchun@hisilicon.com>,
	<shizongxuan@huawei.com>, <cailiwei@hisilicon.com>
Subject: [PATCH 7/8] fb: hisilicon: Add framebuffer driver for hi3660 SoC
Date: Tue, 7 Feb 2017 10:35:58 +0800	[thread overview]
Message-ID: <20170207023559.79455-7-cailiwei@hisilicon.com> (raw)
In-Reply-To: <20170207023559.79455-1-cailiwei@hisilicon.com>

From: Levy-Cai <cailiwei@hisilicon.com>

Add framebuffer driver for hi3660 SoC, this driver include lcd
driver & Hdmi adv7533/adv7535 driver, support lcd display at
1080p@60 and hdmi display at 1080p@60.

Signed-off-by: cailiwei <cailiwei@hisilicon.com>
---
 drivers/video/fbdev/hisi/dss/hisi_overlay_online.c |  733 ++
 drivers/video/fbdev/hisi/dss/hisi_overlay_utils.c  | 8495 ++++++++++++++++++++
 drivers/video/fbdev/hisi/dss/hisi_overlay_utils.h  |  269 +
 .../fbdev/hisi/dss/hisi_overlay_utils_hi3660.c     | 2741 +++++++
 .../fbdev/hisi/dss/hisi_overlay_utils_hi3660.h     |   73 +
 5 files changed, 12311 insertions(+)
 create mode 100755 drivers/video/fbdev/hisi/dss/hisi_overlay_online.c
 create mode 100755 drivers/video/fbdev/hisi/dss/hisi_overlay_utils.c
 create mode 100755 drivers/video/fbdev/hisi/dss/hisi_overlay_utils.h
 create mode 100755 drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.c
 create mode 100755 drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.h

diff --git a/drivers/video/fbdev/hisi/dss/hisi_overlay_online.c b/drivers/video/fbdev/hisi/dss/hisi_overlay_online.c
new file mode 100755
index 000000000000..9cb65225dc63
--- /dev/null
+++ b/drivers/video/fbdev/hisi/dss/hisi_overlay_online.c
@@ -0,0 +1,733 @@
+/* Copyright (c) 2013-2014, Hisilicon Tech. Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "hisi_overlay_utils.h"
+#include "hisi_dpe_utils.h"
+
+static int hisi_get_ov_data_from_user(struct hisi_fb_data_type *hisifd,
+				      dss_overlay_t *pov_req,
+				      void __user *argp)
+{
+	int ret = 0;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	if (NULL == argp) {
+		HISI_FB_ERR("user data is invalid\n");
+		return -EINVAL;
+	}
+	pov_h_block_infos = hisifd->ov_block_infos;
+
+	ret = copy_from_user(pov_req, argp, sizeof(dss_overlay_t));
+	if (ret) {
+		HISI_FB_ERR("fb%d, copy_from_user failed!\n", hisifd->index);
+		return -EINVAL;
+	}
+
+	if ((pov_req->ov_block_nums <= 0) ||
+	    (pov_req->ov_block_nums > HISI_DSS_OV_BLOCK_NUMS)) {
+		HISI_FB_ERR("fb%d, ov_block_nums(%d) is out of range!\n",
+			    hisifd->index, pov_req->ov_block_nums);
+		return -EINVAL;
+	}
+
+	ret =
+	    copy_from_user(pov_h_block_infos,
+			   (dss_overlay_block_t *) pov_req->ov_block_infos_ptr,
+			   pov_req->ov_block_nums *
+			   sizeof(dss_overlay_block_t));
+	if (ret) {
+		HISI_FB_ERR
+		    ("fb%d, dss_overlay_block_t copy_from_user failed!\n",
+		     hisifd->index);
+		return -EINVAL;
+	}
+
+	ret = hisi_dss_check_userdata(hisifd, pov_req, pov_h_block_infos);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_check_userdata failed!\n",
+			    hisifd->index);
+		return -EINVAL;
+	}
+
+	pov_req->ov_block_infos_ptr = (uint64_t) pov_h_block_infos;
+
+	return ret;
+}
+
+int hisi_overlay_pan_display(struct hisi_fb_data_type *hisifd)
+{
+	int ret = 0;
+	struct fb_info *fbi = NULL;
+	dss_overlay_t *pov_req = NULL;
+	dss_overlay_t *pov_req_prev = NULL;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_h_block = NULL;
+	dss_layer_t *layer = NULL;
+	dss_rect_ltrb_t clip_rect;
+	dss_rect_t aligned_rect;
+	bool rdma_stretch_enable = false;
+	uint32_t offset = 0;
+	uint32_t addr = 0;
+	int hal_format = 0;
+	uint32_t cmdlist_pre_idxs = 0;
+	uint32_t cmdlist_idxs = 0;
+	int enable_cmdlist = 0;
+	bool has_base = false;
+
+	if (NULL == hisifd) {
+		HISI_FB_ERR("hisi fd is invalid\n");
+		return -EINVAL;
+	}
+	fbi = hisifd->fbi;
+	if (NULL == fbi) {
+		HISI_FB_ERR("hisifd fbi is invalid\n");
+		return -EINVAL;
+	}
+
+	pov_req = &(hisifd->ov_req);
+	pov_req_prev = &(hisifd->ov_req_prev);
+
+	if (!hisifd->panel_power_on) {
+		HISI_FB_INFO("fb%d, panel is power off!", hisifd->index);
+		return 0;
+	}
+
+	if (g_debug_ldi_underflow) {
+		if (g_err_status &
+		    (DSS_PDP_LDI_UNDERFLOW | DSS_SDP_LDI_UNDERFLOW))
+			return 0;
+	}
+
+	offset = fbi->var.xoffset * (fbi->var.bits_per_pixel >> 3) +
+	    fbi->var.yoffset * fbi->fix.line_length;
+	addr = fbi->fix.smem_start + offset;
+	if (!fbi->fix.smem_start) {
+		HISI_FB_ERR("fb%d, smem_start is null!\n", hisifd->index);
+		return -EINVAL;
+	}
+
+	if (fbi->fix.smem_len <= 0) {
+		HISI_FB_ERR("fb%d, smem_len(%d) is out of range!\n",
+			    hisifd->index, fbi->fix.smem_len);
+		return -EINVAL;
+	}
+
+	hal_format = hisi_get_hal_format(fbi);
+	if (hal_format < 0) {
+		HISI_FB_ERR("fb%d, not support this fb_info's format!\n",
+			    hisifd->index);
+		return -EINVAL;
+	}
+
+	enable_cmdlist = g_enable_ovl_cmdlist_online;
+	if ((hisifd->index == EXTERNAL_PANEL_IDX)
+	    && hisifd->panel_info.fake_hdmi)
+		enable_cmdlist = 0;
+
+	hisifb_activate_vsync(hisifd);
+
+	ret = hisi_vactive0_start_config(hisifd, pov_req);
+	if (ret != 0) {
+		HISI_FB_ERR
+		    ("fb%d, hisi_vactive0_start_config failed! ret = %d\n",
+		     hisifd->index, ret);
+		goto err_return;
+	}
+
+	if (g_debug_ovl_online_composer == 1) {
+		dumpDssOverlay(hisifd, pov_req, false);
+	}
+
+	memset(pov_req, 0, sizeof(dss_overlay_t));
+	pov_req->ov_block_infos_ptr = (uint64_t) (&(hisifd->ov_block_infos));
+	pov_req->ov_block_nums = 1;
+	pov_req->ovl_idx = DSS_OVL0;
+	pov_req->dirty_rect.x = 0;
+	pov_req->dirty_rect.y = 0;
+	pov_req->dirty_rect.w = fbi->var.xres;
+	pov_req->dirty_rect.h = fbi->var.yres;
+
+	pov_req->res_updt_rect.x = 0;
+	pov_req->res_updt_rect.y = 0;
+	pov_req->res_updt_rect.w = fbi->var.xres;
+	pov_req->res_updt_rect.h = fbi->var.yres;
+
+	pov_h_block_infos =
+	    (dss_overlay_block_t *) (pov_req->ov_block_infos_ptr);
+	pov_h_block = &(pov_h_block_infos[0]);
+	pov_h_block->layer_nums = 1;
+
+	layer = &(pov_h_block->layer_infos[0]);
+	layer->img.format = hal_format;
+	layer->img.width = fbi->var.xres;
+	layer->img.height = fbi->var.yres;
+	layer->img.bpp = fbi->var.bits_per_pixel >> 3;
+	layer->img.stride = fbi->fix.line_length;
+	layer->img.buf_size = layer->img.stride * layer->img.height;
+	layer->img.phy_addr = addr;
+	layer->img.vir_addr = addr;
+	layer->img.mmu_enable = 1;
+	layer->src_rect.x = 0;
+	layer->src_rect.y = 0;
+	layer->src_rect.w = fbi->var.xres;
+	layer->src_rect.h = fbi->var.yres;
+	layer->dst_rect.x = 0;
+	layer->dst_rect.y = 0;
+	layer->dst_rect.w = fbi->var.xres;
+	layer->dst_rect.h = fbi->var.yres;
+	layer->transform = HISI_FB_TRANSFORM_NOP;
+	layer->blending = HISI_FB_BLENDING_NONE;
+	layer->glb_alpha = 0xFF;
+	layer->color = 0x0;
+	layer->layer_idx = 0x0;
+	layer->chn_idx = DSS_RCHN_D2;
+	layer->need_cap = 0;
+
+	hisi_dss_handle_cur_ovl_req(hisifd, pov_req);
+
+	ret = hisi_dss_module_init(hisifd);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_module_init failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+
+	hisi_mmbuf_info_get_online(hisifd);
+
+	if (enable_cmdlist) {
+		hisifd->set_reg = hisi_cmdlist_set_reg;
+
+		hisi_cmdlist_data_get_online(hisifd);
+
+		ret =
+		    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev,
+						  &cmdlist_pre_idxs, NULL);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_cmdlist_get_cmdlist_idxs pov_req_prev failed! "
+			     "ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		ret =
+		    hisi_cmdlist_get_cmdlist_idxs(pov_req, &cmdlist_pre_idxs,
+						  &cmdlist_idxs);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_cmdlist_get_cmdlist_idxs pov_req failed! "
+			     "ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_pre_idxs, 0, 0);
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs, 0, 0);
+	} else {
+		hisifd->set_reg = hisifb_set_reg;
+
+		hisi_dss_mctl_mutex_lock(hisifd, pov_req->ovl_idx);
+		cmdlist_pre_idxs = ~0;
+	}
+
+	hisi_dss_prev_module_set_regs(hisifd, pov_req_prev, cmdlist_pre_idxs,
+				      enable_cmdlist, NULL);
+
+	hisi_dss_aif_handler(hisifd, pov_req, pov_h_block);
+
+	ret =
+	    hisi_dss_ovl_base_config(hisifd, pov_req, NULL, NULL,
+				     pov_req->ovl_idx, 0);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_ovl_init failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+
+	ret =
+	    hisi_ov_compose_handler(hisifd, pov_req, pov_h_block, layer, NULL,
+				    NULL, &clip_rect, &aligned_rect,
+				    &rdma_stretch_enable, &has_base, true,
+				    enable_cmdlist);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_ov_compose_handler failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret =
+	    hisi_dss_mctl_ov_config(hisifd, pov_req, pov_req->ovl_idx, has_base,
+				    true);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_mctl_config failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+
+	if (hisifd->panel_info.dirty_region_updt_support) {
+		ret = hisi_dss_dirty_region_dbuf_config(hisifd, pov_req);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_dirty_region_dbuf_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	ret = hisi_dss_post_scf_config(hisifd, pov_req);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_post_scf_config failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+
+	ret =
+	    hisi_dss_ov_module_set_regs(hisifd, pov_req, pov_req->ovl_idx,
+					enable_cmdlist, 0, 0, true);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_module_config failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+	hisi_dss_unflow_handler(hisifd, pov_req, true);
+
+	if (enable_cmdlist) {
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs, 0, 0);
+		hisi_cmdlist_config_stop(hisifd, cmdlist_pre_idxs);
+
+		cmdlist_idxs |= cmdlist_pre_idxs;
+		hisi_cmdlist_flush_cache(hisifd, hisifd->ion_client,
+					 cmdlist_idxs);
+
+		if (g_debug_ovl_cmdlist) {
+			hisi_cmdlist_dump_all_node(hisifd, NULL, cmdlist_idxs);
+		}
+
+		hisi_cmdlist_config_start(hisifd, pov_req->ovl_idx,
+					  cmdlist_idxs, 0);
+	} else {
+		hisi_dss_mctl_mutex_unlock(hisifd, pov_req->ovl_idx);
+	}
+
+	if (hisifd->panel_info.dirty_region_updt_support) {
+		hisi_dss_dirty_region_updt_config(hisifd, pov_req);
+	}
+
+	single_frame_update(hisifd);
+	hisifb_frame_updated(hisifd);
+
+	hisifb_deactivate_vsync(hisifd);
+
+	hisifd->frame_count++;
+	memcpy(&hisifd->ov_req_prev_prev, &hisifd->ov_req_prev,
+	       sizeof(dss_overlay_t));
+	memcpy(&(hisifd->ov_block_infos_prev_prev),
+	       &(hisifd->ov_block_infos_prev),
+	       hisifd->ov_req_prev.ov_block_nums * sizeof(dss_overlay_block_t));
+	hisifd->ov_req_prev_prev.ov_block_infos_ptr =
+	    (uint64_t) (&(hisifd->ov_block_infos_prev_prev));
+
+	memcpy(&hisifd->ov_req_prev, pov_req, sizeof(dss_overlay_t));
+	memcpy(&(hisifd->ov_block_infos_prev), &(hisifd->ov_block_infos),
+	       pov_req->ov_block_nums * sizeof(dss_overlay_block_t));
+	hisifd->ov_req_prev.ov_block_infos_ptr =
+	    (uint64_t) (&(hisifd->ov_block_infos_prev));
+
+	return 0;
+
+ err_return:
+	if (is_mipi_cmd_panel(hisifd)) {
+		hisifd->vactive0_start_flag = 1;
+	} else {
+		single_frame_update(hisifd);
+	}
+	hisifb_deactivate_vsync(hisifd);
+
+	return ret;
+}
+
+int hisi_ov_online_play(struct hisi_fb_data_type *hisifd, void __user *argp)
+{
+	static int dss_free_buffer_refcount;
+	dss_overlay_t *pov_req = NULL;
+	dss_overlay_t *pov_req_prev = NULL;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_h_block = NULL;
+	dss_layer_t *layer = NULL;
+	dss_rect_ltrb_t clip_rect;
+	dss_rect_t aligned_rect;
+	bool rdma_stretch_enable = false;
+	uint32_t cmdlist_pre_idxs = 0;
+	uint32_t cmdlist_idxs = 0;
+	int enable_cmdlist = 0;
+	bool has_base = false;
+#ifdef CONFIG_BUF_SYNC_USED
+	unsigned long flags = 0;
+#endif
+	int need_skip = 0;
+	int i = 0;
+	int m = 0;
+	int ret = 0;
+	uint32_t timediff = 0;
+	struct list_head lock_list;
+	struct timeval tv0;
+	struct timeval tv1;
+	struct timeval tv2;
+	struct timeval tv3;
+
+	if (NULL == hisifd) {
+		HISI_FB_ERR("NULL Pointer!\n");
+		return -EINVAL;
+	}
+
+	if (NULL == argp) {
+		HISI_FB_ERR("NULL Pointer!\n");
+		return -EINVAL;
+	}
+
+	pov_req = &(hisifd->ov_req);
+	pov_req_prev = &(hisifd->ov_req_prev);
+	INIT_LIST_HEAD(&lock_list);
+
+	if (!hisifd->panel_power_on) {
+		HISI_FB_INFO("fb%d, panel is power off!\n", hisifd->index);
+		return 0;
+	}
+
+	if (g_debug_ovl_online_composer_return) {
+		return 0;
+	}
+
+	if (g_debug_ovl_online_composer_timediff & 0x2) {
+		hisifb_get_timestamp(&tv0);
+	}
+
+	enable_cmdlist = g_enable_ovl_cmdlist_online;
+	if ((hisifd->index == EXTERNAL_PANEL_IDX)
+	    && hisifd->panel_info.fake_hdmi) {
+		enable_cmdlist = 0;
+	}
+
+	hisifb_activate_vsync(hisifd);
+
+	if (g_debug_ovl_online_composer_timediff & 0x4) {
+		hisifb_get_timestamp(&tv2);
+	}
+
+	ret = hisi_get_ov_data_from_user(hisifd, pov_req, argp);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_get_ov_data_from_user failed! ret=%d\n",
+			    hisifd->index, ret);
+		need_skip = 1;
+		goto err_return;
+	}
+#ifdef CONFIG_BUF_SYNC_USED
+	if (is_mipi_video_panel(hisifd)) {
+		ret = hisifb_buf_sync_handle(hisifd, pov_req);
+		if (ret < 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisifb_buf_sync_handle failed! ret=%d\n",
+			     hisifd->index, ret);
+			need_skip = 1;
+			goto err_return;
+		}
+	}
+#endif
+
+	ret = hisi_vactive0_start_config(hisifd, pov_req);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_vactive0_start_config failed! ret=%d\n",
+			    hisifd->index, ret);
+		need_skip = 1;
+		goto err_return;
+	}
+	down(&hisifd->blank_sem0);
+
+	if (g_debug_ovl_online_composer_timediff & 0x4) {
+		hisifb_get_timestamp(&tv3);
+		timediff = hisifb_timestamp_diff(&tv2, &tv3);
+		if (timediff >= g_debug_ovl_online_composer_time_threshold)
+			HISI_FB_ERR("ONLINE_VACTIVE_TIMEDIFF is %u us!\n",
+				    timediff);
+	}
+
+	if (g_debug_ovl_online_composer == 1) {
+		dumpDssOverlay(hisifd, pov_req, false);
+	}
+
+	ret = hisifb_layerbuf_lock(hisifd, pov_req, &lock_list);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisifb_layerbuf_lock failed! ret=%d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+
+	hisi_dss_handle_cur_ovl_req(hisifd, pov_req);
+
+	ret = hisi_dss_module_init(hisifd);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_dss_module_init failed! ret = %d\n",
+			    hisifd->index, ret);
+		goto err_return;
+	}
+	hisi_mmbuf_info_get_online(hisifd);
+
+	if (enable_cmdlist) {
+		hisifd->set_reg = hisi_cmdlist_set_reg;
+		hisi_cmdlist_data_get_online(hisifd);
+
+		ret =
+		    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev,
+						  &cmdlist_pre_idxs, NULL);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_cmdlist_get_cmdlist_idxs pov_req_prev failed! "
+			     "ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		ret =
+		    hisi_cmdlist_get_cmdlist_idxs(pov_req, &cmdlist_pre_idxs,
+						  &cmdlist_idxs);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_cmdlist_get_cmdlist_idxs pov_req failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_pre_idxs, 0, 0);
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs, 0, 0);
+	} else {
+		hisifd->set_reg = hisifb_set_reg;
+		hisi_dss_mctl_mutex_lock(hisifd, pov_req->ovl_idx);
+		cmdlist_pre_idxs = ~0;
+	}
+
+	hisi_dss_prev_module_set_regs(hisifd, pov_req_prev, cmdlist_pre_idxs,
+				      enable_cmdlist, NULL);
+
+	pov_h_block_infos =
+	    (dss_overlay_block_t *) (pov_req->ov_block_infos_ptr);
+	for (m = 0; m < pov_req->ov_block_nums; m++) {
+		pov_h_block = &(pov_h_block_infos[m]);
+
+		ret = hisi_dss_module_init(hisifd);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_module_init failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+		hisi_dss_aif_handler(hisifd, pov_req, pov_h_block);
+
+		ret =
+		    hisi_dss_ovl_base_config(hisifd, pov_req, pov_h_block, NULL,
+					     pov_req->ovl_idx, m);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_ovl_init failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		for (i = 0; i < pov_h_block->layer_nums; i++) {
+			layer = &(pov_h_block->layer_infos[i]);
+			memset(&clip_rect, 0, sizeof(dss_rect_ltrb_t));
+			memset(&aligned_rect, 0, sizeof(dss_rect_ltrb_t));
+			rdma_stretch_enable = false;
+
+			ret =
+			    hisi_ov_compose_handler(hisifd, pov_req,
+						    pov_h_block, layer, NULL,
+						    NULL, &clip_rect,
+						    &aligned_rect,
+						    &rdma_stretch_enable,
+						    &has_base, true,
+						    enable_cmdlist);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, hisi_ov_compose_handler failed! ret = %d\n",
+				     hisifd->index, ret);
+				goto err_return;
+			}
+		}
+
+		ret =
+		    hisi_dss_mctl_ov_config(hisifd, pov_req, pov_req->ovl_idx,
+					    has_base, (m == 0));
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_mctl_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		if (m == 0) {
+			if (hisifd->panel_info.dirty_region_updt_support) {
+				ret =
+				    hisi_dss_dirty_region_dbuf_config(hisifd, pov_req);
+				if (ret != 0) {
+					HISI_FB_ERR
+					    ("fb%d, hisi_dss_dirty_region_dbuf_config failed! ret = %d\n",
+					     hisifd->index, ret);
+					goto err_return;
+				}
+			}
+		}
+
+		ret = hisi_dss_post_scf_config(hisifd, pov_req);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_post_scf_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+
+		ret =
+		    hisi_dss_ov_module_set_regs(hisifd, pov_req,
+						pov_req->ovl_idx,
+						enable_cmdlist, 0, 0, (m == 0));
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_module_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	if (enable_cmdlist) {
+		g_online_cmdlist_idxs |= cmdlist_idxs;
+		hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs, 0, 0);
+		hisi_cmdlist_config_stop(hisifd, cmdlist_pre_idxs);
+
+		cmdlist_idxs |= cmdlist_pre_idxs;
+		hisi_cmdlist_flush_cache(hisifd, hisifd->ion_client,
+					 cmdlist_idxs);
+	}
+
+	ret = hisi_crc_enable(hisifd, pov_req);
+	if (ret != 0) {
+		HISI_FB_ERR("fb%d, hisi_crc_enable failed!\n", hisifd->index);
+		goto err_return;
+	}
+	hisi_dss_unflow_handler(hisifd, pov_req, true);
+
+#ifdef CONFIG_BUF_SYNC_USED
+	if (is_mipi_cmd_panel(hisifd)) {
+		ret = hisifb_buf_sync_handle(hisifd, pov_req);
+		if (ret < 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisifb_buf_sync_handle failed! ret=%d\n",
+			     hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	pov_req->release_fence =
+	    hisifb_buf_sync_create_fence(hisifd,
+					 ++hisifd->buf_sync_ctrl.timeline_max);
+	if (pov_req->release_fence < 0) {
+		HISI_FB_INFO
+		    ("fb%d, hisi_create_fence failed! pov_req->release_fence = 0x%x\n",
+		     hisifd->index, pov_req->release_fence);
+	}
+
+	spin_lock_irqsave(&hisifd->buf_sync_ctrl.refresh_lock, flags);
+	hisifd->buf_sync_ctrl.refresh++;
+	spin_unlock_irqrestore(&hisifd->buf_sync_ctrl.refresh_lock, flags);
+#endif
+
+	if (enable_cmdlist) {
+		hisi_cmdlist_config_start(hisifd, pov_req->ovl_idx,
+					  cmdlist_idxs, 0);
+	} else {
+		hisi_dss_mctl_mutex_unlock(hisifd, pov_req->ovl_idx);
+	}
+
+	if (hisifd->panel_info.dirty_region_updt_support) {
+		hisi_dss_dirty_region_updt_config(hisifd, pov_req);
+	}
+
+	single_frame_update(hisifd);
+	hisifb_frame_updated(hisifd);
+	hisi_crc_config(hisifd, pov_req);
+
+	if (copy_to_user((struct dss_overlay_t __user *)argp,
+			 pov_req, sizeof(dss_overlay_t))) {
+		ret = -EFAULT;
+
+		if (pov_req->release_fence >= 0)
+			put_unused_fd(pov_req->release_fence);
+
+		goto err_return;
+	}
+
+	hisifb_deactivate_vsync(hisifd);
+	hisifb_layerbuf_flush(hisifd, &lock_list);
+
+	if ((hisifd->index == PRIMARY_PANEL_IDX)
+	    && (dss_free_buffer_refcount > 1)) {
+		if (!hisifd->fb_mem_free_flag) {
+			hisifb_free_fb_buffer(hisifd);
+			hisifd->fb_mem_free_flag = true;
+		}
+	}
+
+	if (g_debug_ovl_online_composer == 2) {
+		dumpDssOverlay(hisifd, pov_req, true);
+	}
+
+	if (g_debug_ovl_cmdlist && enable_cmdlist)
+		hisi_cmdlist_dump_all_node(hisifd, NULL, cmdlist_idxs);
+
+	hisifd->frame_count++;
+	dss_free_buffer_refcount++;
+	memcpy(&hisifd->ov_req_prev_prev, &hisifd->ov_req_prev,
+	       sizeof(dss_overlay_t));
+	memcpy(&(hisifd->ov_block_infos_prev_prev),
+	       &(hisifd->ov_block_infos_prev),
+	       hisifd->ov_req_prev.ov_block_nums * sizeof(dss_overlay_block_t));
+	hisifd->ov_req_prev_prev.ov_block_infos_ptr =
+	    (uint64_t) (&(hisifd->ov_block_infos_prev_prev));
+
+	memcpy(&hisifd->ov_req_prev, pov_req, sizeof(dss_overlay_t));
+	memcpy(&(hisifd->ov_block_infos_prev), &(hisifd->ov_block_infos),
+	       pov_req->ov_block_nums * sizeof(dss_overlay_block_t));
+	hisifd->ov_req_prev.ov_block_infos_ptr =
+	    (uint64_t) (&(hisifd->ov_block_infos_prev));
+
+	if (g_debug_ovl_online_composer_timediff & 0x2) {
+		hisifb_get_timestamp(&tv1);
+		timediff = hisifb_timestamp_diff(&tv0, &tv1);
+		if (timediff >= g_debug_ovl_online_composer_time_threshold)
+			HISI_FB_ERR("ONLINE_TIMEDIFF is %u us!\n", timediff);
+	}
+	up(&hisifd->blank_sem0);
+
+	return 0;
+
+ err_return:
+	if (is_mipi_cmd_panel(hisifd)) {
+		hisifd->vactive0_start_flag = 1;
+	}
+	hisifb_layerbuf_lock_exception(hisifd, &lock_list);
+	hisifb_deactivate_vsync(hisifd);
+	if (!need_skip) {
+		up(&hisifd->blank_sem0);
+	}
+	return ret;
+}
diff --git a/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.c b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.c
new file mode 100755
index 000000000000..97d71df5a38d
--- /dev/null
+++ b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.c
@@ -0,0 +1,8495 @@
+/* Copyright (c) 2013-2014, Hisilicon Tech. Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ */
+/*lint -e778 -e732*/
+
+#include "hisi_overlay_utils.h"
+#include "hisi_dpe_utils.h"
+
+#define SMMU_RW_ERR_ADDR_SIZE	(128)
+
+/* mmbuf gen pool */
+static struct gen_pool *g_mmbuf_gen_pool = NULL;
+static dss_mmbuf_t g_pre_online_mmbuf[DSS_CHN_MAX_DEFINE] = { {0, 0} };
+
+static uint32_t vactive_timeout_count = 0;
+
+static inline bool hisi_dss_is_sharpness_support(int32_t width, int32_t height)
+{
+	return ((16 <= width) && (width <= 1600) && (4 <= height)
+		&& (height <= 2560));
+}
+
+/*******************************************************************************
+ **
+ */
+static int32_t hisi_transform2degree(uint32_t transform)
+{
+	int ret = 0;
+
+	switch (transform) {
+	case HISI_FB_TRANSFORM_NOP:
+	case HISI_FB_TRANSFORM_FLIP_H:
+	case HISI_FB_TRANSFORM_FLIP_V:
+		ret = 0;
+		break;
+	case HISI_FB_TRANSFORM_ROT_90:
+		ret = 90;
+		break;
+	case HISI_FB_TRANSFORM_ROT_180:
+		ret = 180;
+		break;
+	case HISI_FB_TRANSFORM_ROT_270:
+		ret = 270;
+		break;
+	default:
+		ret = -1;
+		HISI_FB_ERR("not support transform(%d)!", transform);
+		break;
+	}
+
+	return ret;
+}
+
+#define DUMP_BUF_SIZE	SZ_256K
+
+struct dss_dump_data_type {
+	char *dss_buf;
+	uint32_t dss_buf_len;
+	char dss_filename[256];
+
+	char *scene_buf;
+	uint32_t scene_buf_len;
+	char scene_filename[256];
+
+	char image_bin_filename[MAX_DSS_SRC_NUM][256];
+};
+
+void dumpDssOverlay(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req,
+		    bool isNeedSaveFile)
+{
+	uint32_t i = 0;
+	uint32_t k = 0;
+	dss_layer_t const *layer = NULL;
+	dss_wb_layer_t const *wb_layer = NULL;
+	struct timeval tv;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_block_info = NULL;
+
+	struct dss_dump_data_type *dumpDss = NULL;
+	char *image_src_addr = NULL;
+	struct ion_handle *ionhnd = NULL;
+
+	static const char *const layer_format[] = {
+		"RGB565", "RGBX4444", "RGBA4444", "RGBX5551", "RGBA5551",
+		    "RGBX8888", "RGBA8888",
+		"BGR565", "BGRX4444", "BGRA4444", "BGRX5551", "BGRA5551",
+		    "BGRX8888", "BGRA8888",
+		"YCbYCr", "", "", "NV12", "NV21", "", "", "", "YV12", "", ""
+	};
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON((pov_req->ovl_idx < DSS_OVL0)
+	       || (pov_req->ovl_idx >= DSS_OVL_IDX_MAX));
+
+	dumpDss = kmalloc(sizeof(struct dss_dump_data_type), GFP_KERNEL);
+	if (IS_ERR_OR_NULL(dumpDss)) {
+		HISI_FB_ERR("alloc dumpDss failed!\n");
+		goto alloc_dump_dss_data_err;
+	}
+	memset(dumpDss, 0, sizeof(struct dss_dump_data_type));
+
+	if (isNeedSaveFile) {
+		hisifb_get_timestamp(&tv);
+		snprintf(dumpDss->scene_filename,
+			 sizeof(dumpDss->scene_filename),
+			 "/data/dssdump/Scene_%ld.sce", tv.tv_sec);
+		snprintf(dumpDss->dss_filename, sizeof(dumpDss->dss_filename),
+			 "/data/dssdump/Dss_%ld.txt", tv.tv_sec);
+
+
+		dumpDss->scene_buf_len = 0;
+		dumpDss->scene_buf = kmalloc(DUMP_BUF_SIZE, GFP_KERNEL);
+		if (IS_ERR_OR_NULL(dumpDss->scene_buf)) {
+			HISI_FB_ERR("alloc scene_buf failed!\n");
+			goto alloc_scene_buf_err;
+		}
+		memset(dumpDss->scene_buf, 0, DUMP_BUF_SIZE);
+	}
+
+	dumpDss->dss_buf_len = 0;
+	dumpDss->dss_buf = kmalloc(DUMP_BUF_SIZE, GFP_KERNEL);
+	if (IS_ERR_OR_NULL(dumpDss->dss_buf)) {
+		HISI_FB_ERR("alloc dss_buf failed!\n");
+		goto alloc_dss_buf_err;
+	}
+	memset(dumpDss->dss_buf, 0, DUMP_BUF_SIZE);
+
+	dumpDss->dss_buf_len +=
+	    snprintf(dumpDss->dss_buf + dumpDss->dss_buf_len, 4 * SZ_1K,
+		     "\n\n----------------------------<dump begin>----------------------------\n"
+		     "frame_no=%d\n" "ovl_idx=%d\n"
+		     "res_updt_rect(%d, %d, %d, %d)\n"
+		     "dirty_rect(%d,%d, %d,%d)\n" "release_fence=%d\n"
+		     "crc_enable_status=%d\n" "crc_info(%d,%d)\n"
+		     "ov_block_nums=%d\n" "ov_block_infos_ptr=0x%llx\n"
+		     "wb_enable=%d\n" "wb_layer_nums=%d\n"
+		     "wb_ov_rect(%d,%d, %d,%d)\n", pov_req->frame_no,
+		     pov_req->ovl_idx, pov_req->res_updt_rect.x,
+		     pov_req->res_updt_rect.y, pov_req->res_updt_rect.w,
+		     pov_req->res_updt_rect.h, pov_req->dirty_rect.x,
+		     pov_req->dirty_rect.y, pov_req->dirty_rect.w,
+		     pov_req->dirty_rect.h, pov_req->release_fence,
+		     pov_req->crc_enable_status,
+		     pov_req->crc_info.crc_ov_result,
+		     pov_req->crc_info.err_status, pov_req->ov_block_nums,
+		     pov_req->ov_block_infos_ptr, pov_req->wb_enable,
+		     pov_req->wb_layer_nums, pov_req->wb_ov_rect.x,
+		     pov_req->wb_ov_rect.y, pov_req->wb_ov_rect.w,
+		     pov_req->wb_ov_rect.h);
+
+	for (i = 0; i < pov_req->ov_block_nums; i++) {
+		pov_h_block_infos =
+		    (dss_overlay_block_t *) (pov_req->ov_block_infos_ptr);
+		pov_block_info = &(pov_h_block_infos[i]);
+
+		dumpDss->dss_buf_len +=
+		    snprintf(dumpDss->dss_buf + dumpDss->dss_buf_len, 4 * SZ_1K,
+			     "\nov_block_rect(%d,%d, %d,%d)\n"
+			     "layer_nums=%d\n", pov_block_info->ov_block_rect.x,
+			     pov_block_info->ov_block_rect.y,
+			     pov_block_info->ov_block_rect.w,
+			     pov_block_info->ov_block_rect.h,
+			     pov_block_info->layer_nums);
+
+		for (k = 0; k < pov_block_info->layer_nums; k++) {
+			layer = &(pov_block_info->layer_infos[k]);
+
+			dumpDss->dss_buf_len +=
+			    snprintf(dumpDss->dss_buf + dumpDss->dss_buf_len,
+				     4 * SZ_1K,
+				     "\nLayerInfo[%d]:\n" "format=%d\n"
+				     "width=%d\n" "height=%d\n" "bpp=%d\n"
+				     "buf_size=%d\n" "stride=%d\n"
+				     "stride_plane1=0x%x\n"
+				     "stride_plane2=0x%x\n" "phy_addr=0x%llx\n"
+				     "vir_addr=0x%llx\n" "offset_plane1=%d\n"
+				     "offset_plane2=%d\n"
+				     "afbc_header_addr=0x%llx\n"
+				     "afbc_payload_addr=0x%llx\n"
+				     "afbc_header_stride=%d\n"
+				     "afbc_payload_stride=%d\n"
+				     "afbc_scramble_mode=%d\n"
+				     "mmbuf_base=0x%x\n" "mmbuf_size=%d\n"
+				     "mmu_enable=%d\n" "csc_mode=%d\n"
+				     "secure_mode=%d\n" "shared_fd=%d\n"
+				     "src_rect(%d,%d, %d,%d)\n"
+				     "src_rect_mask(%d,%d, %d,%d)\n"
+				     "dst_rect(%d,%d, %d,%d)\n" "transform=%d\n"
+				     "blending=%d\n" "glb_alpha=0x%x\n"
+				     "color=0x%x\n" "layer_idx=%d\n"
+				     "chn_idx=%d\n" "need_cap=0x%x\n"
+				     "acquire_fence=%d\n", k, layer->img.format,
+				     layer->img.width, layer->img.height,
+				     layer->img.bpp, layer->img.buf_size,
+				     layer->img.stride,
+				     layer->img.stride_plane1,
+				     layer->img.stride_plane2,
+				     layer->img.phy_addr, layer->img.vir_addr,
+				     layer->img.offset_plane1,
+				     layer->img.offset_plane2,
+				     layer->img.afbc_header_addr,
+				     layer->img.afbc_payload_addr,
+				     layer->img.afbc_header_stride,
+				     layer->img.afbc_payload_stride,
+				     layer->img.afbc_scramble_mode,
+				     layer->img.mmbuf_base,
+				     layer->img.mmbuf_size,
+				     layer->img.mmu_enable, layer->img.csc_mode,
+				     layer->img.secure_mode,
+				     layer->img.shared_fd, layer->src_rect.x,
+				     layer->src_rect.y, layer->src_rect.w,
+				     layer->src_rect.h, layer->src_rect_mask.x,
+				     layer->src_rect_mask.y,
+				     layer->src_rect_mask.w,
+				     layer->src_rect_mask.h, layer->dst_rect.x,
+				     layer->dst_rect.y, layer->dst_rect.w,
+				     layer->dst_rect.h, layer->transform,
+				     layer->blending, layer->glb_alpha,
+				     layer->color, layer->layer_idx,
+				     layer->chn_idx, layer->need_cap,
+				     layer->acquire_fence);
+
+
+			if (isNeedSaveFile) {
+				if (layer->dst_rect.y <
+				    pov_block_info->ov_block_rect.y)
+					continue;
+
+				dumpDss->scene_buf_len +=
+				    snprintf(dumpDss->scene_buf +
+					     dumpDss->scene_buf_len, SZ_1K,
+					     "[BaseColor]=0x%x\n"
+					     "[ScreenSize]=(%u,%u)\n\n"
+					     "[BlendMode]=%d\n" "[Caption]=\n"
+					     "[Channel]=%u\n"
+					     "[CropLoc]=(%u,%u)\n"
+					     "[CropSize]=(%u,%u)\n"
+					     "[FlipHV]=(%u,%u)\n"
+					     "[Format]=%s\n"
+					     "[GlobalAlpha]=%u\n",
+					     hisifd->dss_module.ov[pov_req->
+								   ovl_idx].
+					     ovl_bg_color,
+					     get_panel_xres(hisifd),
+					     get_panel_yres(hisifd),
+					     layer->blending, layer->chn_idx, 0,
+					     0, layer->src_rect.w,
+					     layer->src_rect.h,
+					     (layer->
+					      transform &
+					      HISI_FB_TRANSFORM_FLIP_H),
+					     (layer->
+					      transform &
+					      HISI_FB_TRANSFORM_FLIP_V),
+					     layer_format[layer->img.format],
+					     layer->glb_alpha);
+
+				if (layer->need_cap & (CAP_DIM | CAP_PURE_COLOR |
+						CAP_BASE)) {
+					if (layer->need_cap & CAP_BASE) {
+						dumpDss->scene_buf_len +=
+						    snprintf(dumpDss->scene_buf +
+							     dumpDss->scene_buf_len,
+							     SZ_1K,
+							     "[BaseColor]=0x%x\n",
+							     layer->color);
+					} else if (layer->need_cap & CAP_PURE_COLOR) {
+						dumpDss->scene_buf_len +=
+						    snprintf(dumpDss->scene_buf +
+							     dumpDss->scene_buf_len,
+							     SZ_1K,
+							     "[Color]=0x%x\n",
+							     layer->color);
+					}
+				} else {
+					dumpDss->scene_buf_len +=
+					    snprintf(dumpDss->scene_buf +
+						     dumpDss->scene_buf_len,
+						     SZ_1K,
+						     "[ImageSource]=pic%d_%ld.bin\n",
+						     k, tv.tv_sec);
+				}
+
+				dumpDss->scene_buf_len +=
+				    snprintf(dumpDss->scene_buf +
+					     dumpDss->scene_buf_len, SZ_1K,
+					     "[Location]=(%u,%u)\n"
+					     "[Rotate]=%u\n" "[Scale]=(%u,%u)\n"
+					     "[Size]=(%u,%u)\n\n",
+					     layer->dst_rect.x,
+					     layer->dst_rect.y,
+					     hisi_transform2degree(layer->transform),
+					     layer->dst_rect.w,
+					     layer->dst_rect.h,
+					     layer->dst_rect.w,
+					     layer->dst_rect.h);
+
+
+				if (layer->need_cap & (CAP_DIM | CAP_PURE_COLOR |
+						CAP_BASE))
+					continue;
+
+				if (layer->img.shared_fd < 0)
+					continue;
+
+				ionhnd =
+				    ion_import_dma_buf(hisifd->ion_client,
+						       layer->img.shared_fd);
+				if (IS_ERR(ionhnd)) {
+					HISI_FB_ERR
+					    ("ion import dma buf err, ionclient %p, share_fd %d, layer index %d",
+					     hisifd->ion_client,
+					     layer->img.shared_fd, i);
+					continue;
+				}
+
+				snprintf(dumpDss->image_bin_filename[k],
+					 sizeof(dumpDss->image_bin_filename[k]),
+					 "/data/dssdump/pic%d_%ld.bin", k,
+					 tv.tv_sec);
+
+				image_src_addr =
+				    ion_map_kernel(hisifd->ion_client, ionhnd);
+				if (image_src_addr) {
+					hisifb_save_file(dumpDss->image_bin_filename[k],
+							 image_src_addr,
+							 layer->img.buf_size);
+					ion_unmap_kernel(hisifd->ion_client, ionhnd);
+				}
+
+				ion_free(hisifd->ion_client, ionhnd);
+				ionhnd = NULL;
+			}
+		}
+	}
+
+	for (k = 0; k < pov_req->wb_layer_nums; k++) {
+		wb_layer = &(pov_req->wb_layer_infos[k]);
+
+		dumpDss->dss_buf_len +=
+		    snprintf(dumpDss->dss_buf + dumpDss->dss_buf_len, 4 * SZ_1K,
+			     "\nWbLayerInfo[%d]:\n" "format=%d\n" "width=%d\n"
+			     "height=%d\n" "bpp=%d\n" "buf_size=%d\n"
+			     "stride=%d\n" "stride_plane1=%d\n"
+			     "stride_plane2=%d\n" "phy_addr=0x%llx\n"
+			     "vir_addr=0x%llx\n" "offset_plane1=%d\n"
+			     "offset_plane2=%d\n" "afbc_header_addr=0x%llx\n"
+			     "afbc_payload_addr=0x%llx\n"
+			     "afbc_header_stride=%d\n"
+			     "afbc_payload_stride=%d\n"
+			     "afbc_scramble_mode=%d\n" "mmbuf_base=0x%x\n"
+			     "mmbuf_size=%d\n" "mmu_enable=%d\n" "csc_mode=%d\n"
+			     "secure_mode=%d\n" "shared_fd=%d\n"
+			     "src_rect(%d,%d, %d,%d)\n"
+			     "dst_rect(%d,%d, %d,%d)\n" "transform=%d\n"
+			     "chn_idx=%d\n" "need_cap=0x%x\n"
+			     "acquire_fence=%d\n" "release_fence=%d\n", k,
+			     wb_layer->dst.format, wb_layer->dst.width,
+			     wb_layer->dst.height, wb_layer->dst.bpp,
+			     wb_layer->dst.buf_size, wb_layer->dst.stride,
+			     wb_layer->dst.stride_plane1,
+			     wb_layer->dst.stride_plane2,
+			     wb_layer->dst.phy_addr, wb_layer->dst.vir_addr,
+			     wb_layer->dst.offset_plane1,
+			     wb_layer->dst.offset_plane2,
+			     wb_layer->dst.afbc_header_addr,
+			     wb_layer->dst.afbc_payload_addr,
+			     wb_layer->dst.afbc_header_stride,
+			     wb_layer->dst.afbc_payload_stride,
+			     wb_layer->dst.afbc_scramble_mode,
+			     wb_layer->dst.mmbuf_base, wb_layer->dst.mmbuf_size,
+			     wb_layer->dst.mmu_enable, wb_layer->dst.csc_mode,
+			     wb_layer->dst.secure_mode, wb_layer->dst.shared_fd,
+			     wb_layer->src_rect.x, wb_layer->src_rect.y,
+			     wb_layer->src_rect.w, wb_layer->src_rect.h,
+			     wb_layer->dst_rect.x, wb_layer->dst_rect.y,
+			     wb_layer->dst_rect.w, wb_layer->dst_rect.h,
+			     wb_layer->transform, wb_layer->chn_idx,
+			     wb_layer->need_cap, wb_layer->acquire_fence,
+			     wb_layer->release_fence);
+	}
+
+	dumpDss->dss_buf_len +=
+	    snprintf(dumpDss->dss_buf + dumpDss->dss_buf_len, 4 * SZ_1K,
+		     "----------------------------<dump end>----------------------------\n\n");
+
+	for (k = 0; k < dumpDss->dss_buf_len; k += 255) {
+		printk("%.255s", dumpDss->dss_buf + k);
+	}
+
+	if (isNeedSaveFile) {
+		if (dumpDss->scene_buf)
+			hisifb_save_file(dumpDss->scene_filename,
+					 dumpDss->scene_buf,
+					 dumpDss->scene_buf_len);
+
+		if (dumpDss->dss_buf)
+			hisifb_save_file(dumpDss->dss_filename,
+					 dumpDss->dss_buf,
+					 dumpDss->dss_buf_len);
+	}
+
+	if (dumpDss->dss_buf) {
+		kfree(dumpDss->dss_buf);
+		dumpDss->dss_buf = NULL;
+		dumpDss->dss_buf_len = 0;
+	}
+
+ alloc_dss_buf_err:
+	if (dumpDss->scene_buf) {
+		kfree(dumpDss->scene_buf);
+		dumpDss->scene_buf = NULL;
+		dumpDss->scene_buf_len = 0;
+	}
+
+ alloc_scene_buf_err:
+	if (dumpDss) {
+		kfree(dumpDss);
+		dumpDss = NULL;
+	}
+
+ alloc_dump_dss_data_err:
+	return;
+}
+
+static int hisi_dss_lcd_refresh_direction_layer(struct hisi_fb_data_type
+						*hisifd,
+						dss_overlay_t *pov_req,
+						dss_layer_t *layer)
+{
+	struct hisi_panel_info *pinfo = NULL;
+	int ret = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON(layer == NULL);
+
+	pinfo = &(hisifd->panel_info);
+
+	if ((pov_req->ovl_idx != DSS_OVL0) && (pov_req->ovl_idx != DSS_OVL1))
+		return 0;
+
+	if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_LEFT_TOP) {
+		;
+	} else if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_RIGHT_TOP) {
+		switch (layer->transform) {
+		case HISI_FB_TRANSFORM_NOP:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_H;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_H:
+			layer->transform = HISI_FB_TRANSFORM_NOP;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_V:
+			layer->transform = HISI_FB_TRANSFORM_ROT_180;
+			break;
+		case HISI_FB_TRANSFORM_ROT_90:
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_H);
+			break;
+		case HISI_FB_TRANSFORM_ROT_180:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_V;
+			break;
+		case HISI_FB_TRANSFORM_ROT_270:
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_V);
+			break;
+
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H):
+			layer->transform = HISI_FB_TRANSFORM_ROT_90;
+			break;
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V):
+			layer->transform = HISI_FB_TRANSFORM_ROT_270;
+			break;
+
+		default:
+			HISI_FB_ERR("not support this transform(%d).\n",
+				    layer->transform);
+			ret = -1;
+			break;
+		}
+
+		if (ret == 0) {
+			if ((pinfo->dirty_region_updt_support == 1) &&
+			    (pov_req->dirty_rect.w > 0) &&
+			    (pov_req->dirty_rect.h > 0)) {
+				layer->dst_rect.x =
+				    (pov_req->dirty_rect.w -
+				     (layer->dst_rect.x + layer->dst_rect.w));
+			} else {
+				layer->dst_rect.x =
+				    (get_panel_xres(hisifd) -
+				     (layer->dst_rect.x + layer->dst_rect.w));
+			}
+		}
+	} else if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_LEFT_BOTTOM) {
+		switch (layer->transform) {
+		case HISI_FB_TRANSFORM_NOP:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_V;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_H:
+			layer->transform = HISI_FB_TRANSFORM_ROT_180;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_V:
+			layer->transform = HISI_FB_TRANSFORM_NOP;
+			break;
+		case HISI_FB_TRANSFORM_ROT_90:
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_V);
+			break;
+		case HISI_FB_TRANSFORM_ROT_180:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_H;
+			break;
+		case HISI_FB_TRANSFORM_ROT_270:
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_H);
+			break;
+
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H):
+			layer->transform = HISI_FB_TRANSFORM_ROT_270;
+			break;
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V):
+			layer->transform = HISI_FB_TRANSFORM_ROT_90;
+			break;
+
+		default:
+			HISI_FB_ERR("not support this transform(%d).\n",
+				    layer->transform);
+			ret = -1;
+			break;
+		}
+
+		if (ret == 0) {
+			if ((pinfo->dirty_region_updt_support == 1) &&
+			    (pov_req->dirty_rect.w > 0) &&
+			    (pov_req->dirty_rect.h > 0)) {
+				layer->dst_rect.y =
+				    (pov_req->dirty_rect.h -
+				     (layer->dst_rect.y + layer->dst_rect.h));
+			} else {
+				layer->dst_rect.y =
+				    (get_panel_yres(hisifd) -
+				     (layer->dst_rect.y + layer->dst_rect.h));
+			}
+		}
+	} else if (pinfo->lcd_refresh_direction_ctrl ==
+		   LCD_REFRESH_RIGHT_BOTTOM) {
+		switch (layer->transform) {
+		case HISI_FB_TRANSFORM_NOP:
+			layer->transform = HISI_FB_TRANSFORM_ROT_180;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_H:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_V;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_V:
+			layer->transform = HISI_FB_TRANSFORM_FLIP_H;
+			break;
+		case HISI_FB_TRANSFORM_ROT_90:
+			layer->transform = HISI_FB_TRANSFORM_ROT_270;
+			break;
+		case HISI_FB_TRANSFORM_ROT_180:
+			layer->transform = HISI_FB_TRANSFORM_NOP;
+			break;
+		case HISI_FB_TRANSFORM_ROT_270:
+			layer->transform = HISI_FB_TRANSFORM_ROT_90;
+			break;
+
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H):
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_V);
+			break;
+		case (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V):
+			layer->transform =
+			    (HISI_FB_TRANSFORM_ROT_90 |
+			     HISI_FB_TRANSFORM_FLIP_H);
+			break;
+
+		default:
+			HISI_FB_ERR("not support this transform(%d).\n",
+				    layer->transform);
+			ret = -1;
+			break;
+		}
+
+		if (ret == 0) {
+			if ((pinfo->dirty_region_updt_support == 1) &&
+			    (pov_req->dirty_rect.w > 0) &&
+			    (pov_req->dirty_rect.h > 0)) {
+				layer->dst_rect.x =
+				    (pov_req->dirty_rect.w -
+				     (layer->dst_rect.x + layer->dst_rect.w));
+				layer->dst_rect.y =
+				    (pov_req->dirty_rect.h -
+				     (layer->dst_rect.y + layer->dst_rect.h));
+			} else {
+				layer->dst_rect.x =
+				    (get_panel_xres(hisifd) -
+				     (layer->dst_rect.x + layer->dst_rect.w));
+				layer->dst_rect.y =
+				    (get_panel_yres(hisifd) -
+				     (layer->dst_rect.y + layer->dst_rect.h));
+			}
+		}
+	} else {
+		HISI_FB_ERR
+		    ("fb%d, not support this lcd_refresh_direction_ctrl(%d)!\n",
+		     hisifd->index, pinfo->lcd_refresh_direction_ctrl);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static int hisi_dss_lcd_refresh_direction_dirty_region(struct hisi_fb_data_type
+						       *hisifd,
+						       dss_overlay_t *pov_req)
+{
+	struct hisi_panel_info *pinfo = NULL;
+	int ret = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	pinfo = &(hisifd->panel_info);
+	if ((pov_req->ovl_idx != DSS_OVL0) && (pov_req->ovl_idx != DSS_OVL1))
+		return 0;
+
+	if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_LEFT_TOP) {
+		;
+	} else if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_RIGHT_TOP) {
+		if (pinfo->dirty_region_updt_support == 1) {
+			pov_req->dirty_rect.x =
+			    (get_panel_xres(hisifd) -
+			     (pov_req->dirty_rect.x + pov_req->dirty_rect.w));
+		}
+	} else if (pinfo->lcd_refresh_direction_ctrl == LCD_REFRESH_LEFT_BOTTOM) {
+		if (pinfo->dirty_region_updt_support == 1) {
+			pov_req->dirty_rect.y =
+			    (get_panel_yres(hisifd) -
+			     (pov_req->dirty_rect.y + pov_req->dirty_rect.h));
+		}
+	} else if (pinfo->lcd_refresh_direction_ctrl ==
+		   LCD_REFRESH_RIGHT_BOTTOM) {
+		if (pinfo->dirty_region_updt_support == 1) {
+			pov_req->dirty_rect.x =
+			    (get_panel_xres(hisifd) -
+			     (pov_req->dirty_rect.x + pov_req->dirty_rect.w));
+			pov_req->dirty_rect.y =
+			    (get_panel_yres(hisifd) -
+			     (pov_req->dirty_rect.y + pov_req->dirty_rect.h));
+		}
+	} else {
+		HISI_FB_ERR
+		    ("fb%d, not support this lcd_refresh_direction_ctrl(%d)!\n",
+		     hisifd->index, pinfo->lcd_refresh_direction_ctrl);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+int hisi_dss_handle_cur_ovl_req(struct hisi_fb_data_type *hisifd,
+				dss_overlay_t *pov_req)
+{
+	struct hisi_panel_info *pinfo = NULL;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_h_block = NULL;
+	dss_layer_t *layer = NULL;
+	int i = 0;
+	int m = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	pinfo = &(hisifd->panel_info);
+
+	hisifd->resolution_rect = pov_req->res_updt_rect;
+
+	pov_h_block_infos =
+	    (dss_overlay_block_t *) (pov_req->ov_block_infos_ptr);
+	for (m = 0; m < pov_req->ov_block_nums; m++) {
+		pov_h_block = &(pov_h_block_infos[m]);
+
+		for (i = 0; i < pov_h_block->layer_nums; i++) {
+			layer = &(pov_h_block->layer_infos[i]);
+
+			hisi_dss_lcd_refresh_direction_layer(hisifd, pov_req,
+							     layer);
+		}
+	}
+	hisi_dss_lcd_refresh_direction_dirty_region(hisifd, pov_req);
+
+	return 0;
+}
+
+/*******************************************************************************
+ **
+ */
+int hisi_get_hal_format(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = NULL;
+	int hal_format = 0;
+
+	BUG_ON(info == NULL);
+	var = &info->var;
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		if (var->blue.offset == 0) {
+			if (var->red.offset == 8) {
+				hal_format = (var->transp.offset == 12) ?
+				    HISI_FB_PIXEL_FORMAT_BGRA_4444 :
+				    HISI_FB_PIXEL_FORMAT_BGRX_4444;
+			} else if (var->red.offset == 10) {
+				hal_format = (var->transp.offset == 12) ?
+				    HISI_FB_PIXEL_FORMAT_BGRA_5551 :
+				    HISI_FB_PIXEL_FORMAT_BGRX_5551;
+			} else if (var->red.offset == 11) {
+				hal_format = HISI_FB_PIXEL_FORMAT_RGB_565;
+			}
+		}
+		break;
+
+	case 32:
+		if (var->blue.offset == 0) {
+			/* BUGFIX: Modified for Standard Android Format */
+			/* hal_format = (var->transp.length == 8) ?
+				HISI_FB_PIXEL_FORMAT_BGRA_8888 : HISI_FB_PIXEL_FORMAT_BGRX_8888; */
+			hal_format = (var->transp.length == 8) ?
+				HISI_FB_PIXEL_FORMAT_RGBA_8888 :
+				HISI_FB_PIXEL_FORMAT_RGBX_8888;
+		} else {
+			hal_format = (var->transp.length == 8) ?
+			    HISI_FB_PIXEL_FORMAT_RGBA_8888 :
+			    HISI_FB_PIXEL_FORMAT_RGBX_8888;
+		}
+		break;
+
+	default:
+		goto err_return;
+	}
+
+	return hal_format;
+
+ err_return:
+	HISI_FB_ERR("not support this bits_per_pixel(%d)!\n",
+		    var->bits_per_pixel);
+	return -1;
+}
+
+static bool hal_format_has_alpha(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_RGBA_4444:
+	case HISI_FB_PIXEL_FORMAT_RGBA_5551:
+	case HISI_FB_PIXEL_FORMAT_RGBA_8888:
+
+	case HISI_FB_PIXEL_FORMAT_BGRA_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRA_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRA_8888:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool isYUVPackage(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YUV_422_I:
+	case HISI_FB_PIXEL_FORMAT_YUYV_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_YVYU_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_UYVY_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_VYUY_422_Pkg:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool isYUVSemiPlanar(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_SP:
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_SP:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool isYUVPlanar(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_P:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool isYUV(uint32_t format)
+{
+	return isYUVPackage(format) ||
+	    isYUVSemiPlanar(format) || isYUVPlanar(format);
+}
+
+bool is_YUV_SP_420(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_SP:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool is_YUV_SP_422(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_SP:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool is_YUV_P_420(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_P:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool is_YUV_P_422(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_P:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool is_RGBX(uint32_t format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_RGBX_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRX_4444:
+	case HISI_FB_PIXEL_FORMAT_RGBX_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRX_5551:
+	case HISI_FB_PIXEL_FORMAT_RGBX_8888:
+	case HISI_FB_PIXEL_FORMAT_BGRX_8888:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+bool isNeedDither(int fmt)
+{
+	return (fmt == DFC_PIXEL_FORMAT_RGB_565) ||
+	    (fmt == DFC_PIXEL_FORMAT_BGR_565);
+}
+
+static bool isNeedRectClip(dss_rect_ltrb_t clip_rect)
+{
+	return ((clip_rect.left > 0) || (clip_rect.top > 0) ||
+		(clip_rect.right > 0) || (clip_rect.bottom > 0));
+}
+
+static bool isSrcRectMasked(dss_layer_t *layer, int aligned_pixel)
+{
+	BUG_ON(layer == NULL);
+
+	return ((layer->src_rect_mask.w != 0) &&
+		(layer->src_rect_mask.h != 0) &&
+		(ALIGN_DOWN
+		 (layer->src_rect_mask.x + layer->src_rect_mask.w,
+		  aligned_pixel) > 1));
+}
+
+static uint32_t isNeedRdmaStretchBlt(struct hisi_fb_data_type *hisifd,
+				     dss_layer_t *layer)
+{
+	uint32_t v_stretch_ratio_threshold = 0;
+	uint32_t v_stretch_ratio = 0;
+
+	BUG_ON(layer == NULL);
+
+	if (layer->need_cap & CAP_AFBCD) {
+#if 0
+		v_stretch_ratio = layer->src_rect.h / layer->dst_rect.h;
+		if (v_stretch_ratio < 2)
+			v_stretch_ratio = 0;
+#else
+		v_stretch_ratio = 0;
+#endif
+	} else {
+		if (is_YUV_SP_420(layer->img.format)
+		    || is_YUV_P_420(layer->img.format)) {
+			v_stretch_ratio_threshold =
+			    ((layer->src_rect.h + layer->dst_rect.h -
+			      1) / layer->dst_rect.h);
+			v_stretch_ratio =
+			    ((layer->src_rect.h / layer->dst_rect.h) / 2) * 2;
+		} else {
+			v_stretch_ratio_threshold =
+			    ((layer->src_rect.h + layer->dst_rect.h -
+			      1) / layer->dst_rect.h);
+			v_stretch_ratio =
+			    (layer->src_rect.h / layer->dst_rect.h);
+		}
+
+		if (v_stretch_ratio_threshold <= g_rdma_stretch_threshold)
+			v_stretch_ratio = 0;
+	}
+
+	return v_stretch_ratio;
+}
+
+static int hisi_adjust_clip_rect(dss_layer_t *layer,
+				 dss_rect_ltrb_t *clip_rect)
+{
+	int ret = 0;
+	uint32_t temp = 0;
+
+	BUG_ON(layer == NULL);
+	BUG_ON(clip_rect == NULL);
+
+	if ((clip_rect->left < 0 || clip_rect->left > DFC_MAX_CLIP_NUM) ||
+	    (clip_rect->right < 0 || clip_rect->right > DFC_MAX_CLIP_NUM) ||
+	    (clip_rect->top < 0 || clip_rect->top > DFC_MAX_CLIP_NUM) ||
+	    (clip_rect->bottom < 0 || clip_rect->bottom > DFC_MAX_CLIP_NUM)) {
+		return -EINVAL;
+	}
+
+	switch (layer->transform) {
+	case HISI_FB_TRANSFORM_NOP:
+
+		break;
+	case HISI_FB_TRANSFORM_FLIP_H:
+		{
+			temp = clip_rect->left;
+			clip_rect->left = clip_rect->right;
+			clip_rect->right = temp;
+		}
+		break;
+	case HISI_FB_TRANSFORM_FLIP_V:
+		{
+			temp = clip_rect->top;
+			clip_rect->top = clip_rect->bottom;
+			clip_rect->bottom = temp;
+		}
+		break;
+	case HISI_FB_TRANSFORM_ROT_180:
+		{
+			temp = clip_rect->left;
+			clip_rect->left = clip_rect->right;
+			clip_rect->right = temp;
+
+			temp = clip_rect->top;
+			clip_rect->top = clip_rect->bottom;
+			clip_rect->bottom = temp;
+		}
+		break;
+	default:
+		HISI_FB_ERR("not supported this transform(%d)!",
+			    layer->transform);
+		break;
+	}
+
+	return ret;
+}
+
+static int hisi_pixel_format_hal2dma(int format)
+{
+	int ret = 0;
+
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_RGB_565:
+	case HISI_FB_PIXEL_FORMAT_BGR_565:
+		ret = DMA_PIXEL_FORMAT_RGB_565;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBX_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRX_4444:
+		ret = DMA_PIXEL_FORMAT_XRGB_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRA_4444:
+		ret = DMA_PIXEL_FORMAT_ARGB_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBX_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRX_5551:
+		ret = DMA_PIXEL_FORMAT_XRGB_5551;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRA_5551:
+		ret = DMA_PIXEL_FORMAT_ARGB_5551;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_RGBX_8888:
+	case HISI_FB_PIXEL_FORMAT_BGRX_8888:
+		ret = DMA_PIXEL_FORMAT_XRGB_8888;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_8888:
+	case HISI_FB_PIXEL_FORMAT_BGRA_8888:
+		ret = DMA_PIXEL_FORMAT_ARGB_8888;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YUV_422_I:
+	case HISI_FB_PIXEL_FORMAT_YUYV_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_YVYU_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_UYVY_422_Pkg:
+	case HISI_FB_PIXEL_FORMAT_VYUY_422_Pkg:
+		ret = DMA_PIXEL_FORMAT_YUYV_422_Pkg;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_P:
+		ret = DMA_PIXEL_FORMAT_YUV_422_P_HP;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_P:
+		ret = DMA_PIXEL_FORMAT_YUV_420_P_HP;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_SP:
+		ret = DMA_PIXEL_FORMAT_YUV_422_SP_HP;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_SP:
+		ret = DMA_PIXEL_FORMAT_YUV_420_SP_HP;
+		break;
+
+	default:
+		HISI_FB_ERR("not support format(%d)!\n", format);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int hisi_transform_hal2dma(int transform, int chn_idx)
+{
+	int ret = 0;
+
+	if (chn_idx < DSS_WCHN_W0 || chn_idx == DSS_RCHN_V2) {
+		switch (transform) {
+		case HISI_FB_TRANSFORM_NOP:
+			ret = DSS_TRANSFORM_NOP;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_H:
+			ret = DSS_TRANSFORM_FLIP_H;
+			break;
+		case HISI_FB_TRANSFORM_FLIP_V:
+			ret = DSS_TRANSFORM_FLIP_V;
+			break;
+		case HISI_FB_TRANSFORM_ROT_180:
+			ret = DSS_TRANSFORM_FLIP_V | DSS_TRANSFORM_FLIP_H;
+			break;
+		default:
+			ret = -1;
+			HISI_FB_ERR("Transform %d is not supported", transform);
+			break;
+		}
+	} else {
+		if (transform == HISI_FB_TRANSFORM_NOP) {
+			ret = DSS_TRANSFORM_NOP;
+		} else if (transform ==
+			   (HISI_FB_TRANSFORM_ROT_90 |
+			    HISI_FB_TRANSFORM_FLIP_V)) {
+			ret = DSS_TRANSFORM_ROT;
+		} else {
+			ret = -1;
+			HISI_FB_ERR("Transform %d is not supported", transform);
+		}
+	}
+
+	return ret;
+}
+
+static int hisi_pixel_format_hal2dfc(int format)
+{
+	int ret = 0;
+
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_RGB_565:
+		ret = DFC_PIXEL_FORMAT_RGB_565;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBX_4444:
+		ret = DFC_PIXEL_FORMAT_XBGR_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_4444:
+		ret = DFC_PIXEL_FORMAT_ABGR_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBX_5551:
+		ret = DFC_PIXEL_FORMAT_XBGR_5551;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_5551:
+		ret = DFC_PIXEL_FORMAT_ABGR_5551;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBX_8888:
+		ret = DFC_PIXEL_FORMAT_XBGR_8888;
+		break;
+	case HISI_FB_PIXEL_FORMAT_RGBA_8888:
+		ret = DFC_PIXEL_FORMAT_ABGR_8888;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_BGR_565:
+		ret = DFC_PIXEL_FORMAT_BGR_565;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRX_4444:
+		ret = DFC_PIXEL_FORMAT_XRGB_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRA_4444:
+		ret = DFC_PIXEL_FORMAT_ARGB_4444;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRX_5551:
+		ret = DFC_PIXEL_FORMAT_XRGB_5551;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRA_5551:
+		ret = DFC_PIXEL_FORMAT_ARGB_5551;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRX_8888:
+		ret = DFC_PIXEL_FORMAT_XRGB_8888;
+		break;
+	case HISI_FB_PIXEL_FORMAT_BGRA_8888:
+		ret = DFC_PIXEL_FORMAT_ARGB_8888;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YUV_422_I:
+	case HISI_FB_PIXEL_FORMAT_YUYV_422_Pkg:
+		ret = DFC_PIXEL_FORMAT_YUYV422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YVYU_422_Pkg:
+		ret = DFC_PIXEL_FORMAT_YVYU422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_UYVY_422_Pkg:
+		ret = DFC_PIXEL_FORMAT_UYVY422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_VYUY_422_Pkg:
+		ret = DFC_PIXEL_FORMAT_VYUY422;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_SP:
+		ret = DFC_PIXEL_FORMAT_YUYV422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_SP:
+		ret = DFC_PIXEL_FORMAT_YVYU422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_SP:
+		ret = DFC_PIXEL_FORMAT_YUYV422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_SP:
+		ret = DFC_PIXEL_FORMAT_YVYU422;
+		break;
+
+	case HISI_FB_PIXEL_FORMAT_YCbCr_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCbCr_420_P:
+		ret = DFC_PIXEL_FORMAT_YUYV422;
+		break;
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_P:
+		ret = DFC_PIXEL_FORMAT_YVYU422;
+		break;
+
+	default:
+		HISI_FB_ERR("not support format(%d)!\n", format);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int hisi_rb_swap(int format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_BGR_565:
+	case HISI_FB_PIXEL_FORMAT_BGRX_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRA_4444:
+	case HISI_FB_PIXEL_FORMAT_BGRX_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRA_5551:
+	case HISI_FB_PIXEL_FORMAT_BGRX_8888:
+	case HISI_FB_PIXEL_FORMAT_BGRA_8888:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int hisi_uv_swap(int format)
+{
+	switch (format) {
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_SP:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_422_P:
+	case HISI_FB_PIXEL_FORMAT_YCrCb_420_P:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
+static int hisi_dfc_get_bpp(int dfc_format)
+{
+	int ret = 0;
+
+	switch (dfc_format) {
+	case DFC_PIXEL_FORMAT_RGB_565:
+	case DFC_PIXEL_FORMAT_XRGB_4444:
+	case DFC_PIXEL_FORMAT_ARGB_4444:
+	case DFC_PIXEL_FORMAT_XRGB_5551:
+	case DFC_PIXEL_FORMAT_ARGB_5551:
+
+	case DFC_PIXEL_FORMAT_BGR_565:
+	case DFC_PIXEL_FORMAT_XBGR_4444:
+	case DFC_PIXEL_FORMAT_ABGR_4444:
+	case DFC_PIXEL_FORMAT_XBGR_5551:
+	case DFC_PIXEL_FORMAT_ABGR_5551:
+		ret = 2;
+		break;
+
+	case DFC_PIXEL_FORMAT_XRGB_8888:
+	case DFC_PIXEL_FORMAT_ARGB_8888:
+	case DFC_PIXEL_FORMAT_XBGR_8888:
+	case DFC_PIXEL_FORMAT_ABGR_8888:
+		ret = 4;
+		break;
+
+	case DFC_PIXEL_FORMAT_YUV444:
+	case DFC_PIXEL_FORMAT_YVU444:
+		ret = 3;
+		break;
+
+	case DFC_PIXEL_FORMAT_YUYV422:
+	case DFC_PIXEL_FORMAT_YVYU422:
+	case DFC_PIXEL_FORMAT_VYUY422:
+	case DFC_PIXEL_FORMAT_UYVY422:
+		ret = 2;
+		break;
+
+	default:
+		HISI_FB_ERR("not support format(%d)!\n", dfc_format);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static uint32_t hisi_calculate_display_addr(bool mmu_enable,
+					    dss_layer_t *layer,
+					    dss_rect_ltrb_t *aligned_rect,
+					    int add_type)
+{
+	uint32_t addr = 0;
+	uint32_t src_addr = 0;
+	uint32_t stride = 0;
+	uint32_t offset = 0;
+	int bpp = 0;
+	int left = 0;
+	int right = 0;
+	int top = 0;
+	int bottom = 0;
+
+	left = aligned_rect->left;
+	right = aligned_rect->right;
+	top = aligned_rect->top;
+	bottom = aligned_rect->bottom;
+
+	if (add_type == DSS_ADDR_PLANE0) {
+		stride = layer->img.stride;
+		offset = 0;
+		src_addr =
+		    mmu_enable ? layer->img.vir_addr : layer->img.phy_addr;
+		bpp = layer->img.bpp;
+	} else if (add_type == DSS_ADDR_PLANE1) {
+		stride = layer->img.stride_plane1;
+		offset = layer->img.offset_plane1;
+		src_addr = mmu_enable ? (layer->img.vir_addr + offset) :
+		    (layer->img.phy_addr + offset);
+		bpp = 1;
+
+		if (is_YUV_P_420(layer->img.format)
+		    || is_YUV_P_422(layer->img.format)) {
+			left /= 2;
+			right /= 2;
+		}
+
+		if (is_YUV_SP_420(layer->img.format)
+		    || is_YUV_P_420(layer->img.format)) {
+			top /= 2;
+			bottom /= 2;
+		}
+	} else if (add_type == DSS_ADDR_PLANE2) {
+		stride = layer->img.stride_plane2;
+		offset = layer->img.offset_plane2;
+		src_addr = mmu_enable ? (layer->img.vir_addr + offset) :
+		    (layer->img.phy_addr + offset);
+		bpp = 1;
+
+		if (is_YUV_P_420(layer->img.format)
+		    || is_YUV_P_422(layer->img.format)) {
+			left /= 2;
+			right /= 2;
+		}
+
+		if (is_YUV_SP_420(layer->img.format)
+		    || is_YUV_P_420(layer->img.format)) {
+			top /= 2;
+			bottom /= 2;
+		}
+	} else {
+		HISI_FB_ERR("NOT SUPPORT this add_type(%d).\n", add_type);
+		BUG_ON(1);
+	}
+
+	switch (layer->transform) {
+	case HISI_FB_TRANSFORM_NOP:
+		addr = src_addr + top * stride + left * bpp;
+		break;
+	case HISI_FB_TRANSFORM_FLIP_H:
+		addr = src_addr + top * stride + right * bpp;
+		break;
+	case HISI_FB_TRANSFORM_FLIP_V:
+		addr = src_addr + bottom * stride + left * bpp;
+		break;
+	case HISI_FB_TRANSFORM_ROT_180:
+		addr = src_addr + bottom * stride + right * bpp;
+		break;
+	default:
+		HISI_FB_ERR("not supported this transform(%d)!",
+			    layer->transform);
+		break;
+	}
+
+	return addr;
+}
+
+/*******************************************************************************
+ ** DSS MIF
+ */
+static void hisi_dss_mif_init(char __iomem *mif_ch_base,
+			      dss_mif_t *s_mif, int chn_idx)
+{
+	uint32_t rw_type = 0;
+
+	BUG_ON(mif_ch_base == NULL);
+	BUG_ON(s_mif == NULL);
+
+	memset(s_mif, 0, sizeof(dss_mif_t));
+
+	s_mif->mif_ctrl1 = 0x00000020;
+	s_mif->mif_ctrl2 = 0x0;
+	s_mif->mif_ctrl3 = 0x0;
+	s_mif->mif_ctrl4 = 0x0;
+	s_mif->mif_ctrl5 = 0x0;
+	rw_type = (chn_idx < DSS_WCHN_W0 || chn_idx == DSS_RCHN_V2) ? 0x0 : 0x1;
+
+	s_mif->mif_ctrl1 = set_bits32(s_mif->mif_ctrl1, 0x0, 1, 5);
+	s_mif->mif_ctrl1 = set_bits32(s_mif->mif_ctrl1, rw_type, 1, 17);
+}
+
+static void hisi_dss_mif_set_reg(struct hisi_fb_data_type *hisifd,
+				 char __iomem *mif_ch_base, dss_mif_t *s_mif,
+				 int chn_idx)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(mif_ch_base == NULL);
+	BUG_ON(s_mif == NULL);
+
+	hisifd->set_reg(hisifd, mif_ch_base + MIF_CTRL1,
+			s_mif->mif_ctrl1, 32, 0);
+	hisifd->set_reg(hisifd, mif_ch_base + MIF_CTRL2,
+			s_mif->mif_ctrl2, 32, 0);
+	hisifd->set_reg(hisifd, mif_ch_base + MIF_CTRL3,
+			s_mif->mif_ctrl3, 32, 0);
+	hisifd->set_reg(hisifd, mif_ch_base + MIF_CTRL4,
+			s_mif->mif_ctrl4, 32, 0);
+	hisifd->set_reg(hisifd, mif_ch_base + MIF_CTRL5,
+			s_mif->mif_ctrl5, 32, 0);
+}
+
+void hisi_dss_mif_on(struct hisi_fb_data_type *hisifd)
+{
+	char __iomem *mif_base = NULL;
+
+	BUG_ON(hisifd == NULL);
+
+	mif_base = hisifd->dss_base + DSS_MIF_OFFSET;
+
+	set_reg(mif_base + MIF_ENABLE, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH0_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH1_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH2_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH3_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH4_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH5_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH6_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH7_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH8_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH9_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+
+	set_reg(hisifd->dss_base + MIF_CH10_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+	set_reg(hisifd->dss_base + MIF_CH11_OFFSET + MIF_CTRL0, 0x1, 1, 0);
+}
+
+int hisi_dss_mif_config(struct hisi_fb_data_type *hisifd,
+			dss_layer_t *layer, dss_wb_layer_t *wb_layer,
+			bool rdma_stretch_enable)
+{
+	dss_mif_t *mif = NULL;
+	int chn_idx = 0;
+	dss_img_t *img = NULL;
+	uint32_t transform = 0;
+	uint32_t invalid_sel = 0;
+	uint32_t need_cap = 0;
+	uint32_t *semi_plane1 = NULL;
+	int v_scaling_factor = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((layer == NULL) && (wb_layer == NULL));
+
+	if (wb_layer) {
+		img = &(wb_layer->dst);
+		chn_idx = wb_layer->chn_idx;
+		transform = wb_layer->transform;
+		need_cap = wb_layer->need_cap;
+		v_scaling_factor = 1;
+	} else {
+		img = &(layer->img);
+		chn_idx = layer->chn_idx;
+		transform = layer->transform;
+		need_cap = layer->need_cap;
+		v_scaling_factor =
+		    layer->src_rect.h / layer->dst_rect.h +
+		    ((layer->src_rect.h % layer->dst_rect.h) > 0 ? 1 : 0);
+	}
+
+	mif = &(hisifd->dss_module.mif[chn_idx]);
+	hisifd->dss_module.mif_used[chn_idx] = 1;
+
+	semi_plane1 = &mif->mif_ctrl4;
+
+	if (img->mmu_enable == 0) {
+		mif->mif_ctrl1 = set_bits32(mif->mif_ctrl1, 0x1, 1, 5);
+	} else {
+		if (need_cap & (CAP_AFBCD | CAP_AFBCE)) {
+			invalid_sel = 0;
+		} else {
+			invalid_sel =
+			    hisi_dss_mif_get_invalid_sel(img, transform,
+							 v_scaling_factor,
+							 ((need_cap & CAP_TILE)
+							  ? 1 : 0),
+							 rdma_stretch_enable);
+		}
+
+		mif->mif_ctrl1 = set_bits32(mif->mif_ctrl1, 0x0, 1, 5);
+		mif->mif_ctrl1 = set_bits32(mif->mif_ctrl1, invalid_sel, 2, 10);
+		mif->mif_ctrl1 =
+		    set_bits32(mif->mif_ctrl1, ((invalid_sel == 0) ? 0x1 : 0x0),
+			       1, 19);
+
+		if (invalid_sel == 0) {
+			mif->mif_ctrl2 = set_bits32(mif->mif_ctrl2, 0x0, 20, 0);
+			mif->mif_ctrl3 = set_bits32(mif->mif_ctrl3, 0x0, 20, 0);
+			mif->mif_ctrl4 = set_bits32(mif->mif_ctrl4, 0x0, 20, 0);
+			mif->mif_ctrl5 = set_bits32(mif->mif_ctrl5, 0x0, 20, 0);
+		} else if ((invalid_sel == 1) || (invalid_sel == 2)) {
+			if (img->stride > 0) {
+				mif->mif_ctrl5 = set_bits32(mif->mif_ctrl5,
+							    ((img->stride /MIF_STRIDE_UNIT) +
+							     (((img->stride % MIF_STRIDE_UNIT) > 0) ?
+							        1 : 0)), 20, 0);
+			}
+
+			if (isYUVSemiPlanar(img->format)) {
+				if (img->stride_plane1 > 0) {
+					*semi_plane1 = set_bits32(*semi_plane1,
+							((img->stride_plane1 / MIF_STRIDE_UNIT) +
+							 (((img->stride_plane1 % MIF_STRIDE_UNIT) >0) ?
+							   1 : 0)), 20, 0);
+				}
+			} else if (isYUVPlanar(img->format)) {
+				if (img->stride_plane1 > 0) {
+					mif->mif_ctrl4 =
+					    set_bits32(mif->mif_ctrl4,
+						       ((img->stride_plane1 /
+							 MIF_STRIDE_UNIT) +
+							(((img->stride_plane1 %
+							   MIF_STRIDE_UNIT) >
+							  0) ? 1 : 0)), 20, 0);
+				}
+
+				if (img->stride_plane2 > 0) {
+					mif->mif_ctrl3 =
+					    set_bits32(mif->mif_ctrl3,
+						       ((img->stride_plane2 /
+							 MIF_STRIDE_UNIT) +
+							(((img->stride_plane2 %
+							   MIF_STRIDE_UNIT) >
+							  0) ? 1 : 0)), 20, 0);
+				}
+			} else {
+				;
+			}
+		} else if (invalid_sel == 3) {
+			if (img->stride > 0) {
+				mif->mif_ctrl5 =
+				    set_bits32(mif->mif_ctrl5,
+					       DSS_MIF_CTRL2_INVAL_SEL3_STRIDE_MASK, 4, 16);
+			}
+			if (isYUVSemiPlanar(img->format)) {
+				if (img->stride_plane1 > 0)
+					*semi_plane1 =
+					    set_bits32(*semi_plane1, 0xE, 4, 16);
+
+			} else if (isYUVPlanar(img->format)) {
+				if (img->stride_plane1 > 0)
+					mif->mif_ctrl3 =
+					    set_bits32(mif->mif_ctrl3, 0xE, 4, 16);
+
+				if (img->stride_plane2 > 0)
+					mif->mif_ctrl4 =
+					    set_bits32(mif->mif_ctrl4, 0xE, 4, 16);
+			} else {
+				;
+			}
+		} else {
+			HISI_FB_ERR("fb%d, invalid_sel(%d) not support!\n",
+				    hisifd->index, invalid_sel);
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS RDMA
+ */
+static void hisi_dss_rdma_init(char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	memset(s_dma, 0, sizeof(dss_rdma_t));
+
+	s_dma->oft_x0 = inp32(dma_base + DMA_OFT_X0);
+	s_dma->oft_y0 = inp32(dma_base + DMA_OFT_Y0);
+	s_dma->oft_x1 = inp32(dma_base + DMA_OFT_X1);
+	s_dma->oft_y1 = inp32(dma_base + DMA_OFT_Y1);
+	s_dma->mask0 = inp32(dma_base + DMA_MASK0);
+	s_dma->mask1 = inp32(dma_base + DMA_MASK1);
+	s_dma->stretch_size_vrt = inp32(dma_base + DMA_STRETCH_SIZE_VRT);
+	s_dma->ctrl = inp32(dma_base + DMA_CTRL);
+	s_dma->tile_scram = inp32(dma_base + DMA_TILE_SCRAM);
+
+	s_dma->ch_rd_shadow = inp32(dma_base + CH_RD_SHADOW);
+	s_dma->ch_ctl = inp32(dma_base + CH_CTL);
+
+	s_dma->data_addr0 = inp32(dma_base + DMA_DATA_ADDR0);
+	s_dma->stride0 = inp32(dma_base + DMA_STRIDE0);
+	s_dma->stretch_stride0 = inp32(dma_base + DMA_STRETCH_STRIDE0);
+	s_dma->data_num0 = inp32(dma_base + DMA_DATA_NUM0);
+
+	s_dma->vpp_ctrl = inp32(dma_base + VPP_CTRL);
+	s_dma->vpp_mem_ctrl = inp32(dma_base + VPP_MEM_CTRL);
+
+	s_dma->dma_buf_ctrl = inp32(dma_base + DMA_BUF_CTRL);
+
+	s_dma->afbcd_hreg_hdr_ptr_lo = inp32(dma_base + AFBCD_HREG_HDR_PTR_LO);
+	s_dma->afbcd_hreg_pic_width = inp32(dma_base + AFBCD_HREG_PIC_WIDTH);
+	s_dma->afbcd_hreg_pic_height = inp32(dma_base + AFBCD_HREG_PIC_HEIGHT);
+	s_dma->afbcd_hreg_format = inp32(dma_base + AFBCD_HREG_FORMAT);
+	s_dma->afbcd_ctl = inp32(dma_base + AFBCD_CTL);
+	s_dma->afbcd_str = inp32(dma_base + AFBCD_STR);
+	s_dma->afbcd_line_crop = inp32(dma_base + AFBCD_LINE_CROP);
+	s_dma->afbcd_input_header_stride =
+	    inp32(dma_base + AFBCD_INPUT_HEADER_STRIDE);
+	s_dma->afbcd_payload_stride = inp32(dma_base + AFBCD_PAYLOAD_STRIDE);
+	s_dma->afbcd_mm_base_0 = inp32(dma_base + AFBCD_MM_BASE_0);
+	s_dma->afbcd_afbcd_payload_pointer =
+	    inp32(dma_base + AFBCD_AFBCD_PAYLOAD_POINTER);
+	s_dma->afbcd_height_bf_str = inp32(dma_base + AFBCD_HEIGHT_BF_STR);
+	s_dma->afbcd_os_cfg = inp32(dma_base + AFBCD_OS_CFG);
+	s_dma->afbcd_mem_ctrl = inp32(dma_base + AFBCD_MEM_CTRL);
+}
+
+static void hisi_dss_rdma_u_init(char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	s_dma->data_addr1 = inp32(dma_base + DMA_DATA_ADDR1);
+	s_dma->stride1 = inp32(dma_base + DMA_STRIDE1);
+	s_dma->stretch_stride1 = inp32(dma_base + DMA_STRETCH_STRIDE1);
+	s_dma->data_num1 = inp32(dma_base + DMA_DATA_NUM1);
+}
+
+static void hisi_dss_rdma_v_init(char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	s_dma->data_addr2 = inp32(dma_base + DMA_DATA_ADDR2);
+	s_dma->stride2 = inp32(dma_base + DMA_STRIDE2);
+	s_dma->stretch_stride2 = inp32(dma_base + DMA_STRETCH_STRIDE2);
+	s_dma->data_num2 = inp32(dma_base + DMA_DATA_NUM2);
+}
+
+void hisi_dss_chn_set_reg_default_value(struct hisi_fb_data_type *hisifd,
+					char __iomem *dma_base)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dma_base == NULL);
+
+	hisifd->set_reg(hisifd, dma_base + CH_REG_DEFAULT, 0x1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + CH_REG_DEFAULT, 0x0, 32, 0);
+}
+
+static void hisi_dss_rdma_set_reg(struct hisi_fb_data_type *hisifd,
+				  char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	hisifd->set_reg(hisifd, dma_base + CH_REG_DEFAULT, 0x1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + CH_REG_DEFAULT, 0x0, 32, 0);
+
+	hisifd->set_reg(hisifd, dma_base + DMA_OFT_X0, s_dma->oft_x0, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_OFT_Y0, s_dma->oft_y0, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_OFT_X1, s_dma->oft_x1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_OFT_Y1, s_dma->oft_y1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_MASK0, s_dma->mask0, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_MASK1, s_dma->mask1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRETCH_SIZE_VRT,
+			s_dma->stretch_size_vrt, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_CTRL, s_dma->ctrl, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_TILE_SCRAM, s_dma->tile_scram,
+			32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_DATA_ADDR0, s_dma->data_addr0,
+			32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRIDE0, s_dma->stride0, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRETCH_STRIDE0,
+			s_dma->stretch_stride0, 32, 0);
+
+	hisifd->set_reg(hisifd, dma_base + CH_RD_SHADOW, s_dma->ch_rd_shadow,
+			32, 0);
+	hisifd->set_reg(hisifd, dma_base + CH_CTL, s_dma->ch_ctl, 32, 0);
+
+	if (s_dma->vpp_used) {
+		hisifd->set_reg(hisifd, dma_base + VPP_CTRL, s_dma->vpp_ctrl,
+				32, 0);
+	}
+
+	hisifd->set_reg(hisifd, dma_base + DMA_BUF_CTRL, s_dma->dma_buf_ctrl,
+			32, 0);
+
+	if (s_dma->afbc_used) {
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HREG_HDR_PTR_LO,
+				s_dma->afbcd_hreg_hdr_ptr_lo, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HREG_PIC_WIDTH,
+				s_dma->afbcd_hreg_pic_width, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HREG_PIC_HEIGHT,
+				s_dma->afbcd_hreg_pic_height, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HREG_FORMAT,
+				s_dma->afbcd_hreg_format, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_CTL, s_dma->afbcd_ctl,
+				32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_STR, s_dma->afbcd_str,
+				32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_LINE_CROP,
+				s_dma->afbcd_line_crop, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_INPUT_HEADER_STRIDE,
+				s_dma->afbcd_input_header_stride, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_PAYLOAD_STRIDE,
+				s_dma->afbcd_payload_stride, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_MM_BASE_0,
+				s_dma->afbcd_mm_base_0, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_AFBCD_PAYLOAD_POINTER,
+				s_dma->afbcd_afbcd_payload_pointer, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HEIGHT_BF_STR,
+				s_dma->afbcd_height_bf_str, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_OS_CFG,
+				s_dma->afbcd_os_cfg, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_SCRAMBLE_MODE,
+				s_dma->afbcd_scramble_mode, 32, 0);
+		hisifd->set_reg(hisifd, dma_base + AFBCD_HEADER_POINTER_OFFSET,
+				s_dma->afbcd_header_pointer_offset, 32, 0);
+	}
+}
+
+static void hisi_dss_rdma_u_set_reg(struct hisi_fb_data_type *hisifd,
+				    char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	hisifd->set_reg(hisifd, dma_base + DMA_DATA_ADDR1, s_dma->data_addr1,
+			32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRIDE1, s_dma->stride1, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRETCH_STRIDE1,
+			s_dma->stretch_stride1, 32, 0);
+}
+
+static void hisi_dss_rdma_v_set_reg(struct hisi_fb_data_type *hisifd,
+				    char __iomem *dma_base, dss_rdma_t *s_dma)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dma_base == NULL);
+	BUG_ON(s_dma == NULL);
+
+	hisifd->set_reg(hisifd, dma_base + DMA_DATA_ADDR2, s_dma->data_addr2,
+			32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRIDE2, s_dma->stride2, 32, 0);
+	hisifd->set_reg(hisifd, dma_base + DMA_STRETCH_STRIDE2,
+			s_dma->stretch_stride2, 32, 0);
+}
+
+static int hisi_get_rdma_tile_interleave(uint32_t stride)
+{
+	int i = 0;
+	uint32_t interleave[MAX_TILE_SURPORT_NUM] = {
+		256, 512, 1024, 2048, 4096, 8192,
+	};
+
+	for (i = 0; i < MAX_TILE_SURPORT_NUM; i++) {
+		if (interleave[i] == stride)
+			return MIN_INTERLEAVE + i;
+	}
+
+	return 0;
+}
+
+int hisi_dss_rdma_config(struct hisi_fb_data_type *hisifd, int ovl_idx,
+			 dss_layer_t *layer, dss_rect_ltrb_t *clip_rect,
+			 dss_rect_t *out_aligned_rect,
+			 bool *rdma_stretch_enable)
+{
+	dss_rdma_t *dma = NULL;
+
+	bool mmu_enable = false;
+	bool is_yuv_semi_planar = false;
+	bool is_yuv_planar = false;
+	bool src_rect_mask_enable = false;
+
+	uint32_t rdma_addr = 0;
+	uint32_t rdma_stride = 0;
+	int rdma_format = 0;
+	int rdma_transform = 0;
+	int rdma_data_num = 0;
+	uint32_t stretch_size_vrt = 0;
+	uint32_t stretched_line_num = 0;
+	uint32_t stretched_stride = 0;
+
+	int bpp = 0;
+	int aligned_pixel = 0;
+	int rdma_oft_x0 = 0;
+	int rdma_oft_y0 = 0;
+	int rdma_oft_x1 = 0;
+	int rdma_oft_y1 = 0;
+	int rdma_mask_x0 = 0;
+	int rdma_mask_y0 = 0;
+	int rdma_mask_x1 = 0;
+	int rdma_mask_y1 = 0;
+
+	int chn_idx = 0;
+	uint32_t l2t_interleave_n = 0;
+	dss_rect_ltrb_t aligned_rect = { 0, 0, 0, 0 };
+	dss_rect_ltrb_t aligned_mask_rect = { 0, 0, 0, 0 };
+	dss_rect_t new_src_rect;
+
+	uint32_t afbcd_half_block_mode = 0;
+	uint32_t afbcd_stretch_acc = 0;
+	uint32_t afbcd_stretch_inc = 0;
+	uint32_t afbcd_height_bf_str = 0;
+	uint32_t afbcd_top_crop_num = 0;
+	uint32_t afbcd_bottom_crop_num = 0;
+	uint32_t afbc_header_addr = 0;
+	uint32_t afbc_header_stride = 0;
+	uint32_t afbc_payload_addr = 0;
+	uint32_t afbc_payload_stride = 0;
+	uint32_t afbc_header_start_pos = 0;
+	uint32_t afbc_header_pointer_offset = 0;
+	uint32_t stride_align = 0;
+	uint32_t addr_align = 0;
+	dss_rect_ltrb_t afbc_rect;
+	uint32_t mm_base_0 = 0;
+	uint32_t mm_base_1 = 0;
+	bool mm_alloc_needed = false;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	chn_idx = layer->chn_idx;
+	new_src_rect = layer->src_rect;
+
+	stretched_line_num = isNeedRdmaStretchBlt(hisifd, layer);
+	*rdma_stretch_enable = (stretched_line_num > 0) ? true : false;
+
+	mmu_enable = (layer->img.mmu_enable == 1) ? true : false;
+	is_yuv_semi_planar = isYUVSemiPlanar(layer->img.format);
+	is_yuv_planar = isYUVPlanar(layer->img.format);
+
+	rdma_format = hisi_pixel_format_hal2dma(layer->img.format);
+	if (rdma_format < 0) {
+		HISI_FB_ERR("layer format(%d) not support !\n",
+			    layer->img.format);
+		return -EINVAL;
+	}
+
+	rdma_transform = hisi_transform_hal2dma(layer->transform, chn_idx);
+	if (rdma_transform < 0) {
+		HISI_FB_ERR("layer transform(%d) not support!\n",
+			    layer->transform);
+		return -EINVAL;
+	}
+
+	bpp = (is_yuv_semi_planar || is_yuv_planar) ? 1 : layer->img.bpp;
+	aligned_pixel = DMA_ALIGN_BYTES / bpp;
+
+	src_rect_mask_enable = isSrcRectMasked(layer, aligned_pixel);
+
+	dma = &(hisifd->dss_module.rdma[chn_idx]);
+	hisifd->dss_module.dma_used[chn_idx] = 1;
+
+	if (layer->need_cap & CAP_YUV_DEINTERLACE) {
+		dma->vpp_used = 1;
+
+		if (layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+			dma->vpp_ctrl = set_bits32(dma->vpp_ctrl, 0x2, 2, 0);
+		} else {
+			dma->vpp_ctrl = set_bits32(dma->vpp_ctrl, 0x3, 2, 0);
+		}
+	}
+
+	if (layer->need_cap & CAP_AFBCD) {
+		if ((layer->img.mmbuf_base > 0) && (layer->img.mmbuf_size > 0)) {
+			mm_base_0 = layer->img.mmbuf_base;
+			mm_base_1 =
+			    layer->img.mmbuf_base + layer->img.mmbuf_size / 2;
+		} else {
+			BUG_ON(hisifd->mmbuf_info == NULL);
+
+			if (ovl_idx <= DSS_OVL1) {
+				mm_alloc_needed = true;
+			} else {
+				if (hisifd->mmbuf_info->mm_used[chn_idx] == 1)
+					mm_alloc_needed = false;
+				else
+					mm_alloc_needed = true;
+			}
+
+			if (mm_alloc_needed) {
+				afbc_rect.left =
+				    ALIGN_DOWN(new_src_rect.x,
+					       MMBUF_ADDR_ALIGN);
+				afbc_rect.right =
+				    ALIGN_UP(new_src_rect.x - afbc_rect.left +
+					     new_src_rect.w, MMBUF_ADDR_ALIGN);
+				hisifd->mmbuf_info->mm_size[chn_idx] =
+				    afbc_rect.right * layer->img.bpp *
+				    MMBUF_LINE_NUM;
+				hisifd->mmbuf_info->mm_base[chn_idx] =
+				    hisi_dss_mmbuf_alloc(g_mmbuf_gen_pool,
+							 hisifd->mmbuf_info->mm_size[chn_idx]);
+				if (hisifd->mmbuf_info->mm_base[chn_idx] <
+				    MMBUF_BASE) {
+					HISI_FB_ERR
+					    ("fb%d, chn%d failed to alloc mmbuf, mm_base=0x%x.\n",
+					     hisifd->index, chn_idx,
+					     hisifd->mmbuf_info->mm_base[chn_idx]);
+					return -EINVAL;
+				}
+			}
+
+			mm_base_0 = hisifd->mmbuf_info->mm_base[chn_idx];
+			mm_base_1 = hisifd->mmbuf_info->mm_base[chn_idx] +
+			    hisifd->mmbuf_info->mm_size[chn_idx] / 2;
+			hisifd->mmbuf_info->mm_used[chn_idx] = 1;
+		}
+
+		mm_base_0 -= MMBUF_BASE;
+		mm_base_1 -= MMBUF_BASE;
+
+		if ((layer->img.width & (AFBC_HEADER_ADDR_ALIGN - 1)) ||
+		    (layer->img.height & (AFBC_BLOCK_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("layer%d img width(%d) is not %d bytes aligned, or "
+			     "img heigh(%d) is not %d bytes aligned!\n",
+			     layer->layer_idx, layer->img.width,
+			     AFBC_HEADER_ADDR_ALIGN, layer->img.height,
+			     AFBC_BLOCK_ALIGN);
+			return -EINVAL;
+		}
+
+		if ((mm_base_0 & (MMBUF_ADDR_ALIGN - 1)) ||
+		    (mm_base_1 & (MMBUF_ADDR_ALIGN - 1)) ||
+		    (layer->img.mmbuf_size & (MMBUF_ADDR_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("layer%d mm_base_0(0x%x) is not %d bytes aligned, or "
+			     "mm_base_1(0x%x) is not %d bytes aligned, or mmbuf_size(0x%x) is "
+			     "not %d bytes aligned!\n", layer->layer_idx,
+			     mm_base_0, MMBUF_ADDR_ALIGN, mm_base_1,
+			     MMBUF_ADDR_ALIGN, layer->img.mmbuf_size,
+			     MMBUF_ADDR_ALIGN);
+			return -EINVAL;
+		}
+
+		dma->afbc_used = 1;
+
+		aligned_rect.left =
+		    ALIGN_DOWN(new_src_rect.x, AFBC_BLOCK_ALIGN);
+		aligned_rect.right =
+		    ALIGN_UP(new_src_rect.x + new_src_rect.w,
+			     AFBC_BLOCK_ALIGN) - 1;
+		aligned_rect.top = ALIGN_DOWN(new_src_rect.y, AFBC_BLOCK_ALIGN);
+		aligned_rect.bottom =
+		    ALIGN_UP(new_src_rect.y + new_src_rect.h,
+			     AFBC_BLOCK_ALIGN) - 1;
+
+		out_aligned_rect->x = 0;
+		out_aligned_rect->y = 0;
+		out_aligned_rect->w =
+		    aligned_rect.right - aligned_rect.left + 1;
+		out_aligned_rect->h =
+		    aligned_rect.bottom - aligned_rect.top + 1;
+
+		afbcd_height_bf_str =
+		    aligned_rect.bottom - aligned_rect.top + 1;
+
+		if (*rdma_stretch_enable) {
+			afbcd_stretch_inc = 0;
+			afbcd_stretch_acc = 0;
+
+			out_aligned_rect->h /= 2;
+			if (layer->transform & HISI_FB_TRANSFORM_FLIP_V) {
+				afbcd_half_block_mode =
+				    AFBC_HALF_BLOCK_LOWER_ONLY;
+			} else {
+				afbcd_half_block_mode =
+				    AFBC_HALF_BLOCK_UPPER_ONLY;
+			}
+		} else {
+			if (layer->transform & HISI_FB_TRANSFORM_FLIP_V) {
+				afbcd_half_block_mode =
+				    AFBC_HALF_BLOCK_LOWER_UPPER_ALL;
+			} else {
+				afbcd_half_block_mode =
+				    AFBC_HALF_BLOCK_UPPER_LOWER_ALL;
+			}
+		}
+
+		if (layer->img.
+		    afbc_header_addr & (AFBC_SUPER_GRAPH_HEADER_ADDR_ALIGN -
+					1)) {
+			HISI_FB_ERR
+			    ("layer%d super graph afbc_header_addr(0x%x) "
+			     "is not %d bytes aligned!\n",
+			     layer->layer_idx, afbc_header_addr,
+			     AFBC_SUPER_GRAPH_HEADER_ADDR_ALIGN);
+			return -EINVAL;
+		}
+
+		clip_rect->left = new_src_rect.x - aligned_rect.left;
+		clip_rect->right =
+		    aligned_rect.right - DSS_WIDTH(new_src_rect.x +
+						   new_src_rect.w);
+		clip_rect->top = new_src_rect.y - aligned_rect.top;
+		clip_rect->bottom =
+		    aligned_rect.bottom - DSS_HEIGHT(new_src_rect.y +
+						     new_src_rect.h);
+		if (hisi_adjust_clip_rect(layer, clip_rect) < 0) {
+			HISI_FB_ERR
+			    ("clip rect invalid => layer_idx=%d, chn_idx=%d, "
+			     "clip_rect(%d, %d, %d, %d).\n",
+			     layer->layer_idx, chn_idx, clip_rect->left,
+			     clip_rect->right, clip_rect->top,
+			     clip_rect->bottom);
+			return -EINVAL;
+		}
+
+		afbcd_top_crop_num = (clip_rect->top > AFBCD_TOP_CROP_MAX) ?
+		    AFBCD_TOP_CROP_MAX : clip_rect->top;
+		afbcd_bottom_crop_num =
+		    (clip_rect->bottom >
+		     AFBCD_BOTTOM_CROP_MAX) ? AFBCD_BOTTOM_CROP_MAX :
+		    clip_rect->bottom;
+
+		clip_rect->top -= afbcd_top_crop_num;
+		BUG_ON(clip_rect->top < 0);
+		clip_rect->bottom -= afbcd_bottom_crop_num;
+		BUG_ON(clip_rect->bottom < 0);
+
+		out_aligned_rect->h -=
+		    (afbcd_top_crop_num + afbcd_bottom_crop_num);
+
+		rdma_oft_x0 = aligned_rect.left / aligned_pixel;
+		rdma_oft_x1 = aligned_rect.right / aligned_pixel;
+		stretch_size_vrt = DSS_HEIGHT(out_aligned_rect->h);
+		stretched_line_num = 0;
+
+		afbc_rect = aligned_rect;
+		afbc_rect.left =
+		    ALIGN_DOWN(new_src_rect.x, AFBC_HEADER_ADDR_ALIGN);
+		afbc_rect.right =
+		    ALIGN_UP(new_src_rect.x + new_src_rect.w,
+			     AFBC_HEADER_ADDR_ALIGN) - 1;
+
+		afbc_header_stride =
+		    (layer->img.width / AFBC_BLOCK_ALIGN) *
+		    AFBC_HEADER_STRIDE_BLOCK;
+		afbc_header_pointer_offset =
+		    (afbc_rect.top / AFBC_BLOCK_ALIGN) * afbc_header_stride +
+		    (afbc_rect.left / AFBC_BLOCK_ALIGN) *
+		    AFBC_HEADER_STRIDE_BLOCK;
+		afbc_header_addr =
+		    layer->img.afbc_header_addr + afbc_header_pointer_offset;
+
+		if ((afbc_header_addr & (AFBC_HEADER_ADDR_ALIGN - 1)) ||
+		    (afbc_header_stride & (AFBC_HEADER_STRIDE_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("layer%d afbc_header_addr(0x%x) is not %d bytes aligned, or "
+			     "afbc_header_stride(0x%x) is not %d bytes aligned!\n",
+			     layer->layer_idx, afbc_header_addr,
+			     AFBC_HEADER_ADDR_ALIGN, afbc_header_stride,
+			     AFBC_HEADER_STRIDE_ALIGN);
+			return -EINVAL;
+		}
+
+		BUG_ON((aligned_rect.left - afbc_rect.left) < 0);
+		afbc_header_start_pos =
+		    (aligned_rect.left - afbc_rect.left) / AFBC_BLOCK_ALIGN;
+
+		if (layer->img.bpp == 4) {
+			stride_align = AFBC_PAYLOAD_STRIDE_ALIGN_32;
+			addr_align = AFBC_PAYLOAD_ADDR_ALIGN_32;
+		} else if (layer->img.bpp == 2) {
+			stride_align = AFBC_PAYLOAD_STRIDE_ALIGN_16;
+			addr_align = AFBC_PAYLOAD_ADDR_ALIGN_16;
+		} else {
+			HISI_FB_ERR("bpp(%d) not supported!\n", layer->img.bpp);
+			return -EINVAL;
+		}
+
+		afbc_payload_stride = layer->img.afbc_payload_stride;
+		if (layer->img.afbc_scramble_mode != DSS_AFBC_SCRAMBLE_MODE2) {
+			afbc_payload_stride =
+			    (layer->img.width / AFBC_BLOCK_ALIGN) *
+			    stride_align;
+		}
+		afbc_payload_addr = layer->img.afbc_payload_addr +
+		    (aligned_rect.top / AFBC_BLOCK_ALIGN) *
+		    afbc_payload_stride +
+		    (aligned_rect.left / AFBC_BLOCK_ALIGN) * stride_align;
+
+		if ((afbc_payload_addr & (addr_align - 1)) ||
+		    (afbc_payload_stride & (stride_align - 1))) {
+			HISI_FB_ERR
+			    ("layer%d afbc_payload_addr(0x%x) is not %d bytes aligned, or "
+			     "afbc_payload_stride(0x%x) is not %d bytes aligned!\n",
+			     layer->layer_idx, afbc_payload_addr, addr_align,
+			     afbc_payload_stride, stride_align);
+			return -EINVAL;
+		}
+
+		if (g_debug_ovl_online_composer) {
+			HISI_FB_INFO
+			    ("fb%d, mm_base_0=0x%x, mm_base_1=0x%x, mmbuf_size=%d, "
+			     "aligned_rect(%d,%d,%d,%d), afbc_rect(%d,%d,%d,%d)!\n",
+			     hisifd->index, mm_base_0, mm_base_1,
+			     layer->img.mmbuf_size, aligned_rect.left,
+			     aligned_rect.top, aligned_rect.right,
+			     aligned_rect.bottom, afbc_rect.left, afbc_rect.top,
+			     afbc_rect.right, afbc_rect.bottom);
+		}
+
+		dma->oft_x0 = set_bits32(dma->oft_x0, rdma_oft_x0, 16, 0);
+		dma->oft_x1 = set_bits32(dma->oft_x1, rdma_oft_x1, 16, 0);
+		dma->stretch_size_vrt = set_bits32(dma->stretch_size_vrt,
+						   (stretch_size_vrt |
+						    (stretched_line_num << 13)),
+						   19, 0);
+		dma->ctrl = set_bits32(dma->ctrl, rdma_format, 5, 3);
+		dma->ctrl =
+		    set_bits32(dma->ctrl, (mmu_enable ? 0x1 : 0x0), 1, 8);
+		dma->ctrl = set_bits32(dma->ctrl, rdma_transform, 3, 9);
+		dma->ctrl =
+		    set_bits32(dma->ctrl, (*rdma_stretch_enable ? 1 : 0), 1,
+			       12);
+		dma->ch_ctl = set_bits32(dma->ch_ctl, 0x1, 1, 0);
+		dma->ch_ctl = set_bits32(dma->ch_ctl, 0x1, 1, 2);
+
+		dma->afbcd_hreg_pic_width =
+		    set_bits32(dma->afbcd_hreg_pic_width,
+			       (aligned_rect.right - aligned_rect.left), 16, 0);
+		dma->afbcd_hreg_pic_height =
+		    set_bits32(dma->afbcd_hreg_pic_height,
+			       (aligned_rect.bottom - aligned_rect.top), 16, 0);
+		dma->afbcd_hreg_format =
+		    set_bits32(dma->afbcd_hreg_format, 0x1, 1, 0);
+		dma->afbcd_hreg_format =
+		    set_bits32(dma->afbcd_hreg_format,
+			       (isYUVPackage(layer->img.format) ? 0x0 : 0x1), 1,
+			       21);
+		dma->afbcd_ctl =
+		    set_bits32(dma->afbcd_ctl, afbcd_half_block_mode, 2, 6);
+		dma->afbcd_str =
+		    set_bits32(dma->afbcd_str,
+			       (afbcd_stretch_acc << 8 | afbcd_stretch_inc), 12,
+			       0);
+		dma->afbcd_line_crop =
+		    set_bits32(dma->afbcd_line_crop,
+			       (afbcd_top_crop_num << 4 |
+				afbcd_bottom_crop_num), 8, 0);
+		dma->afbcd_hreg_hdr_ptr_lo =
+		    set_bits32(dma->afbcd_hreg_hdr_ptr_lo, afbc_header_addr, 32,
+			       0);
+		dma->afbcd_input_header_stride =
+		    set_bits32(dma->afbcd_input_header_stride,
+			       (afbc_header_start_pos << 14) |
+			       afbc_header_stride, 16, 0);
+		dma->afbcd_payload_stride =
+		    set_bits32(dma->afbcd_payload_stride, afbc_payload_stride,
+			       20, 0);
+		dma->afbcd_mm_base_0 =
+		    set_bits32(dma->afbcd_mm_base_0, mm_base_0, 32, 0);
+		dma->afbcd_afbcd_payload_pointer =
+		    set_bits32(dma->afbcd_afbcd_payload_pointer,
+			       afbc_payload_addr, 32, 0);
+		dma->afbcd_height_bf_str =
+		    set_bits32(dma->afbcd_height_bf_str,
+			       DSS_HEIGHT(afbcd_height_bf_str), 16, 0);
+		dma->afbcd_header_pointer_offset =
+		    set_bits32(dma->afbcd_header_pointer_offset,
+			       afbc_header_pointer_offset, 32, 0);
+		dma->afbcd_scramble_mode =
+		    set_bits32(dma->afbcd_scramble_mode,
+			       layer->img.afbc_scramble_mode, 2, 0);
+
+		return 0;
+	}
+
+	rdma_addr = mmu_enable ? layer->img.vir_addr : layer->img.phy_addr;
+	if (rdma_addr & (DMA_ADDR_ALIGN - 1)) {
+		HISI_FB_ERR
+		    ("layer%d rdma_addr(0x%x) is not %d bytes aligned.\n",
+		     layer->layer_idx, rdma_addr, DMA_ADDR_ALIGN);
+		return -EINVAL;
+	}
+
+	if (layer->img.stride & (DMA_STRIDE_ALIGN - 1)) {
+		HISI_FB_ERR("layer%d stride(0x%x) is not %d bytes aligned.\n",
+			    layer->layer_idx, layer->img.stride,
+			    DMA_STRIDE_ALIGN);
+		return -EINVAL;
+	}
+
+	if (layer->need_cap & CAP_TILE) {
+		l2t_interleave_n =
+		    hisi_get_rdma_tile_interleave(layer->img.stride);
+		if (l2t_interleave_n < MIN_INTERLEAVE) {
+			HISI_FB_ERR
+			    ("tile stride should be 256*2^n, error stride:%d!\n",
+			     layer->img.stride);
+			return -EINVAL;
+		}
+
+		if (rdma_addr & (TILE_DMA_ADDR_ALIGN - 1)) {
+			HISI_FB_ERR
+			    ("layer%d tile rdma_addr(0x%x) is not %d bytes aligned.\n",
+			     layer->layer_idx, rdma_addr, TILE_DMA_ADDR_ALIGN);
+			return -EINVAL;
+		}
+	}
+
+	if (is_YUV_P_420(layer->img.format) || is_YUV_P_422(layer->img.format)) {
+		aligned_rect.left =
+		    ALIGN_DOWN(new_src_rect.x, 2 * aligned_pixel);
+		aligned_rect.right =
+		    ALIGN_UP(new_src_rect.x + new_src_rect.w,
+			     2 * aligned_pixel) - 1;
+	} else {
+		aligned_rect.left = ALIGN_DOWN(new_src_rect.x, aligned_pixel);
+		aligned_rect.right =
+		    ALIGN_UP(new_src_rect.x + new_src_rect.w,
+			     aligned_pixel) - 1;
+	}
+
+	if (is_YUV_SP_420(layer->img.format) || is_YUV_P_420(layer->img.format)) {
+		aligned_rect.top = ALIGN_DOWN(new_src_rect.y, 2);
+		aligned_rect.bottom =
+		    ALIGN_UP(new_src_rect.y + new_src_rect.h, 2) - 1;
+	} else {
+		aligned_rect.top = new_src_rect.y;
+		aligned_rect.bottom =
+		    DSS_HEIGHT(new_src_rect.y + new_src_rect.h);
+	}
+
+	if (src_rect_mask_enable) {
+		if (is_YUV_P_420(layer->img.format)
+		    || is_YUV_P_422(layer->img.format)) {
+			aligned_mask_rect.left =
+			    ALIGN_UP(layer->src_rect_mask.x, 2 * aligned_pixel);
+			aligned_mask_rect.right =
+			    ALIGN_DOWN(layer->src_rect_mask.x +
+				       layer->src_rect_mask.w,
+				       2 * aligned_pixel) - 1;
+		} else {
+			aligned_mask_rect.left =
+			    ALIGN_UP(layer->src_rect_mask.x, aligned_pixel);
+			aligned_mask_rect.right =
+			    ALIGN_DOWN(layer->src_rect_mask.x +
+				       layer->src_rect_mask.w,
+				       aligned_pixel) - 1;
+		}
+
+		if (is_YUV_SP_420(layer->img.format)
+		    || is_YUV_P_420(layer->img.format)) {
+			aligned_mask_rect.top =
+			    ALIGN_UP(layer->src_rect_mask.y, 2);
+			aligned_mask_rect.bottom =
+			    ALIGN_DOWN(layer->src_rect_mask.y +
+				       layer->src_rect_mask.h, 2) - 1;
+		} else {
+			aligned_mask_rect.top = layer->src_rect_mask.y;
+			aligned_mask_rect.bottom =
+			    DSS_HEIGHT(layer->src_rect_mask.y +
+				       layer->src_rect_mask.h);
+		}
+	}
+
+	out_aligned_rect->x = 0;
+	out_aligned_rect->y = 0;
+	out_aligned_rect->w = aligned_rect.right - aligned_rect.left + 1;
+	out_aligned_rect->h = aligned_rect.bottom - aligned_rect.top + 1;
+	if (stretched_line_num > 0) {
+		stretch_size_vrt = (out_aligned_rect->h / stretched_line_num) +
+		    ((out_aligned_rect->h % stretched_line_num) ? 1 : 0) - 1;
+
+		out_aligned_rect->h = stretch_size_vrt + 1;
+	} else {
+		stretch_size_vrt = 0x0;
+	}
+
+	clip_rect->left = new_src_rect.x - aligned_rect.left;
+	clip_rect->right =
+	    aligned_rect.right - DSS_WIDTH(new_src_rect.x + new_src_rect.w);
+	clip_rect->top = new_src_rect.y - aligned_rect.top;
+	clip_rect->bottom =
+	    aligned_rect.bottom - DSS_HEIGHT(new_src_rect.y + new_src_rect.h);
+
+	if (hisi_adjust_clip_rect(layer, clip_rect) < 0) {
+		HISI_FB_ERR
+		    ("clip rect invalid => layer_idx=%d, chn_idx=%d, "
+		     "clip_rect(%d, %d, %d, %d).\n",
+		     layer->layer_idx, chn_idx, clip_rect->left,
+		     clip_rect->right, clip_rect->top, clip_rect->bottom);
+		return -EINVAL;
+	}
+
+	rdma_oft_y0 = aligned_rect.top;
+	rdma_oft_y1 = aligned_rect.bottom;
+	rdma_oft_x0 = aligned_rect.left / aligned_pixel;
+	rdma_oft_x1 = aligned_rect.right / aligned_pixel;
+
+	if ((rdma_oft_x1 - rdma_oft_x0) < 0 ||
+	    (rdma_oft_x1 - rdma_oft_x0 + 1) > DMA_IN_WIDTH_MAX) {
+		HISI_FB_ERR
+		    ("out of range, rdma_oft_x0 = %d, rdma_oft_x1 = %d!\n",
+		     rdma_oft_x0, rdma_oft_x1);
+		return -EINVAL;
+	}
+
+	if ((rdma_oft_y1 - rdma_oft_y0) < 0 ||
+	    (rdma_oft_y1 - rdma_oft_y0 + 1) > DMA_IN_HEIGHT_MAX) {
+		HISI_FB_ERR
+		    ("out of range, rdma_oft_y0 = %d, rdma_oft_y1 = %d\n",
+		     rdma_oft_y0, rdma_oft_y1);
+		return -EINVAL;
+	}
+
+	rdma_addr =
+	    hisi_calculate_display_addr(mmu_enable, layer, &aligned_rect,
+					DSS_ADDR_PLANE0);
+	rdma_stride = layer->img.stride;
+	rdma_data_num =
+	    (rdma_oft_x1 - rdma_oft_x0 + 1) * (rdma_oft_y1 - rdma_oft_y0 + 1);
+
+	if (src_rect_mask_enable) {
+		rdma_mask_y0 = aligned_mask_rect.top;
+		rdma_mask_y1 = aligned_mask_rect.bottom;
+		rdma_mask_x0 = aligned_mask_rect.left / aligned_pixel;
+		rdma_mask_x1 = aligned_mask_rect.right / aligned_pixel;
+
+		if ((rdma_mask_x1 - rdma_mask_x0) > 2)
+			rdma_mask_x0 += 2;
+
+		if ((rdma_mask_x0 <= rdma_oft_x0)
+		    || (rdma_mask_x1 >= rdma_oft_x1)
+		    || (rdma_mask_y0 <= rdma_oft_y0)
+		    || (rdma_mask_y1 >= rdma_oft_y1)) {
+			src_rect_mask_enable = false;
+			rdma_mask_x0 = 0;
+			rdma_mask_y0 = 0;
+			rdma_mask_x1 = 0;
+			rdma_mask_y1 = 0;
+		}
+	}
+
+	if (stretched_line_num > 0) {
+		stretched_stride =
+		    stretched_line_num * rdma_stride / DMA_ALIGN_BYTES;
+		rdma_data_num =
+		    (stretch_size_vrt + 1) * (rdma_oft_x1 - rdma_oft_x0 + 1);
+	} else {
+		stretch_size_vrt = rdma_oft_y1 - rdma_oft_y0;
+		stretched_line_num = 0x0;
+		stretched_stride = 0x0;
+	}
+
+	dma->oft_x0 = set_bits32(dma->oft_x0, rdma_oft_x0, 16, 0);
+	dma->oft_y0 = set_bits32(dma->oft_y0, rdma_oft_y0, 16, 0);
+	dma->oft_x1 = set_bits32(dma->oft_x1, rdma_oft_x1, 16, 0);
+	dma->oft_y1 = set_bits32(dma->oft_y1, rdma_oft_y1, 16, 0);
+	dma->mask0 = set_bits32(dma->mask0,
+				(rdma_mask_y0 | (rdma_mask_x0 << 16)), 32, 0);
+	dma->mask1 = set_bits32(dma->mask1,
+				(rdma_mask_y1 | (rdma_mask_x1 << 16)), 32, 0);
+	dma->stretch_size_vrt = set_bits32(dma->stretch_size_vrt,
+					   (stretch_size_vrt |
+					    (stretched_line_num << 13)), 19, 0);
+	dma->ctrl =
+	    set_bits32(dma->ctrl, ((layer->need_cap & CAP_TILE) ? 0x1 : 0x0), 1,
+		       1);
+	dma->ctrl = set_bits32(dma->ctrl, rdma_format, 5, 3);
+	dma->ctrl = set_bits32(dma->ctrl, (mmu_enable ? 0x1 : 0x0), 1, 8);
+	dma->ctrl = set_bits32(dma->ctrl, rdma_transform, 3, 9);
+	dma->ctrl =
+	    set_bits32(dma->ctrl, ((stretched_line_num > 0) ? 0x1 : 0x0), 1,
+		       12);
+	dma->ctrl =
+	    set_bits32(dma->ctrl, (src_rect_mask_enable ? 0x1 : 0x0), 1, 17);
+	dma->tile_scram =
+	    set_bits32(dma->tile_scram,
+		       ((layer->need_cap & CAP_TILE) ? 0x1 : 0x0), 1, 0);
+	dma->ch_ctl = set_bits32(dma->ch_ctl, 0x1, 1, 0);
+
+	dma->data_addr0 = set_bits32(dma->data_addr0, rdma_addr, 32, 0);
+	dma->stride0 = set_bits32(dma->stride0,
+				  ((rdma_stride /
+				    DMA_ALIGN_BYTES) | (l2t_interleave_n <<
+							16)), 20, 0);
+	dma->stretch_stride0 =
+	    set_bits32(dma->stretch_stride0, stretched_stride, 19, 0);
+	dma->data_num0 = set_bits32(dma->data_num0, rdma_data_num, 30, 0);
+
+	if (is_yuv_semi_planar || is_yuv_planar) {
+		if (is_YUV_P_420(layer->img.format)
+		    || is_YUV_P_422(layer->img.format)) {
+			rdma_oft_x0 /= 2;
+			rdma_oft_x1 = (rdma_oft_x1 + 1) / 2 - 1;
+		}
+
+		if (is_YUV_SP_420(layer->img.format)
+		    || is_YUV_P_420(layer->img.format)) {
+			rdma_oft_y0 /= 2;
+			rdma_oft_y1 = (rdma_oft_y1 + 1) / 2 - 1;
+
+			stretched_line_num /= 2;
+		}
+
+		rdma_addr =
+		    hisi_calculate_display_addr(mmu_enable, layer,
+						&aligned_rect, DSS_ADDR_PLANE1);
+		rdma_stride = layer->img.stride_plane1;
+		rdma_data_num =
+		    (rdma_oft_x1 - rdma_oft_x0 + 1) * (rdma_oft_y1 -
+						       rdma_oft_y0 + 1) * 2;
+
+		if (*rdma_stretch_enable) {
+			stretched_stride =
+			    stretched_line_num * rdma_stride / DMA_ALIGN_BYTES;
+			rdma_data_num =
+			    (stretch_size_vrt + 1) * (rdma_oft_x1 -
+						      rdma_oft_x0 + 1) * 2;
+		} else {
+			stretch_size_vrt = 0;
+			stretched_line_num = 0;
+			stretched_stride = 0;
+		}
+
+		dma->data_addr1 = set_bits32(dma->data_addr1, rdma_addr, 32, 0);
+		dma->stride1 = set_bits32(dma->stride1,
+					  ((rdma_stride /
+					    DMA_ALIGN_BYTES) | (l2t_interleave_n << 16)), 20, 0);
+		dma->stretch_stride1 =
+		    set_bits32(dma->stretch_stride1, stretched_stride, 19, 0);
+		dma->data_num1 =
+		    set_bits32(dma->data_num1, rdma_data_num, 30, 0);
+
+		if (is_yuv_planar) {
+			rdma_addr =
+			    hisi_calculate_display_addr(mmu_enable, layer,
+							&aligned_rect,
+							DSS_ADDR_PLANE2);
+			rdma_stride = layer->img.stride_plane2;
+
+			dma->data_addr2 =
+			    set_bits32(dma->data_addr2, rdma_addr, 32, 0);
+			dma->stride2 =
+			    set_bits32(dma->stride2,
+				       ((rdma_stride /
+					     DMA_ALIGN_BYTES) | (l2t_interleave_n << 16)), 20, 0);
+			dma->stretch_stride2 =
+			    set_bits32(dma->stretch_stride1, stretched_stride,
+				       19, 0);
+			dma->data_num2 =
+			    set_bits32(dma->data_num1, rdma_data_num, 30, 0);
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS DFC
+ */
+static void hisi_dss_dfc_init(char __iomem *dfc_base, dss_dfc_t *s_dfc)
+{
+	BUG_ON(dfc_base == NULL);
+	BUG_ON(s_dfc == NULL);
+
+	memset(s_dfc, 0, sizeof(dss_dfc_t));
+
+	s_dfc->disp_size = inp32(dfc_base + DFC_DISP_SIZE);
+	s_dfc->pix_in_num = inp32(dfc_base + DFC_PIX_IN_NUM);
+	s_dfc->disp_fmt = inp32(dfc_base + DFC_DISP_FMT);
+	s_dfc->clip_ctl_hrz = inp32(dfc_base + DFC_CLIP_CTL_HRZ);
+	s_dfc->clip_ctl_vrz = inp32(dfc_base + DFC_CLIP_CTL_VRZ);
+	s_dfc->ctl_clip_en = inp32(dfc_base + DFC_CTL_CLIP_EN);
+	s_dfc->icg_module = inp32(dfc_base + DFC_ICG_MODULE);
+	s_dfc->dither_enable = inp32(dfc_base + DFC_DITHER_ENABLE);
+	s_dfc->padding_ctl = inp32(dfc_base + DFC_PADDING_CTL);
+}
+
+static void hisi_dss_dfc_set_reg(struct hisi_fb_data_type *hisifd,
+				 char __iomem *dfc_base, dss_dfc_t *s_dfc)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dfc_base == NULL);
+	BUG_ON(s_dfc == NULL);
+
+	hisifd->set_reg(hisifd, dfc_base + DFC_DISP_SIZE, s_dfc->disp_size, 32,
+			0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_PIX_IN_NUM, s_dfc->pix_in_num,
+			32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_DISP_FMT, s_dfc->disp_fmt, 32,
+			0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_CLIP_CTL_HRZ,
+			s_dfc->clip_ctl_hrz, 32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_CLIP_CTL_VRZ,
+			s_dfc->clip_ctl_vrz, 32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_CTL_CLIP_EN, s_dfc->ctl_clip_en,
+			32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_ICG_MODULE, s_dfc->icg_module,
+			32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_DITHER_ENABLE,
+			s_dfc->dither_enable, 32, 0);
+	hisifd->set_reg(hisifd, dfc_base + DFC_PADDING_CTL, s_dfc->padding_ctl,
+			32, 0);
+}
+
+int hisi_dss_rdfc_config(struct hisi_fb_data_type *hisifd, dss_layer_t *layer,
+			 dss_rect_t *aligned_rect, dss_rect_ltrb_t clip_rect)
+{
+	dss_dfc_t *dfc = NULL;
+	int chn_idx = 0;
+	int dfc_fmt = 0;
+	int dfc_bpp = 0;
+	int dfc_pix_in_num = 0;
+	int dfc_aligned = 0;
+	int size_hrz = 0;
+	int size_vrt = 0;
+	int dfc_hrz_clip = 0;
+	bool need_clip = false;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+
+	chn_idx = layer->chn_idx;
+
+	dfc = &(hisifd->dss_module.dfc[chn_idx]);
+	hisifd->dss_module.dfc_used[chn_idx] = 1;
+
+	dfc_fmt = hisi_pixel_format_hal2dfc(layer->img.format);
+	if (dfc_fmt < 0) {
+		HISI_FB_ERR("layer format (%d) not support !\n",
+			    layer->img.format);
+		return -EINVAL;
+	}
+
+	dfc_bpp = hisi_dfc_get_bpp(dfc_fmt);
+	if (dfc_bpp <= 0) {
+		HISI_FB_ERR("dfc_bpp(%d) not support !\n", dfc_bpp);
+		return -EINVAL;
+	}
+
+	dfc_pix_in_num = (dfc_bpp <= 2) ? 0x1 : 0x0;
+	dfc_aligned = (dfc_bpp <= 2) ? 4 : 2;
+
+	need_clip = isNeedRectClip(clip_rect);
+
+	size_hrz = DSS_WIDTH(aligned_rect->w);
+	size_vrt = DSS_HEIGHT(aligned_rect->h);
+
+	if (((size_hrz + 1) % dfc_aligned) != 0) {
+		size_hrz -= 1;
+		HISI_FB_ERR("SIZE_HRT=%d mismatch!bpp=%d\n", size_hrz,
+			    layer->img.bpp);
+
+		HISI_FB_ERR("layer_idx%d, format=%d, transform=%d, "
+			    "original_src_rect(%d,%d,%d,%d), rdma_out_rect(%d,%d,%d,%d), "
+			    "dst_rect(%d,%d,%d,%d)!\n",
+			    layer->layer_idx, layer->img.format,
+			    layer->transform, layer->src_rect.x,
+			    layer->src_rect.y, layer->src_rect.w,
+			    layer->src_rect.h, aligned_rect->x, aligned_rect->y,
+			    aligned_rect->w, aligned_rect->h, layer->dst_rect.x,
+			    layer->dst_rect.y, layer->dst_rect.w,
+			    layer->dst_rect.h);
+	}
+
+	dfc_hrz_clip = (size_hrz + 1) % dfc_aligned;
+	if (dfc_hrz_clip) {
+		clip_rect.right += dfc_hrz_clip;
+		size_hrz += dfc_hrz_clip;
+		need_clip = true;
+	}
+
+	dfc->disp_size =
+	    set_bits32(dfc->disp_size, (size_vrt | (size_hrz << 16)), 29, 0);
+	dfc->pix_in_num = set_bits32(dfc->pix_in_num, dfc_pix_in_num, 1, 0);
+	dfc->disp_fmt = set_bits32(dfc->disp_fmt,
+				   ((dfc_fmt << 1) |
+				    (hisi_uv_swap(layer->img.format) << 6) |
+				    (hisi_rb_swap(layer->img.format) << 7)), 8, 0);
+
+	if (need_clip) {
+		dfc->clip_ctl_hrz = set_bits32(dfc->clip_ctl_hrz,
+					       (clip_rect.right | (clip_rect.left << 16)),
+					       32, 0);
+		dfc->clip_ctl_vrz =
+		    set_bits32(dfc->clip_ctl_vrz,
+			       (clip_rect.bottom | (clip_rect.top << 16)), 32, 0);
+		dfc->ctl_clip_en = set_bits32(dfc->ctl_clip_en, 0x1, 1, 0);
+	} else {
+		dfc->clip_ctl_hrz = set_bits32(dfc->clip_ctl_hrz, 0x0, 32, 0);
+		dfc->clip_ctl_vrz = set_bits32(dfc->clip_ctl_vrz, 0x0, 32, 0);
+		dfc->ctl_clip_en = set_bits32(dfc->ctl_clip_en, 0x1, 1, 0);
+	}
+	dfc->icg_module = set_bits32(dfc->icg_module, 0x1, 1, 0);
+	dfc->dither_enable = set_bits32(dfc->dither_enable, 0x0, 1, 0);
+	dfc->padding_ctl = set_bits32(dfc->padding_ctl, 0x0, 17, 0);
+
+	if (need_clip) {
+		aligned_rect->w -= (clip_rect.left + clip_rect.right);
+		aligned_rect->h -= (clip_rect.top + clip_rect.bottom);
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS SCF
+ */
+
+/* Filter coefficients for SCF */
+#define PHASE_NUM	(66)
+#define TAP4	(4)
+#define TAP5	(5)
+#define TAP6	(6)
+#define COEF_LUT_NUM	(2)
+
+static const int COEF_LUT_TAP4[SCL_COEF_IDX_MAX][PHASE_NUM][TAP4] = {
+	/* YUV_COEF_IDX */
+	{
+	 {214, 599, 214, -3},
+	 {207, 597, 223, -3},
+	 {200, 596, 231, -3},
+	 {193, 596, 238, -3},
+	 {186, 595, 246, -3},
+	 {178, 594, 255, -3},
+	 {171, 593, 263, -3},
+	 {165, 591, 271, -3},
+	 {158, 589, 279, -2},
+	 {151, 587, 288, -2},
+	 {145, 584, 296, -1},
+	 {139, 582, 304, -1},
+	 {133, 578, 312, 1},
+	 {127, 575, 321, 1},
+	 {121, 572, 329, 2},
+	 {115, 568, 337, 4},
+	 {109, 564, 346, 5},
+	 {104, 560, 354, 6},
+	 {98, 555, 362, 9},
+	 {94, 550, 370, 10},
+	 {88, 546, 379, 11},
+	 {84, 540, 387, 13},
+	 {79, 535, 395, 15},
+	 {74, 530, 403, 17},
+	 {70, 524, 411, 19},
+	 {66, 518, 419, 21},
+	 {62, 512, 427, 23},
+	 {57, 506, 435, 26},
+	 {54, 499, 443, 28},
+	 {50, 492, 451, 31},
+	 {47, 486, 457, 34},
+	 {43, 479, 465, 37},
+	 {40, 472, 472, 40},
+	 {214, 599, 214, -3},
+	 {207, 597, 223, -3},
+	 {200, 596, 231, -3},
+	 {193, 596, 238, -3},
+	 {186, 595, 246, -3},
+	 {178, 594, 255, -3},
+	 {171, 593, 263, -3},
+	 {165, 591, 271, -3},
+	 {158, 589, 279, -2},
+	 {151, 587, 288, -2},
+	 {145, 584, 296, -1},
+	 {139, 582, 304, -1},
+	 {133, 578, 312, 1},
+	 {127, 575, 321, 1},
+	 {121, 572, 329, 2},
+	 {115, 568, 337, 4},
+	 {109, 564, 346, 5},
+	 {104, 560, 354, 6},
+	 {98, 555, 362, 9},
+	 {94, 550, 370, 10},
+	 {88, 546, 379, 11},
+	 {84, 540, 387, 13},
+	 {79, 535, 395, 15},
+	 {74, 530, 403, 17},
+	 {70, 524, 411, 19},
+	 {66, 518, 419, 21},
+	 {62, 512, 427, 23},
+	 {57, 506, 435, 26},
+	 {54, 499, 443, 28},
+	 {50, 492, 451, 31},
+	 {47, 486, 457, 34},
+	 {43, 479, 465, 37},
+	 {40, 472, 472, 40}
+	 },
+
+	/* RGB_COEF_IDX */
+	{
+	 {0, 1024, 0, 0},
+	 {0, 1008, 16, 0},
+	 {0, 992, 32, 0},
+	 {0, 976, 48, 0},
+	 {0, 960, 64, 0},
+	 {0, 944, 80, 0},
+	 {0, 928, 96, 0},
+	 {0, 912, 112, 0},
+	 {0, 896, 128, 0},
+	 {0, 880, 144, 0},
+	 {0, 864, 160, 0},
+	 {0, 848, 176, 0},
+	 {0, 832, 192, 0},
+	 {0, 816, 208, 0},
+	 {0, 800, 224, 0},
+	 {0, 784, 240, 0},
+	 {0, 768, 256, 0},
+	 {0, 752, 272, 0},
+	 {0, 736, 288, 0},
+	 {0, 720, 304, 0},
+	 {0, 704, 320, 0},
+	 {0, 688, 336, 0},
+	 {0, 672, 352, 0},
+	 {0, 656, 368, 0},
+	 {0, 640, 384, 0},
+	 {0, 624, 400, 0},
+	 {0, 608, 416, 0},
+	 {0, 592, 432, 0},
+	 {0, 576, 448, 0},
+	 {0, 560, 464, 0},
+	 {0, 544, 480, 0},
+	 {0, 528, 496, 0},
+	 {0, 512, 512, 0},
+	 {0, 1024, 0, 0},
+	 {0, 1008, 16, 0},
+	 {0, 992, 32, 0},
+	 {0, 976, 48, 0},
+	 {0, 960, 64, 0},
+	 {0, 944, 80, 0},
+	 {0, 928, 96, 0},
+	 {0, 912, 112, 0},
+	 {0, 896, 128, 0},
+	 {0, 880, 144, 0},
+	 {0, 864, 160, 0},
+	 {0, 848, 176, 0},
+	 {0, 832, 192, 0},
+	 {0, 816, 208, 0},
+	 {0, 800, 224, 0},
+	 {0, 784, 240, 0},
+	 {0, 768, 256, 0},
+	 {0, 752, 272, 0},
+	 {0, 736, 288, 0},
+	 {0, 720, 304, 0},
+	 {0, 704, 320, 0},
+	 {0, 688, 336, 0},
+	 {0, 672, 352, 0},
+	 {0, 656, 368, 0},
+	 {0, 640, 384, 0},
+	 {0, 624, 400, 0},
+	 {0, 608, 416, 0},
+	 {0, 592, 432, 0},
+	 {0, 576, 448, 0},
+	 {0, 560, 464, 0},
+	 {0, 544, 480, 0},
+	 {0, 528, 496, 0},
+	 {0, 512, 512, 0}
+	 }
+};
+
+static const int COEF_LUT_TAP5[SCL_COEF_IDX_MAX][PHASE_NUM][TAP5] = {
+	/* YUV_COEF_IDX */
+	{
+	 {98, 415, 415, 98, -2},
+	 {95, 412, 418, 103, -4},
+	 {91, 408, 422, 107, -4},
+	 {87, 404, 426, 111, -4},
+	 {84, 399, 430, 115, -4},
+	 {80, 395, 434, 119, -4},
+	 {76, 390, 438, 124, -4},
+	 {73, 386, 440, 128, -3},
+	 {70, 381, 444, 132, -3},
+	 {66, 376, 448, 137, -3},
+	 {63, 371, 451, 142, -3},
+	 {60, 366, 455, 146, -3},
+	 {57, 361, 457, 151, -2},
+	 {54, 356, 460, 156, -2},
+	 {51, 351, 463, 161, -2},
+	 {49, 346, 465, 165, -1},
+	 {46, 341, 468, 170, -1},
+	 {43, 336, 470, 175, 0},
+	 {41, 331, 472, 180, 0},
+	 {38, 325, 474, 186, 1},
+	 {36, 320, 476, 191, 1},
+	 {34, 315, 477, 196, 2},
+	 {32, 309, 479, 201, 3},
+	 {29, 304, 481, 206, 4},
+	 {27, 299, 481, 212, 5},
+	 {26, 293, 482, 217, 6},
+	 {24, 288, 484, 222, 6},
+	 {22, 282, 484, 228, 8},
+	 {20, 277, 485, 233, 9},
+	 {19, 271, 485, 238, 11},
+	 {17, 266, 485, 244, 12},
+	 {16, 260, 485, 250, 13},
+	 {14, 255, 486, 255, 14},
+	 {-94, 608, 608, -94, -4},
+	 {-94, 594, 619, -91, -4},
+	 {-96, 579, 635, -89, -5},
+	 {-96, 563, 650, -87, -6},
+	 {-97, 548, 665, -85, -7},
+	 {-97, 532, 678, -82, -7},
+	 {-98, 516, 693, -79, -8},
+	 {-97, 500, 705, -75, -9},
+	 {-97, 484, 720, -72, -11},
+	 {-97, 468, 733, -68, -12},
+	 {-96, 452, 744, -63, -13},
+	 {-95, 436, 755, -58, -14},
+	 {-94, 419, 768, -53, -16},
+	 {-93, 403, 779, -48, -17},
+	 {-92, 387, 789, -42, -18},
+	 {-90, 371, 799, -36, -20},
+	 {-89, 355, 809, -29, -22},
+	 {-87, 339, 817, -22, -23},
+	 {-86, 324, 826, -15, -25},
+	 {-84, 308, 835, -8, -27},
+	 {-82, 293, 842, 0, -29},
+	 {-80, 277, 849, 9, -31},
+	 {-78, 262, 855, 18, -33},
+	 {-75, 247, 860, 27, -35},
+	 {-73, 233, 865, 36, -37},
+	 {-71, 218, 870, 46, -39},
+	 {-69, 204, 874, 56, -41},
+	 {-66, 190, 876, 67, -43},
+	 {-64, 176, 879, 78, -45},
+	 {-62, 163, 882, 89, -48},
+	 {-59, 150, 883, 100, -50},
+	 {-57, 137, 883, 112, -51},
+	 {-55, 125, 884, 125, -55}
+	 },
+
+	/* RGB_COEF_IDX */
+	{
+	 {0, 512, 512, 0, 0},
+	 {0, 496, 528, 0, 0},
+	 {0, 480, 544, 0, 0},
+	 {0, 464, 560, 0, 0},
+	 {0, 448, 576, 0, 0},
+	 {0, 432, 592, 0, 0},
+	 {0, 416, 608, 0, 0},
+	 {0, 400, 624, 0, 0},
+	 {0, 384, 640, 0, 0},
+	 {0, 368, 656, 0, 0},
+	 {0, 352, 672, 0, 0},
+	 {0, 336, 688, 0, 0},
+	 {0, 320, 704, 0, 0},
+	 {0, 304, 720, 0, 0},
+	 {0, 288, 736, 0, 0},
+	 {0, 272, 752, 0, 0},
+	 {0, 256, 768, 0, 0},
+	 {0, 240, 784, 0, 0},
+	 {0, 224, 800, 0, 0},
+	 {0, 208, 816, 0, 0},
+	 {0, 192, 832, 0, 0},
+	 {0, 176, 848, 0, 0},
+	 {0, 160, 864, 0, 0},
+	 {0, 144, 880, 0, 0},
+	 {0, 128, 896, 0, 0},
+	 {0, 112, 912, 0, 0},
+	 {0, 96, 928, 0, 0},
+	 {0, 80, 944, 0, 0},
+	 {0, 64, 960, 0, 0},
+	 {0, 48, 976, 0, 0},
+	 {0, 32, 992, 0, 0},
+	 {0, 16, 1008, 0, 0},
+	 {0, 0, 1024, 0, 0},
+	 {0, 512, 512, 0, 0},
+	 {0, 496, 528, 0, 0},
+	 {0, 480, 544, 0, 0},
+	 {0, 464, 560, 0, 0},
+	 {0, 448, 576, 0, 0},
+	 {0, 432, 592, 0, 0},
+	 {0, 416, 608, 0, 0},
+	 {0, 400, 624, 0, 0},
+	 {0, 384, 640, 0, 0},
+	 {0, 368, 656, 0, 0},
+	 {0, 352, 672, 0, 0},
+	 {0, 336, 688, 0, 0},
+	 {0, 320, 704, 0, 0},
+	 {0, 304, 720, 0, 0},
+	 {0, 288, 736, 0, 0},
+	 {0, 272, 752, 0, 0},
+	 {0, 256, 768, 0, 0},
+	 {0, 240, 784, 0, 0},
+	 {0, 224, 800, 0, 0},
+	 {0, 208, 816, 0, 0},
+	 {0, 192, 832, 0, 0},
+	 {0, 176, 848, 0, 0},
+	 {0, 160, 864, 0, 0},
+	 {0, 144, 880, 0, 0},
+	 {0, 128, 896, 0, 0},
+	 {0, 112, 912, 0, 0},
+	 {0, 96, 928, 0, 0},
+	 {0, 80, 944, 0, 0},
+	 {0, 64, 960, 0, 0},
+	 {0, 48, 976, 0, 0},
+	 {0, 32, 992, 0, 0},
+	 {0, 16, 1008, 0, 0},
+	 {0, 0, 1024, 0, 0}
+	 }
+};
+
+static const int COEF_LUT_TAP6[SCL_COEF_IDX_MAX][PHASE_NUM][TAP6] = {
+	/* YUV_COEF_IDX */
+	{
+	 {2, 264, 500, 264, 2, -8},
+	 {2, 257, 499, 268, 6, -8},
+	 {1, 252, 498, 274, 8, -9},
+	 {-1, 246, 498, 281, 9, -9},
+	 {-2, 241, 497, 286, 12, -10},
+	 {-3, 235, 497, 292, 13, -10},
+	 {-5, 230, 496, 298, 15, -10},
+	 {-6, 225, 495, 303, 18, -11},
+	 {-7, 219, 494, 309, 20, -11},
+	 {-7, 213, 493, 314, 23, -12},
+	 {-9, 208, 491, 320, 26, -12},
+	 {-10, 203, 490, 325, 28, -12},
+	 {-10, 197, 488, 331, 31, -13},
+	 {-10, 192, 486, 336, 33, -13},
+	 {-12, 186, 485, 342, 36, -13},
+	 {-12, 181, 482, 347, 39, -13},
+	 {-13, 176, 480, 352, 42, -13},
+	 {-14, 171, 478, 358, 45, -14},
+	 {-14, 166, 476, 363, 48, -15},
+	 {-14, 160, 473, 368, 52, -15},
+	 {-14, 155, 470, 373, 55, -15},
+	 {-15, 150, 467, 378, 59, -15},
+	 {-15, 145, 464, 383, 62, -15},
+	 {-16, 141, 461, 388, 65, -15},
+	 {-16, 136, 458, 393, 68, -15},
+	 {-16, 131, 455, 398, 72, -16},
+	 {-16, 126, 451, 402, 77, -16},
+	 {-16, 122, 448, 407, 79, -16},
+	 {-16, 117, 444, 411, 84, -16},
+	 {-17, 113, 441, 416, 87, -16},
+	 {-17, 108, 437, 420, 92, -16},
+	 {-17, 104, 433, 424, 96, -16},
+	 {-17, 100, 429, 429, 100, -17},
+	 {-187, 105, 1186, 105, -187, 2},
+	 {-182, 86, 1186, 124, -192, 2},
+	 {-176, 67, 1185, 143, -197, 2},
+	 {-170, 49, 1182, 163, -202, 2},
+	 {-166, 32, 1180, 184, -207, 1},
+	 {-160, 15, 1176, 204, -212, 1},
+	 {-155, -2, 1171, 225, -216, 1},
+	 {-149, -18, 1166, 246, -221, 0},
+	 {-145, -34, 1160, 268, -225, 0},
+	 {-139, -49, 1153, 290, -230, -1},
+	 {-134, -63, 1145, 312, -234, -2},
+	 {-129, -78, 1137, 334, -238, -2},
+	 {-124, -91, 1128, 357, -241, -5},
+	 {-119, -104, 1118, 379, -245, -5},
+	 {-114, -117, 1107, 402, -248, -6},
+	 {-109, -129, 1096, 425, -251, -8},
+	 {-104, -141, 1083, 448, -254, -8},
+	 {-100, -152, 1071, 471, -257, -9},
+	 {-95, -162, 1057, 494, -259, -11},
+	 {-90, -172, 1043, 517, -261, -13},
+	 {-86, -181, 1028, 540, -263, -14},
+	 {-82, -190, 1013, 563, -264, -16},
+	 {-77, -199, 997, 586, -265, -18},
+	 {-73, -207, 980, 609, -266, -19},
+	 {-69, -214, 963, 632, -266, -22},
+	 {-65, -221, 945, 655, -266, -24},
+	 {-62, -227, 927, 678, -266, -26},
+	 {-58, -233, 908, 700, -265, -28},
+	 {-54, -238, 889, 722, -264, -31},
+	 {-51, -243, 870, 744, -262, -34},
+	 {-48, -247, 850, 766, -260, -37},
+	 {-45, -251, 829, 787, -257, -39},
+	 {-42, -255, 809, 809, -255, -42}
+	 },
+
+	/* RGB_COEF_IDX */
+	{
+	 {0, 0, 1024, 0, 0, 0},
+	 {0, 0, 1008, 16, 0, 0},
+	 {0, 0, 992, 32, 0, 0},
+	 {0, 0, 976, 48, 0, 0},
+	 {0, 0, 960, 64, 0, 0},
+	 {0, 0, 944, 80, 0, 0},
+	 {0, 0, 928, 96, 0, 0},
+	 {0, 0, 912, 112, 0, 0},
+	 {0, 0, 896, 128, 0, 0},
+	 {0, 0, 880, 144, 0, 0},
+	 {0, 0, 864, 160, 0, 0},
+	 {0, 0, 848, 176, 0, 0},
+	 {0, 0, 832, 192, 0, 0},
+	 {0, 0, 816, 208, 0, 0},
+	 {0, 0, 800, 224, 0, 0},
+	 {0, 0, 784, 240, 0, 0},
+	 {0, 0, 768, 256, 0, 0},
+	 {0, 0, 752, 272, 0, 0},
+	 {0, 0, 736, 288, 0, 0},
+	 {0, 0, 720, 304, 0, 0},
+	 {0, 0, 704, 320, 0, 0},
+	 {0, 0, 688, 336, 0, 0},
+	 {0, 0, 672, 352, 0, 0},
+	 {0, 0, 656, 368, 0, 0},
+	 {0, 0, 640, 384, 0, 0},
+	 {0, 0, 624, 400, 0, 0},
+	 {0, 0, 608, 416, 0, 0},
+	 {0, 0, 592, 432, 0, 0},
+	 {0, 0, 576, 448, 0, 0},
+	 {0, 0, 560, 464, 0, 0},
+	 {0, 0, 544, 480, 0, 0},
+	 {0, 0, 528, 496, 0, 0},
+	 {0, 0, 512, 512, 0, 0},
+	 {0, 0, 1024, 0, 0, 0},
+	 {0, 0, 1008, 16, 0, 0},
+	 {0, 0, 992, 32, 0, 0},
+	 {0, 0, 976, 48, 0, 0},
+	 {0, 0, 960, 64, 0, 0},
+	 {0, 0, 944, 80, 0, 0},
+	 {0, 0, 928, 96, 0, 0},
+	 {0, 0, 912, 112, 0, 0},
+	 {0, 0, 896, 128, 0, 0},
+	 {0, 0, 880, 144, 0, 0},
+	 {0, 0, 864, 160, 0, 0},
+	 {0, 0, 848, 176, 0, 0},
+	 {0, 0, 832, 192, 0, 0},
+	 {0, 0, 816, 208, 0, 0},
+	 {0, 0, 800, 224, 0, 0},
+	 {0, 0, 784, 240, 0, 0},
+	 {0, 0, 768, 256, 0, 0},
+	 {0, 0, 752, 272, 0, 0},
+	 {0, 0, 736, 288, 0, 0},
+	 {0, 0, 720, 304, 0, 0},
+	 {0, 0, 704, 320, 0, 0},
+	 {0, 0, 688, 336, 0, 0},
+	 {0, 0, 672, 352, 0, 0},
+	 {0, 0, 656, 368, 0, 0},
+	 {0, 0, 640, 384, 0, 0},
+	 {0, 0, 624, 400, 0, 0},
+	 {0, 0, 608, 416, 0, 0},
+	 {0, 0, 592, 432, 0, 0},
+	 {0, 0, 576, 448, 0, 0},
+	 {0, 0, 560, 464, 0, 0},
+	 {0, 0, 544, 480, 0, 0},
+	 {0, 0, 528, 496, 0, 0},
+	 {0, 0, 512, 512, 0, 0}
+	 }
+};
+
+static void hisi_dss_scl_init(char __iomem *scl_base, dss_scl_t *s_scl)
+{
+	BUG_ON(scl_base == NULL);
+	BUG_ON(s_scl == NULL);
+
+	memset(s_scl, 0, sizeof(dss_scl_t));
+
+	s_scl->en_hscl_str = inp32(scl_base + SCF_EN_HSCL_STR);
+	s_scl->en_vscl_str = inp32(scl_base + SCF_EN_VSCL_STR);
+	s_scl->h_v_order = inp32(scl_base + SCF_H_V_ORDER);
+	s_scl->input_width_height = inp32(scl_base + SCF_INPUT_WIDTH_HEIGHT);
+	s_scl->output_width_height = inp32(scl_base + SCF_OUTPUT_WIDTH_HEIGHT);
+	s_scl->en_hscl = inp32(scl_base + SCF_EN_HSCL);
+	s_scl->en_vscl = inp32(scl_base + SCF_EN_VSCL);
+	s_scl->acc_hscl = inp32(scl_base + SCF_ACC_HSCL);
+	s_scl->inc_hscl = inp32(scl_base + SCF_INC_HSCL);
+	s_scl->inc_vscl = inp32(scl_base + SCF_INC_VSCL);
+	s_scl->en_mmp = inp32(scl_base + SCF_EN_MMP);
+}
+
+void hisi_dss_scl_set_reg(struct hisi_fb_data_type *hisifd,
+			  char __iomem *scl_base, dss_scl_t *s_scl)
+{
+	BUG_ON(scl_base == NULL);
+	BUG_ON(s_scl == NULL);
+
+	if (hisifd) {
+		hisifd->set_reg(hisifd, scl_base + SCF_EN_HSCL_STR,
+				s_scl->en_hscl_str, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_EN_VSCL_STR,
+				s_scl->en_vscl_str, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_H_V_ORDER,
+				s_scl->h_v_order, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_INPUT_WIDTH_HEIGHT,
+				s_scl->input_width_height, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_OUTPUT_WIDTH_HEIGHT,
+				s_scl->output_width_height, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_EN_HSCL,
+				s_scl->en_hscl, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_EN_VSCL,
+				s_scl->en_vscl, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_ACC_HSCL,
+				s_scl->acc_hscl, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_INC_HSCL,
+				s_scl->inc_hscl, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_INC_VSCL,
+				s_scl->inc_vscl, 32, 0);
+		hisifd->set_reg(hisifd, scl_base + SCF_EN_MMP,
+				s_scl->en_mmp, 32, 0);
+	} else {
+		set_reg(scl_base + SCF_EN_HSCL_STR, s_scl->en_hscl_str, 32, 0);
+		set_reg(scl_base + SCF_EN_VSCL_STR, s_scl->en_vscl_str, 32, 0);
+		set_reg(scl_base + SCF_H_V_ORDER, s_scl->h_v_order, 32, 0);
+		set_reg(scl_base + SCF_INPUT_WIDTH_HEIGHT,
+			s_scl->input_width_height, 32, 0);
+		set_reg(scl_base + SCF_OUTPUT_WIDTH_HEIGHT,
+			s_scl->output_width_height, 32, 0);
+		set_reg(scl_base + SCF_EN_HSCL, s_scl->en_hscl, 32, 0);
+		set_reg(scl_base + SCF_EN_VSCL, s_scl->en_vscl, 32, 0);
+		set_reg(scl_base + SCF_ACC_HSCL, s_scl->acc_hscl, 32, 0);
+		set_reg(scl_base + SCF_INC_HSCL, s_scl->inc_hscl, 32, 0);
+		set_reg(scl_base + SCF_INC_VSCL, s_scl->inc_vscl, 32, 0);
+		set_reg(scl_base + SCF_EN_MMP, s_scl->en_mmp, 32, 0);
+	}
+}
+
+int hisi_dss_scl_write_coefs(struct hisi_fb_data_type *hisifd,
+			     bool enable_cmdlist, char __iomem *addr,
+			     const int **p, int row, int col)
+{
+	int groups[3] = { 0 };
+	int offset = 0;
+	int valid_num = 0;
+	int i = 0;
+	int j = 0;
+	int k = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(addr == NULL);
+
+	if ((row != PHASE_NUM) || (col < TAP4 || col > TAP6)) {
+		HISI_FB_ERR
+		    ("SCF filter coefficients is err, phase_num = %d, tap_num = %d\n",
+		     row, col);
+		return -EINVAL;
+	}
+
+	/*byte */
+	offset = (col == TAP4) ? 8 : 16;
+	valid_num = (offset == 16) ? 3 : 2;
+
+	for (i = 0; i < row; i++) {
+		for (j = 0; j < col; j += 2) {
+			if ((col % 2) && (j == col - 1)) {
+				groups[j / 2] =
+				    (*((int *)p + i * col + j) & 0xFFF) | (0 <<
+									   16);
+			} else {
+				groups[j / 2] =
+				    (*((int *)p + i * col + j) & 0xFFF) |
+				    (*((int *)p + i * col + j + 1) << 16);
+			}
+		}
+
+		for (k = 0; k < valid_num; k++) {
+			if (enable_cmdlist) {
+				hisifd->set_reg(hisifd,
+						addr + offset * i +
+						k * sizeof(int), groups[k], 32,
+						0);
+			} else {
+				set_reg(addr + offset * i + k * sizeof(int),
+					groups[k], 32, 0);
+			}
+			groups[k] = 0;
+		}
+	}
+
+	return 0;
+}
+
+int hisi_dss_chn_scl_load_filter_coef_set_reg(struct hisi_fb_data_type *hisifd,
+					      bool enable_cmdlist, int chn_idx,
+					      uint32_t format)
+{
+	uint32_t module_base = 0;
+	char __iomem *h0_y_addr = NULL;
+	char __iomem *y_addr = NULL;
+	char __iomem *uv_addr = NULL;
+	int ret = 0;
+	int chn_coef_idx = SCL_COEF_YUV_IDX;
+
+	BUG_ON(hisifd == NULL);
+	if ((chn_idx != DSS_RCHN_V0) && (chn_idx != DSS_RCHN_V1)
+	    && (chn_idx != DSS_RCHN_V2))
+		return 0;
+
+	if (isYUV(format)) {
+		chn_coef_idx = SCL_COEF_YUV_IDX;
+	} else {
+		chn_coef_idx = SCL_COEF_RGB_IDX;
+	}
+
+	if (g_scf_lut_chn_coef_idx[chn_idx] == chn_coef_idx)
+		return 0;
+
+	g_scf_lut_chn_coef_idx[chn_idx] = chn_coef_idx;
+
+	module_base = g_dss_module_base[chn_idx][MODULE_SCL_LUT];
+	BUG_ON(module_base == 0);
+
+	h0_y_addr = hisifd->dss_base + module_base + DSS_SCF_H0_Y_COEF_OFFSET;
+	y_addr = hisifd->dss_base + module_base + DSS_SCF_Y_COEF_OFFSET;
+	uv_addr = hisifd->dss_base + module_base + DSS_SCF_UV_COEF_OFFSET;
+
+	ret =
+	    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist, h0_y_addr,
+				     (const int **)COEF_LUT_TAP6[chn_coef_idx],
+				     PHASE_NUM, TAP6);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write H0_Y_COEF coefficients.\n");
+	}
+
+	ret =
+	    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist, y_addr,
+				     (const int **)COEF_LUT_TAP5[chn_coef_idx],
+				     PHASE_NUM, TAP5);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write Y_COEF coefficients.\n");
+	}
+
+	ret =
+	    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist, uv_addr,
+				     (const int **)COEF_LUT_TAP4[chn_coef_idx],
+				     PHASE_NUM, TAP4);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write UV_COEF coefficients.\n");
+	}
+
+	return ret;
+}
+
+int hisi_dss_scl_coef_on(struct hisi_fb_data_type *hisifd, bool enable_cmdlist,
+			 int coef_lut_idx)
+{
+	int i = 0;
+	uint32_t module_base = 0;
+	char __iomem *h0_y_addr = NULL;
+	char __iomem *y_addr = NULL;
+	char __iomem *uv_addr = NULL;
+	int ret = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+		module_base = g_dss_module_base[i][MODULE_SCL_LUT];
+		if (module_base != 0) {
+			h0_y_addr =
+			    hisifd->dss_base + module_base +
+			    DSS_SCF_H0_Y_COEF_OFFSET;
+			y_addr =
+			    hisifd->dss_base + module_base +
+			    DSS_SCF_Y_COEF_OFFSET;
+			uv_addr =
+			    hisifd->dss_base + module_base +
+			    DSS_SCF_UV_COEF_OFFSET;
+
+			g_scf_lut_chn_coef_idx[i] = coef_lut_idx;
+
+			ret =
+			    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist,
+						     h0_y_addr,
+						     (const int **)
+						     COEF_LUT_TAP6
+						     [coef_lut_idx], PHASE_NUM,
+						     TAP6);
+			if (ret < 0) {
+				HISI_FB_ERR
+				    ("Error to write H0_Y_COEF coefficients.\n");
+			}
+
+			if (i == DSS_RCHN_V0) {
+				hisi_dss_arsr2p_coef_on(hisifd, enable_cmdlist);
+				continue;
+			}
+
+			ret =
+			    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist, y_addr,
+						     (const int **)COEF_LUT_TAP5[coef_lut_idx],
+						     PHASE_NUM, TAP5);
+			if (ret < 0) {
+				HISI_FB_ERR
+				    ("Error to write Y_COEF coefficients.\n");
+			}
+
+			ret =
+			    hisi_dss_scl_write_coefs(hisifd, enable_cmdlist, uv_addr,
+						     (const int **)COEF_LUT_TAP4[coef_lut_idx],
+						     PHASE_NUM, TAP4);
+			if (ret < 0) {
+				HISI_FB_ERR
+				    ("Error to write UV_COEF coefficients.\n");
+			}
+		}
+	}
+
+	return 0;
+}
+
+int hisi_dss_scl_config(struct hisi_fb_data_type *hisifd,
+			dss_layer_t *layer, dss_rect_t *aligned_rect,
+			bool rdma_stretch_enable)
+{
+	dss_scl_t *scl = NULL;
+	dss_rect_t src_rect;
+	dss_rect_t dst_rect;
+	uint32_t need_cap = 0;
+	int chn_idx = 0;
+	uint32_t transform = 0;
+	dss_block_info_t *pblock_info = NULL;
+
+	bool has_pixel_alpha = false;
+	bool en_hscl = false;
+	bool en_vscl = false;
+	bool en_mmp = false;
+	uint32_t h_ratio = 0;
+	uint32_t v_ratio = 0;
+	uint32_t h_v_order = 0;
+	uint32_t acc_hscl = 0;
+	uint32_t acc_vscl = 0;
+	uint32_t scf_en_vscl = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+
+	need_cap = layer->need_cap;
+	chn_idx = layer->chn_idx;
+	transform = layer->transform;
+	if (aligned_rect)
+		src_rect = *aligned_rect;
+	else
+		src_rect = layer->src_rect;
+	dst_rect = layer->dst_rect;
+	pblock_info = &(layer->block_info);
+
+	if (pblock_info && pblock_info->both_vscfh_arsr2p_used) {
+		dst_rect = pblock_info->arsr2p_in_rect;
+	}
+
+	if (chn_idx == DSS_RCHN_V0) {
+		dst_rect.h = src_rect.h;
+	}
+
+	do {
+		if (chn_idx == DSS_RCHN_V0 && pblock_info->h_ratio_arsr2p
+		    && pblock_info->h_ratio) {
+			h_ratio = pblock_info->h_ratio;
+			en_hscl = true;
+			break;
+		} else if (chn_idx == DSS_RCHN_V0 && !pblock_info->h_ratio
+			   && pblock_info->h_ratio_arsr2p) {
+			break;
+		}
+
+		if (pblock_info && (pblock_info->h_ratio != 0)
+		    && (pblock_info->h_ratio != SCF_INC_FACTOR)) {
+			h_ratio = pblock_info->h_ratio;
+			en_hscl = true;
+			break;
+		}
+
+		if (chn_idx == DSS_RCHN_V0) {
+			dst_rect.w =
+			    (src_rect.w > dst_rect.w ? dst_rect.w : src_rect.w);
+		}
+
+		if (src_rect.w == dst_rect.w)
+			break;
+
+		en_hscl = true;
+
+		if ((src_rect.w < SCF_MIN_INPUT)
+		    || (dst_rect.w < SCF_MIN_OUTPUT)) {
+			HISI_FB_ERR
+			    ("src_rect.w(%d) small than 16, "
+			     "or dst_rect.w(%d) small than 16\n",
+			     src_rect.w, dst_rect.w);
+			return -EINVAL;
+		}
+
+		h_ratio =
+		    (DSS_HEIGHT(src_rect.w) * SCF_INC_FACTOR +
+		     SCF_INC_FACTOR / 2 - acc_hscl) / DSS_HEIGHT(dst_rect.w);
+
+		if ((dst_rect.w > (src_rect.w * SCF_UPSCALE_MAX))
+		    || (src_rect.w > (dst_rect.w * SCF_DOWNSCALE_MAX))) {
+			HISI_FB_ERR
+			    ("width out of range, original_src_rec(%d, %d, %d, %d) "
+			     "new_src_rect(%d, %d, %d, %d), "
+			     "dst_rect(%d, %d, %d, %d), rdma_stretch_enable=%d\n",
+			     layer->src_rect.x, layer->src_rect.y,
+			     layer->src_rect.w, layer->src_rect.h, src_rect.x,
+			     src_rect.y, src_rect.w, src_rect.h, dst_rect.x,
+			     dst_rect.y, dst_rect.w, dst_rect.h,
+			     rdma_stretch_enable);
+
+			return -EINVAL;
+		}
+	} while (0);
+
+	do {
+		if (src_rect.h == dst_rect.h)
+			break;
+
+		en_vscl = true;
+		scf_en_vscl = 1;
+
+		v_ratio =
+		    (DSS_HEIGHT(src_rect.h) * SCF_INC_FACTOR +
+		     SCF_INC_FACTOR / 2 - acc_vscl) / DSS_HEIGHT(dst_rect.h);
+
+		if ((dst_rect.h > (src_rect.h * SCF_UPSCALE_MAX))
+		    || (src_rect.h > (dst_rect.h * SCF_DOWNSCALE_MAX))) {
+			HISI_FB_ERR
+			    ("height out of range, original_src_rec(%d, %d, %d, %d) "
+			     "new_src_rect(%d, %d, %d, %d), "
+			     "dst_rect(%d, %d, %d, %d), rdma_stretch_enable=%d.\n",
+			     layer->src_rect.x, layer->src_rect.y,
+			     layer->src_rect.w, layer->src_rect.h, src_rect.x,
+			     src_rect.y, src_rect.w, src_rect.h, dst_rect.x,
+			     dst_rect.y, dst_rect.w, dst_rect.h,
+			     rdma_stretch_enable);
+			return -EINVAL;
+		}
+	} while (0);
+
+	if (!en_hscl && !en_vscl) {
+		return 0;
+	}
+
+	/* scale down, do hscl first; scale up, do vscl first */
+	h_v_order = (src_rect.w > dst_rect.w) ? 0 : 1;
+
+	if (pblock_info && (pblock_info->acc_hscl != 0)) {
+		acc_hscl = pblock_info->acc_hscl;
+	}
+
+	scl = &(hisifd->dss_module.scl[chn_idx]);
+	hisifd->dss_module.scl_used[chn_idx] = 1;
+
+	has_pixel_alpha = hal_format_has_alpha(layer->img.format);
+
+	scl->en_hscl_str = set_bits32(scl->en_hscl_str, 0x0, 1, 0);
+
+	if (v_ratio >= 2 * SCF_INC_FACTOR) {
+		if (has_pixel_alpha)
+			scl->en_vscl_str =
+			    set_bits32(scl->en_vscl_str, 0x3, 2, 0);
+		else
+			scl->en_vscl_str =
+			    set_bits32(scl->en_vscl_str, 0x1, 2, 0);
+	} else {
+		scl->en_vscl_str = set_bits32(scl->en_vscl_str, 0x0, 1, 0);
+	}
+
+	if (src_rect.h > dst_rect.h) {
+		scf_en_vscl = 0x3;
+	}
+	en_mmp = 0x1;
+
+	scl->h_v_order = set_bits32(scl->h_v_order, h_v_order, 1, 0);
+	scl->input_width_height = set_bits32(scl->input_width_height,
+					     DSS_HEIGHT(src_rect.h), 13, 0);
+	scl->input_width_height = set_bits32(scl->input_width_height,
+					     DSS_WIDTH(src_rect.w), 13, 16);
+	scl->output_width_height = set_bits32(scl->output_width_height,
+					      DSS_HEIGHT(dst_rect.h), 13, 0);
+	scl->output_width_height = set_bits32(scl->output_width_height,
+					      DSS_WIDTH(dst_rect.w), 13, 16);
+	scl->en_hscl = set_bits32(scl->en_hscl, (en_hscl ? 0x1 : 0x0), 1, 0);
+	scl->en_vscl = set_bits32(scl->en_vscl, scf_en_vscl, 2, 0);
+	scl->acc_hscl = set_bits32(scl->acc_hscl, acc_hscl, 31, 0);
+	scl->inc_hscl = set_bits32(scl->inc_hscl, h_ratio, 24, 0);
+	scl->inc_vscl = set_bits32(scl->inc_vscl, v_ratio, 24, 0);
+	scl->en_mmp = set_bits32(scl->en_mmp, en_mmp, 1, 0);
+	scl->fmt = layer->img.format;
+
+	return 0;
+}
+
+static void hisi_dss_post_scf_init(char __iomem *post_scf_base,
+				   dss_arsr1p_t *s_post_scf)
+{
+	BUG_ON(post_scf_base == NULL);
+	BUG_ON(s_post_scf == NULL);
+
+	memset(s_post_scf, 0, sizeof(dss_arsr1p_t));
+
+	s_post_scf->ihleft = inp32(post_scf_base + ARSR1P_IHLEFT);
+	s_post_scf->ihright = inp32(post_scf_base + ARSR1P_IHRIGHT);
+	s_post_scf->ihleft1 = inp32(post_scf_base + ARSR1P_IHLEFT1);
+	s_post_scf->ihright1 = inp32(post_scf_base + ARSR1P_IHRIGHT1);
+	s_post_scf->ivtop = inp32(post_scf_base + ARSR1P_IVTOP);
+	s_post_scf->ivbottom = inp32(post_scf_base + ARSR1P_IVBOTTOM);
+	s_post_scf->uv_offset = inp32(post_scf_base + ARSR1P_UV_OFFSET);
+	s_post_scf->ihinc = inp32(post_scf_base + ARSR1P_IHINC);
+	s_post_scf->ivinc = inp32(post_scf_base + ARSR1P_IVINC);
+	s_post_scf->mode = inp32(post_scf_base + ARSR1P_MODE);
+	s_post_scf->format = inp32(post_scf_base + ARSR1P_FORMAT);
+
+	s_post_scf->skin_thres_y = inp32(post_scf_base + ARSR1P_SKIN_THRES_Y);
+	s_post_scf->skin_thres_u = inp32(post_scf_base + ARSR1P_SKIN_THRES_U);
+	s_post_scf->skin_thres_v = inp32(post_scf_base + ARSR1P_SKIN_THRES_V);
+	s_post_scf->skin_expected = inp32(post_scf_base + ARSR1P_SKIN_EXPECTED);
+	s_post_scf->skin_cfg = inp32(post_scf_base + ARSR1P_SKIN_CFG);
+	s_post_scf->shoot_cfg1 = inp32(post_scf_base + ARSR1P_SHOOT_CFG1);
+	s_post_scf->shoot_cfg2 = inp32(post_scf_base + ARSR1P_SHOOT_CFG2);
+	s_post_scf->sharp_cfg1 = inp32(post_scf_base + ARSR1P_SHARP_CFG1);
+	s_post_scf->sharp_cfg2 = inp32(post_scf_base + ARSR1P_SHARP_CFG2);
+	s_post_scf->sharp_cfg3 = inp32(post_scf_base + ARSR1P_SHARP_CFG3);
+	s_post_scf->sharp_cfg4 = inp32(post_scf_base + ARSR1P_SHARP_CFG4);
+	s_post_scf->sharp_cfg5 = inp32(post_scf_base + ARSR1P_SHARP_CFG5);
+	s_post_scf->sharp_cfg6 = inp32(post_scf_base + ARSR1P_SHARP_CFG6);
+	s_post_scf->sharp_cfg7 = inp32(post_scf_base + ARSR1P_SHARP_CFG7);
+	s_post_scf->sharp_cfg8 = inp32(post_scf_base + ARSR1P_SHARP_CFG8);
+	s_post_scf->sharp_cfg9 = inp32(post_scf_base + ARSR1P_SHARP_CFG9);
+	s_post_scf->sharp_cfg10 = inp32(post_scf_base + ARSR1P_SHARP_CFG10);
+	s_post_scf->sharp_cfg11 = inp32(post_scf_base + ARSR1P_SHARP_CFG11);
+	s_post_scf->diff_ctrl = inp32(post_scf_base + ARSR1P_DIFF_CTRL);
+	s_post_scf->lsc_cfg1 = inp32(post_scf_base + ARSR1P_LSC_CFG1);
+	s_post_scf->lsc_cfg2 = inp32(post_scf_base + ARSR1P_LSC_CFG2);
+	s_post_scf->lsc_cfg3 = inp32(post_scf_base + ARSR1P_LSC_CFG3);
+	s_post_scf->force_clk_on_cfg =
+	    inp32(post_scf_base + ARSR1P_FORCE_CLK_ON_CFG);
+}
+
+static void hisi_dss_post_scf_set_reg(struct hisi_fb_data_type *hisifd,
+				      char __iomem *post_scf_base,
+				      dss_arsr1p_t *s_post_scf)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(post_scf_base == NULL);
+	BUG_ON(s_post_scf == NULL);
+
+	hisifd->set_reg(hisifd,
+			hisifd->dss_base + DSS_DPP_OFFSET + DPP_IMG_SIZE_BEF_SR,
+			((DSS_HEIGHT(s_post_scf->dpp_img_vrt_bef_sr) << 16) |
+			 (DSS_WIDTH(s_post_scf->dpp_img_hrz_bef_sr))), 32, 0);
+	hisifd->set_reg(hisifd,
+			hisifd->dss_base + DSS_DPP_OFFSET + DPP_IMG_SIZE_AFT_SR,
+			((DSS_HEIGHT(s_post_scf->dpp_img_vrt_aft_sr) << 16) |
+			 (DSS_WIDTH(s_post_scf->dpp_img_hrz_aft_sr))), 32, 0);
+
+	outp32(post_scf_base + ARSR1P_IHLEFT, s_post_scf->ihleft);
+	outp32(post_scf_base + ARSR1P_IHRIGHT, s_post_scf->ihright);
+	outp32(post_scf_base + ARSR1P_IHLEFT1, s_post_scf->ihleft1);
+	outp32(post_scf_base + ARSR1P_IHRIGHT1, s_post_scf->ihright1);
+	outp32(post_scf_base + ARSR1P_IVTOP, s_post_scf->ivtop);
+	outp32(post_scf_base + ARSR1P_IVBOTTOM, s_post_scf->ivbottom);
+	outp32(post_scf_base + ARSR1P_UV_OFFSET, s_post_scf->uv_offset);
+	outp32(post_scf_base + ARSR1P_IHINC, s_post_scf->ihinc);
+	outp32(post_scf_base + ARSR1P_IVINC, s_post_scf->ivinc);
+	outp32(post_scf_base + ARSR1P_MODE, s_post_scf->mode);
+	outp32(post_scf_base + ARSR1P_FORMAT, s_post_scf->format);
+
+	outp32(post_scf_base + ARSR1P_SKIN_THRES_Y, s_post_scf->skin_thres_y);
+	outp32(post_scf_base + ARSR1P_SKIN_THRES_U, s_post_scf->skin_thres_u);
+	outp32(post_scf_base + ARSR1P_SKIN_THRES_V, s_post_scf->skin_thres_v);
+	outp32(post_scf_base + ARSR1P_SKIN_EXPECTED, s_post_scf->skin_expected);
+	outp32(post_scf_base + ARSR1P_SKIN_CFG, s_post_scf->skin_cfg);
+	outp32(post_scf_base + ARSR1P_SHOOT_CFG1, s_post_scf->shoot_cfg1);
+	outp32(post_scf_base + ARSR1P_SHOOT_CFG2, s_post_scf->shoot_cfg2);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG1, s_post_scf->sharp_cfg1);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG2, s_post_scf->sharp_cfg2);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG3, s_post_scf->sharp_cfg3);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG4, s_post_scf->sharp_cfg4);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG5, s_post_scf->sharp_cfg5);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG6, s_post_scf->sharp_cfg6);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG7, s_post_scf->sharp_cfg7);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG8, s_post_scf->sharp_cfg8);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG9, s_post_scf->sharp_cfg9);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG10, s_post_scf->sharp_cfg10);
+	outp32(post_scf_base + ARSR1P_SHARP_CFG11, s_post_scf->sharp_cfg11);
+	outp32(post_scf_base + ARSR1P_DIFF_CTRL, s_post_scf->diff_ctrl);
+	outp32(post_scf_base + ARSR1P_LSC_CFG1, s_post_scf->lsc_cfg1);
+	outp32(post_scf_base + ARSR1P_LSC_CFG2, s_post_scf->lsc_cfg2);
+	outp32(post_scf_base + ARSR1P_LSC_CFG3, s_post_scf->lsc_cfg3);
+	outp32(post_scf_base + ARSR1P_FORCE_CLK_ON_CFG,
+	       s_post_scf->force_clk_on_cfg);
+}
+
+int hisi_dss_post_scf_config(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req)
+{
+	struct hisi_panel_info *pinfo = NULL;
+	dss_rect_t src_rect = { 0 };
+	dss_rect_t dst_rect = { 0 };
+	dss_arsr1p_t *post_scf = NULL;
+
+	int32_t ihinc = 0;
+	int32_t ivinc = 0;
+	int32_t ihleft = 0;
+	int32_t ihright = 0;
+	int32_t ihleft1 = 0;
+	int32_t ihright1 = 0;
+	int32_t ivtop = 0;
+	int32_t ivbottom = 0;
+	int32_t extraw = 0;
+	int32_t extraw_left = 0;
+	int32_t extraw_right = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	pinfo = &(hisifd->panel_info);
+
+	if (!HISI_DSS_SUPPORT_DPP_MODULE_BIT(DPP_MODULE_POST_SCF)) {
+		return 0;
+	}
+
+	if ((pov_req->res_updt_rect.w == 0) && (pov_req->res_updt_rect.h == 0)) {
+		return 0;
+	}
+
+	if ((pov_req->res_updt_rect.w < 0) || (pov_req->res_updt_rect.h < 0)) {
+		HISI_FB_ERR("fb%d, res_updt_rect[%d,%d, %d,%d] is invalid!\n",
+			    hisifd->index, pov_req->res_updt_rect.x,
+			    pov_req->res_updt_rect.y, pov_req->res_updt_rect.w,
+			    pov_req->res_updt_rect.h);
+		return 0;
+	}
+
+	if ((pov_req->res_updt_rect.w == hisifd->res_updt_rect.w)
+	    && (pov_req->res_updt_rect.h == hisifd->res_updt_rect.h)) {
+
+		return 0;
+	}
+
+	HISI_FB_DEBUG
+	    ("fb%d, post scf res_updt_rect[%d, %d]->lcd_rect[%d, %d]\n",
+	     hisifd->index, pov_req->res_updt_rect.w, pov_req->res_updt_rect.h,
+	     pinfo->xres, pinfo->yres);
+
+	hisifd->res_updt_rect = pov_req->res_updt_rect;
+
+	src_rect = pov_req->res_updt_rect;
+	dst_rect.x = 0;
+	dst_rect.y = 0;
+	dst_rect.w = pinfo->xres;
+	dst_rect.h = pinfo->yres;
+
+	post_scf = &(hisifd->dss_module.post_scf);
+	hisifd->dss_module.post_scf_used = 1;
+
+	if ((src_rect.w < 16) || (src_rect.h < 16)
+	    || (src_rect.w > 3840) || (src_rect.h > 8192)
+	    || (dst_rect.w > 8192) || (dst_rect.h > 8192)) {
+		HISI_FB_ERR
+		    ("invalid input size: src_rect(%d,%d,%d,%d) "
+		     "should be larger than 16*16, less than 3840*8192!\n"
+		     "invalid output size: dst_rect(%d,%d,%d,%d) "
+		     "should be less than 8192*8192!\n",
+		     src_rect.x, src_rect.y, src_rect.w, src_rect.h, dst_rect.x,
+		     dst_rect.y, dst_rect.w, dst_rect.h);
+		post_scf->mode = 0x1;
+		return 0;
+	}
+
+	ihinc = ARSR1P_INC_FACTOR * src_rect.w / dst_rect.w;
+	ivinc = ARSR1P_INC_FACTOR * src_rect.h / dst_rect.h;
+
+	if ((ihinc == ARSR1P_INC_FACTOR)
+	    && (ivinc == ARSR1P_INC_FACTOR)
+	    && (pinfo->arsr1p_sharpness_support != 1)) {
+		post_scf->mode = 0x1;
+		return 0;
+	}
+
+	/* 0x2000<=ihinc<=0x80000; 0x2000<=ivinc<=0x80000; */
+	if ((ihinc < 0x2000) || (ihinc > ARSR1P_INC_FACTOR)
+	    || (ivinc < 0x2000) || (ivinc > ARSR1P_INC_FACTOR)) {
+		HISI_FB_ERR("invalid ihinc(0x%x), ivinc(0x%x)!\n", ihinc,
+			    ivinc);
+		post_scf->mode = 0x1;
+		return -1;
+	}
+
+	if ((ihinc > ARSR1P_INC_FACTOR) || (ivinc > ARSR1P_INC_FACTOR)) {
+		HISI_FB_ERR
+		    ("scaling down is not supported by ARSR1P, "
+		     "ihinc = 0x%x, ivinc = 0x%x\n",
+		     ihinc, ivinc);
+		post_scf->mode = 0x1;
+		return -1;
+	}
+
+	post_scf->mode = 0x0;
+	if (pinfo->arsr1p_sharpness_support) {
+		post_scf->mode |= 0xe;
+	}
+
+	post_scf->mode |= 0x20;
+	if ((ihinc < ARSR1P_INC_FACTOR) || (ivinc < ARSR1P_INC_FACTOR)) {
+		post_scf->mode |= 0x10;
+	} else {
+		post_scf->mode |= 0x40;
+	}
+
+	post_scf->dpp_img_hrz_bef_sr = src_rect.w;
+	post_scf->dpp_img_vrt_bef_sr = src_rect.h;
+	post_scf->dpp_img_hrz_aft_sr = dst_rect.w;
+	post_scf->dpp_img_vrt_aft_sr = dst_rect.h;
+
+	extraw = (8 * ARSR1P_INC_FACTOR) / ihinc;
+	extraw_left = (extraw % 2) ? (extraw + 1) : (extraw);
+	extraw = (2 * ARSR1P_INC_FACTOR) / ihinc;
+	extraw_right = (extraw % 2) ? (extraw + 1) : (extraw);
+
+	ihleft1 = dst_rect.x * ihinc - src_rect.x * ARSR1P_INC_FACTOR;
+	if (ihleft1 < 0)
+		ihleft1 = 0;
+	ihleft = ihleft1 - extraw_left * ihinc;
+	if (ihleft < 0)
+		ihleft = 0;
+
+	ihright1 = ihleft1 + (dst_rect.w - 1) * ihinc;
+	ihright = ihright1 + extraw_right * ihinc;
+	if (ihright >= src_rect.w * ARSR1P_INC_FACTOR)
+		ihright = src_rect.w * ARSR1P_INC_FACTOR - 1;
+
+	ivtop = dst_rect.y * ivinc - src_rect.y * ARSR1P_INC_FACTOR;
+	if (ivtop < 0)
+		ivtop = 0;
+	ivbottom = ivtop + (dst_rect.h - 1) * ivinc;
+	if (ivbottom >= src_rect.h * ARSR1P_INC_FACTOR)
+		ivbottom = src_rect.h * ARSR1P_INC_FACTOR - 1;
+
+	if ((ihleft1 - ihleft) % (ihinc)) {
+		HISI_FB_ERR
+		    ("(ihleft1(%d)-ihleft(%d))  ihinc(%d) != 0, invalid!\n",
+		     ihleft1, ihleft, ihinc);
+		post_scf->mode = 0x1;
+		return -1;
+	}
+
+	if ((ihright1 - ihleft1) % ihinc) {
+		HISI_FB_ERR
+		    ("(ihright1(%d)-ihleft1(%d))  ihinc(%d) != 0, invalid!\n",
+		     ihright1, ihleft1, ihinc);
+		post_scf->mode = 0x1;
+		return -1;
+	}
+
+	post_scf->ihleft = set_bits32(post_scf->ihleft, ihleft, 32, 0);
+	post_scf->ihright = set_bits32(post_scf->ihright, ihright, 32, 0);
+	post_scf->ihleft1 = set_bits32(post_scf->ihleft1, ihleft1, 32, 0);
+	post_scf->ihright1 = set_bits32(post_scf->ihright1, ihright1, 32, 0);
+	post_scf->ivtop = set_bits32(post_scf->ivtop, ivtop, 32, 0);
+	post_scf->ivbottom = set_bits32(post_scf->ivbottom, ivbottom, 32, 0);
+	post_scf->ihinc = set_bits32(post_scf->ihinc, ihinc, 32, 0);
+	post_scf->ivinc = set_bits32(post_scf->ivinc, ivinc, 32, 0);
+
+	post_scf->skin_thres_y =
+	    set_bits32(post_scf->skin_thres_y, 0x534b, 32, 0);
+	post_scf->skin_thres_u =
+	    set_bits32(post_scf->skin_thres_u, 0x330a05, 32, 0);
+	post_scf->skin_thres_v =
+	    set_bits32(post_scf->skin_thres_v, 0xaa0c06, 32, 0);
+	post_scf->skin_expected =
+	    set_bits32(post_scf->skin_expected, 0x917198, 32, 0);
+	post_scf->skin_cfg = set_bits32(post_scf->skin_cfg, 0x30a06, 32, 0);
+	post_scf->shoot_cfg1 = set_bits32(post_scf->shoot_cfg1, 0x14, 32, 0);
+	post_scf->shoot_cfg2 = set_bits32(post_scf->shoot_cfg2, 0x1f0, 32, 0);
+	post_scf->sharp_cfg1 =
+	    set_bits32(post_scf->sharp_cfg1, 0x40300602, 32, 0);
+	post_scf->sharp_cfg2 =
+	    set_bits32(post_scf->sharp_cfg2, 0x40300602, 32, 0);
+	post_scf->sharp_cfg3 =
+	    set_bits32(post_scf->sharp_cfg3, 0x12c0000, 32, 0);
+	post_scf->sharp_cfg4 = set_bits32(post_scf->sharp_cfg4, 0x0, 32, 0);
+	post_scf->sharp_cfg5 =
+	    set_bits32(post_scf->sharp_cfg5, 0x1900000, 32, 0);
+	post_scf->sharp_cfg6 =
+	    set_bits32(post_scf->sharp_cfg6, 0xffff641e, 32, 0);
+	post_scf->sharp_cfg7 =
+	    set_bits32(post_scf->sharp_cfg7, 0x1a00018, 32, 0);
+	post_scf->sharp_cfg8 =
+	    set_bits32(post_scf->sharp_cfg8, 0x200640, 32, 0);
+	post_scf->sharp_cfg9 =
+	    set_bits32(post_scf->sharp_cfg9, 0x2006400, 32, 0);
+	post_scf->sharp_cfg10 = set_bits32(post_scf->sharp_cfg10, 0x0, 32, 0);
+	post_scf->sharp_cfg11 = set_bits32(post_scf->sharp_cfg11, 0x0, 32, 0);
+
+	post_scf->diff_ctrl = set_bits32(post_scf->diff_ctrl, 0x1410, 32, 0);
+	post_scf->lsc_cfg1 = set_bits32(post_scf->lsc_cfg1, 0x3c618410, 32, 0);
+	post_scf->lsc_cfg2 = set_bits32(post_scf->lsc_cfg2, 0x0, 32, 0);
+	post_scf->lsc_cfg3 = set_bits32(post_scf->lsc_cfg3, 0x800600, 32, 0);
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS POST_CLIP
+ */
+static void hisi_dss_post_clip_init(char __iomem *post_clip_base,
+				    dss_post_clip_t *s_post_clip)
+{
+	BUG_ON(post_clip_base == NULL);
+	BUG_ON(s_post_clip == NULL);
+
+	memset(s_post_clip, 0, sizeof(dss_post_clip_t));
+}
+
+int hisi_dss_post_clip_config(struct hisi_fb_data_type *hisifd,
+			      dss_layer_t *layer)
+{
+	dss_post_clip_t *post_clip = NULL;
+	int chn_idx = 0;
+	dss_rect_t post_clip_rect;
+
+	chn_idx = layer->chn_idx;
+	post_clip_rect = layer->dst_rect;
+
+	if (((chn_idx >= DSS_RCHN_V0) && (chn_idx <= DSS_RCHN_G1))
+	    || (chn_idx == DSS_RCHN_V2)) {
+		post_clip = &(hisifd->dss_module.post_clip[chn_idx]);
+		hisifd->dss_module.post_cilp_used[chn_idx] = 1;
+
+		post_clip->disp_size =
+		    set_bits32(post_clip->disp_size,
+			       DSS_HEIGHT(post_clip_rect.h), 13, 0);
+		post_clip->disp_size =
+		    set_bits32(post_clip->disp_size,
+			       DSS_WIDTH(post_clip_rect.w), 13, 16);
+
+		if ((chn_idx == DSS_RCHN_V0)
+		    && layer->block_info.arsr2p_left_clip) {
+			post_clip->clip_ctl_hrz =
+			    set_bits32(post_clip->clip_ctl_hrz,
+				       layer->block_info.arsr2p_left_clip, 6, 16);
+			post_clip->clip_ctl_hrz =
+			    set_bits32(post_clip->clip_ctl_hrz, 0x0, 6, 0);
+		} else {
+			post_clip->clip_ctl_hrz =
+			    set_bits32(post_clip->clip_ctl_hrz, 0x0, 32, 0);
+		}
+
+		post_clip->clip_ctl_vrz =
+		    set_bits32(post_clip->clip_ctl_vrz, 0x0, 32, 0);
+		post_clip->ctl_clip_en =
+		    set_bits32(post_clip->ctl_clip_en, 0x1, 32, 0);
+	}
+
+	return 0;
+}
+
+void hisi_dss_post_clip_set_reg(struct hisi_fb_data_type *hisifd,
+				char __iomem *post_clip_base,
+				dss_post_clip_t *s_post_clip)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(post_clip_base == NULL);
+	BUG_ON(s_post_clip == NULL);
+
+	hisifd->set_reg(hisifd, post_clip_base + POST_CLIP_DISP_SIZE,
+			s_post_clip->disp_size, 32, 0);
+	hisifd->set_reg(hisifd, post_clip_base + POST_CLIP_CTL_HRZ,
+			s_post_clip->clip_ctl_hrz, 32, 0);
+	hisifd->set_reg(hisifd, post_clip_base + POST_CLIP_CTL_VRZ,
+			s_post_clip->clip_ctl_vrz, 32, 0);
+	hisifd->set_reg(hisifd, post_clip_base + POST_CLIP_EN,
+			s_post_clip->ctl_clip_en, 32, 0);
+}
+
+/*******************************************************************************
+ ** DSS MCTL
+ */
+static void hisi_dss_mctl_init(char __iomem *mctl_base, dss_mctl_t *s_mctl)
+{
+	BUG_ON(mctl_base == NULL);
+	BUG_ON(s_mctl == NULL);
+
+	memset(s_mctl, 0, sizeof(dss_mctl_t));
+}
+
+static void hisi_dss_mctl_ch_starty_init(char __iomem *mctl_ch_starty_base,
+					 dss_mctl_ch_t *s_mctl_ch)
+{
+	BUG_ON(mctl_ch_starty_base == NULL);
+	BUG_ON(s_mctl_ch == NULL);
+
+	memset(s_mctl_ch, 0, sizeof(dss_mctl_ch_t));
+
+	s_mctl_ch->chn_starty = inp32(mctl_ch_starty_base);
+}
+
+static void hisi_dss_mctl_ch_mod_dbg_init(char __iomem *mctl_ch_dbg_base,
+					  dss_mctl_ch_t *s_mctl_ch)
+{
+	BUG_ON(mctl_ch_dbg_base == NULL);
+	BUG_ON(s_mctl_ch == NULL);
+
+	s_mctl_ch->chn_mod_dbg = inp32(mctl_ch_dbg_base);
+}
+
+static void hisi_dss_mctl_sys_init(char __iomem *mctl_sys_base,
+				   dss_mctl_sys_t *s_mctl_sys)
+{
+	int i = 0;
+
+	BUG_ON(mctl_sys_base == NULL);
+	BUG_ON(s_mctl_sys == NULL);
+
+	memset(s_mctl_sys, 0, sizeof(dss_mctl_sys_t));
+
+	for (i = 0; i < DSS_OVL_IDX_MAX; i++) {
+		s_mctl_sys->chn_ov_sel[i] = 0xFFFFFFFF;
+	}
+
+	for (i = 0; i < DSS_WCH_MAX; i++) {
+		s_mctl_sys->wchn_ov_sel[i] = 0x0;
+	}
+}
+
+static void hisi_dss_mctl_sys_set_reg(struct hisi_fb_data_type *hisifd,
+				      char __iomem *mctl_sys_base,
+				      dss_mctl_sys_t *s_mctl_sys, int ovl_idx)
+{
+	int k = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(mctl_sys_base == NULL);
+	BUG_ON(s_mctl_sys == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if (s_mctl_sys->chn_ov_sel_used[ovl_idx]) {
+		hisifd->set_reg(hisifd,
+				mctl_sys_base + MCTL_RCH_OV0_SEL + ovl_idx * 0x4,
+				s_mctl_sys->chn_ov_sel[ovl_idx], 32, 0);
+	}
+
+	for (k = 0; k < DSS_WCH_MAX; k++) {
+		if (s_mctl_sys->wch_ov_sel_used[k]) {
+			hisifd->set_reg(hisifd,
+					mctl_sys_base + MCTL_WCH_OV2_SEL + k * 0x4,
+					s_mctl_sys->wchn_ov_sel[k], 32, 0);
+		}
+	}
+
+	if (s_mctl_sys->ov_flush_en_used[ovl_idx]) {
+		hisifd->set_reg(hisifd,
+				mctl_sys_base + MCTL_OV0_FLUSH_EN + ovl_idx * 0x4,
+				s_mctl_sys->ov_flush_en[ovl_idx], 32, 0);
+	}
+}
+
+static void hisi_dss_mctl_ov_set_reg(struct hisi_fb_data_type *hisifd,
+				     char __iomem *mctl_base,
+				     dss_mctl_t *s_mctl, int ovl_idx,
+				     bool enable_cmdlist)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(mctl_base == NULL);
+	BUG_ON(s_mctl == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if ((ovl_idx == DSS_OVL0) || (ovl_idx == DSS_OVL1)) {
+		hisifd->set_reg(hisifd, mctl_base + MCTL_CTL_MUTEX_DBUF,
+				s_mctl->ctl_mutex_dbuf, 32, 0);
+		hisi_dss_mctl_ov_set_ctl_dbg_reg(hisifd, mctl_base,
+						 enable_cmdlist);
+	}
+
+	hisifd->set_reg(hisifd, mctl_base + MCTL_CTL_MUTEX_OV,
+			s_mctl->ctl_mutex_ov, 32, 0);
+}
+
+static void hisi_dss_mctl_ch_set_reg(struct hisi_fb_data_type *hisifd,
+				     dss_mctl_ch_base_t *mctl_ch_base,
+				     dss_mctl_ch_t *s_mctl_ch,
+				     int32_t mctl_idx)
+{
+	char __iomem *chn_mutex_base = NULL;
+	int i = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(mctl_ch_base == NULL);
+	BUG_ON(s_mctl_ch == NULL);
+	BUG_ON((mctl_idx < DSS_MCTL0) || (mctl_idx >= DSS_MCTL_IDX_MAX));
+
+	for (i = 0; i < DSS_MCTL_IDX_MAX; i++) {
+		if (g_dss_module_ovl_base[i][MODULE_MCTL_BASE] == 0)
+			continue;
+		chn_mutex_base = mctl_ch_base->chn_mutex_base +
+		    g_dss_module_ovl_base[i][MODULE_MCTL_BASE];
+
+		if (i != mctl_idx) {
+			hisifd->set_reg(hisifd, chn_mutex_base, 0, 32, 0);
+		}
+	}
+
+	chn_mutex_base = mctl_ch_base->chn_mutex_base +
+	    g_dss_module_ovl_base[mctl_idx][MODULE_MCTL_BASE];
+	BUG_ON(chn_mutex_base == NULL);
+
+	hisifd->set_reg(hisifd, chn_mutex_base, s_mctl_ch->chn_mutex, 32, 0);
+}
+
+static void hisi_dss_mctl_sys_ch_set_reg(struct hisi_fb_data_type *hisifd,
+					 dss_mctl_ch_base_t *mctl_ch_base,
+					 dss_mctl_ch_t *s_mctl_ch, int chn_idx,
+					 bool normal)
+{
+	char __iomem *mctl_sys_base = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(mctl_ch_base == NULL);
+	BUG_ON(s_mctl_ch == NULL);
+
+	mctl_sys_base = hisifd->dss_base + DSS_MCTRL_SYS_OFFSET;
+
+	if (normal == true) {
+		if (chn_idx == DSS_RCHN_V2) {
+			hisifd->set_reg(hisifd, mctl_sys_base + MCTL_MOD19_DBG,
+					0xA0000, 32, 0);
+		}
+
+		if (chn_idx == DSS_WCHN_W2) {
+			hisifd->set_reg(hisifd, mctl_sys_base + MCTL_MOD20_DBG,
+					0xA0000, 32, 0);
+		}
+	}
+
+	if (normal == false) {
+		if (chn_idx == DSS_RCHN_V2) {
+			hisifd->set_reg(hisifd, mctl_sys_base + MCTL_MOD19_DBG,
+					0xA0002, 32, 0);
+		}
+
+		if (chn_idx == DSS_WCHN_W2) {
+			hisifd->set_reg(hisifd, mctl_sys_base + MCTL_MOD20_DBG,
+					0xA0002, 32, 0);
+		}
+	}
+
+	if (mctl_ch_base->chn_ov_en_base) {
+		hisifd->set_reg(hisifd, mctl_ch_base->chn_ov_en_base,
+				s_mctl_ch->chn_ov_oen, 32, 0);
+	}
+
+	hisifd->set_reg(hisifd, mctl_ch_base->chn_flush_en_base,
+			s_mctl_ch->chn_flush_en, 32, 0);
+}
+
+void hisi_dss_mctl_mutex_lock(struct hisi_fb_data_type *hisifd, int ovl_idx)
+{
+	char __iomem *mctl_base = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	mctl_base = hisifd->dss_module.mctl_base[ovl_idx];
+
+	hisifd->set_reg(hisifd, mctl_base + MCTL_CTL_MUTEX, 0x1, 1, 0);
+}
+
+void hisi_dss_mctl_mutex_unlock(struct hisi_fb_data_type *hisifd, int ovl_idx)
+{
+	char __iomem *mctl_base = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	mctl_base = hisifd->dss_module.mctl_base[ovl_idx];
+
+	hisifd->set_reg(hisifd, mctl_base + MCTL_CTL_MUTEX, 0x0, 1, 0);
+}
+
+void hisi_dss_mctl_on(struct hisi_fb_data_type *hisifd, int mctl_idx,
+		      bool enable_cmdlist, bool fastboot_enable)
+{
+	char __iomem *mctl_base = NULL;
+	char __iomem *mctl_sys_base = NULL;
+	int i = 0;
+	int tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((mctl_idx < DSS_MCTL0) || (mctl_idx >= DSS_MCTL_IDX_MAX));
+
+	mctl_base = hisifd->dss_base +
+	    g_dss_module_ovl_base[mctl_idx][MODULE_MCTL_BASE];
+	mctl_sys_base = hisifd->dss_base + DSS_MCTRL_SYS_OFFSET;
+
+	set_reg(mctl_base + MCTL_CTL_EN, 0x1, 32, 0);
+
+	if ((mctl_idx == DSS_MCTL0) || (mctl_idx == DSS_MCTL1)) {
+		set_reg(mctl_base + MCTL_CTL_MUTEX_ITF, mctl_idx + 1, 32, 0);
+	}
+
+	if (enable_cmdlist) {
+		tmp = MCTL_MOD_DBG_CH_NUM + MCTL_MOD_DBG_OV_NUM +
+		    MCTL_MOD_DBG_DBUF_NUM + MCTL_MOD_DBG_SCF_NUM;
+		for (i = 0; i < tmp; i++) {
+			set_reg(mctl_sys_base + MCTL_MOD0_DBG + i * 0x4,
+				0xA0000, 32, 0);
+		}
+
+		for (i = 0; i < MCTL_MOD_DBG_ITF_NUM; i++) {
+			set_reg(mctl_sys_base + MCTL_MOD17_DBG + i * 0x4,
+				0xA0F00, 32, 0);
+		}
+
+		if (!fastboot_enable) {
+			set_reg(mctl_base + MCTL_CTL_TOP, 0x1, 32, 0);
+		}
+	} else {
+		set_reg(mctl_base + MCTL_CTL_DBG, 0xB13A00, 32, 0);
+		if (is_mipi_cmd_panel(hisifd)) {
+			set_reg(mctl_base + MCTL_CTL_TOP, 0x1, 32, 0);
+		} else {
+			if (mctl_idx == DSS_MCTL0) {
+				set_reg(mctl_base + MCTL_CTL_TOP, 0x2, 32, 0);
+			} else if (mctl_idx == DSS_MCTL1) {
+				set_reg(mctl_base + MCTL_CTL_TOP, 0x3, 32, 0);
+			} else {
+				set_reg(mctl_base + MCTL_CTL_TOP, 0x1, 32, 0);
+			}
+		}
+	}
+}
+
+int hisi_dss_mctl_ch_config(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req, dss_layer_t *layer,
+			    dss_wb_layer_t *wb_layer, int ovl_idx,
+			    dss_rect_t *wb_ov_block_rect, bool has_base)
+{
+	int chn_idx = 0;
+	int layer_idx = 0;
+	dss_mctl_ch_t *mctl_ch = NULL;
+	dss_mctl_sys_t *mctl_sys = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON((layer == NULL) && (wb_layer == NULL));
+
+	if (wb_layer) {
+		chn_idx = wb_layer->chn_idx;
+
+		mctl_sys = &(hisifd->dss_module.mctl_sys);
+		hisifd->dss_module.mctl_sys_used = 1;
+
+		mctl_ch = &(hisifd->dss_module.mctl_ch[chn_idx]);
+		hisifd->dss_module.mctl_ch_used[chn_idx] = 1;
+
+		if (chn_idx != DSS_WCHN_W2) {
+			mctl_ch->chn_ov_oen = set_bits32(mctl_ch->chn_ov_oen,
+							 (ovl_idx - 1), 32, 0);
+
+			if (pov_req->wb_layer_nums == MAX_DSS_DST_NUM) {
+				mctl_sys->wchn_ov_sel[0] =
+				    set_bits32(mctl_sys->wchn_ov_sel[0], 3, 32, 0);
+				mctl_sys->wch_ov_sel_used[0] = 1;
+				mctl_sys->wchn_ov_sel[1] =
+				    set_bits32(mctl_sys->wchn_ov_sel[1], 3, 32, 0);
+				mctl_sys->wch_ov_sel_used[1] = 1;
+			} else {
+				mctl_sys->wchn_ov_sel[ovl_idx - DSS_OVL2] =
+				    set_bits32(mctl_sys->wchn_ov_sel[ovl_idx - DSS_OVL2],
+					       (chn_idx - DSS_WCHN_W0 + 1), 32, 0);
+				mctl_sys->wch_ov_sel_used[ovl_idx - DSS_OVL2] = 1;
+			}
+		}
+
+		mctl_ch->chn_mutex = set_bits32(mctl_ch->chn_mutex, 0x1, 1, 0);
+		mctl_ch->chn_flush_en =
+		    set_bits32(mctl_ch->chn_flush_en, 0x1, 1, 0);
+	} else {
+		chn_idx = layer->chn_idx;
+		layer_idx = layer->layer_idx;
+
+		if (layer->need_cap & CAP_BASE)
+			return 0;
+
+		if (has_base) {
+			layer_idx -= 1;
+			if (layer_idx < 0) {
+				HISI_FB_ERR
+				    ("fb%d, layer_idx(%d) is out of range!",
+				     hisifd->index, layer_idx);
+				return -EINVAL;
+			}
+		}
+
+		mctl_sys = &(hisifd->dss_module.mctl_sys);
+		hisifd->dss_module.mctl_sys_used = 1;
+
+		if (layer->need_cap & (CAP_DIM | CAP_PURE_COLOR)) {
+			mctl_sys->chn_ov_sel[ovl_idx] =
+			    set_bits32(mctl_sys->chn_ov_sel[ovl_idx], 0x8, 4,
+				       (layer_idx + 1) * 4);
+			mctl_sys->chn_ov_sel_used[ovl_idx] = 1;
+		} else {
+			mctl_ch = &(hisifd->dss_module.mctl_ch[chn_idx]);
+			hisifd->dss_module.mctl_ch_used[chn_idx] = 1;
+
+			mctl_ch->chn_mutex =
+			    set_bits32(mctl_ch->chn_mutex, 0x1, 1, 0);
+			mctl_ch->chn_flush_en =
+			    set_bits32(mctl_ch->chn_flush_en, 0x1, 1, 0);
+
+			if (chn_idx != DSS_RCHN_V2) {
+				mctl_ch->chn_ov_oen =
+				    set_bits32(mctl_ch->chn_ov_oen,
+					       ((1 << (layer_idx + 1)) |
+						(0x100 << ovl_idx)), 32, 0);
+
+				if (wb_ov_block_rect) {
+					mctl_ch->chn_starty =
+					    set_bits32(mctl_ch->chn_starty,
+						       ((layer->dst_rect.y -
+							 wb_ov_block_rect->y) | (0x8 << 16)), 32, 0);
+				} else {
+					mctl_ch->chn_starty =
+					    set_bits32(mctl_ch->chn_starty,
+						       (layer->dst_rect.y | (0x8 << 16)), 32, 0);
+				}
+
+				mctl_sys->chn_ov_sel[ovl_idx] =
+				    set_bits32(mctl_sys->chn_ov_sel[ovl_idx],
+					       chn_idx, 4, (layer_idx + 1) * 4);
+				mctl_sys->chn_ov_sel_used[ovl_idx] = 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int hisi_dss_mctl_ov_config(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req, int ovl_idx, bool has_base,
+			    bool is_first_ov_block)
+{
+	dss_mctl_t *mctl = NULL;
+	dss_mctl_sys_t *mctl_sys = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if (pov_req && pov_req->wb_layer_infos[0].chn_idx == DSS_WCHN_W2) {
+		return 0;
+	}
+
+	mctl = &(hisifd->dss_module.mctl[ovl_idx]);
+	hisifd->dss_module.mctl_used[ovl_idx] = 1;
+
+	if (ovl_idx == DSS_OVL0) {
+		mctl->ctl_mutex_itf =
+		    set_bits32(mctl->ctl_mutex_itf, 0x1, 2, 0);
+		mctl->ctl_mutex_dbuf =
+		    set_bits32(mctl->ctl_mutex_dbuf, 0x1, 2, 0);
+	} else if (ovl_idx == DSS_OVL1) {
+		mctl->ctl_mutex_itf =
+		    set_bits32(mctl->ctl_mutex_itf, 0x2, 2, 0);
+		mctl->ctl_mutex_dbuf =
+		    set_bits32(mctl->ctl_mutex_dbuf, 0x2, 2, 0);
+	} else {
+		;
+	}
+
+	mctl->ctl_mutex_ov = set_bits32(mctl->ctl_mutex_ov, 1 << ovl_idx, 4, 0);
+
+	mctl_sys = &(hisifd->dss_module.mctl_sys);
+	hisifd->dss_module.mctl_sys_used = 1;
+
+	mctl_sys->chn_ov_sel[ovl_idx] =
+	    set_bits32(mctl_sys->chn_ov_sel[ovl_idx], 0x8, 4, 0);
+	mctl_sys->chn_ov_sel_used[ovl_idx] = 1;
+
+	if ((ovl_idx == DSS_OVL0) || (ovl_idx == DSS_OVL1)) {
+		if (is_first_ov_block) {
+			mctl_sys->ov_flush_en[ovl_idx] =
+			    set_bits32(mctl_sys->ov_flush_en[ovl_idx], 0xd, 4, 0);
+		} else {
+			mctl_sys->ov_flush_en[ovl_idx] =
+			    set_bits32(mctl_sys->ov_flush_en[ovl_idx], 0x1, 1, 0);
+		}
+		mctl_sys->ov_flush_en_used[ovl_idx] = 1;
+	} else {
+		mctl_sys->ov_flush_en[ovl_idx] =
+		    set_bits32(mctl_sys->ov_flush_en[ovl_idx], 0x1, 1, 0);
+		mctl_sys->ov_flush_en_used[ovl_idx] = 1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS OVL
+ */
+static dss_ovl_alpha_t g_ovl_alpha[DSS_BLEND_MAX] = {
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
+	{1, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0},
+	{0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0},
+	{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0},
+	{3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+	{3, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0},
+	{3, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0},
+	{3, 0, 0, 0, 1, 0, 3, 0, 0, 1, 0},
+	{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+	{3, 0, 0, 0, 1, 0, 3, 0, 0, 0, 1},
+	{3, 0, 0, 0, 1, 0, 3, 2, 0, 0, 0},
+	{3, 0, 0, 0, 1, 1, 3, 1, 0, 0, 1},
+	{2, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+	{1, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0},
+	{3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0},
+	{2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{2, 2, 0, 0, 0, 0, 3, 2, 0, 0, 0},
+	{3, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0},
+	{2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0},
+	{3, 2, 0, 0, 0, 0, 3, 2, 0, 0, 0},
+	{2, 1, 0, 0, 0, 0, 3, 2, 0, 0, 0},
+	{2, 1, 0, 0, 0, 0, 3, 1, 0, 0, 1},
+	{0, 0, 0, 0, 0, 1, 3, 0, 1, 0, 0},
+
+	{2, 1, 0, 0, 0, 1, 3, 2, 0, 0, 0},
+	{2, 1, 0, 0, 0, 1, 3, 1, 0, 0, 1},
+	{0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+};
+
+static uint32_t get_ovl_blending_mode(dss_overlay_t *pov_req,
+				      dss_layer_t *layer)
+{
+	uint32_t blend_mode = 0;
+	bool has_per_pixel_alpha = false;
+
+	BUG_ON(layer == NULL);
+
+	has_per_pixel_alpha = hal_format_has_alpha(layer->img.format);
+
+	/* delete it for DTS2015061204735 and DTS2015060408590 */
+	/*
+	   if (layer->layer_idx == 0) {
+	   if (has_per_pixel_alpha) {
+	   blend_mode = DSS_BLEND_SRC;
+	   } else {
+	   blend_mode= DSS_BLEND_FIX_PER17;
+	   }
+	   } else
+	 */
+	{
+		if (layer->blending == HISI_FB_BLENDING_PREMULT) {
+			if (has_per_pixel_alpha) {
+				blend_mode =
+				    (layer->glb_alpha <
+				     0xFF) ? DSS_BLEND_FIX_PER12 :
+				    DSS_BLEND_SRC_OVER_DST;
+			} else {
+				blend_mode =
+				    (layer->glb_alpha <
+				     0xFF) ? DSS_BLEND_FIX_PER8 : DSS_BLEND_SRC;
+			}
+		} else if (layer->blending == HISI_FB_BLENDING_COVERAGE) {
+			if (has_per_pixel_alpha) {
+				blend_mode =
+				    (layer->glb_alpha <
+				     0xFF) ? DSS_BLEND_FIX_PER13 :
+				    DSS_BLEND_FIX_OVER;
+			} else {
+				blend_mode =
+				    (layer->glb_alpha <
+				     0xFF) ? DSS_BLEND_FIX_PER8 : DSS_BLEND_SRC;
+			}
+		} else {
+			if (has_per_pixel_alpha) {
+				blend_mode = DSS_BLEND_SRC;
+			} else {
+				blend_mode = DSS_BLEND_FIX_PER17;
+			}
+		}
+	}
+
+	if (g_debug_ovl_online_composer) {
+		HISI_FB_INFO
+		    ("layer_idx(%d), blending=%d, fomat=%d, "
+		     "has_per_pixel_alpha=%d, blend_mode=%d.\n",
+		     layer->layer_idx, layer->blending, layer->img.format,
+		     has_per_pixel_alpha, blend_mode);
+	}
+
+	return blend_mode;
+}
+
+static void hisi_dss_ovl_init(char __iomem *ovl_base, dss_ovl_t *s_ovl,
+			      int ovl_idx)
+{
+	int i = 0;
+
+	BUG_ON(ovl_base == NULL);
+	BUG_ON(s_ovl == NULL);
+
+	memset(s_ovl, 0, sizeof(dss_ovl_t));
+
+	s_ovl->ovl_size = inp32(ovl_base + OVL_SIZE);
+	s_ovl->ovl_bg_color = inp32(ovl_base + OVL_BG_COLOR);
+	s_ovl->ovl_dst_startpos = inp32(ovl_base + OVL_DST_STARTPOS);
+	s_ovl->ovl_dst_endpos = inp32(ovl_base + OVL_DST_ENDPOS);
+	s_ovl->ovl_gcfg = inp32(ovl_base + OVL_GCFG);
+
+	if ((ovl_idx == DSS_OVL1) || (ovl_idx == DSS_OVL3)) {
+		for (i = 0; i < OVL_2LAYER_NUM; i++) {
+			s_ovl->ovl_layer[i].layer_pos =
+			    inp32(ovl_base + OVL_LAYER0_POS + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_size =
+			    inp32(ovl_base + OVL_LAYER0_SIZE + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_pattern =
+			    inp32(ovl_base + OVL_LAYER0_PATTERN + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_alpha =
+			    inp32(ovl_base + OVL_LAYER0_ALPHA + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_cfg =
+			    inp32(ovl_base + OVL_LAYER0_CFG + i * 0x3C);
+
+			s_ovl->ovl_layer_pos[i].layer_pspos =
+			    inp32(ovl_base + OVL_LAYER0_PSPOS + i * 0x3C);
+			s_ovl->ovl_layer_pos[i].layer_pepos =
+			    inp32(ovl_base + OVL_LAYER0_PEPOS + i * 0x3C);
+		}
+
+		s_ovl->ovl_block_size = inp32(ovl_base + OVL2_BLOCK_SIZE);
+	} else {
+		for (i = 0; i < OVL_6LAYER_NUM; i++) {
+			s_ovl->ovl_layer[i].layer_pos =
+			    inp32(ovl_base + OVL_LAYER0_POS + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_size =
+			    inp32(ovl_base + OVL_LAYER0_SIZE + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_pattern =
+			    inp32(ovl_base + OVL_LAYER0_PATTERN + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_alpha =
+			    inp32(ovl_base + OVL_LAYER0_ALPHA + i * 0x3C);
+			s_ovl->ovl_layer[i].layer_cfg =
+			    inp32(ovl_base + OVL_LAYER0_CFG + i * 0x3C);
+
+			s_ovl->ovl_layer_pos[i].layer_pspos =
+			    inp32(ovl_base + OVL_LAYER0_PSPOS + i * 0x3C);
+			s_ovl->ovl_layer_pos[i].layer_pepos =
+			    inp32(ovl_base + OVL_LAYER0_PEPOS + i * 0x3C);
+		}
+
+		s_ovl->ovl_block_size = inp32(ovl_base + OVL6_BLOCK_SIZE);
+	}
+}
+
+static void hisi_dss_ovl_set_reg(struct hisi_fb_data_type *hisifd,
+				 char __iomem *ovl_base, dss_ovl_t *s_ovl,
+				 int ovl_idx)
+{
+	int i = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(ovl_base == NULL);
+	BUG_ON(s_ovl == NULL);
+
+	if ((ovl_idx == DSS_OVL1) || (ovl_idx == DSS_OVL3)) {
+		hisifd->set_reg(hisifd, ovl_base + OVL2_REG_DEFAULT, 0x1, 32, 0);
+		hisifd->set_reg(hisifd, ovl_base + OVL2_REG_DEFAULT, 0x0, 32, 0);
+	} else {
+		hisifd->set_reg(hisifd, ovl_base + OVL6_REG_DEFAULT, 0x1, 32, 0);
+		hisifd->set_reg(hisifd, ovl_base + OVL6_REG_DEFAULT, 0x0, 32, 0);
+	}
+
+	hisifd->set_reg(hisifd, ovl_base + OVL_SIZE, s_ovl->ovl_size, 32, 0);
+	hisifd->set_reg(hisifd, ovl_base + OVL_BG_COLOR,
+			s_ovl->ovl_bg_color, 32, 0);
+	hisifd->set_reg(hisifd, ovl_base + OVL_DST_STARTPOS,
+			s_ovl->ovl_dst_startpos, 32, 0);
+	hisifd->set_reg(hisifd, ovl_base + OVL_DST_ENDPOS,
+			s_ovl->ovl_dst_endpos, 32, 0);
+	hisifd->set_reg(hisifd, ovl_base + OVL_GCFG, s_ovl->ovl_gcfg, 32, 0);
+
+	if ((ovl_idx == DSS_OVL1) || (ovl_idx == DSS_OVL3)) {
+		for (i = 0; i < OVL_2LAYER_NUM; i++) {
+			if (s_ovl->ovl_layer_used[i] == 1) {
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_POS + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_SIZE + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_size, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PATTERN + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pattern, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_ALPHA + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_alpha, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_CFG + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_cfg, 32, 0);
+
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PSPOS + i * 0x3C,
+						s_ovl->ovl_layer_pos[i].layer_pspos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PEPOS + i * 0x3C,
+						s_ovl->ovl_layer_pos[i].layer_pepos, 32, 0);
+			} else {
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_POS + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_SIZE + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_size, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_CFG + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_cfg, 32, 0);
+			}
+		}
+
+		hisifd->set_reg(hisifd, ovl_base + OVL2_BLOCK_SIZE,
+				s_ovl->ovl_block_size, 32, 0);
+	} else {
+		for (i = 0; i < OVL_6LAYER_NUM; i++) {
+			if (s_ovl->ovl_layer_used[i] == 1) {
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_POS + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_SIZE + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_size, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PATTERN + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pattern, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_ALPHA + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_alpha, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_CFG + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_cfg, 32, 0);
+
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PSPOS + i * 0x3C,
+						s_ovl->ovl_layer_pos[i].layer_pspos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_PEPOS +i * 0x3C,
+						s_ovl->ovl_layer_pos[i].layer_pepos, 32, 0);
+			} else {
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_POS +i * 0x3C,
+						s_ovl->ovl_layer[i].layer_pos, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_SIZE + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_size, 32, 0);
+				hisifd->set_reg(hisifd,
+						ovl_base + OVL_LAYER0_CFG + i * 0x3C,
+						s_ovl->ovl_layer[i].layer_cfg, 32, 0);
+			}
+		}
+
+		hisifd->set_reg(hisifd, ovl_base + OVL6_BLOCK_SIZE,
+				s_ovl->ovl_block_size, 32, 0);
+	}
+}
+
+void hisi_dss_ov_set_reg_default_value(struct hisi_fb_data_type *hisifd,
+				       char __iomem *ovl_base, int ovl_idx)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(ovl_base == NULL);
+
+	if ((ovl_idx == DSS_OVL1) || (ovl_idx == DSS_OVL3)) {
+		hisifd->set_reg(hisifd, ovl_base + OVL2_REG_DEFAULT, 0x1, 32,
+				0);
+		hisifd->set_reg(hisifd, ovl_base + OVL2_REG_DEFAULT, 0x0, 32,
+				0);
+	} else {
+		hisifd->set_reg(hisifd, ovl_base + OVL6_REG_DEFAULT, 0x1, 32,
+				0);
+		hisifd->set_reg(hisifd, ovl_base + OVL6_REG_DEFAULT, 0x0, 32,
+				0);
+	}
+}
+
+int hisi_dss_ovl_base_config(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req,
+			     dss_overlay_block_t *pov_h_block,
+			     dss_rect_t *wb_ov_block_rect, int ovl_idx,
+			     int ov_h_block_idx)
+{
+	dss_ovl_t *ovl = NULL;
+	int img_width = 0;
+	int img_height = 0;
+	int block_size = 0x7FFF;
+	int temp = 0;
+	int i = 0;
+	int m = 0;
+
+	dss_overlay_block_t *pov_h_block_infos_tmp = NULL;
+	dss_overlay_block_t *pov_h_block_tmp = NULL;
+	dss_layer_t *layer = NULL;
+	int pov_h_block_idx = 0;
+	int layer_idx = 0;
+	bool has_base = false;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if (pov_req && pov_req->wb_layer_infos[0].chn_idx == DSS_WCHN_W2) {
+		return 0;
+	}
+
+	ovl = &(hisifd->dss_module.ov[ovl_idx]);
+	hisifd->dss_module.ov_used[ovl_idx] = 1;
+
+	if (wb_ov_block_rect) {
+		img_width = wb_ov_block_rect->w;
+		img_height = wb_ov_block_rect->h;
+	} else {
+		if ((!pov_req)
+		    || (pov_req->dirty_rect.x == 0 && pov_req->dirty_rect.y == 0
+			&& pov_req->dirty_rect.w == 0
+			&& pov_req->dirty_rect.h == 0)) {
+			img_width = get_panel_xres(hisifd);
+			img_height = get_panel_yres(hisifd);
+		} else {
+			img_width = pov_req->dirty_rect.w;
+			img_height = pov_req->dirty_rect.h;
+		}
+	}
+
+	if (pov_h_block && (pov_req->ov_block_nums != 0)) {
+		if (pov_req->ov_block_nums > 1) {
+			pov_h_block_infos_tmp =
+			    (dss_overlay_block_t *) (pov_req->ov_block_infos_ptr);
+			for (m = ov_h_block_idx; m < pov_req->ov_block_nums;
+			     m++) {
+				pov_h_block_tmp = &(pov_h_block_infos_tmp[m]);
+				has_base = false;
+
+				for (i = 0; i < pov_h_block_tmp->layer_nums;
+				     i++) {
+					layer =
+					    &(pov_h_block_tmp->layer_infos[i]);
+					if (layer->need_cap & CAP_BASE) {
+						HISI_FB_INFO
+						    ("layer%d is base, i=%d!\n",
+						     layer->layer_idx, i);
+						has_base = true;
+						continue;
+					}
+
+					layer_idx = i;
+					if (has_base) {
+						layer_idx = i - 1;
+					}
+
+					if (layer_idx >= pov_h_block_idx) {
+						ovl->ovl_layer[layer_idx].layer_pos =
+						    set_bits32(ovl->ovl_layer
+							       [layer_idx].layer_pos, 0, 15, 0);
+						ovl->ovl_layer[layer_idx].layer_pos =
+						    set_bits32(ovl->ovl_layer
+							       [layer_idx].layer_pos,
+							       img_height, 15, 16);
+
+						ovl->ovl_layer[layer_idx].layer_size =
+						    set_bits32(ovl->ovl_layer
+							       [layer_idx].layer_size,
+							       img_width, 15, 0);
+						ovl->ovl_layer[layer_idx].layer_size =
+						    set_bits32(ovl->ovl_layer
+							       [layer_idx].layer_size,
+							       img_height + 1, 15, 16);
+						ovl->ovl_layer[layer_idx].layer_cfg =
+						    set_bits32(ovl->ovl_layer
+							       [layer_idx].layer_cfg,
+							       0x1, 1, 0);
+
+						if (layer->need_cap & (CAP_DIM |
+								CAP_PURE_COLOR)) {
+
+							ovl->ovl_layer[layer_idx].layer_pattern =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_pattern,
+								       layer->color, 32, 0);
+							ovl->ovl_layer[layer_idx].layer_cfg =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_cfg,
+								       0x1, 1, 0);
+							ovl->ovl_layer[layer_idx].layer_cfg =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_cfg,
+								       0x1, 1, 8);
+						} else {
+							ovl->ovl_layer[layer_idx].layer_pattern =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_pattern,
+								       0x0, 32, 0);
+							ovl->ovl_layer[layer_idx].layer_cfg =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_cfg,
+								       0x1, 1, 0);
+							ovl->ovl_layer[layer_idx].layer_cfg =
+							    set_bits32(ovl->ovl_layer
+								       [layer_idx].layer_cfg,
+								       0x0, 1, 8);
+						}
+
+						ovl->ovl_layer_used[layer_idx] = 1;
+						pov_h_block_idx = layer_idx + 1;
+					}
+				}
+			}
+		}
+
+		if (wb_ov_block_rect) {
+			if ((pov_req->wb_layer_infos[0].transform &
+					HISI_FB_TRANSFORM_ROT_90)
+			   || (pov_req->wb_layer_infos[1].transform &
+			   		HISI_FB_TRANSFORM_ROT_90)) {
+				block_size = DSS_HEIGHT(wb_ov_block_rect->h);
+			} else {
+				temp =
+				    pov_h_block->ov_block_rect.y +
+				    DSS_HEIGHT(pov_h_block->ov_block_rect.h) -
+				    wb_ov_block_rect->y;
+				if (temp >= wb_ov_block_rect->h) {
+					block_size =
+					    DSS_HEIGHT(wb_ov_block_rect->h);
+				} else {
+					block_size = temp;
+				}
+			}
+		} else {
+			block_size =
+			    pov_h_block->ov_block_rect.y +
+			    DSS_HEIGHT(pov_h_block->ov_block_rect.h);
+		}
+	}
+
+	ovl->ovl_size = set_bits32(ovl->ovl_size, DSS_WIDTH(img_width), 15, 0);
+	ovl->ovl_size =
+	    set_bits32(ovl->ovl_size, DSS_HEIGHT(img_height), 15, 16);
+#ifdef CONFIG_HISI_FB_OV_BASE_USED
+	ovl->ovl_bg_color = set_bits32(ovl->ovl_bg_color, 0xFFFF0000, 32, 0);
+#else
+	ovl->ovl_bg_color = set_bits32(ovl->ovl_bg_color, 0xFF000000, 32, 0);
+#endif
+	ovl->ovl_dst_startpos = set_bits32(ovl->ovl_dst_startpos, 0x0, 32, 0);
+	ovl->ovl_dst_endpos =
+	    set_bits32(ovl->ovl_dst_endpos, DSS_WIDTH(img_width), 15, 0);
+	ovl->ovl_dst_endpos =
+	    set_bits32(ovl->ovl_dst_endpos, DSS_HEIGHT(img_height), 15, 16);
+	ovl->ovl_gcfg = set_bits32(ovl->ovl_gcfg, 0x1, 1, 0);
+	ovl->ovl_gcfg = set_bits32(ovl->ovl_gcfg, 0x1, 1, 16);
+	ovl->ovl_block_size =
+	    set_bits32(ovl->ovl_block_size, block_size, 15, 16);
+
+	return 0;
+}
+
+int hisi_dss_ovl_layer_config(struct hisi_fb_data_type *hisifd,
+			      dss_overlay_t *pov_req, dss_layer_t *layer,
+			      dss_rect_t *wb_ov_block_rect, bool has_base)
+{
+	dss_ovl_t *ovl = NULL;
+	int ovl_idx = 0;
+	int layer_idx = 0;
+	int blend_mode = 0;
+	dss_rect_t wb_ov_rect;
+	dss_rect_t dst_rect;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+
+	ovl_idx = hisifd->ov_req.ovl_idx;
+	layer_idx = layer->layer_idx;
+
+	if (layer->chn_idx == DSS_RCHN_V2) {
+		return 0;
+	}
+
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+	ovl = &(hisifd->dss_module.ov[ovl_idx]);
+	hisifd->dss_module.ov_used[ovl_idx] = 1;
+
+	if (layer->need_cap & CAP_BASE) {
+		ovl->ovl_bg_color =
+		    set_bits32(ovl->ovl_bg_color, layer->color, 32, 0);
+		ovl->ovl_gcfg = set_bits32(ovl->ovl_gcfg, 0x1, 1, 16);
+		return 0;
+	}
+
+	if (layer->glb_alpha < 0) {
+		layer->glb_alpha = 0;
+		HISI_FB_ERR("layer's glb_alpha(0x%x) is out of range!",
+			    layer->glb_alpha);
+	} else if (layer->glb_alpha > 0xFF) {
+		layer->glb_alpha = 0xFF;
+		HISI_FB_ERR("layer's glb_alpha(0x%x) is out of range!",
+			    layer->glb_alpha);
+	}
+
+	blend_mode = get_ovl_blending_mode(pov_req, layer);
+	BUG_ON((blend_mode < 0) || (blend_mode >= DSS_BLEND_MAX));
+
+	if (has_base) {
+		layer_idx -= 1;
+		if (layer_idx < 0) {
+			HISI_FB_ERR("layer_idx(%d) is out of range!\n",
+				    layer_idx);
+			return -EINVAL;
+		}
+	}
+
+	ovl->ovl_layer_used[layer_idx] = 1;
+
+	if ((layer->chn_idx == DSS_RCHN_V0)
+	    && layer->block_info.arsr2p_left_clip) {
+		dst_rect.x =
+		    layer->dst_rect.x + layer->block_info.arsr2p_left_clip;
+		dst_rect.y = layer->dst_rect.y;
+		dst_rect.w =
+		    layer->dst_rect.w - layer->block_info.arsr2p_left_clip;
+		dst_rect.h = layer->dst_rect.h;
+	} else {
+		dst_rect = layer->dst_rect;
+	}
+
+	if (wb_ov_block_rect) {
+		wb_ov_rect.x = pov_req->wb_ov_rect.x + wb_ov_block_rect->x;
+		wb_ov_rect.y = pov_req->wb_ov_rect.y;
+
+		ovl->ovl_layer[layer_idx].layer_pos =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pos,
+			       (dst_rect.x - wb_ov_rect.x), 15, 0);
+		ovl->ovl_layer[layer_idx].layer_pos =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pos,
+			       (dst_rect.y - wb_ov_rect.y), 15, 16);
+
+		ovl->ovl_layer[layer_idx].layer_size =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_size,
+			       (dst_rect.x - wb_ov_rect.x +
+				DSS_WIDTH(dst_rect.w)), 15, 0);
+		ovl->ovl_layer[layer_idx].layer_size =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_size,
+			       (dst_rect.y - wb_ov_rect.y +
+				DSS_HEIGHT(dst_rect.h)), 15, 16);
+	} else {
+		ovl->ovl_layer[layer_idx].layer_pos =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pos, dst_rect.x,
+			       15, 0);
+		ovl->ovl_layer[layer_idx].layer_pos =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pos, dst_rect.y,
+			       15, 16);
+
+		ovl->ovl_layer[layer_idx].layer_size =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_size,
+			       DSS_WIDTH(dst_rect.x + dst_rect.w), 15, 0);
+		ovl->ovl_layer[layer_idx].layer_size =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_size,
+			       DSS_HEIGHT(dst_rect.y + dst_rect.h), 15, 16);
+	}
+
+	ovl->ovl_layer[layer_idx].layer_alpha =
+	    set_bits32(ovl->ovl_layer[layer_idx].layer_alpha,
+		       ((layer->glb_alpha << 0) |
+		        (g_ovl_alpha[blend_mode].fix_mode << 8) |
+				(g_ovl_alpha[blend_mode].dst_pmode << 9) |
+				(g_ovl_alpha[blend_mode].alpha_offdst << 10) |
+				(g_ovl_alpha[blend_mode].dst_gmode << 12) |
+				(g_ovl_alpha[blend_mode].dst_amode << 14) |
+				(layer->glb_alpha <<16) |
+				(g_ovl_alpha[blend_mode].alpha_smode << 24) |
+				(g_ovl_alpha[blend_mode].src_pmode << 25) |
+				(g_ovl_alpha[blend_mode].src_lmode << 26) |
+				(g_ovl_alpha[blend_mode].alpha_offdst << 27) |
+				(g_ovl_alpha[blend_mode].src_gmode << 28) |
+				(g_ovl_alpha[blend_mode].src_amode << 30)), 32, 0);
+
+	if (layer->need_cap & (CAP_DIM | CAP_PURE_COLOR)) {
+		ovl->ovl_layer[layer_idx].layer_pattern =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pattern,
+			       layer->color, 32, 0);
+		ovl->ovl_layer[layer_idx].layer_cfg =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_cfg, 0x1, 1, 0);
+		ovl->ovl_layer[layer_idx].layer_cfg =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_cfg, 0x1, 1, 8);
+	} else {
+		ovl->ovl_layer[layer_idx].layer_pattern =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_pattern, 0x0, 32,
+			       0);
+		ovl->ovl_layer[layer_idx].layer_cfg =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_cfg, 0x1, 1, 0);
+		ovl->ovl_layer[layer_idx].layer_cfg =
+		    set_bits32(ovl->ovl_layer[layer_idx].layer_cfg, 0x0, 1, 8);
+	}
+
+	ovl->ovl_layer_pos[layer_idx].layer_pspos =
+	    set_bits32(ovl->ovl_layer_pos[layer_idx].layer_pspos, dst_rect.x,
+		       15, 0);
+	ovl->ovl_layer_pos[layer_idx].layer_pspos =
+	    set_bits32(ovl->ovl_layer_pos[layer_idx].layer_pspos, dst_rect.y,
+		       15, 16);
+	ovl->ovl_layer_pos[layer_idx].layer_pepos =
+	    set_bits32(ovl->ovl_layer_pos[layer_idx].layer_pepos,
+		       DSS_WIDTH(dst_rect.x + dst_rect.w), 15, 0);
+	ovl->ovl_layer_pos[layer_idx].layer_pepos =
+	    set_bits32(ovl->ovl_layer_pos[layer_idx].layer_pepos,
+		       DSS_HEIGHT(dst_rect.y + dst_rect.h), 15, 16);
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** dirty_region_updt
+ */
+static void hisi_dss_dirty_region_dbuf_set_reg(struct hisi_fb_data_type *hisifd,
+					       char __iomem *dss_base,
+					       dirty_region_updt_t *
+					       s_dirty_region_updt)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dss_base == NULL);
+	BUG_ON(s_dirty_region_updt == NULL);
+
+	hisifd->set_reg(hisifd, dss_base + DSS_DBUF0_OFFSET + DBUF_FRM_SIZE,
+			s_dirty_region_updt->dbuf_frm_size, 32, 0);
+	hisifd->set_reg(hisifd, dss_base + DSS_DBUF0_OFFSET + DBUF_FRM_HSIZE,
+			s_dirty_region_updt->dbuf_frm_hsize, 32, 0);
+	hisifd->set_reg(hisifd, dss_base + DSS_DPP_OFFSET + DPP_IMG_SIZE_BEF_SR,
+			((s_dirty_region_updt->dpp_img_vrt_bef_sr << 16) |
+			  s_dirty_region_updt->dpp_img_hrz_bef_sr), 32, 0);
+	hisifd->set_reg(hisifd, dss_base + DSS_DPP_OFFSET + DPP_IMG_SIZE_AFT_SR,
+			((s_dirty_region_updt->dpp_img_vrt_aft_sr << 16) |
+			  s_dirty_region_updt->dpp_img_hrz_aft_sr), 32, 0);
+}
+
+static void hisi_dss_dirty_region_updt_set_reg(struct hisi_fb_data_type *hisifd,
+					       char __iomem *dss_base,
+					       dirty_region_updt_t *
+					       s_dirty_region_updt)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(dss_base == NULL);
+	BUG_ON(s_dirty_region_updt == NULL);
+
+	set_reg(dss_base + DSS_MIPI_DSI0_OFFSET + MIPIDSI_EDPI_CMD_SIZE_OFFSET,
+		s_dirty_region_updt->edpi_cmd_size, 32, 0);
+	if (is_dual_mipi_panel(hisifd)) {
+		set_reg(dss_base + DSS_MIPI_DSI1_OFFSET +
+			MIPIDSI_EDPI_CMD_SIZE_OFFSET,
+			s_dirty_region_updt->edpi_cmd_size, 32, 0);
+	}
+
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI0_HRZ_CTRL0,
+		s_dirty_region_updt->ldi_dpi0_hrz_ctrl0, 29, 0);
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI0_HRZ_CTRL1,
+		s_dirty_region_updt->ldi_dpi0_hrz_ctrl1, 13, 0);
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI0_HRZ_CTRL2,
+		s_dirty_region_updt->ldi_dpi0_hrz_ctrl2, 13, 0);
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_VRT_CTRL0,
+		s_dirty_region_updt->ldi_vrt_ctrl0, 29, 0);
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_VRT_CTRL1,
+		s_dirty_region_updt->ldi_vrt_ctrl1, 13, 0);
+	set_reg(dss_base + DSS_LDI0_OFFSET + LDI_VRT_CTRL2,
+		s_dirty_region_updt->ldi_vrt_ctrl2, 13, 0);
+
+	if (is_dual_mipi_panel(hisifd)) {
+		set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI1_HRZ_CTRL0,
+			s_dirty_region_updt->ldi_dpi1_hrz_ctrl0, 29, 0);
+		set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI1_HRZ_CTRL1,
+			s_dirty_region_updt->ldi_dpi1_hrz_ctrl1, 13, 0);
+		set_reg(dss_base + DSS_LDI0_OFFSET + LDI_DPI1_HRZ_CTRL2,
+			s_dirty_region_updt->ldi_dpi1_hrz_ctrl2, 13, 0);
+	}
+
+	if (hisifd->panel_info.ifbc_type != IFBC_TYPE_NONE) {
+		if (!is_ifbc_vesa_panel(hisifd)) {
+			set_reg(dss_base + DSS_IFBC_OFFSET + IFBC_SIZE,
+				s_dirty_region_updt->ifbc_size, 32, 0);
+		} else {
+			set_reg(dss_base + DSS_DSC_OFFSET + DSC_PIC_SIZE,
+				s_dirty_region_updt->ifbc_size, 32, 0);
+		}
+	}
+}
+
+int hisi_dss_dirty_region_dbuf_config(struct hisi_fb_data_type *hisifd,
+				      dss_overlay_t *pov_req)
+{
+	struct hisi_panel_info *pinfo = NULL;
+	dirty_region_updt_t *dirty_region_updt = NULL;
+	struct dss_rect dirty = { 0 };
+
+	BUG_ON(hisifd == NULL);
+	pinfo = &(hisifd->panel_info);
+
+	if ((hisifd->index != PRIMARY_PANEL_IDX) ||
+	    !pinfo->dirty_region_updt_support)
+		return 0;
+
+	if ((!pov_req)
+	    || (pov_req->dirty_rect.x == 0 && pov_req->dirty_rect.y == 0
+		&& pov_req->dirty_rect.w == 0 && pov_req->dirty_rect.h == 0)) {
+		dirty.x = 0;
+		dirty.y = 0;
+		dirty.w = hisifd->panel_info.xres;
+		dirty.h = hisifd->panel_info.yres;
+	} else {
+		dirty = pov_req->dirty_rect;
+	}
+
+	if ((dirty.x == hisifd->dirty_region_updt.x)
+	    && (dirty.y == hisifd->dirty_region_updt.y)
+	    && (dirty.w == hisifd->dirty_region_updt.w)
+	    && (dirty.h == hisifd->dirty_region_updt.h)) {
+		return 0;
+	}
+
+	dirty_region_updt = &(hisifd->dss_module.dirty_region_updt);
+	hisifd->dss_module.dirty_region_updt_used = 1;
+	dirty_region_updt->dpp_img_hrz_bef_sr =
+	    set_bits32(dirty_region_updt->dpp_img_hrz_bef_sr,
+		       DSS_WIDTH(dirty.w), 13, 0);
+	dirty_region_updt->dpp_img_vrt_bef_sr =
+	    set_bits32(dirty_region_updt->dpp_img_vrt_bef_sr,
+		       DSS_WIDTH(dirty.h), 13, 0);
+	dirty_region_updt->dpp_img_hrz_aft_sr =
+	    set_bits32(dirty_region_updt->dpp_img_hrz_aft_sr,
+		       DSS_WIDTH(dirty.w), 13, 0);
+	dirty_region_updt->dpp_img_vrt_aft_sr =
+	    set_bits32(dirty_region_updt->dpp_img_vrt_aft_sr,
+		       DSS_WIDTH(dirty.h), 13, 0);
+
+	dirty_region_updt->dbuf_frm_size =
+	    set_bits32(dirty_region_updt->dbuf_frm_size, dirty.w * dirty.h, 27,
+		       0);
+	dirty_region_updt->dbuf_frm_hsize =
+	    set_bits32(dirty_region_updt->dbuf_frm_hsize, DSS_WIDTH(dirty.w),
+		       13, 0);
+
+	return 0;
+}
+
+void hisi_dss_dirty_region_updt_config(struct hisi_fb_data_type *hisifd,
+				       dss_overlay_t *pov_req)
+{
+	struct hisi_fb_panel_data *pdata = NULL;
+	struct hisi_panel_info *pinfo = NULL;
+	dirty_region_updt_t *dirty_region_updt = NULL;
+	struct dss_rect dirty = { 0 };
+	uint32_t h_porch_pading = 0;
+	uint32_t v_porch_pading = 0;
+	dss_rect_t rect = { 0 };
+	uint32_t max_latency = 0;
+	uint32_t bits_per_pixel = 0;
+	uint32_t h_front_porch_max = 0;
+	uint32_t h_front_porch = 0;
+	uint32_t h_back_porch = 0;
+
+	BUG_ON(hisifd == NULL);
+	pdata = dev_get_platdata(&hisifd->pdev->dev);
+	BUG_ON(pdata == NULL);
+	pinfo = &(hisifd->panel_info);
+
+	if ((hisifd->index != PRIMARY_PANEL_IDX) ||
+	    !pinfo->dirty_region_updt_support)
+		return;
+
+	if ((!pov_req) || (pov_req->dirty_rect.w == 0)
+	    || (pov_req->dirty_rect.h == 0)) {
+		dirty.x = 0;
+		dirty.y = 0;
+		dirty.w = hisifd->panel_info.xres;
+		dirty.h = hisifd->panel_info.yres;
+	} else {
+		dirty = pov_req->dirty_rect;
+	}
+
+	if (hisifd->panel_info.xres >= dirty.w) {
+		h_porch_pading = hisifd->panel_info.xres - dirty.w;
+	}
+
+	if (hisifd->panel_info.yres >= dirty.h) {
+		v_porch_pading = hisifd->panel_info.yres - dirty.h;
+	}
+
+	if ((dirty.x == hisifd->dirty_region_updt.x)
+	    && (dirty.y == hisifd->dirty_region_updt.y)
+	    && (dirty.w == hisifd->dirty_region_updt.w)
+	    && (dirty.h == hisifd->dirty_region_updt.h)) {
+		return;
+	}
+
+	rect.x = 0;
+	rect.y = 0;
+	rect.w = dirty.w;
+	rect.h = dirty.h;
+	mipi_ifbc_get_rect(hisifd, &rect);
+
+	h_front_porch = pinfo->ldi.h_front_porch;
+	h_back_porch = pinfo->ldi.h_back_porch;
+
+	h_porch_pading = h_porch_pading * rect.w / dirty.w;
+	v_porch_pading = v_porch_pading * rect.h / dirty.h;
+
+	if (pinfo->bpp == LCD_RGB888)
+		bits_per_pixel = 24;
+	else if (pinfo->bpp == LCD_RGB565)
+		bits_per_pixel = 16;
+	else
+		bits_per_pixel = 24;
+
+	if (pinfo->pxl_clk_rate_div == 0)
+		pinfo->pxl_clk_rate_div = 1;
+	max_latency =
+	    (rect.w * bits_per_pixel / 8 + 1 + 6) / (pinfo->mipi.lane_nums + 1);
+
+	h_front_porch_max =
+	    max_latency * (pinfo->pxl_clk_rate / pinfo->pxl_clk_rate_div) /
+	    pinfo->dsi_phy_ctrl.lane_byte_clk;
+	HISI_FB_DEBUG("bits_per_pixel = %d\n" "data_lane_lp2hs_time = %d\n"
+		      "max_latency = %d\n" "pxl_clk_rate = %lld\n"
+		      "pxl_clk_rate_div = %d\n"
+		      "dsi_phy_ctrl.lane_byte_clk = %lld\n"
+		      "h_front_porch_max = %d\n", bits_per_pixel,
+		      pinfo->dsi_phy_ctrl.data_lane_lp2hs_time, max_latency,
+		      pinfo->pxl_clk_rate, pinfo->pxl_clk_rate_div,
+		      pinfo->dsi_phy_ctrl.lane_byte_clk, h_front_porch_max);
+
+	if (h_front_porch > h_front_porch_max) {
+		h_back_porch += (h_front_porch - h_front_porch_max);
+		h_front_porch = h_front_porch_max;
+	}
+
+	dirty_region_updt = &(hisifd->dss_module.dirty_region_updt);
+
+	dirty_region_updt->ldi_dpi0_hrz_ctrl0 =
+	    set_bits32(dirty_region_updt->ldi_dpi0_hrz_ctrl0,
+		       (h_front_porch) | ((h_back_porch + h_porch_pading) <<
+					  16), 29, 0);
+	dirty_region_updt->ldi_dpi0_hrz_ctrl1 =
+	    set_bits32(dirty_region_updt->ldi_dpi0_hrz_ctrl1,
+		       DSS_WIDTH(pinfo->ldi.h_pulse_width), 13, 0);
+	dirty_region_updt->ldi_dpi0_hrz_ctrl2 =
+	    set_bits32(dirty_region_updt->ldi_dpi0_hrz_ctrl2, DSS_WIDTH(rect.w),
+		       13, 0);
+
+	if (is_dual_mipi_panel(hisifd)) {
+		dirty_region_updt->ldi_dpi1_hrz_ctrl0 =
+		    set_bits32(dirty_region_updt->ldi_dpi1_hrz_ctrl0,
+			       (h_back_porch + h_porch_pading) << 16, 29, 0);
+		dirty_region_updt->ldi_dpi1_hrz_ctrl1 =
+		    set_bits32(dirty_region_updt->ldi_dpi1_hrz_ctrl1,
+			       DSS_WIDTH(pinfo->ldi.h_pulse_width), 13, 0);
+		dirty_region_updt->ldi_dpi1_hrz_ctrl2 =
+		    set_bits32(dirty_region_updt->ldi_dpi1_hrz_ctrl2,
+			       DSS_WIDTH(rect.w), 13, 0);
+	}
+
+	dirty_region_updt->ldi_vrt_ctrl0 =
+	    set_bits32(dirty_region_updt->ldi_vrt_ctrl0,
+		       (pinfo->ldi.v_front_porch +
+			v_porch_pading) | ((pinfo->ldi.v_back_porch) << 16), 29,
+		       0);
+	dirty_region_updt->ldi_vrt_ctrl1 =
+	    set_bits32(dirty_region_updt->ldi_vrt_ctrl1,
+		       DSS_HEIGHT(pinfo->ldi.v_pulse_width), 13, 0);
+	dirty_region_updt->ldi_vrt_ctrl2 =
+	    set_bits32(dirty_region_updt->ldi_vrt_ctrl2, DSS_HEIGHT(rect.h), 13,
+		       0);
+
+	dirty_region_updt->edpi_cmd_size =
+	    set_bits32(dirty_region_updt->edpi_cmd_size, rect.w, 16, 0);
+
+	if (pinfo->ifbc_type != IFBC_TYPE_NONE) {
+		if ((pinfo->ifbc_type == IFBC_TYPE_VESA2X_DUAL) ||
+		    (pinfo->ifbc_type == IFBC_TYPE_VESA3X_DUAL)) {
+			dirty_region_updt->ifbc_size =
+			    set_bits32(dirty_region_updt->ifbc_size,
+				       ((DSS_WIDTH(dirty.w / 2) << 16) |
+					DSS_HEIGHT(dirty.h)), 32, 0);
+		} else {
+			dirty_region_updt->ifbc_size =
+			    set_bits32(dirty_region_updt->ifbc_size,
+				       ((DSS_WIDTH(dirty.w) << 16) |
+					DSS_HEIGHT(dirty.h)), 32, 0);
+		}
+	}
+
+	/*if (pdata && pdata->set_display_region) {
+	   pdata->set_display_region(hisifd->pdev, &dirty);
+	   } */
+
+	hisifd->dirty_region_updt = dirty;
+
+	hisi_dss_dirty_region_updt_set_reg(hisifd, hisifd->dss_base,
+					   &(hisifd->dss_module.
+					     dirty_region_updt));
+
+	if (g_debug_dirty_region_updt) {
+		HISI_FB_INFO
+		    ("dirty_region(%d,%d, %d,%d), h_porch_pading=%d, v_porch_pading=%d.\n",
+		     dirty.x, dirty.y, dirty.w, dirty.h, h_porch_pading,
+		     v_porch_pading);
+	}
+}
+
+/*******************************************************************************
+ ** WCHN
+ */
+static uint32_t hisi_calculate_display_addr_wb(bool mmu_enable,
+					       dss_wb_layer_t *wb_layer,
+					       dss_rect_t aligned_rect,
+					       dss_rect_t *ov_block_rect,
+					       int add_type)
+{
+	uint32_t addr = 0;
+	uint32_t dst_addr = 0;
+	uint32_t stride = 0;
+	uint32_t offset = 0;
+	int left = 0, top = 0;
+	int bpp = 0;
+
+	if (wb_layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+		left = wb_layer->dst_rect.x;
+		top =
+		    ov_block_rect->x - wb_layer->dst_rect.x +
+		    wb_layer->dst_rect.y;
+	} else {
+		left = aligned_rect.x;
+		top = aligned_rect.y;
+	}
+
+	if (add_type == DSS_ADDR_PLANE0) {
+		stride = wb_layer->dst.stride;
+		dst_addr =
+		    mmu_enable ? wb_layer->dst.vir_addr : wb_layer->dst.
+		    phy_addr;
+	} else if (add_type == DSS_ADDR_PLANE1) {
+		stride = wb_layer->dst.stride_plane1;
+		offset = wb_layer->dst.offset_plane1;
+		dst_addr =
+		    mmu_enable ? (wb_layer->dst.vir_addr +
+				  offset) : (wb_layer->dst.phy_addr + offset);
+		top /= 2;
+	} else {
+		HISI_FB_ERR("NOT SUPPORT this add_type(%d).\n", add_type);
+		BUG_ON(1);
+	}
+
+	bpp = wb_layer->dst.bpp;
+	addr = dst_addr + left * bpp + top * stride;
+
+	return addr;
+}
+
+int hisi_dss_wdfc_config(struct hisi_fb_data_type *hisifd,
+			 dss_wb_layer_t *layer, dss_rect_t *aligned_rect,
+			 dss_rect_t *ov_block_rect)
+{
+	dss_dfc_t *dfc = NULL;
+	int chn_idx = 0;
+	dss_rect_t in_rect;
+	bool need_dither = false;
+
+	int size_hrz = 0;
+	int size_vrt = 0;
+	int dfc_fmt = 0;
+	int dfc_pix_in_num = 0;
+	int aligned_line = 0;
+	uint32_t dfc_w = 0;
+	int aligned_pixel = 0;
+
+	uint32_t left_pad = 0;
+	uint32_t right_pad = 0;
+	uint32_t top_pad = 0;
+	uint32_t bottom_pad = 0;
+
+	uint32_t addr = 0;
+	uint32_t dst_addr = 0;
+	uint32_t bpp = 0;
+	bool mmu_enable = false;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+	BUG_ON(aligned_rect == NULL);
+
+	chn_idx = layer->chn_idx;
+
+	dfc = &(hisifd->dss_module.dfc[chn_idx]);
+	hisifd->dss_module.dfc_used[chn_idx] = 1;
+
+	dfc_fmt = hisi_pixel_format_hal2dfc(layer->dst.format);
+	if (dfc_fmt < 0) {
+		HISI_FB_ERR("layer format (%d) not support !\n",
+			    layer->dst.format);
+		return -EINVAL;
+	}
+
+	if (layer->need_cap & CAP_AFBCE) {
+		aligned_pixel = AFBC_BLOCK_ALIGN;
+	} else {
+		aligned_pixel = DMA_ALIGN_BYTES / layer->dst.bpp;
+	}
+
+	need_dither = isNeedDither(dfc_fmt);
+	if (ov_block_rect) {
+		memcpy(&in_rect, ov_block_rect, sizeof(dss_rect_t));
+	} else {
+		in_rect = layer->src_rect;
+	}
+
+	size_hrz = DSS_WIDTH(in_rect.w);
+	size_vrt = DSS_HEIGHT(in_rect.h);
+
+	if ((size_hrz + 1) % 2 == 1) {
+		size_hrz += 1;
+		dfc_w = 1;
+	}
+
+	dfc_pix_in_num = (layer->dst.bpp <= 2) ? 0x1 : 0x0;
+
+	if (layer->need_cap & CAP_AFBCE) {
+		aligned_rect->x = ALIGN_DOWN(in_rect.x, aligned_pixel);
+		aligned_rect->w =
+		    ALIGN_UP(in_rect.x - aligned_rect->x + in_rect.w + dfc_w,
+			     aligned_pixel);
+		aligned_rect->y = ALIGN_DOWN(in_rect.y, aligned_pixel);
+		aligned_rect->h =
+		    ALIGN_UP(in_rect.y - aligned_rect->y + in_rect.h,
+			     aligned_pixel);
+
+		left_pad = in_rect.x - aligned_rect->x;
+		right_pad =
+		    aligned_rect->w - (in_rect.x - aligned_rect->x + in_rect.w +
+				       dfc_w);
+		top_pad = in_rect.y - aligned_rect->y;
+		bottom_pad =
+		    aligned_rect->h - (in_rect.y - aligned_rect->y + in_rect.h);
+	} else if (layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+		aligned_line = (layer->dst.bpp <= 2) ? 32 : 16;
+		mmu_enable = (layer->dst.mmu_enable == 1) ? true : false;
+		dst_addr =
+		    mmu_enable ? layer->dst.vir_addr : layer->dst.phy_addr;
+		bpp = layer->dst.bpp;
+		addr =
+		    dst_addr + layer->dst_rect.x * bpp +
+		    (in_rect.x - layer->dst_rect.x + layer->dst_rect.y) *
+		    	layer->dst.stride;
+
+		if (is_YUV_SP_420(layer->dst.format)) {
+			top_pad = (addr & 0x1F) / bpp;
+		} else {
+			top_pad = (addr & 0x3F) / bpp;
+		}
+
+		aligned_rect->x = in_rect.x;
+		aligned_rect->y = in_rect.y;
+		aligned_rect->w = size_hrz + 1;
+		aligned_rect->h = ALIGN_UP(in_rect.h + top_pad, aligned_line);
+
+		left_pad = 0;
+		right_pad = 0;
+		bottom_pad = aligned_rect->h - in_rect.h - top_pad;
+	} else {
+		aligned_rect->x = ALIGN_DOWN(in_rect.x, aligned_pixel);
+		aligned_rect->w =
+		    ALIGN_UP(in_rect.x - aligned_rect->x + in_rect.w + dfc_w,
+			     aligned_pixel);
+		aligned_rect->y = in_rect.y;
+
+		if (is_YUV_SP_420(layer->dst.format)) {
+			aligned_rect->h = ALIGN_UP(in_rect.h, 2);
+		} else {
+			aligned_rect->h = in_rect.h;
+		}
+
+		left_pad = in_rect.x - aligned_rect->x;
+		right_pad = aligned_rect->w - (left_pad + in_rect.w + dfc_w);
+		top_pad = 0;
+		bottom_pad = aligned_rect->h - in_rect.h;
+	}
+
+	dfc->disp_size =
+	    set_bits32(dfc->disp_size, (size_vrt | (size_hrz << 16)), 32, 0);
+	dfc->pix_in_num = set_bits32(dfc->pix_in_num, dfc_pix_in_num, 1, 0);
+	dfc->disp_fmt = set_bits32(dfc->disp_fmt, dfc_fmt, 5, 1);
+	dfc->clip_ctl_hrz = set_bits32(dfc->clip_ctl_hrz, 0x0, 12, 0);
+	dfc->clip_ctl_vrz = set_bits32(dfc->clip_ctl_vrz, 0x0, 12, 0);
+	dfc->ctl_clip_en = set_bits32(dfc->ctl_clip_en, 0x0, 1, 0);
+	dfc->icg_module = set_bits32(dfc->icg_module, 0x1, 1, 0);
+	if (need_dither) {
+		dfc->dither_enable = set_bits32(dfc->dither_enable, 0x1, 1, 0);
+	} else {
+		dfc->dither_enable = set_bits32(dfc->dither_enable, 0x0, 1, 0);
+	}
+
+	if (left_pad || right_pad || top_pad || bottom_pad) {
+		dfc->padding_ctl = set_bits32(dfc->padding_ctl, (left_pad |
+								 (right_pad << 8) | (top_pad << 16) |
+								 (bottom_pad << 24) | (0x1 << 31)), 32, 0);
+	} else {
+		dfc->padding_ctl = set_bits32(dfc->padding_ctl, 0x0, 32, 0);
+	}
+
+	return 0;
+}
+
+static void hisi_dss_wdma_init(char __iomem *wdma_base, dss_wdma_t *s_wdma)
+{
+	BUG_ON(wdma_base == NULL);
+	BUG_ON(s_wdma == NULL);
+
+	memset(s_wdma, 0, sizeof(dss_wdma_t));
+
+	s_wdma->oft_x0 = inp32(wdma_base + DMA_OFT_X0);
+	s_wdma->oft_y0 = inp32(wdma_base + DMA_OFT_Y0);
+	s_wdma->oft_x1 = inp32(wdma_base + DMA_OFT_X1);
+	s_wdma->oft_y1 = inp32(wdma_base + DMA_OFT_Y1);
+	s_wdma->mask0 = inp32(wdma_base + DMA_MASK0);
+	s_wdma->mask1 = inp32(wdma_base + DMA_MASK1);
+	s_wdma->stretch_size_vrt = inp32(wdma_base + DMA_STRETCH_SIZE_VRT);
+	s_wdma->ctrl = inp32(wdma_base + DMA_CTRL);
+	s_wdma->tile_scram = inp32(wdma_base + DMA_TILE_SCRAM);
+	s_wdma->sw_mask_en = inp32(wdma_base + WDMA_DMA_SW_MASK_EN);
+	s_wdma->start_mask0 = inp32(wdma_base + WDMA_DMA_START_MASK0);
+	s_wdma->end_mask0 = inp32(wdma_base + WDMA_DMA_END_MASK1);
+	s_wdma->start_mask1 = inp32(wdma_base + WDMA_DMA_START_MASK1);
+	s_wdma->end_mask1 = inp32(wdma_base + WDMA_DMA_END_MASK1);
+	s_wdma->data_addr = inp32(wdma_base + DMA_DATA_ADDR0);
+	s_wdma->stride0 = inp32(wdma_base + DMA_STRIDE0);
+	s_wdma->data1_addr = inp32(wdma_base + DMA_DATA_ADDR1);
+	s_wdma->stride1 = inp32(wdma_base + DMA_STRIDE1);
+	s_wdma->stretch_stride = inp32(wdma_base + DMA_STRETCH_STRIDE0);
+	s_wdma->data_num = inp32(wdma_base + DMA_DATA_NUM0);
+
+	s_wdma->ch_rd_shadow = inp32(wdma_base + CH_RD_SHADOW);
+	s_wdma->ch_ctl = inp32(wdma_base + CH_CTL);
+	s_wdma->ch_secu_en = inp32(wdma_base + CH_SECU_EN);
+	s_wdma->ch_sw_end_req = inp32(wdma_base + CH_SW_END_REQ);
+
+	s_wdma->afbce_hreg_pic_blks = inp32(wdma_base + AFBCE_HREG_PIC_BLKS);
+	s_wdma->afbce_hreg_format = inp32(wdma_base + AFBCE_HREG_FORMAT);
+	s_wdma->afbce_hreg_hdr_ptr_lo =
+	    inp32(wdma_base + AFBCE_HREG_HDR_PTR_LO);
+	s_wdma->afbce_hreg_pld_ptr_lo =
+	    inp32(wdma_base + AFBCE_HREG_PLD_PTR_LO);
+	s_wdma->afbce_picture_size = inp32(wdma_base + AFBCE_PICTURE_SIZE);
+	s_wdma->afbce_ctl = inp32(wdma_base + AFBCE_CTL);
+	s_wdma->afbce_header_srtide = inp32(wdma_base + AFBCE_HEADER_SRTIDE);
+	s_wdma->afbce_payload_stride = inp32(wdma_base + AFBCE_PAYLOAD_STRIDE);
+	s_wdma->afbce_enc_os_cfg = inp32(wdma_base + AFBCE_ENC_OS_CFG);
+	s_wdma->afbce_mem_ctrl = inp32(wdma_base + AFBCE_MEM_CTRL);
+}
+
+static void hisi_dss_wdma_set_reg(struct hisi_fb_data_type *hisifd,
+				  char __iomem *wdma_base, dss_wdma_t *s_wdma)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(wdma_base == NULL);
+	BUG_ON(s_wdma == NULL);
+
+	hisifd->set_reg(hisifd, wdma_base + CH_REG_DEFAULT, 0x1, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + CH_REG_DEFAULT, 0x0, 32, 0);
+
+	hisifd->set_reg(hisifd, wdma_base + DMA_OFT_X0, s_wdma->oft_x0, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_OFT_Y0, s_wdma->oft_y0, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_OFT_X1, s_wdma->oft_x1, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_OFT_Y1, s_wdma->oft_y1, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_CTRL, s_wdma->ctrl, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_TILE_SCRAM,
+			s_wdma->tile_scram, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + WDMA_DMA_SW_MASK_EN,
+			s_wdma->sw_mask_en, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + WDMA_DMA_START_MASK0,
+			s_wdma->start_mask0, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + WDMA_DMA_END_MASK0,
+			s_wdma->end_mask0, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_DATA_ADDR0,
+			s_wdma->data_addr, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_STRIDE0,
+			s_wdma->stride0, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_DATA_ADDR1,
+			s_wdma->data1_addr, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_STRIDE1,
+			s_wdma->stride1, 32, 0);
+
+	hisifd->set_reg(hisifd, wdma_base + CH_CTL, s_wdma->ch_ctl, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + ROT_SIZE, s_wdma->rot_size, 32, 0);
+	hisifd->set_reg(hisifd, wdma_base + DMA_BUF_SIZE,
+			s_wdma->dma_buf_size, 32, 0);
+
+	if (s_wdma->afbc_used == 1) {
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HREG_PIC_BLKS,
+				s_wdma->afbce_hreg_pic_blks, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HREG_FORMAT,
+				s_wdma->afbce_hreg_format, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HREG_HDR_PTR_LO,
+				s_wdma->afbce_hreg_hdr_ptr_lo, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HREG_PLD_PTR_LO,
+				s_wdma->afbce_hreg_pld_ptr_lo, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_PICTURE_SIZE,
+				s_wdma->afbce_picture_size, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HEADER_SRTIDE,
+				s_wdma->afbce_header_srtide, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_PAYLOAD_STRIDE,
+				s_wdma->afbce_payload_stride, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_ENC_OS_CFG,
+				s_wdma->afbce_enc_os_cfg, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_THRESHOLD,
+				s_wdma->afbce_threshold, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_SCRAMBLE_MODE,
+				s_wdma->afbce_scramble_mode, 32, 0);
+		hisifd->set_reg(hisifd, wdma_base + AFBCE_HEADER_POINTER_OFFSET,
+				s_wdma->afbce_header_pointer_offset, 32, 0);
+	}
+}
+
+int hisi_dss_wdma_config(struct hisi_fb_data_type *hisifd,
+			 dss_overlay_t *pov_req, dss_wb_layer_t *layer,
+			 dss_rect_t aligned_rect, dss_rect_t *ov_block_rect,
+			 bool last_block)
+{
+	dss_wdma_t *wdma = NULL;
+	int chn_idx = 0;
+	int wdma_format = 0;
+	int wdma_transform = 0;
+	uint32_t oft_x0 = 0;
+	uint32_t oft_x1 = 0;
+	uint32_t oft_y0 = 0;
+	uint32_t oft_y1 = 0;
+	uint32_t data_num = 0;
+	uint32_t wdma_addr = 0;
+	uint32_t wdma_stride = 0;
+
+	uint32_t wdma_buf_width = 0;
+	uint32_t wdma_buf_height = 0;
+
+	dss_rect_t in_rect;
+	int temp = 0;
+	int aligned_pixel = 0;
+	int l2t_interleave_n = 0;
+	bool mmu_enable = false;
+
+	dss_rect_ltrb_t afbc_header_rect = { 0 };
+	dss_rect_ltrb_t afbc_payload_rect = { 0 };
+	uint32_t afbce_hreg_pic_blks;
+	uint32_t afbc_header_addr = 0;
+	uint32_t afbc_header_stride = 0;
+	uint32_t afbc_payload_addr = 0;
+	uint32_t afbc_payload_stride = 0;
+	int32_t afbc_header_start_pos = 0;
+	uint32_t afbc_header_pointer_offset = 0;
+	uint32_t stride_align = 0;
+	uint32_t addr_align = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON(layer == NULL);
+
+	chn_idx = layer->chn_idx;
+
+	wdma = &(hisifd->dss_module.wdma[chn_idx]);
+	hisifd->dss_module.dma_used[chn_idx] = 1;
+
+	wdma_format = hisi_pixel_format_hal2dma(layer->dst.format);
+	if (wdma_format < 0) {
+		HISI_FB_ERR("hisi_pixel_format_hal2dma failed!\n");
+		return -EINVAL;
+	}
+
+	in_rect = aligned_rect;
+	aligned_pixel = DMA_ALIGN_BYTES / layer->dst.bpp;
+
+	wdma_transform = hisi_transform_hal2dma(layer->transform, chn_idx);
+	if (wdma_transform < 0) {
+		HISI_FB_ERR("hisi_transform_hal2dma failed!\n");
+		return -EINVAL;
+	}
+
+	mmu_enable = (layer->dst.mmu_enable == 1) ? true : false;
+	wdma_addr = mmu_enable ? layer->dst.vir_addr : layer->dst.phy_addr;
+
+	if (layer->need_cap & CAP_AFBCE) {
+		wdma->afbc_used = 1;
+		if ((layer->dst.width & (AFBC_HEADER_ADDR_ALIGN - 1)) ||
+		    (layer->dst.height & (AFBC_BLOCK_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("wb_layer img width(%d) is not %d bytes aligned, or "
+			     "img heigh(%d) is not %d bytes aligned!\n",
+			     layer->dst.width, AFBC_HEADER_ADDR_ALIGN,
+			     layer->dst.height, AFBC_BLOCK_ALIGN);
+			return -EINVAL;
+		}
+
+		if ((in_rect.w < AFBC_PIC_WIDTH_MIN)
+		    || (in_rect.w > AFBCE_IN_WIDTH_MAX)
+		    || (in_rect.h < AFBC_PIC_HEIGHT_MIN)
+		    || (in_rect.h > AFBC_PIC_HEIGHT_MAX)
+		    || (in_rect.w & (AFBC_BLOCK_ALIGN - 1))
+		    || (in_rect.h & (AFBC_BLOCK_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("afbce in_rect(%d,%d, %d,%d) is out of range!",
+			     in_rect.x, in_rect.y, in_rect.w, in_rect.h);
+			return -EINVAL;
+		}
+
+		afbc_header_rect.right =
+		    ALIGN_UP(in_rect.x + in_rect.w, AFBC_HEADER_ADDR_ALIGN) - 1;
+		afbc_header_rect.bottom =
+		    ALIGN_UP(in_rect.y + in_rect.h, AFBC_BLOCK_ALIGN) - 1;
+		if (layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+			afbc_header_rect.left =
+			    ALIGN_DOWN(layer->dst_rect.x,
+				       AFBC_HEADER_ADDR_ALIGN);
+			afbc_header_rect.top =
+			    ALIGN_DOWN(layer->dst_rect.y +
+				       (ov_block_rect->x - layer->dst_rect.x),
+				       AFBC_BLOCK_ALIGN);
+
+			afbc_payload_rect.left =
+			    ALIGN_DOWN(layer->dst_rect.x, AFBC_BLOCK_ALIGN);
+			afbc_payload_rect.top = afbc_header_rect.top;
+
+			afbc_header_start_pos =
+			    (layer->dst_rect.x -
+			     afbc_header_rect.left) / AFBC_BLOCK_ALIGN;
+		} else {
+			afbc_header_rect.left =
+			    ALIGN_DOWN(in_rect.x, AFBC_HEADER_ADDR_ALIGN);
+			afbc_header_rect.top =
+			    ALIGN_DOWN(in_rect.y, AFBC_BLOCK_ALIGN);
+
+			afbc_payload_rect.left =
+			    ALIGN_DOWN(in_rect.x, AFBC_BLOCK_ALIGN);
+			afbc_payload_rect.top = afbc_header_rect.top;
+
+			afbc_header_start_pos =
+			    (in_rect.x -
+			     afbc_header_rect.left) / AFBC_BLOCK_ALIGN;
+		}
+
+		if (afbc_header_start_pos < 0) {
+			HISI_FB_ERR("afbc_header_start_pos(%d) is invalid!\n",
+				    afbc_header_start_pos);
+			return -EINVAL;
+		}
+
+		afbce_hreg_pic_blks =
+		    (in_rect.w / AFBC_BLOCK_ALIGN) * (in_rect.h /
+						      AFBC_BLOCK_ALIGN) - 1;
+
+		afbc_header_stride =
+		    (layer->dst.width / AFBC_BLOCK_ALIGN) *
+		    AFBC_HEADER_STRIDE_BLOCK;
+
+		afbc_header_pointer_offset =
+		    (afbc_header_rect.top / AFBC_BLOCK_ALIGN) *
+		    afbc_header_stride +
+		    (afbc_header_rect.left / AFBC_BLOCK_ALIGN) *
+		    AFBC_HEADER_STRIDE_BLOCK;
+
+		afbc_header_addr =
+		    layer->dst.afbc_header_addr + afbc_header_pointer_offset;
+
+		if ((afbc_header_addr & (AFBC_HEADER_ADDR_ALIGN - 1)) ||
+		    (afbc_header_stride & (AFBC_HEADER_STRIDE_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("wb_layer afbc_header_addr(0x%x) is not %d bytes aligned, or "
+			     "afbc_header_stride(0x%x) is not %d bytes aligned!\n",
+			     afbc_header_addr, AFBC_HEADER_ADDR_ALIGN,
+			     afbc_header_stride, AFBC_HEADER_STRIDE_ALIGN);
+			return -EINVAL;
+		}
+
+		if (layer->dst.bpp == 4) {
+			stride_align = AFBC_PAYLOAD_STRIDE_ALIGN_32;
+			addr_align = AFBC_PAYLOAD_ADDR_ALIGN_32;
+		} else if (layer->dst.bpp == 2) {
+			stride_align = AFBC_PAYLOAD_STRIDE_ALIGN_16;
+			addr_align = AFBC_PAYLOAD_ADDR_ALIGN_16;
+		} else {
+			HISI_FB_ERR("bpp(%d) not supported!\n", layer->dst.bpp);
+			return -EINVAL;
+		}
+
+		afbc_payload_stride = layer->dst.afbc_payload_stride;
+		if (layer->dst.afbc_scramble_mode != DSS_AFBC_SCRAMBLE_MODE2) {
+			afbc_payload_stride =
+			    (layer->dst.width / AFBC_BLOCK_ALIGN) *
+			    stride_align;
+		}
+		afbc_payload_addr = layer->dst.afbc_payload_addr +
+		    (afbc_payload_rect.top / AFBC_BLOCK_ALIGN) *
+		    afbc_payload_stride +
+		    (afbc_payload_rect.left / AFBC_BLOCK_ALIGN) * stride_align;
+
+		if ((afbc_payload_addr & (addr_align - 1)) ||
+		    (afbc_payload_stride & (stride_align - 1))) {
+			HISI_FB_ERR
+			    ("afbc_payload_addr(0x%x) is not %d bytes aligned, or "
+			     "afbc_payload_stride(0x%x) is not %d bytes aligned!\n",
+			     afbc_payload_addr, addr_align, afbc_payload_stride,
+			     stride_align);
+			return -EINVAL;
+		}
+
+		if (g_debug_ovl_online_composer) {
+			HISI_FB_INFO
+			    ("aligned_rect(%d,%d,%d,%d), afbc_rect(%d,%d,%d,%d)!\n",
+			     in_rect.x, in_rect.y,
+			     DSS_WIDTH(in_rect.x + in_rect.w),
+			     DSS_WIDTH(in_rect.y + in_rect.h),
+			     afbc_payload_rect.left, afbc_payload_rect.top,
+			     afbc_payload_rect.right, afbc_payload_rect.bottom);
+		}
+
+		wdma->ctrl = set_bits32(wdma->ctrl, wdma_format, 5, 3);
+		wdma->ctrl =
+		    set_bits32(wdma->ctrl, (mmu_enable ? 0x1 : 0x0), 1, 8);
+		wdma->ctrl = set_bits32(wdma->ctrl, wdma_transform, 3, 9);
+		if (last_block) {
+			wdma->ch_ctl = set_bits32(wdma->ch_ctl, 0x1d, 5, 0);
+		} else {
+			wdma->ch_ctl = set_bits32(wdma->ch_ctl, 0xd, 5, 0);
+		}
+
+		wdma->rot_size = set_bits32(wdma->rot_size,
+					    (DSS_WIDTH(in_rect.w) |
+					     (DSS_HEIGHT(in_rect.h) << 16)), 32, 0);
+
+		wdma->afbce_hreg_pic_blks =
+		    set_bits32(wdma->afbce_hreg_pic_blks,
+		    		afbce_hreg_pic_blks, 24, 0);
+
+		wdma->afbce_hreg_format =
+		    set_bits32(wdma->afbce_hreg_format,
+			       (isYUVPackage(layer->dst.format) ? 0x0 : 0x1), 1, 21);
+
+		wdma->afbce_hreg_hdr_ptr_lo =
+		    set_bits32(wdma->afbce_hreg_hdr_ptr_lo,
+		    		afbc_header_addr, 32, 0);
+
+		wdma->afbce_hreg_pld_ptr_lo =
+		    set_bits32(wdma->afbce_hreg_pld_ptr_lo,
+		    		afbc_payload_addr, 32, 0);
+
+		wdma->afbce_picture_size =
+		    set_bits32(wdma->afbce_picture_size,
+			       ((DSS_WIDTH(in_rect.w) << 16) |
+			          DSS_HEIGHT(in_rect.h)), 32, 0);
+
+		wdma->afbce_header_srtide =
+		    set_bits32(wdma->afbce_header_srtide,
+			       ((afbc_header_start_pos << 14) |
+				afbc_header_stride), 16, 0);
+
+		wdma->afbce_payload_stride =
+		    set_bits32(wdma->afbce_payload_stride, afbc_payload_stride, 20, 0);
+
+		wdma->afbce_enc_os_cfg =
+		    set_bits32(wdma->afbce_enc_os_cfg,
+			       DSS_AFBCE_ENC_OS_CFG_DEFAULT_VAL, 3, 0);
+
+		wdma->afbce_mem_ctrl =
+		    set_bits32(wdma->afbce_mem_ctrl, 0x0, 12, 0);
+		wdma->afbce_threshold =
+		    set_bits32(wdma->afbce_threshold, 0x2, 32, 0);
+		wdma->afbce_header_pointer_offset =
+		    set_bits32(wdma->afbce_header_pointer_offset,
+			       afbc_header_pointer_offset, 32, 0);
+		wdma->afbce_scramble_mode =
+		    set_bits32(wdma->afbce_scramble_mode,
+			       layer->dst.afbc_scramble_mode, 2, 0);
+
+		return 0;
+	}
+
+	if (layer->need_cap & CAP_TILE) {
+		l2t_interleave_n =
+		    hisi_get_rdma_tile_interleave(layer->dst.stride);
+		if (l2t_interleave_n < MIN_INTERLEAVE) {
+			HISI_FB_ERR
+			    ("tile stride should be 256*2^n, error stride:%d!\n",
+			     layer->dst.stride);
+			return -EINVAL;
+		}
+
+		if (wdma_addr & (TILE_DMA_ADDR_ALIGN - 1)) {
+			HISI_FB_ERR
+			    ("tile wdma_addr(0x%x) is not %d bytes aligned.\n",
+			     wdma_addr, TILE_DMA_ADDR_ALIGN);
+			return -EINVAL;
+		}
+	}
+
+	if (layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+		temp = in_rect.w;
+		in_rect.w = in_rect.h;
+		in_rect.h = temp;
+
+		oft_x0 = 0;
+		oft_x1 = DSS_WIDTH(in_rect.w) / aligned_pixel;
+		oft_y0 = 0;
+		oft_y1 = DSS_HEIGHT(ov_block_rect->w);
+	} else {
+		oft_x0 = in_rect.x / aligned_pixel;
+		oft_x1 = DSS_WIDTH(in_rect.x + in_rect.w) / aligned_pixel;
+		oft_y0 = in_rect.y;
+		oft_y1 = DSS_HEIGHT(in_rect.y + in_rect.h);
+	}
+
+	wdma_addr =
+	    hisi_calculate_display_addr_wb(mmu_enable, layer, in_rect,
+					   ov_block_rect, DSS_ADDR_PLANE0);
+	wdma_stride = layer->dst.stride / DMA_ALIGN_BYTES;
+
+	data_num = (oft_x1 - oft_x0 + 1) * (oft_y1 - oft_y0 + 1);
+	if (layer->transform & HISI_FB_TRANSFORM_ROT_90) {
+		wdma->rot_size = set_bits32(wdma->rot_size,
+					    (DSS_WIDTH(ov_block_rect->w) |
+					     (DSS_HEIGHT(aligned_rect.h) << 16)), 32, 0);
+
+		if (ov_block_rect) {
+			wdma_buf_width = DSS_HEIGHT(ov_block_rect->h);
+			wdma_buf_height = DSS_WIDTH(ov_block_rect->w);
+		} else {
+			wdma_buf_width = DSS_HEIGHT(layer->src_rect.h);
+			wdma_buf_height = DSS_WIDTH(layer->src_rect.w);
+		}
+	} else {
+		if (ov_block_rect) {
+			wdma_buf_width = DSS_WIDTH(ov_block_rect->w);
+			wdma_buf_height = DSS_HEIGHT(ov_block_rect->h);
+		} else {
+			wdma_buf_width = DSS_WIDTH(layer->src_rect.w);
+			wdma_buf_height = DSS_HEIGHT(layer->src_rect.h);
+		}
+	}
+
+	wdma->oft_x0 = set_bits32(wdma->oft_x0, oft_x0, 12, 0);
+	wdma->oft_y0 = set_bits32(wdma->oft_y0, oft_y0, 16, 0);
+	wdma->oft_x1 = set_bits32(wdma->oft_x1, oft_x1, 12, 0);
+	wdma->oft_y1 = set_bits32(wdma->oft_y1, oft_y1, 16, 0);
+
+	wdma->ctrl = set_bits32(wdma->ctrl, wdma_format, 5, 3);
+	wdma->ctrl = set_bits32(wdma->ctrl, wdma_transform, 3, 9);
+	wdma->ctrl = set_bits32(wdma->ctrl, (mmu_enable ? 0x1 : 0x0), 1, 8);
+	wdma->data_num = set_bits32(wdma->data_num, data_num, 30, 0);
+
+	wdma->ctrl =
+	    set_bits32(wdma->ctrl, ((layer->need_cap & CAP_TILE) ? 0x1 : 0x0),
+		       1, 1);
+	wdma->tile_scram =
+	    set_bits32(wdma->tile_scram,
+		       ((layer->need_cap & CAP_TILE) ? 0x1 : 0x0), 1, 0);
+
+	wdma->data_addr = set_bits32(wdma->data_addr, wdma_addr, 32, 0);
+	wdma->stride0 =
+	    set_bits32(wdma->stride0, wdma_stride | (l2t_interleave_n << 16),
+		       20, 0);
+
+	if (is_YUV_SP_420(layer->dst.format)) {
+		wdma_addr =
+		    hisi_calculate_display_addr_wb(mmu_enable, layer, in_rect,
+						   ov_block_rect, DSS_ADDR_PLANE1);
+
+		wdma_stride = layer->dst.stride_plane1 / DMA_ALIGN_BYTES;
+		wdma->data1_addr =
+		    set_bits32(wdma->data1_addr, wdma_addr, 32, 0);
+		wdma->stride1 = set_bits32(wdma->stride1, wdma_stride, 13, 0);
+	}
+
+	if (last_block) {
+		wdma->ch_ctl = set_bits32(wdma->ch_ctl, 1, 1, 4);
+	} else {
+		wdma->ch_ctl = set_bits32(wdma->ch_ctl, 0, 1, 4);
+	}
+	wdma->ch_ctl = set_bits32(wdma->ch_ctl, 1, 1, 3);
+	wdma->ch_ctl = set_bits32(wdma->ch_ctl, 1, 1, 0);
+
+	wdma->dma_buf_size = set_bits32(wdma->dma_buf_size,
+					wdma_buf_width | (wdma_buf_height << 16), 32, 0);
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS GLOBAL
+ */
+int hisi_dss_module_init(struct hisi_fb_data_type *hisifd)
+{
+	BUG_ON(hisifd == NULL);
+
+	memcpy(&(hisifd->dss_module), &(hisifd->dss_module_default),
+	       sizeof(dss_module_reg_t));
+
+	return 0;
+}
+
+int hisi_dss_module_default(struct hisi_fb_data_type *hisifd)
+{
+	dss_module_reg_t *dss_module = NULL;
+	uint32_t module_base = 0;
+	char __iomem *dss_base = NULL;
+	int i = 0;
+
+	BUG_ON(hisifd == NULL);
+	dss_base = hisifd->dss_base;
+	BUG_ON(dss_base == NULL);
+
+	dss_module = &(hisifd->dss_module_default);
+	memset(dss_module, 0, sizeof(dss_module_reg_t));
+
+	for (i = 0; i < DSS_MCTL_IDX_MAX; i++) {
+		module_base = g_dss_module_ovl_base[i][MODULE_MCTL_BASE];
+		if (module_base != 0) {
+			dss_module->mctl_base[i] = dss_base + module_base;
+			hisi_dss_mctl_init(dss_module->mctl_base[i],
+					   &(dss_module->mctl[i]));
+		}
+	}
+
+	for (i = 0; i < DSS_OVL_IDX_MAX; i++) {
+		module_base = g_dss_module_ovl_base[i][MODULE_OVL_BASE];
+		if (module_base != 0) {
+			dss_module->ov_base[i] = dss_base + module_base;
+			hisi_dss_ovl_init(dss_module->ov_base[i],
+					  &(dss_module->ov[i]), i);
+		}
+	}
+
+	for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+		module_base = g_dss_module_base[i][MODULE_AIF0_CHN];
+		if (module_base != 0) {
+			dss_module->aif_ch_base[i] = dss_base + module_base;
+			hisi_dss_aif_init(dss_module->aif_ch_base[i],
+					  &(dss_module->aif[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_AIF1_CHN];
+		if (module_base != 0) {
+			dss_module->aif1_ch_base[i] = dss_base + module_base;
+			hisi_dss_aif_init(dss_module->aif1_ch_base[i],
+					  &(dss_module->aif1[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MIF_CHN];
+		if (module_base != 0) {
+			dss_module->mif_ch_base[i] = dss_base + module_base;
+			hisi_dss_mif_init(dss_module->mif_ch_base[i],
+					  &(dss_module->mif[i]), i);
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MCTL_CHN_MUTEX];
+		if (module_base != 0) {
+			dss_module->mctl_ch_base[i].chn_mutex_base =
+			    dss_base + module_base;
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MCTL_CHN_FLUSH_EN];
+		if (module_base != 0) {
+			dss_module->mctl_ch_base[i].chn_flush_en_base =
+			    dss_base + module_base;
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MCTL_CHN_OV_OEN];
+		if (module_base != 0) {
+			dss_module->mctl_ch_base[i].chn_ov_en_base =
+			    dss_base + module_base;
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MCTL_CHN_STARTY];
+		if (module_base != 0) {
+			dss_module->mctl_ch_base[i].chn_starty_base =
+			    dss_base + module_base;
+			hisi_dss_mctl_ch_starty_init(
+				dss_module->mctl_ch_base[i].chn_starty_base,
+				&(dss_module->mctl_ch[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_MCTL_CHN_MOD_DBG];
+		if (module_base != 0) {
+			dss_module->mctl_ch_base[i].chn_mod_dbg_base =
+			    dss_base + module_base;
+			hisi_dss_mctl_ch_mod_dbg_init(
+				dss_module->mctl_ch_base[i].chn_mod_dbg_base,
+				&(dss_module->mctl_ch[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_DMA];
+		if (module_base != 0) {
+			dss_module->dma_base[i] = dss_base + module_base;
+			if (i < DSS_WCHN_W0 || i == DSS_RCHN_V2) {
+				hisi_dss_rdma_init(dss_module->dma_base[i],
+						   &(dss_module->rdma[i]));
+			} else {
+				hisi_dss_wdma_init(dss_module->dma_base[i],
+						   &(dss_module->wdma[i]));
+			}
+
+			if ((i == DSS_RCHN_V0) || (i == DSS_RCHN_V1)
+			    || (i == DSS_RCHN_V2)) {
+				hisi_dss_rdma_u_init(dss_module->dma_base[i],
+						     &(dss_module->rdma[i]));
+				hisi_dss_rdma_v_init(dss_module->dma_base[i],
+						     &(dss_module->rdma[i]));
+			}
+		}
+
+		module_base = g_dss_module_base[i][MODULE_DFC];
+		if (module_base != 0) {
+			dss_module->dfc_base[i] = dss_base + module_base;
+			hisi_dss_dfc_init(dss_module->dfc_base[i],
+					  &(dss_module->dfc[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_SCL];
+		if (module_base != 0) {
+			dss_module->scl_base[i] = dss_base + module_base;
+			hisi_dss_scl_init(dss_module->scl_base[i],
+					  &(dss_module->scl[i]));
+		}
+
+		module_base = DSS_POST_SCF_OFFSET;
+		if (module_base != 0) {
+			dss_module->post_scf_base = dss_base + module_base;
+			hisi_dss_post_scf_init(dss_module->post_scf_base,
+					       &(dss_module->post_scf));
+		}
+		module_base = g_dss_module_base[i][MODULE_PCSC];
+		if (module_base != 0) {
+			dss_module->pcsc_base[i] = dss_base + module_base;
+			hisi_dss_csc_init(dss_module->pcsc_base[i],
+					  &(dss_module->pcsc[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_ARSR2P];
+		if (module_base != 0) {
+			dss_module->arsr2p_base[i] = dss_base + module_base;
+			hisi_dss_arsr2p_init(dss_module->arsr2p_base[i],
+					     &(dss_module->arsr2p[i]));
+		}
+		module_base = g_dss_module_base[i][MODULE_POST_CLIP];
+		if (module_base != 0) {
+			dss_module->post_clip_base[i] = dss_base + module_base;
+			hisi_dss_post_clip_init(dss_module->post_clip_base[i],
+						&(dss_module->post_clip[i]));
+		}
+
+		module_base = g_dss_module_base[i][MODULE_CSC];
+		if (module_base != 0) {
+			dss_module->csc_base[i] = dss_base + module_base;
+			hisi_dss_csc_init(dss_module->csc_base[i],
+					  &(dss_module->csc[i]));
+		}
+	}
+
+	module_base = DSS_MCTRL_SYS_OFFSET;
+	if (module_base != 0) {
+		dss_module->mctl_sys_base = dss_base + module_base;
+		hisi_dss_mctl_sys_init(dss_module->mctl_sys_base,
+				       &(dss_module->mctl_sys));
+	}
+
+	module_base = DSS_SMMU_OFFSET;
+	if (module_base != 0) {
+		dss_module->smmu_base = dss_base + module_base;
+		hisi_dss_smmu_init(dss_module->smmu_base, &(dss_module->smmu));
+	}
+
+	return 0;
+}
+
+int hisi_dss_ch_module_set_regs(struct hisi_fb_data_type *hisifd,
+				int32_t mctl_idx, int chn_idx, uint32_t wb_type,
+				bool enable_cmdlist)
+{
+	dss_module_reg_t *dss_module = NULL;
+	int i = 0;
+	int ret = 0;
+	uint32_t tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((chn_idx < 0) || (chn_idx >= DSS_CHN_MAX_DEFINE));
+
+	dss_module = &(hisifd->dss_module);
+	i = chn_idx;
+
+	if (enable_cmdlist) {
+		if (chn_idx == DSS_RCHN_V2) {
+			tmp = (0x1 << DSS_CMDLIST_V2);
+			hisifd->cmdlist_idx = DSS_CMDLIST_V2;
+		} else if (chn_idx == DSS_WCHN_W2) {
+			tmp = (0x1 << DSS_CMDLIST_W2);
+			hisifd->cmdlist_idx = DSS_CMDLIST_W2;
+		} else {
+			tmp = (0x1 << chn_idx);
+			hisifd->cmdlist_idx = chn_idx;
+		}
+
+		ret =
+		    hisi_cmdlist_add_new_node(hisifd, tmp, 0, 0, 0, 0, wb_type);
+		if (ret != 0) {
+			HISI_FB_ERR("fb%d, hisi_cmdlist_add_new_node err:%d \n",
+				    hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	if (dss_module->mctl_ch_used[i] == 1) {
+		hisi_dss_mctl_ch_set_reg(hisifd,
+					 &(dss_module->mctl_ch_base[i]),
+					 &(dss_module->mctl_ch[i]), mctl_idx);
+	}
+
+	if (dss_module->smmu_used == 1) {
+		hisi_dss_smmu_ch_set_reg(hisifd, dss_module->smmu_base,
+					 &(dss_module->smmu), i);
+	}
+
+	if (dss_module->dma_used[i] == 1) {
+		if (i < DSS_WCHN_W0 || i == DSS_RCHN_V2) {
+			hisi_dss_rdma_set_reg(hisifd, dss_module->dma_base[i],
+					      &(dss_module->rdma[i]));
+		} else {
+			hisi_dss_wdma_set_reg(hisifd, dss_module->dma_base[i],
+					      &(dss_module->wdma[i]));
+		}
+
+		if ((i == DSS_RCHN_V0) || (i == DSS_RCHN_V1)
+		    || (i == DSS_RCHN_V2)) {
+			hisi_dss_rdma_u_set_reg(hisifd, dss_module->dma_base[i],
+						&(dss_module->rdma[i]));
+			hisi_dss_rdma_v_set_reg(hisifd, dss_module->dma_base[i],
+						&(dss_module->rdma[i]));
+		}
+	}
+
+	if (dss_module->aif_ch_used[i] == 1) {
+		hisi_dss_aif_ch_set_reg(hisifd, dss_module->aif_ch_base[i],
+					&(dss_module->aif[i]));
+	}
+
+	if (dss_module->aif1_ch_used[i] == 1) {
+		hisi_dss_aif_ch_set_reg(hisifd, dss_module->aif1_ch_base[i],
+					&(dss_module->aif1[i]));
+	}
+
+	if (dss_module->mif_used[i] == 1) {
+		hisi_dss_mif_set_reg(hisifd, dss_module->mif_ch_base[i],
+				     &(dss_module->mif[i]), i);
+	}
+
+	if (dss_module->dfc_used[i] == 1) {
+		hisi_dss_dfc_set_reg(hisifd, dss_module->dfc_base[i],
+				     &(dss_module->dfc[i]));
+	}
+
+	if (dss_module->scl_used[i] == 1) {
+		hisi_dss_chn_scl_load_filter_coef_set_reg(hisifd, false,
+							  chn_idx,
+							  dss_module->scl[i].fmt);
+		hisi_dss_scl_set_reg(hisifd, dss_module->scl_base[i],
+				     &(dss_module->scl[i]));
+	}
+	if (hisifd->dss_module.post_cilp_used[i]) {
+		hisi_dss_post_clip_set_reg(hisifd,
+					   dss_module->post_clip_base[i],
+					   &(dss_module->post_clip[i]));
+	}
+	if (dss_module->pcsc_used[i] == 1) {
+		hisi_dss_csc_set_reg(hisifd, dss_module->pcsc_base[i],
+				     &(dss_module->pcsc[i]));
+	}
+
+	if (dss_module->arsr2p_used[i] == 1) {
+		hisi_dss_arsr2p_set_reg(hisifd, dss_module->arsr2p_base[i],
+					&(dss_module->arsr2p[i]));
+	}
+
+	if (dss_module->csc_used[i] == 1) {
+		hisi_dss_csc_set_reg(hisifd, dss_module->csc_base[i],
+				     &(dss_module->csc[i]));
+	}
+
+	if (dss_module->mctl_ch_used[i] == 1) {
+		hisi_dss_mctl_sys_ch_set_reg(hisifd,
+					     &(dss_module->mctl_ch_base[i]),
+					     &(dss_module->mctl_ch[i]), i, true);
+	}
+
+	return 0;
+
+ err_return:
+	return ret;
+}
+
+int hisi_dss_ov_module_set_regs(struct hisi_fb_data_type *hisifd,
+				dss_overlay_t *pov_req, int ovl_idx,
+				bool enable_cmdlist, int task_end, int last,
+				bool is_first_ov_block)
+{
+	dss_module_reg_t *dss_module = NULL;
+	int i = 0;
+	int ret = 0;
+	uint32_t tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	if (pov_req && pov_req->wb_layer_infos[0].chn_idx == DSS_WCHN_W2) {
+		return 0;
+	}
+
+	dss_module = &(hisifd->dss_module);
+	i = ovl_idx;
+
+	if (enable_cmdlist) {
+		tmp = (0x1 << (DSS_CMDLIST_OV0 + ovl_idx));
+		hisifd->cmdlist_idx = DSS_CMDLIST_OV0 + ovl_idx;
+
+		ret =
+		    hisi_cmdlist_add_new_node(hisifd, tmp, 0, task_end, 0, last,
+					      0);
+		if (ret != 0) {
+			HISI_FB_ERR("fb%d, hisi_cmdlist_add_new_node err:%d \n",
+				    hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	if (dss_module->mctl_used[i] == 1) {
+		hisi_dss_mctl_ov_set_reg(hisifd, dss_module->mctl_base[i],
+					 &(dss_module->mctl[i]), ovl_idx,
+					 enable_cmdlist);
+	}
+
+	if (is_first_ov_block) {
+		if (dss_module->dirty_region_updt_used == 1)
+			hisi_dss_dirty_region_dbuf_set_reg(hisifd,
+							   hisifd->dss_base,
+							   &(dss_module->
+							     dirty_region_updt));
+	}
+
+	if (dss_module->ov_used[i] == 1) {
+		hisi_dss_ovl_set_reg(hisifd, dss_module->ov_base[i],
+				     &(dss_module->ov[i]), ovl_idx);
+	}
+
+	if (hisifd->dss_module.post_scf_used == 1) {
+		hisi_dss_post_scf_set_reg(hisifd,
+					  hisifd->dss_module.post_scf_base,
+					  &(hisifd->dss_module.post_scf));
+	}
+
+	if (dss_module->mctl_sys_used == 1) {
+		hisi_dss_mctl_sys_set_reg(hisifd, dss_module->mctl_sys_base,
+					  &(dss_module->mctl_sys), ovl_idx);
+	}
+
+	return 0;
+
+ err_return:
+	return ret;
+}
+
+int hisi_dss_prev_module_set_regs(struct hisi_fb_data_type *hisifd,
+				  dss_overlay_t *pov_req,
+				  uint32_t cmdlist_pre_idxs,
+				  bool enable_cmdlist, bool *use_comm_mmbuf)
+{
+	dss_module_reg_t *dss_module = NULL;
+	dss_layer_t *layer = NULL;
+	dss_wb_layer_t *wb_layer = NULL;
+	int32_t ovl_idx = 0;
+	int32_t layer_idx = 0;
+	int32_t mctl_idx = 0;
+	int chn_idx = 0;
+	int i = 0;
+	int j = 0;
+	int k = 0;
+	int m = 0;
+	bool has_base = false;
+	int ret = 0;
+	uint32_t tmp = 0;
+	uint32_t cmdlist_idxs_temp = 0;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_h_block = NULL;
+	dss_mmbuf_t offline_mmbuf[DSS_CHN_MAX_DEFINE];
+	bool has_rot = false;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	ovl_idx = pov_req->ovl_idx;
+	dss_module = &(hisifd->dss_module);
+
+	if (enable_cmdlist) {
+		if (pov_req->wb_enable) {
+			ret =
+			    hisi_cmdlist_add_new_node(hisifd, cmdlist_pre_idxs,
+						      0, 1, 1, 1, 0);
+		} else {
+			ret =
+			    hisi_cmdlist_add_new_node(hisifd, cmdlist_pre_idxs,
+						      0, 0, 0, 0, 0);
+		}
+		if (ret != 0) {
+			HISI_FB_ERR("fb%d, hisi_cmdlist_add_new_node err:%d \n",
+				    hisifd->index, ret);
+			goto err_return;
+		}
+	}
+
+	memset(offline_mmbuf, 0x0, sizeof(offline_mmbuf));
+	cmdlist_idxs_temp = cmdlist_pre_idxs;
+	pov_h_block_infos = (dss_overlay_block_t *) pov_req->ov_block_infos_ptr;
+	for (m = 0; m < pov_req->ov_block_nums; m++) {
+		pov_h_block = &(pov_h_block_infos[m]);
+
+		for (i = 0; i < pov_h_block->layer_nums; i++) {
+			layer = &(pov_h_block->layer_infos[i]);
+			chn_idx = layer->chn_idx;
+			layer_idx = layer->layer_idx;
+
+			if (chn_idx == DSS_RCHN_V2) {
+				mctl_idx = DSS_MCTL5;
+			} else {
+				mctl_idx = ovl_idx;
+			}
+
+			if (layer->need_cap & (CAP_BASE | CAP_DIM | CAP_PURE_COLOR)) {
+				if (layer->need_cap & CAP_BASE)
+					has_base = true;
+
+				continue;
+			}
+
+			if (ovl_idx == DSS_OVL0) {
+				if ((layer->need_cap & CAP_AFBCD)
+				    && (layer->dst_rect.y >=
+					pov_h_block->ov_block_rect.y)) {
+					if (j < DSS_CHN_MAX_DEFINE) {
+						g_pre_online_mmbuf[j].addr =
+						    layer->img.mmbuf_base;
+						g_pre_online_mmbuf[j].size =
+						    layer->img.mmbuf_size;
+						j++;
+					}
+				}
+			}
+
+			if (ovl_idx == DSS_OVL2) {
+				if (layer->need_cap & CAP_AFBCD) {
+					if (j < DSS_CHN_MAX_DEFINE) {
+						offline_mmbuf[j].addr =
+						    layer->img.mmbuf_base;
+						offline_mmbuf[j].size =
+						    layer->img.mmbuf_size;
+						j++;
+					}
+				}
+			}
+
+			if (chn_idx == DSS_RCHN_V2) {
+				tmp = (0x1 << DSS_CMDLIST_V2);
+				hisifd->cmdlist_idx = DSS_CMDLIST_V2;
+			} else {
+				tmp = (0x1 << chn_idx);
+				hisifd->cmdlist_idx = chn_idx;
+			}
+
+			if ((cmdlist_idxs_temp & tmp) != tmp) {
+				continue;
+			} else {
+				cmdlist_idxs_temp &= (~tmp);
+			}
+
+			hisi_dss_chn_set_reg_default_value(hisifd,
+							   dss_module->dma_base[chn_idx]);
+			hisi_dss_smmu_ch_set_reg(hisifd, dss_module->smmu_base,
+						 &(dss_module->smmu), chn_idx);
+			hisi_dss_mif_set_reg(hisifd,
+					     dss_module->mif_ch_base[chn_idx],
+					     &(dss_module->mif[chn_idx]), chn_idx);
+			hisi_dss_aif_ch_set_reg(hisifd,
+						dss_module->aif_ch_base[chn_idx],
+						&(dss_module->aif[chn_idx]));
+
+			dss_module->mctl_ch[chn_idx].chn_mutex =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_mutex,
+				       0x1, 1, 0);
+			dss_module->mctl_ch[chn_idx].chn_flush_en =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_flush_en,
+			    	   0x1, 1, 0);
+			dss_module->mctl_ch[chn_idx].chn_ov_oen =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_ov_oen,
+				       0x0, 32, 0);
+			dss_module->mctl_ch_used[chn_idx] = 1;
+
+			hisi_dss_mctl_sys_ch_set_reg(hisifd,
+						     &(dss_module->mctl_ch_base[chn_idx]),
+						     &(dss_module->mctl_ch[chn_idx]),
+						     chn_idx, false);
+		}
+	}
+
+	if (g_debug_dump_mmbuf) {
+		if (ovl_idx == DSS_OVL0) {
+			for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+				HISI_FB_INFO
+				    ("g_pre_online_mmbuf[%d].addr=%d, size=%d, j=%d\n",
+				     i, g_pre_online_mmbuf[i].addr,
+				     g_pre_online_mmbuf[i].size, j);
+			}
+		}
+	}
+
+	if (pov_req->wb_enable
+	    && ((ovl_idx > DSS_OVL1) || (mctl_idx == DSS_MCTL5))) {
+		if (mctl_idx != DSS_MCTL5) {
+			hisifd->cmdlist_idx = DSS_CMDLIST_OV0 + ovl_idx;
+
+
+			hisi_dss_ov_set_reg_default_value(hisifd,
+							  dss_module->ov_base[ovl_idx],
+							  ovl_idx);
+		}
+
+		for (k = 0; k < pov_req->wb_layer_nums; k++) {
+			wb_layer = &(pov_req->wb_layer_infos[k]);
+			chn_idx = wb_layer->chn_idx;
+			if (wb_layer->transform & HISI_FB_TRANSFORM_ROT_90)
+				has_rot = true;
+
+			if (chn_idx == DSS_WCHN_W2) {
+				hisifd->cmdlist_idx = DSS_CMDLIST_W2;
+			} else {
+				hisifd->cmdlist_idx = chn_idx;
+			}
+
+			hisi_dss_chn_set_reg_default_value(hisifd,
+							   dss_module->dma_base[chn_idx]);
+			hisi_dss_mif_set_reg(hisifd,
+					     dss_module->mif_ch_base[chn_idx],
+					     &(dss_module->mif[chn_idx]), chn_idx);
+			hisi_dss_aif_ch_set_reg(hisifd,
+						dss_module->aif_ch_base[chn_idx],
+						&(dss_module->aif[chn_idx]));
+
+			dss_module->mctl_ch[chn_idx].chn_mutex =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_mutex,
+				       0x1, 1, 0);
+			dss_module->mctl_ch[chn_idx].chn_flush_en =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_flush_en,
+			    	   0x1, 1, 0);
+			dss_module->mctl_ch[chn_idx].chn_ov_oen =
+			    set_bits32(dss_module->mctl_ch[chn_idx].chn_ov_oen,
+				       0x0, 32, 0);
+			dss_module->mctl_ch_used[chn_idx] = 1;
+
+			hisi_dss_mctl_sys_ch_set_reg(hisifd,
+						     &(dss_module->mctl_ch_base[chn_idx]),
+						     &(dss_module->mctl_ch[chn_idx]),
+						     chn_idx, false);
+		}
+
+		if (mctl_idx != DSS_MCTL5) {
+			hisifd->cmdlist_idx = DSS_CMDLIST_OV0 + ovl_idx;
+
+			dss_module->mctl_sys.chn_ov_sel_used[ovl_idx] = 1;
+			dss_module->mctl_sys.wch_ov_sel_used[ovl_idx -
+							     DSS_OVL2] = 1;
+			dss_module->mctl_sys.ov_flush_en_used[ovl_idx] = 1;
+			dss_module->mctl_sys.ov_flush_en[ovl_idx] =
+			    set_bits32(dss_module->mctl_sys.ov_flush_en[ovl_idx],
+			    	   0x1, 1, 0);
+			hisi_dss_mctl_sys_set_reg(hisifd,
+						  dss_module->mctl_sys_base,
+						  &(dss_module->mctl_sys), ovl_idx);
+		}
+
+		for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+			for (k = 0; k < DSS_CHN_MAX_DEFINE; k++) {
+				if ((((offline_mmbuf[i].addr <
+					   g_pre_online_mmbuf[k].addr + g_pre_online_mmbuf[k].size)
+				      && (offline_mmbuf[i].addr >=
+				       g_pre_online_mmbuf[k].addr))
+				     ||
+				      ((g_pre_online_mmbuf[k].addr <
+				       offline_mmbuf[i].addr + offline_mmbuf[i].size)
+				      && (g_pre_online_mmbuf[k].addr >=
+					   offline_mmbuf[i].addr)))
+				    && offline_mmbuf[i].size) {
+					if (use_comm_mmbuf) {
+						*use_comm_mmbuf = true;
+						break;
+					}
+				}
+			}
+		}
+
+		if (g_debug_dump_mmbuf) {
+			for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+				HISI_FB_INFO
+				    ("offline_mmbuf[%d].addr=%d, size=%d, use_comm_mmbuf=%d, j=%d\n",
+				     i, offline_mmbuf[i].addr,
+				     offline_mmbuf[i].size, *use_comm_mmbuf, j);
+			}
+		}
+
+		if (!has_rot) {
+			memset(g_pre_online_mmbuf, 0x0,
+			       sizeof(g_pre_online_mmbuf));
+		}
+	}
+
+	return 0;
+
+ err_return:
+	return ret;
+}
+
+void hisi_dss_unflow_handler(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req, bool unmask)
+{
+	uint32_t tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+	if (pov_req->ovl_idx == DSS_OVL0) {
+		tmp =
+		    inp32(hisifd->dss_base + DSS_LDI0_OFFSET +
+			  LDI_CPU_ITF_INT_MSK);
+		if (unmask) {
+			tmp &= ~BIT_LDI_UNFLOW;
+		} else {
+			tmp |= BIT_LDI_UNFLOW;
+		}
+		outp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK,
+		       tmp);
+
+	} else if (pov_req->ovl_idx == DSS_OVL1) {
+		tmp =
+		    inp32(hisifd->dss_base + DSS_LDI1_OFFSET +
+			  LDI_CPU_ITF_INT_MSK);
+		if (unmask) {
+			tmp &= ~BIT_LDI_UNFLOW;
+		} else {
+			tmp |= BIT_LDI_UNFLOW;
+		}
+		outp32(hisifd->dss_base + DSS_LDI1_OFFSET + LDI_CPU_ITF_INT_MSK,
+		       tmp);
+	} else {
+		;
+	}
+}
+
+/*******************************************************************************
+ ** compose handler
+ */
+int hisi_ov_compose_handler(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req,
+			    dss_overlay_block_t *pov_h_block,
+			    dss_layer_t *layer,
+			    dss_rect_t *wb_dst_rect,
+			    dss_rect_t *wb_ov_block_rect,
+			    dss_rect_ltrb_t *clip_rect,
+			    dss_rect_t *aligned_rect,
+			    bool *rdma_stretch_enable,
+			    bool *has_base,
+			    bool csc_needed, bool enable_cmdlist)
+{
+	int ret = 0;
+	int32_t mctl_idx = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_h_block == NULL);
+	BUG_ON(layer == NULL);
+	BUG_ON(clip_rect == NULL);
+	BUG_ON(aligned_rect == NULL);
+	BUG_ON(rdma_stretch_enable == NULL);
+
+	ret = hisi_dss_check_layer_par(hisifd, layer);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_check_layer_par failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	if (layer->need_cap & (CAP_BASE | CAP_DIM | CAP_PURE_COLOR)) {
+		if (layer->need_cap & CAP_BASE)
+			*has_base = true;
+
+		ret =
+		    hisi_dss_ovl_layer_config(hisifd, pov_req, layer,
+					      wb_ov_block_rect, *has_base);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("hisi_dss_ovl_config failed! need_cap=0x%x, ret=%d\n",
+			     layer->need_cap, ret);
+			goto err_return;
+		}
+
+		ret =
+		    hisi_dss_mctl_ch_config(hisifd, pov_req, layer, NULL,
+					    pov_req->ovl_idx, wb_ov_block_rect,
+					    *has_base);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("hisi_dss_mctl_ch_config failed! ret = %d\n", ret);
+			goto err_return;
+		}
+
+		return ret;
+	}
+
+	if (g_debug_ovl_block_composer) {
+		HISI_FB_INFO
+		    ("layer->dst_rect.y=%d, pov_h_block->ov_block_rect.y=%d,"
+		     "layer->chn_idx=%d, layer->layer_idx=%d\n",
+		     layer->dst_rect.y, pov_h_block->ov_block_rect.y,
+		     layer->chn_idx, layer->layer_idx);
+	}
+
+	if (layer->dst_rect.y < pov_h_block->ov_block_rect.y) {
+		if (g_debug_ovl_block_composer) {
+			HISI_FB_INFO
+			    ("layer->dst_rect.y=%d, pov_h_block->ov_block_rect.y=%d,"
+			     "layer->chn_idx=%d, layer->layer_idx=%d!!!!\n",
+			     layer->dst_rect.y, pov_h_block->ov_block_rect.y,
+			     layer->chn_idx, layer->layer_idx);
+		}
+
+		ret =
+		    hisi_dss_ovl_layer_config(hisifd, pov_req, layer,
+					      wb_ov_block_rect, *has_base);
+		if (ret != 0) {
+			HISI_FB_ERR("hisi_dss_ovl_config failed, ret = %d\n",
+				    ret);
+			goto err_return;
+		}
+
+		ret =
+		    hisi_dss_mctl_ch_config(hisifd, pov_req, layer, NULL,
+					    pov_req->ovl_idx, wb_ov_block_rect,
+					    *has_base);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("hisi_dss_mctl_ch_config failed! ret = %d\n", ret);
+			goto err_return;
+		}
+
+		return ret;
+	}
+
+	ret = hisi_dss_smmu_ch_config(hisifd, layer, NULL);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_smmu_ch_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	if (g_debug_ovl_online_composer) {
+		HISI_FB_INFO
+		    ("fb%d, rdma input, src_rect(%d,%d,%d,%d), "
+		     "src_rect_mask(%d,%d,%d,%d), dst_rect(%d,%d,%d,%d).\n",
+		     hisifd->index, layer->src_rect.x, layer->src_rect.y,
+		     layer->src_rect.w, layer->src_rect.h,
+		     layer->src_rect_mask.x, layer->src_rect_mask.y,
+		     layer->src_rect_mask.w, layer->src_rect_mask.h,
+		     layer->dst_rect.x, layer->dst_rect.y, layer->dst_rect.w,
+		     layer->dst_rect.h);
+	}
+
+	ret = hisi_dss_rdma_config(hisifd, pov_req->ovl_idx, layer,
+				   clip_rect, aligned_rect,
+				   rdma_stretch_enable);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_rdma_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	if (g_debug_ovl_online_composer) {
+		HISI_FB_INFO
+		    ("fb%d, rdma output, clip_rect(%d,%d,%d,%d), "
+		     "aligned_rect(%d,%d,%d,%d), dst_rect(%d,%d,%d,%d).\n",
+		     hisifd->index, clip_rect->left, clip_rect->right,
+		     clip_rect->top, clip_rect->bottom, aligned_rect->x,
+		     aligned_rect->y, aligned_rect->w, aligned_rect->h,
+		     layer->dst_rect.x, layer->dst_rect.y, layer->dst_rect.w,
+		     layer->dst_rect.h);
+	}
+
+	ret =
+	    hisi_dss_aif_ch_config(hisifd, pov_req, layer, wb_dst_rect, NULL,
+				   pov_req->ovl_idx);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_aif_ch_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret =
+	    hisi_dss_aif1_ch_config(hisifd, pov_req, layer, NULL,
+				    pov_req->ovl_idx);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_aif1_ch_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret = hisi_dss_mif_config(hisifd, layer, NULL, *rdma_stretch_enable);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_mif_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret = hisi_dss_rdfc_config(hisifd, layer, aligned_rect, *clip_rect);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_rdfc_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	if (g_debug_ovl_online_composer) {
+		HISI_FB_INFO
+		    ("fb%d, rdfc output, clip_rect(%d,%d,%d,%d), "
+		     "aligned_rect(%d,%d,%d,%d), dst_rect(%d,%d,%d,%d).\n",
+		     hisifd->index, clip_rect->left, clip_rect->right,
+		     clip_rect->top, clip_rect->bottom, aligned_rect->x,
+		     aligned_rect->y, aligned_rect->w, aligned_rect->h,
+		     layer->dst_rect.x, layer->dst_rect.y, layer->dst_rect.w,
+		     layer->dst_rect.h);
+	}
+
+	ret =
+	    hisi_dss_scl_config(hisifd, layer, aligned_rect,
+				*rdma_stretch_enable);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_scl_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+	ret =
+	    hisi_dss_arsr2p_config(hisifd, layer, aligned_rect,
+				   *rdma_stretch_enable);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_arsr2p_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret = hisi_dss_post_clip_config(hisifd, layer);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_post_clip_config failed! ret = %d\n",
+			    ret);
+		goto err_return;
+	}
+
+	if (g_debug_ovl_online_composer) {
+		HISI_FB_INFO
+		    ("fb%d, scf output, clip_rect(%d,%d,%d,%d), "
+		     "aligned_rect(%d,%d,%d,%d), dst_rect(%d,%d,%d,%d).\n",
+		     hisifd->index, clip_rect->left, clip_rect->right,
+		     clip_rect->top, clip_rect->bottom, aligned_rect->x,
+		     aligned_rect->y, aligned_rect->w, aligned_rect->h,
+		     layer->dst_rect.x, layer->dst_rect.y, layer->dst_rect.w,
+		     layer->dst_rect.h);
+	}
+
+	if (csc_needed) {
+		ret = hisi_dss_csc_config(hisifd, layer, NULL);
+		if (ret != 0) {
+			HISI_FB_ERR("hisi_dss_csc_config failed! ret = %d\n",
+				    ret);
+			goto err_return;
+		}
+	}
+
+	ret =
+	    hisi_dss_ovl_layer_config(hisifd, pov_req, layer, wb_ov_block_rect,
+				      *has_base);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_ovl_config failed, ret = %d\n", ret);
+		goto err_return;
+	}
+
+	ret =
+	    hisi_dss_mctl_ch_config(hisifd, pov_req, layer, NULL,
+				    pov_req->ovl_idx, wb_ov_block_rect,
+				    *has_base);
+	if (ret != 0) {
+		HISI_FB_ERR("hisi_dss_mctl_ch_config failed! ret = %d\n", ret);
+		goto err_return;
+	}
+
+	if (layer->chn_idx == DSS_RCHN_V2) {
+		mctl_idx = DSS_MCTL5;
+	} else {
+		mctl_idx = pov_req->ovl_idx;
+	}
+
+	ret =
+	    hisi_dss_ch_module_set_regs(hisifd, mctl_idx, layer->chn_idx, 0,
+					enable_cmdlist);
+	if (ret != 0) {
+		HISI_FB_ERR
+		    ("fb%d, hisi_dss_ch_module_set_regs failed! ret = %d\n",
+		     hisifd->index, ret);
+		goto err_return;
+	}
+
+	return 0;
+
+ err_return:
+	return ret;
+}
+
+/*******************************************************************************
+ **
+ */
+DEFINE_SEMAPHORE(hisi_dss_mmbuf_sem);
+static int mmbuf_refcount = 0;
+static int dss_sr_refcount = 0;
+
+struct hisifb_mmbuf {
+	struct list_head list_node;
+	uint32_t addr;
+	uint32_t size;
+};
+
+static struct list_head *g_mmbuf_list = NULL;
+
+static void hisifb_dss_on(struct hisi_fb_data_type *hisifd, int enable_cmdlist)
+{
+	int prev_refcount = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +.\n", hisifd->index);
+
+	down(&hisi_dss_mmbuf_sem);
+
+	prev_refcount = dss_sr_refcount++;
+	if (!prev_refcount) {
+		hisi_dss_qos_on(hisifd);
+		hisi_dss_mmbuf_on(hisifd);
+		hisi_dss_mif_on(hisifd);
+		hisi_dss_smmu_on(hisifd);
+		hisi_dss_scl_coef_on(hisifd, false, SCL_COEF_YUV_IDX);
+
+		if (enable_cmdlist) {
+			hisi_dss_cmdlist_qos_on(hisifd);
+		}
+	}
+
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("fb%d, -, dss_sr_refcount=%d.\n", hisifd->index,
+		      dss_sr_refcount);
+}
+
+static void hisifb_dss_off(struct hisi_fb_data_type *hisifd, bool is_lp)
+{
+	struct hisifb_mmbuf *node, *_node_;
+	int new_refcount = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +.\n", hisifd->index);
+
+	down(&hisi_dss_mmbuf_sem);
+	new_refcount = --dss_sr_refcount;
+	WARN_ON(new_refcount < 0);
+
+	if (is_lp) {
+		if (!new_refcount) {
+			hisifd->ldi_data_gate_en = 0;
+
+			memset(&(hisifd->ov_block_infos_prev_prev), 0,
+			       HISI_DSS_OV_BLOCK_NUMS *
+			       sizeof(dss_overlay_block_t));
+			memset(&hisifd->ov_req_prev_prev, 0,
+			       sizeof(dss_overlay_t));
+			memset(&(hisifd->ov_block_infos_prev), 0,
+			       HISI_DSS_OV_BLOCK_NUMS *
+			       sizeof(dss_overlay_block_t));
+			memset(&hisifd->ov_req_prev, 0, sizeof(dss_overlay_t));
+			memset(&(hisifd->ov_block_infos), 0,
+			       HISI_DSS_OV_BLOCK_NUMS *
+			       sizeof(dss_overlay_block_t));
+			memset(&hisifd->ov_req, 0, sizeof(dss_overlay_t));
+		}
+	}
+
+	if (!g_mmbuf_list || is_lp) {
+		up(&hisi_dss_mmbuf_sem);
+		return;
+	}
+
+	if (!new_refcount) {
+		list_for_each_entry_safe(node, _node_, g_mmbuf_list, list_node) {
+			if ((node->addr > 0) && (node->size > 0)) {
+				gen_pool_free(hisifd->mmbuf_gen_pool,
+					      node->addr, node->size);
+				HISI_FB_DEBUG
+				    ("hisi_dss_mmbuf_free, addr=0x%x, size=%d.\n",
+				     node->addr, node->size);
+			}
+
+			list_del(&node->list_node);
+			kfree(node);
+		}
+	}
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("fb%d, -, dss_sr_refcount=%d.\n", hisifd->index,
+		      dss_sr_refcount);
+}
+
+void *hisi_dss_mmbuf_init(struct hisi_fb_data_type *hisifd)
+{
+	struct gen_pool *pool = NULL;
+	int order = 3;
+	size_t size = MMBUF_SIZE_MAX;
+	uint32_t addr = MMBUF_BASE;
+	int prev_refcount = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +.\n", hisifd->index);
+
+	down(&hisi_dss_mmbuf_sem);
+
+	prev_refcount = mmbuf_refcount++;
+	if (!prev_refcount) {
+		pool = gen_pool_create(order, 0);
+		if (pool == NULL) {
+			HISI_FB_ERR("fb%d, gen_pool_create failed!",
+				    hisifd->index);
+			goto err_out;
+		}
+
+		if (gen_pool_add(pool, addr, size, 0) != 0) {
+			gen_pool_destroy(pool);
+			HISI_FB_ERR("fb%d, gen_pool_add failed!",
+				    hisifd->index);
+			goto err_out;
+		}
+
+		g_mmbuf_gen_pool = pool;
+
+		if (!g_mmbuf_list) {
+			g_mmbuf_list =
+			    kzalloc(sizeof(struct list_head), GFP_KERNEL);
+			BUG_ON(g_mmbuf_list == NULL);
+			INIT_LIST_HEAD(g_mmbuf_list);
+		}
+#ifdef CONFIG_SMMU_RWERRADDR_USED
+		if (!g_smmu_rwerraddr_virt) {
+			g_smmu_rwerraddr_virt =
+			    kmalloc(SMMU_RW_ERR_ADDR_SIZE,
+				    GFP_KERNEL | __GFP_DMA);
+			if (g_smmu_rwerraddr_virt) {
+				memset(g_smmu_rwerraddr_virt, 0,
+				       SMMU_RW_ERR_ADDR_SIZE);
+			} else {
+				HISI_FB_ERR
+				    ("kmalloc g_smmu_rwerraddr_virt fail.\n");
+			}
+		}
+#endif
+	}
+
+	hisifd->mmbuf_gen_pool = g_mmbuf_gen_pool;
+	hisifd->mmbuf_list = g_mmbuf_list;
+
+ err_out:
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("fb%d, -, mmbuf_refcount=%d.\n", hisifd->index,
+		      mmbuf_refcount);
+
+	return pool;
+}
+
+void hisi_dss_mmbuf_deinit(struct hisi_fb_data_type *hisifd)
+{
+	int new_refcount = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +.\n", hisifd->index);
+
+	hisifb_dss_off(hisifd, false);
+
+	down(&hisi_dss_mmbuf_sem);
+	new_refcount = --mmbuf_refcount;
+	WARN_ON(new_refcount < 0);
+
+	if (!new_refcount) {
+		if (g_mmbuf_gen_pool) {
+			gen_pool_destroy(g_mmbuf_gen_pool);
+			g_mmbuf_gen_pool = NULL;
+		}
+
+		if (g_mmbuf_list) {
+			kfree(g_mmbuf_list);
+			g_mmbuf_list = NULL;
+		}
+#ifdef CONFIG_SMMU_RWERRADDR_USED
+		if (g_smmu_rwerraddr_virt) {
+			kfree(g_smmu_rwerraddr_virt);
+			g_smmu_rwerraddr_virt = NULL;
+		}
+#endif
+	}
+
+	hisifd->mmbuf_gen_pool = NULL;
+	hisifd->mmbuf_list = NULL;
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("fb%d, -, mmbuf_refcount=%d.\n", hisifd->index,
+		      mmbuf_refcount);
+}
+
+uint32_t hisi_dss_mmbuf_alloc(void *handle, uint32_t size)
+{
+	uint32_t addr = 0;
+	struct hisifb_mmbuf *node = NULL;
+	struct hisifb_mmbuf *mmbuf_node, *_node_;
+
+	if (NULL == handle) {
+		HISI_FB_ERR("handle is NULL!\n");
+		return addr;
+	}
+
+	if (NULL == g_mmbuf_list) {
+		HISI_FB_ERR("g_mmbuf_list is NULL!\n");
+		return addr;
+	}
+
+	if (size <= 0 || size > MMBUF_SIZE_MAX) {
+		HISI_FB_ERR("mmbuf size is invalid, size=%d!\n", size);
+		return addr;
+	}
+
+	down(&hisi_dss_mmbuf_sem);
+
+	addr = gen_pool_alloc(handle, size);
+	if (addr <= 0) {
+		HISI_FB_INFO("note: mmbuf not enough,addr=0x%x\n", addr);
+	} else {
+		node = kzalloc(sizeof(struct hisifb_mmbuf), GFP_KERNEL);
+		if (node) {
+			node->addr = addr;
+			node->size = size;
+			list_add_tail(&node->list_node, g_mmbuf_list);
+		} else {
+			HISI_FB_ERR("kzalloc struct hisifb_mmbuf fail!\n");
+		}
+
+		if ((addr & (MMBUF_ADDR_ALIGN - 1))
+		    || (size & (MMBUF_ADDR_ALIGN - 1))) {
+			HISI_FB_ERR
+			    ("addr(0x%x) is not %d bytes aligned, "
+			     "or size(0x%x) is not %d bytes"
+			     "aligned!\n", addr, MMBUF_ADDR_ALIGN, size,
+			     MMBUF_ADDR_ALIGN);
+
+			list_for_each_entry_safe(mmbuf_node, _node_,
+						 g_mmbuf_list, list_node) {
+				HISI_FB_ERR
+				    ("mmbuf_node_addr(0x%x), mmbuf_node_size(0x%x)!\n",
+				     mmbuf_node->addr, mmbuf_node->size);
+			}
+		}
+	}
+
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("addr=0x%x, size=%d.\n", addr, size);
+
+	return addr;
+}
+
+void hisi_dss_mmbuf_free(void *handle, uint32_t addr, uint32_t size)
+{
+	struct hisifb_mmbuf *node, *_node_;
+
+	if (NULL == handle) {
+		HISI_FB_ERR("handle is NULL!\n");
+		return;
+	}
+
+	if (NULL == g_mmbuf_list) {
+		HISI_FB_ERR("g_mmbuf_list is NULL!\n");
+		return;
+	}
+
+	down(&hisi_dss_mmbuf_sem);
+
+	list_for_each_entry_safe(node, _node_, g_mmbuf_list, list_node) {
+		if ((node->addr == addr) && (node->size == size)) {
+			gen_pool_free(handle, addr, size);
+			list_del(&node->list_node);
+			kfree(node);
+		}
+	}
+
+	up(&hisi_dss_mmbuf_sem);
+
+	HISI_FB_DEBUG("addr=0x%x, size=%d.\n", addr, size);
+}
+
+void hisi_dss_mmbuf_info_clear(struct hisi_fb_data_type *hisifd, int idx)
+{
+	int i = 0;
+	dss_mmbuf_info_t *mmbuf_info = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((idx < 0) || (idx >= HISI_DSS_CMDLIST_DATA_MAX));
+
+	mmbuf_info = &(hisifd->mmbuf_infos[idx]);
+	for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+		if (mmbuf_info->mm_used[i] == 1) {
+			hisi_dss_mmbuf_free(g_mmbuf_gen_pool,
+					    mmbuf_info->mm_base[i],
+					    mmbuf_info->mm_size[i]);
+
+			if (g_debug_ovl_online_composer) {
+				HISI_FB_INFO("fb%d, mm_base(0x%x, %d).\n",
+					     hisifd->index,
+					     mmbuf_info->mm_base[i],
+					     mmbuf_info->mm_size[i]);
+			}
+
+			mmbuf_info->mm_base[i] = 0;
+			mmbuf_info->mm_size[i] = 0;
+			mmbuf_info->mm_used[i] = 0;
+		}
+	}
+}
+
+void hisi_mmbuf_info_get_online(struct hisi_fb_data_type *hisifd)
+{
+	int tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	tmp = (hisifd->frame_count + 1) % HISI_DSS_CMDLIST_DATA_MAX;
+	hisi_dss_mmbuf_info_clear(hisifd, tmp);
+
+	tmp = hisifd->frame_count % HISI_DSS_CMDLIST_DATA_MAX;
+	hisifd->mmbuf_info = &(hisifd->mmbuf_infos[tmp]);
+}
+
+/*******************************************************************************
+ **
+ */
+void hisi_dss_mmbuf_on(struct hisi_fb_data_type *hisifd)
+{
+	BUG_ON(hisifd == NULL);
+#if 0
+	outp32(hisifd->mmbuf_crg_base + SMC_LOCK, 0x5A5A5A5A);
+	outp32(hisifd->mmbuf_crg_base + SMC_MEM_LP, 0x00000712);
+#endif
+}
+
+static int hisi_overlay_fastboot(struct hisi_fb_data_type *hisifd)
+{
+	dss_overlay_t *pov_req_prev = NULL;
+	dss_overlay_block_t *pov_h_block_infos = NULL;
+	dss_overlay_block_t *pov_h_block = NULL;
+	dss_layer_t *layer = NULL;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +\n", hisifd->index);
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		pov_req_prev = &(hisifd->ov_req_prev);
+		memset(pov_req_prev, 0, sizeof(dss_overlay_t));
+		pov_req_prev->ov_block_infos_ptr =
+		    (uint64_t) (&(hisifd->ov_block_infos_prev));
+		pov_req_prev->ov_block_nums = 1;
+		pov_req_prev->ovl_idx = DSS_OVL0;
+
+		pov_h_block_infos =
+		    (dss_overlay_block_t *) pov_req_prev->ov_block_infos_ptr;
+		pov_h_block = &(pov_h_block_infos[0]);
+		pov_h_block->layer_nums = 1;
+
+		layer = &(pov_h_block->layer_infos[0]);
+		layer->img.mmu_enable = 0;
+		layer->layer_idx = 0x0;
+		layer->chn_idx = DSS_RCHN_D0;
+		layer->need_cap = 0;
+
+		memcpy(&(hisifd->dss_module_default.rdma[DSS_RCHN_D0]),
+		       &(hisifd->dss_module_default.rdma[DSS_RCHN_D3]),
+		       sizeof(dss_rdma_t));
+		memcpy(&(hisifd->dss_module_default.dfc[DSS_RCHN_D0]),
+		       &(hisifd->dss_module_default.dfc[DSS_RCHN_D3]),
+		       sizeof(dss_dfc_t));
+		memcpy(&(hisifd->dss_module_default.ov[DSS_OVL0].ovl_layer[0]),
+		       &(hisifd->dss_module_default.ov[DSS_OVL0].ovl_layer[1]),
+		       sizeof(dss_ovl_layer_t));
+
+		memset(&(hisifd->dss_module_default.mctl_ch[DSS_RCHN_D0]), 0,
+		       sizeof(dss_mctl_ch_t));
+		memset(&(hisifd->dss_module_default.mctl[DSS_OVL0]), 0,
+		       sizeof(dss_mctl_t));
+
+		hisifd->dss_module_default.mctl_sys.chn_ov_sel[DSS_OVL0] =
+		    0xFFFFFFFF;
+		hisifd->dss_module_default.mctl_sys.ov_flush_en[DSS_OVL0] = 0x0;
+
+		if (is_mipi_cmd_panel(hisifd)) {
+			if (hisifd->vactive0_start_flag == 0) {
+				hisifd->vactive0_start_flag = 1;
+				hisifd->vactive0_end_flag = 1;
+			}
+		}
+	}
+
+	HISI_FB_DEBUG("fb%d, -\n", hisifd->index);
+
+	return 0;
+}
+
+int hisi_overlay_on(struct hisi_fb_data_type *hisifd, bool fastboot_enable)
+{
+	int ret = 0;
+	int ovl_idx = 0;
+	int mctl_idx = 0;
+	uint32_t cmdlist_idxs = 0;
+	int enable_cmdlist = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_DEBUG("fb%d, +\n", hisifd->index);
+
+	memset(&(hisifd->sbl), 0, sizeof(dss_sbl_t));
+	hisifd->sbl_enable = 0;
+	hisifd->sbl_lsensor_value = 0;
+	hisifd->sbl_level = 0;
+
+	hisifd->vactive0_start_flag = 0;
+	hisifd->vactive0_end_flag = 0;
+	hisifd->crc_flag = 0;
+
+	hisifd->dirty_region_updt.x = 0;
+	hisifd->dirty_region_updt.y = 0;
+	hisifd->dirty_region_updt.w = hisifd->panel_info.xres;
+	hisifd->dirty_region_updt.h = hisifd->panel_info.yres;
+
+	hisifd->resolution_rect.x = 0;
+	hisifd->resolution_rect.y = 0;
+	hisifd->resolution_rect.w = hisifd->panel_info.xres;
+	hisifd->resolution_rect.h = hisifd->panel_info.yres;
+
+	hisifd->res_updt_rect.x = 0;
+	hisifd->res_updt_rect.y = 0;
+	hisifd->res_updt_rect.w = hisifd->panel_info.xres;
+	hisifd->res_updt_rect.h = hisifd->panel_info.yres;
+
+	memset(&hisifd->ov_req, 0, sizeof(dss_overlay_t));
+	hisifd->ov_req.frame_no = 0xFFFFFFFF;
+
+	g_offline_cmdlist_idxs = 0;
+
+#if 0
+	if (g_dss_module_resource_initialized == 0) {
+		hisi_dss_module_default(hisifd);
+		g_dss_module_resource_initialized = 1;
+		hisifd->dss_module_resource_initialized = true;
+	}
+
+	if (!hisifd->dss_module_resource_initialized) {
+		if (hisifd->index != PRIMARY_PANEL_IDX) {
+			memcpy(&(hisifd->dss_module_default),
+			       &(hisifd_list[PRIMARY_PANEL_IDX]->
+				 dss_module_default), sizeof(dss_module_reg_t));
+		}
+		hisifd->dss_module_resource_initialized = true;
+	}
+#else
+	if ((hisifd->index == PRIMARY_PANEL_IDX) ||
+	    (hisifd->index == EXTERNAL_PANEL_IDX)) {
+		hisifb_activate_vsync(hisifd);
+	}
+
+	if (g_dss_module_resource_initialized == 0) {
+		hisi_dss_module_default(hisifd);
+		g_dss_module_resource_initialized = 1;
+		hisifd->dss_module_resource_initialized = true;
+	} else {
+		if (!hisifd->dss_module_resource_initialized) {
+			if (hisifd->index != PRIMARY_PANEL_IDX) {
+				if (hisifd_list[PRIMARY_PANEL_IDX]) {
+					memcpy(&(hisifd->dss_module_default),
+					       &(hisifd_list
+						 [PRIMARY_PANEL_IDX]->
+						 dss_module_default),
+					       sizeof(dss_module_reg_t));
+				}
+			}
+			hisifd->dss_module_resource_initialized = true;
+		}
+	}
+#endif
+
+	enable_cmdlist = g_enable_ovl_cmdlist_online;
+	hisifb_dss_on(hisifd, enable_cmdlist);
+
+	if ((hisifd->index == PRIMARY_PANEL_IDX) ||
+	    (hisifd->index == EXTERNAL_PANEL_IDX)) {
+		if (hisifd->index == PRIMARY_PANEL_IDX) {
+			ovl_idx = DSS_OVL0;
+			mctl_idx = DSS_MCTL0;
+		} else {
+			ovl_idx = DSS_OVL1;
+			mctl_idx = DSS_MCTL1;
+		}
+
+		if ((hisifd->index == EXTERNAL_PANEL_IDX)
+		    && hisifd->panel_info.fake_hdmi)
+			enable_cmdlist = 0;
+
+		ldi_data_gate(hisifd, true);
+
+		hisi_dss_mctl_on(hisifd, mctl_idx, enable_cmdlist,
+				 fastboot_enable);
+
+		if (fastboot_enable) {
+			hisi_overlay_fastboot(hisifd);
+		} else {
+			ret = hisi_dss_module_init(hisifd);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, failed to hisi_dss_module_init! ret = %d\n",
+				     hisifd->index, ret);
+				goto err_out;
+			}
+
+			if (enable_cmdlist) {
+				hisifd->set_reg = hisi_cmdlist_set_reg;
+
+				hisi_cmdlist_data_get_online(hisifd);
+
+				cmdlist_idxs =
+				    (0x1 << (ovl_idx + DSS_CMDLIST_OV0));
+				hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs,
+							  0, 0);
+			} else {
+				hisifd->set_reg = hisifb_set_reg;
+
+				hisi_dss_mctl_mutex_lock(hisifd, ovl_idx);
+			}
+
+			hisifd->ov_req_prev.ovl_idx = ovl_idx;
+
+			ret =
+			    hisi_dss_ovl_base_config(hisifd, NULL, NULL, NULL,
+						     ovl_idx, 0);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, faile to hisi_dss_ovl_base_config! ret=%d\n",
+				     hisifd->index, ret);
+				goto err_out;
+			}
+
+			ret =
+			    hisi_dss_mctl_ov_config(hisifd, NULL, ovl_idx,
+						    false, true);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, faile to hisi_dss_mctl_config! ret=%d\n",
+				     hisifd->index, ret);
+				goto err_out;
+			}
+
+			ret =
+			    hisi_dss_ov_module_set_regs(hisifd, NULL, ovl_idx,
+							enable_cmdlist, 1, 0,
+							true);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, failed to hisi_dss_module_config! ret = %d\n",
+				     hisifd->index, ret);
+				goto err_out;
+			}
+
+			if (enable_cmdlist) {
+				hisi_cmdlist_flush_cache(hisifd,
+							 hisifd->ion_client,
+							 cmdlist_idxs);
+				hisi_cmdlist_config_start(hisifd, mctl_idx,
+							  cmdlist_idxs, 0);
+			} else {
+				hisi_dss_mctl_mutex_unlock(hisifd, ovl_idx);
+			}
+
+			single_frame_update(hisifd);
+			enable_ldi(hisifd);
+			hisifb_frame_updated(hisifd);
+			hisifd->frame_count++;
+
+			if (g_debug_ovl_cmdlist) {
+				hisi_cmdlist_dump_all_node(hisifd, NULL,
+							   cmdlist_idxs);
+			}
+		}
+ err_out:
+		hisifb_deactivate_vsync(hisifd);
+	} else if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		enable_cmdlist = g_enable_ovl_cmdlist_offline;
+
+		hisi_dss_mctl_on(hisifd, DSS_MCTL2, enable_cmdlist, 0);
+		hisi_dss_mctl_on(hisifd, DSS_MCTL3, enable_cmdlist, 0);
+		hisi_dss_mctl_on(hisifd, DSS_MCTL5, enable_cmdlist, 0);
+	} else {
+		HISI_FB_ERR("fb%d, not supported!", hisifd->index);
+	}
+
+	HISI_FB_DEBUG("fb%d, -\n", hisifd->index);
+
+	return 0;
+}
+
+int hisi_overlay_off(struct hisi_fb_data_type *hisifd)
+{
+	int ret = 0;
+	int ovl_idx = 0;
+	uint32_t cmdlist_pre_idxs = 0;
+	uint32_t cmdlist_idxs = 0;
+	int enable_cmdlist = 0;
+	dss_overlay_t *pov_req_prev = NULL;
+
+	BUG_ON(hisifd == NULL);
+
+	pov_req_prev = &(hisifd->ov_req_prev);
+
+	HISI_FB_DEBUG("fb%d, +\n", hisifd->index);
+
+	if ((hisifd->index == PRIMARY_PANEL_IDX) ||
+	    (hisifd->index == EXTERNAL_PANEL_IDX)) {
+		hisifb_activate_vsync(hisifd);
+
+		ret = hisi_vactive0_start_config(hisifd, pov_req_prev);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_vactive0_start_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		if (hisifd->aod_function == 1) {
+			HISI_FB_INFO("fb%d, aod mode\n", hisifd->index);
+			goto err_out;
+		}
+
+		if (hisifd->index == PRIMARY_PANEL_IDX) {
+			ovl_idx = DSS_OVL0;
+		} else {
+			ovl_idx = DSS_OVL1;
+		}
+
+		enable_cmdlist = g_enable_ovl_cmdlist_online;
+		if ((hisifd->index == EXTERNAL_PANEL_IDX)
+		    && hisifd->panel_info.fake_hdmi)
+			enable_cmdlist = 0;
+
+		ret = hisi_dss_module_init(hisifd);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, failed to hisi_dss_module_init! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		if (enable_cmdlist) {
+			hisifd->set_reg = hisi_cmdlist_set_reg;
+
+			hisi_cmdlist_data_get_online(hisifd);
+
+			ret =
+			    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev,
+							  &cmdlist_pre_idxs,
+							  NULL);
+			if (ret != 0) {
+				HISI_FB_ERR
+				    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+				     "pov_req_prev failed! ret = %d\n",
+				     hisifd->index, ret);
+				goto err_out;
+			}
+
+			cmdlist_idxs = (1 << (DSS_CMDLIST_OV0 + ovl_idx));
+			cmdlist_pre_idxs &= (~(cmdlist_idxs));
+
+			hisi_cmdlist_add_nop_node(hisifd, cmdlist_pre_idxs, 0,
+						  0);
+			hisi_cmdlist_add_nop_node(hisifd, cmdlist_idxs, 0, 0);
+		} else {
+			hisifd->set_reg = hisifb_set_reg;
+
+			hisi_dss_mctl_mutex_lock(hisifd, ovl_idx);
+			cmdlist_pre_idxs = ~0;
+		}
+
+		hisi_dss_prev_module_set_regs(hisifd, pov_req_prev,
+					      cmdlist_pre_idxs, enable_cmdlist,
+					      NULL);
+
+		ret =
+		    hisi_dss_ovl_base_config(hisifd, NULL, NULL, NULL, ovl_idx,
+					     0);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, faile to hisi_dss_ovl_base_config! ret=%d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		ret =
+		    hisi_dss_mctl_ov_config(hisifd, NULL, ovl_idx, false, true);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, faile to hisi_dss_mctl_config! ret=%d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		ret = hisi_dss_dirty_region_dbuf_config(hisifd, NULL);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, hisi_dss_dirty_region_dbuf_config failed! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		ret =
+		    hisi_dss_ov_module_set_regs(hisifd, NULL, ovl_idx,
+						enable_cmdlist, 1, 0, true);
+		if (ret != 0) {
+			HISI_FB_ERR
+			    ("fb%d, failed to hisi_dss_module_config! ret = %d\n",
+			     hisifd->index, ret);
+			goto err_out;
+		}
+
+		if (enable_cmdlist) {
+			hisi_cmdlist_config_stop(hisifd, cmdlist_pre_idxs);
+
+			cmdlist_idxs |= cmdlist_pre_idxs;
+			hisi_cmdlist_flush_cache(hisifd, hisifd->ion_client,
+						 cmdlist_idxs);
+
+			if (g_debug_ovl_cmdlist) {
+				hisi_cmdlist_dump_all_node(hisifd, NULL,
+							   cmdlist_idxs);
+			}
+
+			hisi_cmdlist_config_start(hisifd, ovl_idx, cmdlist_idxs, 0);
+		} else {
+			hisi_dss_mctl_mutex_unlock(hisifd, ovl_idx);
+		}
+
+		if (hisifd->panel_info.dirty_region_updt_support) {
+			hisi_dss_dirty_region_updt_config(hisifd, NULL);
+		}
+
+		ldi_data_gate(hisifd, true);
+
+		single_frame_update(hisifd);
+		hisifb_frame_updated(hisifd);
+
+		if (!hisi_dss_check_reg_reload_status(hisifd)) {
+			mdelay(20);
+		}
+
+		ldi_data_gate(hisifd, false);
+
+		if (is_mipi_cmd_panel(hisifd)) {
+			hisifd->ldi_data_gate_en = 1;
+		}
+
+		hisifd->frame_count++;
+ err_out:
+		hisifb_deactivate_vsync(hisifd);
+	} else if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		;
+	} else {
+		HISI_FB_ERR("fb%d, not support !\n", hisifd->index);
+		BUG_ON(1);
+	}
+
+	if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		hisifb_dss_off(hisifd, true);
+	} else {
+		hisifb_dss_off(hisifd, false);
+	}
+
+	hisifd->ldi_data_gate_en = 0;
+
+	memset(&(hisifd->ov_block_infos_prev_prev), 0,
+	       HISI_DSS_OV_BLOCK_NUMS * sizeof(dss_overlay_block_t));
+	memset(&hisifd->ov_req_prev_prev, 0, sizeof(dss_overlay_t));
+	memset(&(hisifd->ov_block_infos_prev), 0,
+	       HISI_DSS_OV_BLOCK_NUMS * sizeof(dss_overlay_block_t));
+	memset(&hisifd->ov_req_prev, 0, sizeof(dss_overlay_t));
+	memset(&(hisifd->ov_block_infos), 0,
+	       HISI_DSS_OV_BLOCK_NUMS * sizeof(dss_overlay_block_t));
+	memset(&hisifd->ov_req, 0, sizeof(dss_overlay_t));
+
+	HISI_FB_DEBUG("fb%d, -\n", hisifd->index);
+
+	return 0;
+}
+
+bool hisi_dss_check_reg_reload_status(struct hisi_fb_data_type *hisifd)
+{
+	mdelay(50);
+
+	return true;
+}
+
+bool hisi_dss_check_crg_sctrl_status(struct hisi_fb_data_type *hisifd)
+{
+	uint32_t crg_state_check = 0;
+	uint32_t sctrl_mmbuf_dss_check = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	crg_state_check = inp32(hisifd->peri_crg_base + PERCLKEN3);
+	if ((crg_state_check & 0x23000) != 0x23000) {
+		HISI_FB_ERR
+		    ("dss crg_clk_enable failed, crg_state_check = 0x%x\n",
+		     crg_state_check);
+		return false;
+	}
+
+	crg_state_check = inp32(hisifd->peri_crg_base + PERRSTSTAT3);
+	if ((crg_state_check | 0xfffff3ff) != 0xfffff3ff) {
+		HISI_FB_ERR("dss crg_reset failed, crg_state_check = 0x%x\n",
+			    crg_state_check);
+		return false;
+	}
+
+	crg_state_check = inp32(hisifd->peri_crg_base + ISOSTAT);
+	if ((crg_state_check | 0xffffffbf) != 0xffffffbf) {
+		HISI_FB_ERR("dss iso_disable failed, crg_state_check = 0x%x\n",
+			    crg_state_check);
+		return false;
+	}
+
+	crg_state_check = inp32(hisifd->peri_crg_base + PERPWRSTAT);
+	if ((crg_state_check & 0x20) != 0x20) {
+		HISI_FB_ERR
+		    ("dss subsys regulator_enabel failed, crg_state_check = 0x%x\n",
+		     crg_state_check);
+		return false;
+	}
+
+	sctrl_mmbuf_dss_check = inp32(hisifd->sctrl_base + SCPERCLKEN1);
+	if ((sctrl_mmbuf_dss_check & 0x1000000) != 0x1000000) {
+		HISI_FB_ERR
+		    ("dss subsys mmbuf_dss_clk_enable failed, sctrl_mmbuf_dss_check = 0x%x\n",
+		     sctrl_mmbuf_dss_check);
+		return false;
+	}
+
+	return true;
+}
+
+int hisi_overlay_ioctl_handler(struct hisi_fb_data_type *hisifd,
+			       uint32_t cmd, void __user *argp)
+{
+	int ret = 0;
+	uint32_t timediff = 0;
+	struct timeval tv0;
+	struct timeval tv1;
+	struct hisi_panel_info *pinfo = NULL;
+
+	if (NULL == hisifd) {
+		HISI_FB_ERR("NULL Pointer\n");
+		return -EINVAL;
+	}
+	pinfo = &(hisifd->panel_info);
+
+	switch (cmd) {
+	case HISIFB_OV_ONLINE_PLAY:
+		if (hisifd->ov_online_play) {
+			if (g_debug_ovl_online_composer_timediff & 0x1)
+				hisifb_get_timestamp(&tv0);
+
+			down(&hisifd->blank_sem);
+			ret = hisifd->ov_online_play(hisifd, argp);
+			if (ret != 0) {
+				HISI_FB_ERR("fb%d ov_online_play failed!\n",
+					    hisifd->index);
+			}
+			up(&hisifd->blank_sem);
+
+			if (g_debug_ovl_online_composer_timediff & 0x1) {
+				hisifb_get_timestamp(&tv1);
+				timediff = hisifb_timestamp_diff(&tv0, &tv1);
+				if (timediff >=
+				    g_debug_ovl_online_composer_time_threshold)
+					HISI_FB_ERR
+					    ("ONLING_IOCTL_TIMEDIFF is %u us!\n",
+					     timediff);
+			}
+
+			if (ret == 0) {
+				if (hisifd->bl_update) {
+					hisifd->bl_update(hisifd);
+				}
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int hisi_overlay_init(struct hisi_fb_data_type *hisifd)
+{
+	char wq_name[128] = { 0 };
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(hisifd->dss_base == NULL);
+
+	hisifd->dss_module_resource_initialized = false;
+
+	hisifd->vactive0_start_flag = 0;
+	hisifd->vactive0_end_flag = 0;
+	init_waitqueue_head(&hisifd->vactive0_start_wq);
+	hisifd->ldi_data_gate_en = 0;
+
+	hisifd->crc_flag = 0;
+
+	hisifd->frame_update_flag = 0;
+
+	memset(&hisifd->ov_req, 0, sizeof(dss_overlay_t));
+	memset(&hisifd->dss_module, 0, sizeof(dss_module_reg_t));
+	memset(&hisifd->dss_module_default, 0, sizeof(dss_module_reg_t));
+
+	hisifd->dirty_region_updt.x = 0;
+	hisifd->dirty_region_updt.y = 0;
+	hisifd->dirty_region_updt.w = hisifd->panel_info.xres;
+	hisifd->dirty_region_updt.h = hisifd->panel_info.yres;
+
+	hisifd->resolution_rect.x = 0;
+	hisifd->resolution_rect.y = 0;
+	hisifd->resolution_rect.w = hisifd->panel_info.xres;
+	hisifd->resolution_rect.h = hisifd->panel_info.yres;
+
+	hisifd->res_updt_rect.x = 0;
+	hisifd->res_updt_rect.y = 0;
+	hisifd->res_updt_rect.w = hisifd->panel_info.xres;
+	hisifd->res_updt_rect.h = hisifd->panel_info.yres;
+
+	hisifd->pan_display_fnc = hisi_overlay_pan_display;
+	hisifd->ov_ioctl_handler = hisi_overlay_ioctl_handler;
+
+	hisifd->dss_debug_wq = NULL;
+	hisifd->ldi_underflow_wq = NULL;
+	hisifd->rch2_ce_end_wq = NULL;
+	hisifd->rch4_ce_end_wq = NULL;
+	hisifd->dpp_ce_end_wq = NULL;
+	hisifd->hiace_end_wq = NULL;
+
+	if ((hisifd->index == PRIMARY_PANEL_IDX) ||
+	    (hisifd->index == EXTERNAL_PANEL_IDX
+	     && !hisifd->panel_info.fake_hdmi)) {
+		snprintf(wq_name, 128, "fb%d_dss_debug", hisifd->index);
+		hisifd->dss_debug_wq = create_singlethread_workqueue(wq_name);
+		if (!hisifd->dss_debug_wq) {
+			HISI_FB_ERR
+			    ("fb%d, create dss debug workqueue failed!\n",
+			     hisifd->index);
+			return -EINVAL;
+		}
+		INIT_WORK(&hisifd->dss_debug_work, hisi_dss_debug_func);
+
+		snprintf(wq_name, 128, "fb%d_ldi_underflow", hisifd->index);
+		hisifd->ldi_underflow_wq =
+		    create_singlethread_workqueue(wq_name);
+		if (!hisifd->ldi_underflow_wq) {
+			HISI_FB_ERR
+			    ("fb%d, create ldi underflow workqueue failed!\n",
+			     hisifd->index);
+			return -EINVAL;
+		}
+		INIT_WORK(&hisifd->ldi_underflow_work,
+			  hisi_ldi_underflow_handle_func);
+	}
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		hisifd->set_reg = hisi_cmdlist_set_reg;
+		hisifd->ov_online_play = hisi_ov_online_play;
+		hisifd->ov_wb_isr_handler = NULL;
+		hisifd->ov_vactive0_start_isr_handler =
+		    hisi_vactive0_start_isr_handler;
+
+		hisifd->crc_isr_handler = NULL;
+
+	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
+		hisifd->set_reg = hisifb_set_reg;
+		hisifd->ov_online_play = hisi_ov_online_play;
+		hisifd->ov_wb_isr_handler = NULL;
+		hisifd->ov_vactive0_start_isr_handler =
+		    hisi_vactive0_start_isr_handler;
+
+		hisifd->crc_isr_handler = NULL;
+	} else if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		hisifd->set_reg = hisi_cmdlist_set_reg;
+		hisifd->ov_online_play = NULL;
+		hisifd->ov_wb_isr_handler = NULL;
+		hisifd->ov_vactive0_start_isr_handler = NULL;
+
+		hisifd->crc_isr_handler = NULL;
+	} else {
+		HISI_FB_ERR("fb%d not support this device!\n", hisifd->index);
+		return -EINVAL;
+	}
+
+	hisi_cmdlist_init(hisifd);
+
+	hisi_dss_mmbuf_init(hisifd);
+
+	return 0;
+}
+
+int hisi_overlay_deinit(struct hisi_fb_data_type *hisifd)
+{
+	BUG_ON(hisifd == NULL);
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+	}
+
+	if (hisifd->rch4_ce_end_wq) {
+		destroy_workqueue(hisifd->rch4_ce_end_wq);
+		hisifd->rch4_ce_end_wq = NULL;
+	}
+
+	if (hisifd->rch2_ce_end_wq) {
+		destroy_workqueue(hisifd->rch2_ce_end_wq);
+		hisifd->rch2_ce_end_wq = NULL;
+	}
+
+	if (hisifd->dpp_ce_end_wq) {
+		destroy_workqueue(hisifd->dpp_ce_end_wq);
+		hisifd->dpp_ce_end_wq = NULL;
+	}
+
+	if (hisifd->hiace_end_wq) {
+		destroy_workqueue(hisifd->hiace_end_wq);
+		hisifd->hiace_end_wq = NULL;
+	}
+
+	if (hisifd->dss_debug_wq) {
+		destroy_workqueue(hisifd->dss_debug_wq);
+		hisifd->dss_debug_wq = NULL;
+	}
+
+	if (hisifd->ldi_underflow_wq) {
+		destroy_workqueue(hisifd->ldi_underflow_wq);
+		hisifd->ldi_underflow_wq = NULL;
+	}
+
+	hisi_cmdlist_deinit(hisifd);
+
+	hisi_dss_mmbuf_deinit(hisifd);
+
+	return 0;
+}
+
+void hisi_vactive0_start_isr_handler(struct hisi_fb_data_type *hisifd)
+{
+	BUG_ON(hisifd == NULL);
+
+	if (is_mipi_cmd_panel(hisifd) && (hisifd->frame_update_flag == 0)) {
+		hisifd->vactive0_start_flag = 1;
+	} else {
+		hisifd->vactive0_start_flag++;
+	}
+
+	wake_up_interruptible_all(&hisifd->vactive0_start_wq);
+}
+
+int hisi_vactive0_start_config(struct hisi_fb_data_type *hisifd,
+			       dss_overlay_t *pov_req)
+{
+	int ret = 0;
+	int ret1 = 0;
+	int times = 0;
+	uint32_t prev_vactive0_start = 0;
+	uint32_t isr_s1 = 0;
+	uint32_t isr_s2 = 0;
+	uint32_t isr_s2_mask = 0;
+	char __iomem *ldi_base = NULL;
+	struct timeval tv0;
+	struct timeval tv1;
+	dss_overlay_t *pov_req_dump = NULL;
+	dss_overlay_t *pov_req_prev = NULL;
+	dss_overlay_t *pov_req_prev_prev = NULL;
+	uint32_t cmdlist_idxs = 0;
+	uint32_t cmdlist_idxs_prev = 0;
+	uint32_t cmdlist_idxs_prev_prev = 0;
+	uint32_t read_value[4] = { 0 };
+	uint32_t ldi_vstate = 0;
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	pov_req_prev = &(hisifd->ov_req_prev);
+	pov_req_prev_prev = &(hisifd->ov_req_prev_prev);
+	if (is_mipi_cmd_panel(hisifd) && (hisifd->frame_update_flag == 0)) {
+		pov_req_dump = &(hisifd->ov_req_prev_prev);
+		if (hisifd->vactive0_start_flag == 1) {
+			hisifd->vactive0_start_flag = 0;
+			single_frame_update(hisifd);
+		}
+
+		if (hisifd->vactive0_start_flag == 0) {
+			hisifb_get_timestamp(&tv0);
+
+ REDO_0:
+			ret =
+			    wait_event_interruptible_timeout(hisifd->vactive0_start_wq,
+							     hisifd->vactive0_start_flag,
+							     msecs_to_jiffies
+							     (DSS_COMPOSER_TIMEOUT_THRESHOLD_ASIC));
+			if (ret == -ERESTARTSYS) {
+				if (times < 50) {
+					times++;
+					mdelay(10);
+					goto REDO_0;
+				}
+			}
+			times = 0;
+
+			if (ret <= 0) {
+				hisifb_get_timestamp(&tv1);
+
+				ret1 =
+				    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev,
+								  &cmdlist_idxs_prev,
+								  NULL);
+				if (ret1 != 0) {
+					HISI_FB_INFO
+					    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+					     "pov_req_prev failed! ret = %d\n",
+					     hisifd->index, ret1);
+				}
+
+				ret1 =
+				    hisi_cmdlist_get_cmdlist_idxs
+				    (pov_req_prev_prev, &cmdlist_idxs_prev_prev,
+				     NULL);
+				if (ret1 != 0) {
+					HISI_FB_INFO
+					    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+					     "pov_req_prev_prev failed! ret = %d\n",
+					     hisifd->index, ret1);
+				}
+
+				cmdlist_idxs =
+				    cmdlist_idxs_prev | cmdlist_idxs_prev_prev;
+
+				HISI_FB_ERR
+				    ("fb%d, 1wait_for vactive0_start_flag timeout!ret=%d, "
+				     "vactive0_start_flag=%d, pre_pre_frame_no=%u, "
+				     "frame_no=%u, TIMESTAMP_DIFF is %u us, "
+				     "cmdlist_idxs_prev=0x%x, cmdlist_idxs_prev_prev=0x%x, "
+				     "cmdlist_idxs=0x%x, itf0_ints=0x%x\n",
+				     hisifd->index, ret,
+				     hisifd->vactive0_start_flag,
+				     pov_req_dump->frame_no, pov_req->frame_no,
+				     hisifb_timestamp_diff(&tv0, &tv1),
+				     cmdlist_idxs_prev, cmdlist_idxs_prev_prev,
+				     cmdlist_idxs,
+				     inp32(hisifd->dss_base + DSS_LDI0_OFFSET +
+					   LDI_CPU_ITF_INTS)
+				    );
+
+				if (g_debug_ovl_online_composer_hold) {
+					dumpDssOverlay(hisifd, pov_req_dump,
+						       (g_debug_need_save_file
+							== 1));
+					hisi_cmdlist_dump_all_node(hisifd, NULL,
+								   cmdlist_idxs);
+					mdelay(HISI_DSS_COMPOSER_HOLD_TIME);
+				}
+
+				if (g_debug_ldi_underflow_clear
+				    && g_ldi_data_gate_en) {
+#if 1
+					hisi_cmdlist_config_reset(hisifd,
+								  pov_req_dump,
+								  cmdlist_idxs);
+
+					ldi_data_gate(hisifd, false);
+					mdelay(10);
+#else
+					if (hisifd->ldi_underflow_wq) {
+						queue_work(hisifd->
+							   ldi_underflow_wq,
+							   &hisifd->
+							   ldi_underflow_work);
+					}
+#endif
+
+					mipi_panel_check_reg(hisifd,
+							     read_value);
+					ldi_vstate =
+					    inp32(hisifd->dss_base +
+						  DSS_LDI0_OFFSET + LDI_VSTATE);
+					HISI_FB_ERR("fb%d, "
+						    "Number of the Errors on DSI : 0x05 = 0x%x\n"
+						    "Display Power Mode : 0x0A = 0x%x\n"
+						    "Display Signal Mode : 0x0E = 0x%x\n"
+						    "Display Self-Diagnostic Result : 0x0F = 0x%x\n"
+						    "LDI vstate : 0x%x, LDI dpi0_hstate : 0x%x\n",
+						    hisifd->index,
+						    read_value[0],
+						    read_value[1],
+						    read_value[2],
+						    read_value[3], ldi_vstate,
+						    inp32(hisifd->dss_base +
+							  DSS_LDI0_OFFSET +
+							  LDI_DPI0_HSTATE));
+
+					memset(&(hisifd->ov_block_infos_prev), 0,
+					       HISI_DSS_OV_BLOCK_NUMS *
+					       sizeof(dss_overlay_block_t));
+
+					memset(&(hisifd->ov_req_prev), 0,
+					       sizeof(dss_overlay_t));
+
+					if (LDI_VSTATE_V_WAIT_TE0 == ldi_vstate) {
+						vactive_timeout_count++;
+						if ((vactive_timeout_count >= 3)
+						    && hisifd->panel_info.esd_enable) {
+							hisifd->esd_recover_state =
+								ESD_RECOVER_STATE_START;
+							if (hisifd->esd_ctrl.esd_check_wq) {
+								queue_work(hisifd->esd_ctrl.esd_check_wq,
+								     &(hisifd->esd_ctrl.esd_check_work));
+							}
+						}
+					}
+					return 0;
+				}
+
+				ldi_data_gate(hisifd, false);
+				mipi_panel_check_reg(hisifd, read_value);
+				ldi_vstate =
+				    inp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_VSTATE);
+				HISI_FB_ERR("fb%d, "
+					    "Number of the Errors on DSI : 0x05 = 0x%x\n"
+					    "Display Power Mode : 0x0A = 0x%x\n"
+					    "Display Signal Mode : 0x0E = 0x%x\n"
+					    "Display Self-Diagnostic Result : 0x0F = 0x%x\n"
+					    "LDI vstate : 0x%x, LDI dpi0_hstate : 0x%x \n",
+					    hisifd->index, read_value[0],
+					    read_value[1], read_value[2],
+					    read_value[3], ldi_vstate,
+					    inp32(hisifd->dss_base +
+						  DSS_LDI0_OFFSET +
+						  LDI_DPI0_HSTATE));
+
+ REDO_1:
+				ret =
+				    wait_event_interruptible_timeout(hisifd->vactive0_start_wq,
+								     hisifd->vactive0_start_flag,
+								     msecs_to_jiffies
+								     (DSS_COMPOSER_TIMEOUT_THRESHOLD_ASIC));
+				if (ret == -ERESTARTSYS) {
+					if (times < 50) {
+						times++;
+						mdelay(10);
+						goto REDO_1;
+					}
+				}
+				times = 0;
+
+				if (ret <= 0) {
+					HISI_FB_ERR
+					    ("fb%d, 2wait_for vactive0_start_flag timeout!ret=%d, "
+					     "vactive0_start_flag=%d, frame_no=%u.\n",
+					     hisifd->index, ret,
+					     hisifd->vactive0_start_flag,
+					     pov_req_dump->frame_no);
+
+					ldi_data_gate(hisifd, false);
+					ret = -ETIMEDOUT;
+					if (LDI_VSTATE_V_WAIT_TE0 == ldi_vstate) {
+						vactive_timeout_count++;
+						if ((vactive_timeout_count >= 1)
+						    && hisifd->panel_info.esd_enable) {
+							hisifd->esd_recover_state =
+							    ESD_RECOVER_STATE_START;
+							if (hisifd->esd_ctrl.esd_check_wq) {
+								queue_work(hisifd->esd_ctrl.esd_check_wq,
+								     &(hisifd->esd_ctrl.esd_check_work));
+							}
+							ret = 0;
+						}
+					}
+				} else {
+					ldi_data_gate(hisifd, true);
+					ret = 0;
+				}
+			} else {
+				ldi_data_gate(hisifd, true);
+				ret = 0;
+			}
+		}
+
+		ldi_data_gate(hisifd, true);
+		hisifd->vactive0_start_flag = 0;
+		hisifd->vactive0_end_flag = 0;
+		if (ret >= 0) {
+			vactive_timeout_count = 0;
+		}
+	} else {
+		pov_req_dump = &(hisifd->ov_req_prev);
+
+		hisifb_get_timestamp(&tv0);
+		ldi_data_gate(hisifd, false);
+		prev_vactive0_start = hisifd->vactive0_start_flag;
+
+ REDO_2:
+		ret =
+		    wait_event_interruptible_timeout(hisifd->vactive0_start_wq,
+						     (prev_vactive0_start !=
+						      hisifd->vactive0_start_flag),
+						     msecs_to_jiffies
+						     (DSS_COMPOSER_TIMEOUT_THRESHOLD_ASIC));
+		if (ret == -ERESTARTSYS) {
+			if (times < 50) {
+				times++;
+				mdelay(10);
+				goto REDO_2;
+			}
+		}
+
+		if (ret <= 0) {
+			hisifb_get_timestamp(&tv1);
+			ret =
+			    hisi_cmdlist_get_cmdlist_idxs(pov_req_dump,
+							  &cmdlist_idxs, NULL);
+			if (ret != 0) {
+				HISI_FB_INFO
+				    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+				     "pov_req_prev failed! ret = %d\n",
+				     hisifd->index, ret);
+			}
+
+			HISI_FB_ERR
+			    ("fb%d, 1wait_for vactive0_start_flag timeout!ret=%d, "
+			     "vactive0_start_flag=%d, frame_no=%u, "
+			     "TIMESTAMP_DIFF is %u us, cmdlist_idxs=0x%x!\n",
+			     hisifd->index, ret,
+			     hisifd->vactive0_start_flag,
+			     pov_req_dump->frame_no,
+			     hisifb_timestamp_diff(&tv0, &tv1),
+			     cmdlist_idxs);
+
+			if (g_debug_ovl_online_composer_hold) {
+				dumpDssOverlay(hisifd, pov_req_dump,
+					       (g_debug_need_save_file == 1));
+				hisi_cmdlist_dump_all_node(hisifd, NULL,
+							   cmdlist_idxs);
+				mdelay(HISI_DSS_COMPOSER_HOLD_TIME);
+			}
+			mipi_dsi_reset(hisifd);
+
+			ret = -ETIMEDOUT;
+		} else {
+			ret = 0;
+		}
+	}
+
+	if (ret == -ETIMEDOUT) {
+		if (pov_req_dump && pov_req_dump->ovl_idx == DSS_OVL0) {
+			isr_s1 = inp32(hisifd->dss_base + GLB_CPU_PDP_INTS);
+			isr_s2_mask =
+			    inp32(hisifd->dss_base + DSS_LDI0_OFFSET +
+				  LDI_CPU_ITF_INT_MSK);
+			isr_s2 =
+			    inp32(hisifd->dss_base + DSS_LDI0_OFFSET +
+				  LDI_CPU_ITF_INTS);
+			ldi_base = hisifd->dss_base + DSS_LDI0_OFFSET;
+		} else if (pov_req_dump && pov_req_dump->ovl_idx == DSS_OVL1) {
+			isr_s1 = inp32(hisifd->dss_base + GLB_CPU_SDP_INTS);
+			isr_s2_mask =
+			    inp32(hisifd->dss_base + DSS_LDI1_OFFSET +
+				  LDI_CPU_ITF_INT_MSK);
+			isr_s2 =
+			    inp32(hisifd->dss_base + DSS_LDI1_OFFSET +
+				  LDI_CPU_ITF_INTS);
+			ldi_base = hisifd->dss_base + DSS_LDI1_OFFSET;
+		} else {
+			;
+		}
+
+		HISI_FB_ERR("fb%d, isr_s1=0x%x, isr_s2_mask=0x%x, isr_s2=0x%x, "
+			    "LDI_CTRL(0x%x), LDI_FRM_MSK(0x%x).\n",
+			    hisifd->index, isr_s1, isr_s2_mask, isr_s2,
+			    inp32(ldi_base + LDI_CTRL),
+			    inp32(ldi_base + LDI_FRM_MSK));
+	}
+
+	return ret;
+}
+
+int hisi_crc_enable(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req)
+{
+	uint32_t tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	if (g_enable_crc_debug == 0)
+		return 0;
+
+	if (pov_req->crc_enable_status <= 0)
+		return 0;
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		tmp = inp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK);
+
+		if (pov_req->crc_enable_status == DSS_CRC_OV_EN) {
+			outp32(hisifd->dss_base + DSS_DBG_OFFSET +
+			       DBG_CRC_OV0_EN, 0x1);
+
+			tmp &= ~BIT_CRC_OV0_INT;
+		} else if (pov_req->crc_enable_status == DSS_CRC_LDI_EN) {
+
+			tmp &= ~BIT_CRC_ITF0_INT;
+		} else if (pov_req->crc_enable_status == DSS_CRC_SUM_EN) {
+			outp32(hisifd->dss_base + DSS_DBG_OFFSET +
+			       DBG_CRC_SUM_EN, 0x1);
+
+			tmp &= ~BIT_CRC_SUM_INT;
+		}
+		outp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK, tmp);
+	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
+		tmp = inp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK);
+
+		if (pov_req->crc_enable_status == DSS_CRC_OV_EN) {
+			outp32(hisifd->dss_base + DSS_DBG_OFFSET +
+			       DBG_CRC_OV1_EN, 0x1);
+
+			tmp &= ~BIT_CRC_OV1_INT;
+		} else if (pov_req->crc_enable_status == DSS_CRC_LDI_EN) {
+			outp32(hisifd->dss_base + GLB_CRC_LDI1_EN, 0x1);
+
+			tmp &= ~BIT_CRC_ITF1_INT;
+		} else if (pov_req->crc_enable_status == DSS_CRC_SUM_EN) {
+			outp32(hisifd->dss_base + DSS_DBG_OFFSET +
+			       DBG_CRC_SUM_EN, 0x1);
+
+			tmp &= ~BIT_CRC_SUM_INT;
+		}
+		outp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK, tmp);
+	} else {
+		HISI_FB_ERR("fb%d, not support!", hisifd->index);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hisi_crc_disable(struct hisi_fb_data_type *hisifd)
+{
+	uint32_t tmp = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		outp32(hisifd->dss_base + DSS_DBG_OFFSET + DBG_CRC_OV0_EN, 0x0);
+
+		outp32(hisifd->dss_base + DSS_DBG_OFFSET + DBG_CRC_SUM_EN, 0x0);
+		tmp = inp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK);
+		tmp |= (BIT_CRC_OV0_INT | BIT_CRC_ITF0_INT | BIT_CRC_SUM_INT);
+		outp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK, tmp);
+	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
+		outp32(hisifd->dss_base + DSS_DBG_OFFSET + DBG_CRC_OV1_EN, 0x0);
+		outp32(hisifd->dss_base + GLB_CRC_LDI1_EN, 0x0);
+		outp32(hisifd->dss_base + DSS_DBG_OFFSET + DBG_CRC_SUM_EN, 0x0);
+		tmp = inp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK);
+		tmp |= (BIT_CRC_OV1_INT | BIT_CRC_ITF1_INT | BIT_CRC_SUM_INT);
+		outp32(hisifd->dss_base + DSS_DPP_OFFSET + DPP_INT_MSK, tmp);
+	} else {
+		HISI_FB_ERR("fb%d, not support!", hisifd->index);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hisi_crc_get_result(struct hisi_fb_data_type *hisifd,
+			       dss_overlay_t *pov_req)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		if (pov_req->crc_enable_status == DSS_CRC_OV_EN) {
+			pov_req->crc_info.crc_ov_result =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_DBG_OV0);
+			pov_req->crc_info.crc_ov_frm =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_OV0_FRM);
+		} else if (pov_req->crc_enable_status == DSS_CRC_LDI_EN) {
+			pov_req->crc_info.crc_ldi_result =
+			    inp32(hisifd->dss_base + GLB_CRC_DBG_LDI0);
+			pov_req->crc_info.crc_ldi_frm =
+			    inp32(hisifd->dss_base + GLB_CRC_LDI0_FRM);
+		} else if (pov_req->crc_enable_status == DSS_CRC_SUM_EN) {
+			pov_req->crc_info.crc_ldi_result =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_DBG_SUM);
+			pov_req->crc_info.crc_ldi_frm =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_SUM_FRM);
+		}
+	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
+		if (pov_req->crc_enable_status == DSS_CRC_OV_EN) {
+			pov_req->crc_info.crc_ov_result =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_DBG_OV1);
+			pov_req->crc_info.crc_ov_frm =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_OV1_FRM);
+		} else if (pov_req->crc_enable_status == DSS_CRC_LDI_EN) {
+			pov_req->crc_info.crc_ldi_result =
+			    inp32(hisifd->dss_base + GLB_CRC_DBG_LDI1);
+			pov_req->crc_info.crc_ldi_frm =
+			    inp32(hisifd->dss_base + GLB_CRC_LDI1_FRM);
+		} else if (pov_req->crc_enable_status == DSS_CRC_SUM_EN) {
+			pov_req->crc_info.crc_ldi_result =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_DBG_SUM);
+			pov_req->crc_info.crc_ldi_frm =
+			    inp32(hisifd->dss_base + DSS_DBG_OFFSET +
+				  DBG_CRC_SUM_FRM);
+		}
+	} else {
+		HISI_FB_ERR("fb%d, not support!", hisifd->index);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void hisi_crc_isr_handler(struct hisi_fb_data_type *hisifd)
+{
+	BUG_ON(hisifd == NULL);
+
+	hisi_crc_disable(hisifd);
+
+	hisifd->crc_flag++;
+	wake_up_interruptible_all(&hisifd->crc_wq);
+}
+
+int hisi_crc_config(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req)
+{
+	int ret = 0;
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+
+	if (g_enable_crc_debug == 0)
+		return 0;
+
+	if (pov_req->crc_enable_status <= 0)
+		return 0;
+
+#if 1
+	mdelay(100);
+	hisi_crc_get_result(hisifd, pov_req);
+	hisi_crc_disable(hisifd);
+#else
+	prev_crc_flag = hisifd->crc_flag;
+	ret = wait_event_interruptible_timeout(hisifd->crc_wq,
+					       (prev_crc_flag !=
+						hisifd->crc_flag), 1 * HZ);
+	if (ret == -ERESTARTSYS) {
+		HISI_FB_DEBUG
+		    ("fb%d, wait_for crc_flag, "
+		     "Returns -ERESTARTSYS if interrupted by a signal!\n",
+		     hisifd->index);
+		ret =
+		    wait_event_interruptible_timeout(hisifd->crc_wq,
+						     (prev_crc_flag !=
+						      hisifd->crc_flag), 1 * HZ);
+	}
+
+	if (ret <= 0) {
+		HISI_FB_ERR("fb%d, wait_for crc_flag timeout!ret=%d, "
+			    "prev_crc_flag=%d, crc_flag=%d\n",
+			    hisifd->index, ret, prev_crc_flag,
+			    hisifd->crc_flag);
+		ret = -ETIMEDOUT;
+	} else {
+		ret = 0;
+
+		hisi_crc_get_result(hisifd, pov_req);
+	}
+#endif
+
+	return ret;
+}
+
+void hisi_dss_debug_func(struct work_struct *work)
+{
+	struct hisi_fb_data_type *hisifd = NULL;
+
+	hisifd = container_of(work, struct hisi_fb_data_type, dss_debug_work);
+	BUG_ON(hisifd == NULL);
+
+	dumpDssOverlay(hisifd, &hisifd->ov_req, true);
+}
+
+void hisi_ldi_underflow_handle_func(struct work_struct *work)
+{
+	struct hisi_fb_data_type *hisifd = NULL;
+	dss_overlay_t *pov_req_prev = NULL;
+	dss_overlay_t *pov_req_prev_prev = NULL;
+	uint32_t cmdlist_idxs_prev = 0;
+	uint32_t cmdlist_idxs_prev_prev = 0;
+	int ret = 0;
+	uint32_t tmp = 0;
+	uint32_t isr_s1 = 0;
+	uint32_t isr_s2 = 0;
+
+	hisifd =
+	    container_of(work, struct hisi_fb_data_type, ldi_underflow_work);
+	BUG_ON(hisifd == NULL);
+
+	HISI_FB_INFO("fb%d, +.\n", hisifd->index);
+
+	down(&hisifd->blank_sem0);
+	if (!hisifd->panel_power_on) {
+		HISI_FB_INFO("fb%d, panel is power off!", hisifd->index);
+		up(&hisifd->blank_sem0);
+		return;
+	}
+	hisifb_activate_vsync(hisifd);
+
+	pov_req_prev = &(hisifd->ov_req_prev);
+	pov_req_prev_prev = &(hisifd->ov_req_prev_prev);
+
+	ret =
+	    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev, &cmdlist_idxs_prev, NULL);
+	if (ret != 0) {
+		HISI_FB_ERR
+		    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+		     "pov_req_prev failed! ret = %d\n",
+		     hisifd->index, ret);
+	}
+
+	ret =
+	    hisi_cmdlist_get_cmdlist_idxs(pov_req_prev_prev,
+					  &cmdlist_idxs_prev_prev, NULL);
+	if (ret != 0) {
+		HISI_FB_ERR
+		    ("fb%d, hisi_cmdlist_get_cmdlist_idxs "
+		     "pov_req_prev_prev failed! ret = %d\n",
+		     hisifd->index, ret);
+	}
+
+	hisi_cmdlist_config_reset(hisifd, pov_req_prev,
+				  cmdlist_idxs_prev | cmdlist_idxs_prev_prev);
+
+	enable_ldi(hisifd);
+	isr_s1 = inp32(hisifd->dss_base + GLB_CPU_PDP_INTS);
+	isr_s2 = inp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INTS);
+	outp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INTS, isr_s2);
+	outp32(hisifd->dss_base + GLB_CPU_PDP_INTS, isr_s1);
+
+	tmp = inp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK);
+	tmp &= ~BIT_LDI_UNFLOW;
+	outp32(hisifd->dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK, tmp);
+
+	hisifb_deactivate_vsync(hisifd);
+
+	up(&hisifd->blank_sem0);
+
+	HISI_FB_INFO
+	    ("fb%d, -. cmdlist_idxs_prev = 0x%x, cmdlist_idxs_prev_prev = 0x%x\n",
+	     hisifd->index, cmdlist_idxs_prev, cmdlist_idxs_prev_prev);
+}
+
+/*lint +e778 +e732*/
diff --git a/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.h b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.h
new file mode 100755
index 000000000000..31088fbe2c73
--- /dev/null
+++ b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils.h
@@ -0,0 +1,269 @@
+/* Copyright (c) 2013-2014, Hisilicon Tech. Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef HISI_OVERLAY_UTILS_H
+#define HISI_OVERLAY_UTILS_H
+
+#include "hisi_fb.h"
+
+/*******************************************************************************
+ **
+ */
+extern uint32_t g_dss_module_base[DSS_CHN_MAX_DEFINE][MODULE_CHN_MAX];
+extern uint32_t g_dss_module_ovl_base[DSS_MCTL_IDX_MAX][MODULE_OVL_MAX];
+extern uint32_t g_dss_module_cap[DSS_CHN_MAX_DEFINE][MODULE_CAP_MAX];
+extern uint32_t g_dss_mif_sid_map[DSS_CHN_MAX_DEFINE];
+extern uint32_t g_dss_smmu_smrx_idx[DSS_CHN_MAX_DEFINE];
+extern int g_scf_lut_chn_coef_idx[DSS_CHN_MAX_DEFINE];
+extern unsigned int g_dss_smmu_outstanding;
+extern void *g_smmu_rwerraddr_virt;
+
+#define DSS_COMPOSER_TIMEOUT_THRESHOLD_FPGA	(10000)
+#define DSS_COMPOSER_TIMEOUT_THRESHOLD_ASIC	(300)
+
+enum ENUM_LDI_VSTATE {
+	LDI_VSTATE_IDLE = 0x1,
+	LDI_VSTATE_VSW = 0x2,
+	LDI_VSTATE_VBP = 0x4,
+	LDI_VSTATE_VACTIVE0 = 0x8,
+	LDI_VSTATE_VACTIVE_SPACE = 0x10,
+	LDI_VSTATE_VACTIVE1 = 0x20,
+	LDI_VSTATE_VFP = 0x40,
+	LDI_VSTATE_V_WAIT_TE0 = 0x80,
+	LDI_VSTATE_V_WAIT_TE1 = 0x100,
+	LDI_VSTATE_V_WAIT_TE_EN = 0x200,
+};
+
+void dumpDssOverlay(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req,
+		    bool isNeedSaveFile);
+
+int hisi_get_hal_format(struct fb_info *info);
+int hisi_overlay_init(struct hisi_fb_data_type *hisifd);
+int hisi_overlay_deinit(struct hisi_fb_data_type *hisifd);
+int hisi_overlay_on(struct hisi_fb_data_type *hisifd, bool fastboot_enable);
+int hisi_overlay_off(struct hisi_fb_data_type *hisifd);
+bool hisi_dss_check_reg_reload_status(struct hisi_fb_data_type *hisifd);
+bool hisi_dss_check_crg_sctrl_status(struct hisi_fb_data_type *hisifd);
+
+void hisifb_adjust_block_rect(int block_num, dss_rect_t *ov_block_rects[],
+			      dss_wb_layer_t *wb_layer);
+void hisifb_disreset_dss(struct hisi_fb_data_type *hisifd);
+
+void hisi_vactive0_start_isr_handler(struct hisi_fb_data_type *hisifd);
+int hisi_vactive0_start_config(struct hisi_fb_data_type *hisifd,
+			       dss_overlay_t *pov_req);
+
+int hisi_dss_dirty_region_dbuf_config(struct hisi_fb_data_type *hisifd,
+				      dss_overlay_t *pov_req);
+void hisi_dss_dirty_region_updt_config(struct hisi_fb_data_type *hisifd,
+				       dss_overlay_t *pov_req);
+
+int hisi_dss_handle_cur_ovl_req(struct hisi_fb_data_type *hisifd,
+				dss_overlay_t *pov_req);
+
+int hisi_ov_compose_handler(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req,
+			    dss_overlay_block_t *pov_h_block,
+			    dss_layer_t *layer,
+			    dss_rect_t *wb_dst_rect,
+			    dss_rect_t *wb_ov_block_rect,
+			    dss_rect_ltrb_t *clip_rect,
+			    dss_rect_t *aligned_rect,
+			    bool *rdma_stretch_enable,
+			    bool *has_base,
+			    bool csc_needed, bool enable_cmdlist);
+
+void hisi_dss_qos_on(struct hisi_fb_data_type *hisifd);
+void hisi_dss_mmbuf_on(struct hisi_fb_data_type *hisifd);
+void hisi_dss_mif_on(struct hisi_fb_data_type *hisifd);
+void hisi_dss_smmu_on(struct hisi_fb_data_type *hisifd);
+void hisi_dss_smmu_init(char __iomem *smmu_base, dss_smmu_t *s_smmu);
+void hisi_dss_smmu_ch_set_reg(struct hisi_fb_data_type *hisifd,
+			      char __iomem *smmu_base, dss_smmu_t *s_smmu,
+			      int chn_idx);
+void hisi_dss_smmu_ov_set_reg(struct hisi_fb_data_type *hisifd,
+			      char __iomem *smmu_base, dss_smmu_t *s_smmu);
+int hisi_dss_scl_coef_on(struct hisi_fb_data_type *hisifd, bool enable_cmdlist,
+			 int coef_lut_idx);
+
+int hisi_overlay_pan_display(struct hisi_fb_data_type *hisifd);
+int hisi_ov_online_play(struct hisi_fb_data_type *hisifd, void __user *argp);
+int hisi_overlay_ioctl_handler(struct hisi_fb_data_type *hisifd,
+			       uint32_t cmd, void __user *argp);
+
+void hisi_dss_unflow_handler(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req, bool unmask);
+
+void hisi_dss_chn_set_reg_default_value(struct hisi_fb_data_type *hisifd,
+					char __iomem *dma_base);
+void hisi_dss_ov_set_reg_default_value(struct hisi_fb_data_type *hisifd,
+				       char __iomem *ovl_base, int ovl_idx);
+int hisi_dss_prev_module_set_regs(struct hisi_fb_data_type *hisifd,
+				  dss_overlay_t *pov_req,
+				  uint32_t cmdlist_pre_idxs,
+				  bool enable_cmdlist, bool *use_comm_mmbuf);
+
+int hisi_dss_check_pure_layer(struct hisi_fb_data_type *hisifd,
+			      dss_overlay_block_t *pov_h_block,
+			      void __user *argp);
+
+int hisi_dss_check_userdata(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req,
+			    dss_overlay_block_t *pov_h_block_infos);
+int hisi_dss_check_layer_par(struct hisi_fb_data_type *hisifd,
+			     dss_layer_t *layer);
+
+int hisi_dss_aif_handler(struct hisi_fb_data_type *hisifd,
+			 dss_overlay_t *pov_req,
+			 dss_overlay_block_t *pov_h_block);
+void hisi_dss_aif_init(char __iomem *aif_ch_base, dss_aif_t *s_aif);
+void hisi_dss_aif_ch_set_reg(struct hisi_fb_data_type *hisifd,
+			     char __iomem *aif_ch_base, dss_aif_t *s_aif);
+int hisi_dss_aif_ch_config(struct hisi_fb_data_type *hisifd,
+			   dss_overlay_t *pov_req, dss_layer_t *layer,
+			   dss_rect_t *wb_dst_rect, dss_wb_layer_t *wb_layer,
+			   int ovl_idx);
+
+int hisi_dss_aif1_ch_config(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req, dss_layer_t *layer,
+			    dss_wb_layer_t *wb_layer, int ovl_idx);
+
+int hisi_dss_mif_config(struct hisi_fb_data_type *hisifd,
+			dss_layer_t *layer, dss_wb_layer_t *wb_layer,
+			bool rdma_stretch_enable);
+
+int hisi_dss_smmu_ch_config(struct hisi_fb_data_type *hisifd,
+			    dss_layer_t *layer, dss_wb_layer_t *wb_layer);
+
+int hisi_dss_rdma_config(struct hisi_fb_data_type *hisifd, int ovl_idx,
+			 dss_layer_t *layer, dss_rect_ltrb_t *clip_rect,
+			 dss_rect_t *aligned_rect, bool *rdma_stretch_enable);
+int hisi_dss_wdma_config(struct hisi_fb_data_type *hisifd,
+			 dss_overlay_t *pov_req, dss_wb_layer_t *layer,
+			 dss_rect_t aligned_rect, dss_rect_t *ov_block_rect,
+			 bool last_block);
+int hisi_dss_rdfc_config(struct hisi_fb_data_type *hisifd, dss_layer_t *layer,
+			 dss_rect_t *aligned_rect, dss_rect_ltrb_t clip_rect);
+int hisi_dss_wdfc_config(struct hisi_fb_data_type *hisifd,
+			 dss_wb_layer_t *layer, dss_rect_t *aligned_rect,
+			 dss_rect_t *ov_block_rect);
+
+void hisi_dss_scl_set_reg(struct hisi_fb_data_type *hisifd,
+			  char __iomem *scl_base, dss_scl_t *s_scl);
+int hisi_dss_chn_scl_load_filter_coef_set_reg(struct hisi_fb_data_type *hisifd,
+					      bool enable_cmdlist, int chn_idx,
+					      uint32_t format);
+int hisi_dss_post_scl_load_filter_coef(struct hisi_fb_data_type *hisifd,
+				       bool enable_cmdlist,
+				       char __iomem *scl_lut_base,
+				       int coef_lut_idx);
+int hisi_dss_scl_config(struct hisi_fb_data_type *hisifd, dss_layer_t *layer,
+			dss_rect_t *aligned_rect, bool rdma_stretch_enable);
+
+int hisi_dss_post_scf_config(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req);
+void hisi_dss_csc_init(char __iomem *csc_base, dss_csc_t *s_csc);
+void hisi_dss_csc_set_reg(struct hisi_fb_data_type *hisifd,
+			  char __iomem *csc_base, dss_csc_t *s_csc);
+int hisi_dss_csc_config(struct hisi_fb_data_type *hisifd, dss_layer_t *layer,
+			dss_wb_layer_t *wb_layer);
+
+int hisi_dss_ovl_base_config(struct hisi_fb_data_type *hisifd,
+			     dss_overlay_t *pov_req,
+			     dss_overlay_block_t *pov_h_block,
+			     dss_rect_t *wb_ov_block_rect, int ovl_idx,
+			     int ov_h_block_idx);
+int hisi_dss_ovl_layer_config(struct hisi_fb_data_type *hisifd,
+			      dss_overlay_t *pov_req, dss_layer_t *layer,
+			      dss_rect_t *wb_ov_block_rect, bool has_base);
+
+void hisi_dss_mctl_mutex_lock(struct hisi_fb_data_type *hisifd, int ovl_idx);
+void hisi_dss_mctl_mutex_unlock(struct hisi_fb_data_type *hisifd, int ovl_idx);
+void hisi_dss_mctl_on(struct hisi_fb_data_type *hisifd,
+		      int mctl_idx, bool enable_cmdlist, bool fastboot_enable);
+int hisi_dss_mctl_ch_config(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req, dss_layer_t *layer,
+			    dss_wb_layer_t *wb_layer, int ovl_idx,
+			    dss_rect_t *wb_ov_block_rect, bool has_base);
+int hisi_dss_mctl_ov_config(struct hisi_fb_data_type *hisifd,
+			    dss_overlay_t *pov_req, int ovl_idx, bool has_base,
+			    bool is_first_ov_block);
+
+int hisi_dss_sharpness_config(struct hisi_fb_data_type *hisifd,
+			      dss_layer_t *layer);
+int hisi_dss_post_clip_config(struct hisi_fb_data_type *hisifd,
+			      dss_layer_t *layer);
+int hisi_dss_ce_config(struct hisi_fb_data_type *hisifd, dss_layer_t *layer);
+
+int hisi_dss_module_default(struct hisi_fb_data_type *hisifd);
+int hisi_dss_module_init(struct hisi_fb_data_type *hisifd);
+int hisi_dss_ch_module_set_regs(struct hisi_fb_data_type *hisifd,
+				int32_t mctl_idx, int chn_idx, uint32_t wb_type,
+				bool enable_cmdlist);
+int hisi_dss_ov_module_set_regs(struct hisi_fb_data_type *hisifd,
+				dss_overlay_t *pov_req, int ovl_idx,
+				bool enable_cmdlist, int task_end, int last,
+				bool is_first_ov_block);
+
+void hisi_dss_secure_layer_check_config(struct hisi_fb_data_type *hisifd,
+					dss_overlay_t *pov_req);
+void hisi_rch2_ce_end_handle_func(struct work_struct *work);
+void hisi_rch4_ce_end_handle_func(struct work_struct *work);
+void hisi_dss_dpp_acm_ce_end_handle_func(struct work_struct *work);
+
+void hisi_crc_isr_handler(struct hisi_fb_data_type *hisifd);
+int hisi_crc_enable(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req);
+int hisi_crc_config(struct hisi_fb_data_type *hisifd, dss_overlay_t *pov_req);
+void hisi_dss_debug_func(struct work_struct *work);
+void hisi_ldi_underflow_handle_func(struct work_struct *work);
+
+void *hisi_dss_mmbuf_init(struct hisi_fb_data_type *hisifd);
+void hisi_dss_mmbuf_deinit(struct hisi_fb_data_type *hisifd);
+uint32_t hisi_dss_mmbuf_alloc(void *handle, uint32_t size);
+void hisi_dss_mmbuf_free(void *handle, uint32_t addr, uint32_t size);
+void hisi_dss_mmbuf_info_clear(struct hisi_fb_data_type *hisifd, int idx);
+void hisi_mmbuf_info_get_online(struct hisi_fb_data_type *hisifd);
+void hisi_dss_mctl_ov_set_ctl_dbg_reg(struct hisi_fb_data_type *hisifd,
+				      char __iomem *mctl_base,
+				      bool enable_cmdlist);
+uint32_t hisi_dss_mif_get_invalid_sel(dss_img_t *img, uint32_t transform,
+				      int v_scaling_factor, uint8_t is_tile,
+				      bool rdma_stretch_enable);
+
+bool isYUVPackage(uint32_t format);
+bool isYUVSemiPlanar(uint32_t format);
+bool isYUVPlanar(uint32_t format);
+bool isYUV(uint32_t format);
+
+bool is_YUV_SP_420(uint32_t format);
+bool is_YUV_SP_422(uint32_t format);
+bool is_YUV_P_420(uint32_t format);
+bool is_YUV_P_422(uint32_t format);
+bool is_RGBX(uint32_t format);
+
+int hisi_dss_arsr1p_write_coefs(struct hisi_fb_data_type *hisifd,
+				bool enable_cmdlist, char __iomem *addr,
+				const int **p, int row, int col);
+
+/*arsr2p interface*/
+void hisi_dss_arsr2p_init(char __iomem *arsr2p_base, dss_arsr2p_t *s_arsr2p);
+void hisi_dss_arsr2p_set_reg(struct hisi_fb_data_type *hisifd,
+			     char __iomem *arsr2p_base,
+			     dss_arsr2p_t *s_arsr2p);
+void hisi_dss_arsr2p_coef_on(struct hisi_fb_data_type *hisifd,
+			     bool enable_cmdlist);
+int hisi_dss_arsr2p_config(struct hisi_fb_data_type *hisifd,
+				dss_layer_t *layer, dss_rect_t *aligned_rect, bool rdma_stretch_enable);
+void hisi_remove_mctl_mutex(struct hisi_fb_data_type *hisifd, int mctl_idx,
+			    uint32_t cmdlist_idxs);
+
+#endif				/* HISI_OVERLAY_UTILS_H */
diff --git a/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.c b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.c
new file mode 100755
index 000000000000..fb7628e0aa3e
--- /dev/null
+++ b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.c
@@ -0,0 +1,2741 @@
+/* Copyright (c) 2013-2014, Hisilicon Tech. Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "hisi_overlay_utils.h"
+
+uint32_t g_dss_module_base[DSS_CHN_MAX_DEFINE][MODULE_CHN_MAX] = {
+	/* D0 */
+	{
+	 MIF_CH0_OFFSET,
+	 AIF0_CH0_OFFSET,
+	 AIF1_CH0_OFFSET,
+	 MCTL_CTL_MUTEX_RCH0,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH0_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH0_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH0_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD0_DBG,
+	 DSS_RCH_D0_DMA_OFFSET,
+	 DSS_RCH_D0_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_D0_CSC_OFFSET,
+	 }
+	,
+
+	/* D1 */
+	{
+	 MIF_CH1_OFFSET,
+	 AIF0_CH1_OFFSET,
+	 AIF1_CH1_OFFSET,
+	 MCTL_CTL_MUTEX_RCH1,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH1_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH1_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH1_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD1_DBG,
+	 DSS_RCH_D1_DMA_OFFSET,
+	 DSS_RCH_D1_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_D1_CSC_OFFSET,
+	 }
+	,
+
+	/* V0 */
+	{
+	 MIF_CH2_OFFSET,
+	 AIF0_CH2_OFFSET,
+	 AIF1_CH2_OFFSET,
+	 MCTL_CTL_MUTEX_RCH2,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH2_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH2_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH2_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD2_DBG,
+	 DSS_RCH_VG0_DMA_OFFSET,
+	 DSS_RCH_VG0_DFC_OFFSET,
+	 DSS_RCH_VG0_SCL_OFFSET,
+	 DSS_RCH_VG0_SCL_LUT_OFFSET,
+	 DSS_RCH_VG0_ARSR_OFFSET,
+	 DSS_RCH_VG0_ARSR_LUT_OFFSET,
+	 DSS_RCH_VG0_POST_CLIP_OFFSET,
+	 DSS_RCH_VG0_PCSC_OFFSET,
+	 DSS_RCH_VG0_CSC_OFFSET,
+	 }
+	,
+
+	/* G0 */
+	{
+	 MIF_CH3_OFFSET,
+	 AIF0_CH3_OFFSET,
+	 AIF1_CH3_OFFSET,
+	 MCTL_CTL_MUTEX_RCH3,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH3_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH3_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH3_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD3_DBG,
+	 DSS_RCH_G0_DMA_OFFSET,
+	 DSS_RCH_G0_DFC_OFFSET,
+	 DSS_RCH_G0_SCL_OFFSET,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_G0_POST_CLIP_OFFSET,
+	 0,
+	 DSS_RCH_G0_CSC_OFFSET,
+	 }
+	,
+
+	/* V1 */
+	{
+	 MIF_CH4_OFFSET,
+	 AIF0_CH4_OFFSET,
+	 AIF1_CH4_OFFSET,
+	 MCTL_CTL_MUTEX_RCH4,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH4_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH4_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH4_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD4_DBG,
+	 DSS_RCH_VG1_DMA_OFFSET,
+	 DSS_RCH_VG1_DFC_OFFSET,
+	 DSS_RCH_VG1_SCL_OFFSET,
+	 DSS_RCH_VG1_SCL_LUT_OFFSET,
+	 0,
+	 0,
+	 DSS_RCH_VG1_POST_CLIP_OFFSET,
+	 0,
+	 DSS_RCH_VG1_CSC_OFFSET,
+	 }
+	,
+
+	/* G1 */
+	{
+	 MIF_CH5_OFFSET,
+	 AIF0_CH5_OFFSET,
+	 AIF1_CH5_OFFSET,
+	 MCTL_CTL_MUTEX_RCH5,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH5_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH5_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH5_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD5_DBG,
+	 DSS_RCH_G1_DMA_OFFSET,
+	 DSS_RCH_G1_DFC_OFFSET,
+	 DSS_RCH_G1_SCL_OFFSET,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_G1_POST_CLIP_OFFSET,
+	 0,
+	 DSS_RCH_G1_CSC_OFFSET,
+	 }
+	,
+
+	/* D2 */
+	{
+	 MIF_CH6_OFFSET,
+	 AIF0_CH6_OFFSET,
+	 AIF1_CH6_OFFSET,
+	 MCTL_CTL_MUTEX_RCH6,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH6_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH6_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH6_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD6_DBG,
+	 DSS_RCH_D2_DMA_OFFSET,
+	 DSS_RCH_D2_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_D2_CSC_OFFSET,
+	 }
+	,
+
+	/* D3 */
+	{
+	 MIF_CH7_OFFSET,
+	 AIF0_CH7_OFFSET,
+	 AIF1_CH7_OFFSET,
+	 MCTL_CTL_MUTEX_RCH7,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH7_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH7_OV_OEN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH7_STARTY,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD7_DBG,
+	 DSS_RCH_D3_DMA_OFFSET,
+	 DSS_RCH_D3_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_RCH_D3_CSC_OFFSET,
+	 }
+	,
+
+	/* W0 */
+	{
+	 MIF_CH8_OFFSET,
+	 AIF0_CH8_OFFSET,
+	 AIF1_CH8_OFFSET,
+	 MCTL_CTL_MUTEX_WCH0,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_WCH0_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_WCH0_OV_IEN,
+	 0,
+	 0,
+	 DSS_WCH0_DMA_OFFSET,
+	 DSS_WCH0_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_WCH0_CSC_OFFSET,
+	 }
+	,
+
+	/* W1 */
+	{
+	 MIF_CH9_OFFSET,
+	 AIF0_CH9_OFFSET,
+	 AIF1_CH9_OFFSET,
+	 MCTL_CTL_MUTEX_WCH1,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_WCH1_FLUSH_EN,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_WCH1_OV_IEN,
+	 0,
+	 0,
+	 DSS_WCH1_DMA_OFFSET,
+	 DSS_WCH1_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_WCH1_CSC_OFFSET,
+	 }
+	,
+
+	/* V2 */
+	{
+	 MIF_CH10_OFFSET,
+	 AIF0_CH11_OFFSET,
+	 AIF1_CH11_OFFSET,
+	 MCTL_CTL_MUTEX_RCH8,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_RCH8_FLUSH_EN,
+	 0,
+	 0,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_MOD8_DBG,
+	 DSS_RCH_VG2_DMA_OFFSET,
+	 DSS_RCH_VG2_DFC_OFFSET,
+	 DSS_RCH_VG2_SCL_OFFSET,
+	 DSS_RCH_VG2_SCL_LUT_OFFSET,
+	 0,
+	 0,
+	 DSS_RCH_VG2_POST_CLIP_OFFSET,
+	 0,
+	 DSS_RCH_VG2_CSC_OFFSET,
+	 }
+	,
+	/* W2 */
+	{
+	 MIF_CH11_OFFSET,
+	 AIF0_CH12_OFFSET,
+	 AIF1_CH12_OFFSET,
+	 MCTL_CTL_MUTEX_WCH2,
+	 DSS_MCTRL_SYS_OFFSET + MCTL_WCH2_FLUSH_EN,
+	 0,
+	 0,
+	 0,
+	 DSS_WCH2_DMA_OFFSET,
+	 DSS_WCH2_DFC_OFFSET,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 0,
+	 DSS_WCH2_CSC_OFFSET,
+	 }
+	,
+};
+
+uint32_t g_dss_module_ovl_base[DSS_MCTL_IDX_MAX][MODULE_OVL_MAX] = {
+	{DSS_OVL0_OFFSET,
+	 DSS_MCTRL_CTL0_OFFSET}
+	,
+
+	{DSS_OVL1_OFFSET,
+	 DSS_MCTRL_CTL1_OFFSET}
+	,
+
+	{DSS_OVL2_OFFSET,
+	 DSS_MCTRL_CTL2_OFFSET}
+	,
+
+	{DSS_OVL3_OFFSET,
+	 DSS_MCTRL_CTL3_OFFSET}
+	,
+
+	{0,
+	 DSS_MCTRL_CTL4_OFFSET}
+	,
+
+	{0,
+	 DSS_MCTRL_CTL5_OFFSET}
+	,
+};
+
+int g_scf_lut_chn_coef_idx[DSS_CHN_MAX_DEFINE] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+uint32_t g_dss_module_cap[DSS_CHN_MAX_DEFINE][MODULE_CAP_MAX] = {
+	/* D2 */
+	{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1},
+	/* D3 */
+	{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
+	/* V0 */
+	{0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1},
+	/* G0 */
+	{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+	/* V1 */
+	{0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1},
+	/* G1 */
+	{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+	/* D0 */
+	{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
+	/* D1 */
+	{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
+
+	/* W0 */
+	{1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1},
+	/* W1 */
+	{1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1},
+
+	/* V2 */
+	{0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1},
+	/* W2 */
+	{1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1},
+};
+
+/* number of smrx idx for each channel */
+uint32_t g_dss_chn_sid_num[DSS_CHN_MAX_DEFINE] = {
+	4, 1, 4, 4, 4, 4, 1, 1, 3, 3, 3, 2
+};
+
+/* start idx of each channel */
+/* smrx_idx = g_dss_smmu_smrx_idx[chn_idx] + (0 ~ g_dss_chn_sid_num[chn_idx]) */
+uint32_t g_dss_smmu_smrx_idx[DSS_CHN_MAX_DEFINE] = {
+	0, 4, 5, 9, 13, 17, 21, 22, 26, 29, 23, 32
+};
+
+void *g_smmu_rwerraddr_virt = NULL;
+static void aif_bw_sort(dss_aif_bw_t a[], int n)
+{
+	int i = 0;
+	int j = 0;
+	dss_aif_bw_t tmp;
+
+	for (; i < n; ++i) {
+		for (j = i; j < n - 1; ++j) {
+			if (a[j].bw > a[j + 1].bw) {
+				tmp = a[j];
+				a[j] = a[j + 1];
+				a[j + 1] = tmp;
+			}
+		}
+	}
+}
+
+int hisi_dss_aif_handler(struct hisi_fb_data_type *hisifd,
+		     dss_overlay_t *pov_req, dss_overlay_block_t *pov_h_block)
+{
+	int i = 0;
+	int k = 0;
+	dss_layer_t *layer = NULL;
+	dss_wb_layer_t *wb_layer = NULL;
+	int chn_idx = 0;
+	dss_aif_bw_t *aif_bw = NULL;
+	uint32_t tmp = 0;
+	uint32_t bw_sum = 0;
+
+	int rch_cnt = 0;
+	int axi0_cnt = 0;
+	int axi1_cnt = 0;
+	dss_aif_bw_t aif_bw_tmp[DSS_CHN_MAX_DEFINE];
+
+	dss_aif_bw_t *aif1_bw = NULL;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON(pov_h_block == NULL);
+
+	memset(aif_bw_tmp, 0, sizeof(aif_bw_tmp));
+
+	if (pov_req->wb_enable) {
+		for (k = 0; k < pov_req->wb_layer_nums; k++) {
+			wb_layer = &(pov_req->wb_layer_infos[k]);
+			chn_idx = wb_layer->chn_idx;
+
+			aif_bw = &(hisifd->dss_module.aif_bw[chn_idx]);
+			aif_bw->bw = (uint64_t) wb_layer->dst.buf_size *
+			    (wb_layer->src_rect.w * wb_layer->src_rect.h) /
+			    (wb_layer->dst.width * wb_layer->dst.height);
+			aif_bw->chn_idx = chn_idx;
+			aif_bw->axi_sel = AXI_CHN1;
+			aif_bw->is_used = 1;
+		}
+
+		if (pov_req->wb_compose_type == DSS_WB_COMPOSE_COPYBIT) {
+			for (i = 0; i < pov_h_block->layer_nums; i++) {
+				layer = &pov_h_block->layer_infos[i];
+				chn_idx = layer->chn_idx;
+				aif_bw_tmp[i].chn_idx = chn_idx;
+				aif_bw_tmp[i].axi_sel = AXI_CHN0;
+				aif_bw_tmp[i].is_used = 1;
+				hisifd->dss_module.aif_bw[chn_idx] =
+				    aif_bw_tmp[i];
+			}
+			return 0;
+		}
+	}
+
+	rch_cnt = 0;
+	for (i = 0; i < pov_h_block->layer_nums; i++) {
+		layer = &pov_h_block->layer_infos[i];
+		chn_idx = layer->chn_idx;
+
+		if (layer->need_cap & (CAP_BASE | CAP_DIM | CAP_PURE_COLOR))
+			continue;
+
+		if (layer->need_cap & CAP_AFBCD) {
+			aif1_bw = &(hisifd->dss_module.aif1_bw[chn_idx]);
+			aif1_bw->is_used = 1;
+			aif1_bw->chn_idx = chn_idx;
+			if ((pov_req->ovl_idx == DSS_OVL0) ||
+			    (pov_req->ovl_idx == DSS_OVL1)) {
+				if ((i % 2) == 0) {
+					aif1_bw->axi_sel = AXI_CHN0;
+				} else {
+					aif1_bw->axi_sel = AXI_CHN1;
+				}
+			} else {
+				if ((i % 2) == 0) {
+					aif1_bw->axi_sel = AXI_CHN1;
+				} else {
+					aif1_bw->axi_sel = AXI_CHN0;
+				}
+			}
+
+			if (g_debug_ovl_online_composer) {
+				HISI_FB_INFO
+				    ("fb%d, aif1, chn_idx=%d, axi_sel=%d.\n",
+				     hisifd->index, chn_idx, aif1_bw->axi_sel);
+			}
+		}
+
+		aif_bw_tmp[i].bw = (uint64_t) layer->img.buf_size *
+		    (layer->src_rect.w * layer->src_rect.h) /
+		    (layer->img.width * layer->img.height);
+		aif_bw_tmp[i].chn_idx = chn_idx;
+		aif_bw_tmp[i].axi_sel = AXI_CHN0;
+		aif_bw_tmp[i].is_used = 1;
+
+		bw_sum += aif_bw_tmp[i].bw;
+		rch_cnt++;
+	}
+
+	aif_bw_sort(aif_bw_tmp, rch_cnt);
+
+	for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+		if (aif_bw_tmp[i].is_used != 1)
+			continue;
+
+		tmp += aif_bw_tmp[i].bw;
+
+		if ((pov_req->ovl_idx == DSS_OVL0)
+		    || (pov_req->ovl_idx == DSS_OVL1)) {
+			if (tmp <= (bw_sum / 2)) {
+				aif_bw_tmp[i].axi_sel = AXI_CHN0;
+				if (axi0_cnt >= AXI0_MAX_DSS_CHN_THRESHOLD) {
+					aif_bw_tmp[i -
+						   AXI0_MAX_DSS_CHN_THRESHOLD].axi_sel
+					    = AXI_CHN1;
+					axi1_cnt++;
+					axi0_cnt--;
+				}
+				axi0_cnt++;
+			} else {
+				aif_bw_tmp[i].axi_sel = AXI_CHN1;
+				axi1_cnt++;
+			}
+		} else {
+			if (tmp <= (bw_sum / 2)) {
+				aif_bw_tmp[i].axi_sel = AXI_CHN1;
+				if (axi1_cnt >= AXI1_MAX_DSS_CHN_THRESHOLD) {
+					aif_bw_tmp[i -
+						   AXI1_MAX_DSS_CHN_THRESHOLD].axi_sel
+					    = AXI_CHN0;
+					axi0_cnt++;
+					axi1_cnt--;
+				}
+				axi1_cnt++;
+			} else {
+				aif_bw_tmp[i].axi_sel = AXI_CHN0;
+				axi0_cnt++;
+			}
+		}
+
+		chn_idx = aif_bw_tmp[i].chn_idx;
+		hisifd->dss_module.aif_bw[chn_idx] = aif_bw_tmp[i];
+
+		if (g_debug_ovl_online_composer) {
+			HISI_FB_INFO
+			    ("fb%d, aif0, chn_idx=%d, axi_sel=%d, bw=%llu.\n",
+			     hisifd->index, chn_idx, aif_bw_tmp[i].axi_sel,
+			     aif_bw_tmp[i].bw);
+		}
+	}
+
+	return 0;
+}
+
+void hisi_dss_qos_on(struct hisi_fb_data_type *hisifd)
+{
+	outp32(hisifd->noc_dss_base + 0xc, 0x2);
+	outp32(hisifd->noc_dss_base + 0x8c, 0x2);
+	outp32(hisifd->noc_dss_base + 0x10c, 0x2);
+	outp32(hisifd->noc_dss_base + 0x18c, 0x2);
+}
+
+/*******************************************************************************
+ ** DSS AIF
+ */
+static int mid_array[DSS_CHN_MAX_DEFINE] = {
+	0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x2, 0x1, 0x3, 0x0
+};
+#define CREDIT_STEP_LOWER_ENABLE
+void hisi_dss_aif_init(char __iomem *aif_ch_base, dss_aif_t *s_aif)
+{
+	BUG_ON(aif_ch_base == NULL);
+	BUG_ON(s_aif == NULL);
+
+	memset(s_aif, 0, sizeof(dss_aif_t));
+
+	s_aif->aif_ch_ctl = inp32(aif_ch_base + AIF_CH_CTL);
+	s_aif->aif_ch_ctl_add = inp32(aif_ch_base + AIF_CH_CTL_ADD);
+}
+
+void hisi_dss_aif_ch_set_reg(struct hisi_fb_data_type *hisifd,
+			char __iomem *aif_ch_base, dss_aif_t *s_aif)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(aif_ch_base == NULL);
+	BUG_ON(s_aif == NULL);
+
+	hisifd->set_reg(hisifd, aif_ch_base + AIF_CH_CTL, s_aif->aif_ch_ctl, 32,
+			0);
+	hisifd->set_reg(hisifd, aif_ch_base + AIF_CH_CTL_ADD,
+			s_aif->aif_ch_ctl_add, 32, 0);
+}
+
+int hisi_dss_aif_ch_config(struct hisi_fb_data_type *hisifd,
+		       dss_overlay_t *pov_req, dss_layer_t *layer,
+		       dss_rect_t *wb_dst_rect,
+		       dss_wb_layer_t *wb_layer, int ovl_idx)
+{
+	dss_aif_t *aif = NULL;
+	dss_aif_bw_t *aif_bw = NULL;
+	int chn_idx = 0;
+	int mid = 0;
+	uint32_t credit_step = 0;
+	uint32_t credit_step_lower = 0;
+	uint64_t dss_core_rate = 0;
+	uint32_t scfd_h = 0;
+	uint32_t scfd_v = 0;
+	uint32_t online_offline_rate = 1;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON((layer == NULL) && (wb_layer == NULL));
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if (wb_layer) {
+		chn_idx = wb_layer->chn_idx;
+	} else {
+		chn_idx = layer->chn_idx;
+	}
+
+	aif = &(hisifd->dss_module.aif[chn_idx]);
+	hisifd->dss_module.aif_ch_used[chn_idx] = 1;
+
+	aif_bw = &(hisifd->dss_module.aif_bw[chn_idx]);
+	BUG_ON(aif_bw->is_used != 1);
+
+	mid = mid_array[chn_idx];
+	BUG_ON(mid < 0 || mid > 0xb);
+
+	aif->aif_ch_ctl = set_bits32(aif->aif_ch_ctl, aif_bw->axi_sel, 1, 0);
+	aif->aif_ch_ctl = set_bits32(aif->aif_ch_ctl, mid, 4, 4);
+
+	if ((ovl_idx == DSS_OVL2) || (ovl_idx == DSS_OVL3)
+	    || (layer->chn_idx == DSS_RCHN_V2)) {
+		if (layer && ((layer->need_cap & CAP_AFBCD) != CAP_AFBCD)) {
+			dss_core_rate = hisifd->dss_clk_rate.dss_pri_clk_rate;
+			if (dss_core_rate == 0) {
+				HISI_FB_ERR
+				    ("fb%d, dss_core_rate(%llu) is invalid!",
+				     hisifd->index, dss_core_rate);
+				dss_core_rate = DEFAULT_DSS_CORE_CLK_07V_RATE;
+			}
+
+			credit_step_lower =
+			    g_dss_min_bandwidth_inbusbusy * 1000000UL * 8 /
+			    dss_core_rate;
+
+			if ((layer->src_rect.w > layer->dst_rect.w) &&
+			    (layer->src_rect.w > get_panel_xres(hisifd))) {
+				scfd_h =
+				    layer->src_rect.w * 100 /
+				    get_panel_xres(hisifd);
+			} else {
+				scfd_h = 100;
+			}
+
+			if (layer->src_rect.h > layer->dst_rect.h) {
+				scfd_v =
+				    layer->src_rect.h * 100 / layer->dst_rect.h;
+			} else {
+				scfd_v = 100;
+			}
+
+			if (pov_req->wb_compose_type == DSS_WB_COMPOSE_COPYBIT) {
+				if (wb_dst_rect) {
+					online_offline_rate =
+					    wb_dst_rect->w * wb_dst_rect->h /
+					    (hisifd->panel_info.xres *
+					     hisifd->panel_info.yres);
+				}
+
+				if (online_offline_rate == 0)
+					online_offline_rate = 1;
+			}
+
+			credit_step =
+			    hisifd->panel_info.pxl_clk_rate *
+			    online_offline_rate * 32 * scfd_h * scfd_v /
+			    dss_core_rate / (100 * 100);
+
+			if (g_debug_ovl_online_composer
+			    || g_debug_ovl_credit_step) {
+				HISI_FB_INFO
+				    ("fb%d, layer_idx(%d), chn_idx(%d), src_rect(%d,%d,%d,%d),"
+				     "dst_rect(%d,%d,%d,%d), scfd_h=%d, "
+				     "scfd_v=%d, credit_step=%d.\n",
+				     hisifd->index, layer->layer_idx,
+				     layer->chn_idx, layer->src_rect.x,
+				     layer->src_rect.y, layer->src_rect.w,
+				     layer->src_rect.h, layer->dst_rect.x,
+				     layer->dst_rect.y, layer->dst_rect.w,
+				     layer->dst_rect.h, scfd_h, scfd_v,
+				     credit_step);
+			}
+
+			if (credit_step < 32) {
+				credit_step = 32;
+			}
+#ifndef CREDIT_STEP_LOWER_ENABLE
+			if (credit_step > 64) {
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, 0x0, 1, 11);
+			} else {
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, 0x1, 1, 11);
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, credit_step, 7,
+					       16);
+			}
+#else
+			/* credit en lower */
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, 1, 1, 11);
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, 2, 4, 12);
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, credit_step_lower,
+				       7, 16);
+			aif->aif_ch_ctl =
+			    set_bits32(aif->aif_ch_ctl, 0x2, 2, 8);
+			aif->aif_ch_ctl =
+			    set_bits32(aif->aif_ch_ctl, 0x0, 1, 11);
+#endif
+		}
+
+		if (wb_layer) {
+			dss_core_rate = hisifd->dss_clk_rate.dss_pri_clk_rate;
+			if (dss_core_rate == 0) {
+				HISI_FB_ERR
+				    ("fb%d, dss_core_rate(%llu) is invalid!",
+				     hisifd->index, dss_core_rate);
+				dss_core_rate = DEFAULT_DSS_CORE_CLK_07V_RATE;
+			}
+
+			credit_step_lower =
+			    g_dss_min_bandwidth_inbusbusy * 1000000UL * 8 /
+			    dss_core_rate;
+
+			scfd_h = 100;
+			scfd_v = 100;
+			online_offline_rate = 1;
+			credit_step =
+			    hisifd->panel_info.pxl_clk_rate *
+			    online_offline_rate * 32 * scfd_h * scfd_v /
+			    dss_core_rate / (100 * 100);
+
+			if (credit_step < 32) {
+				credit_step = 32;
+			}
+#ifndef CREDIT_STEP_LOWER_ENABLE
+			if (credit_step > 64) {
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, 0x0, 1, 11);
+			} else {
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, 0x1, 1, 11);
+				aif->aif_ch_ctl =
+				    set_bits32(aif->aif_ch_ctl, credit_step, 7,
+					       16);
+			}
+#else
+			/* credit en lower */
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, 1, 1, 11);
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, 2, 4, 12);
+			aif->aif_ch_ctl_add =
+			    set_bits32(aif->aif_ch_ctl_add, credit_step_lower,
+				       7, 16);
+			aif->aif_ch_ctl =
+			    set_bits32(aif->aif_ch_ctl, 0x2, 2, 8);
+			aif->aif_ch_ctl =
+			    set_bits32(aif->aif_ch_ctl, 0x0, 1, 11);
+#endif
+		}
+	}
+	return 0;
+}
+
+int hisi_dss_aif1_ch_config(struct hisi_fb_data_type *hisifd,
+			dss_overlay_t *pov_req, dss_layer_t *layer,
+			dss_wb_layer_t *wb_layer, int ovl_idx)
+{
+	dss_aif_t *aif1 = NULL;
+	dss_aif_bw_t *aif1_bw = NULL;
+	int chn_idx = 0;
+	uint32_t need_cap = 0;
+	int mid = 0;
+	uint32_t credit_step = 0;
+	uint32_t credit_step_lower = 0;
+	uint64_t dss_core_rate = 0;
+	uint32_t scfd_h = 0;
+	uint32_t scfd_v = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(pov_req == NULL);
+	BUG_ON((layer == NULL) && (wb_layer == NULL));
+	BUG_ON((ovl_idx < DSS_OVL0) || (ovl_idx >= DSS_OVL_IDX_MAX));
+
+	if (wb_layer) {
+		chn_idx = wb_layer->chn_idx;
+		need_cap = wb_layer->need_cap;
+	} else {
+		chn_idx = layer->chn_idx;
+		need_cap = layer->need_cap;
+	}
+
+	if (!(need_cap & CAP_AFBCD))
+		return 0;
+
+	aif1 = &(hisifd->dss_module.aif1[chn_idx]);
+	hisifd->dss_module.aif1_ch_used[chn_idx] = 1;
+
+	aif1_bw = &(hisifd->dss_module.aif1_bw[chn_idx]);
+	BUG_ON(aif1_bw->is_used != 1);
+
+	mid = mid_array[chn_idx];
+	BUG_ON(mid < 0 || mid > 0xb);
+
+	aif1->aif_ch_ctl = set_bits32(aif1->aif_ch_ctl, aif1_bw->axi_sel, 1, 0);
+	aif1->aif_ch_ctl = set_bits32(aif1->aif_ch_ctl, mid, 4, 4);
+
+	if ((ovl_idx == DSS_OVL0) || (ovl_idx == DSS_OVL1)) {
+		if (layer && (layer->need_cap & CAP_AFBCD)) {
+			dss_core_rate = hisifd->dss_clk_rate.dss_pri_clk_rate;
+			if (dss_core_rate == 0) {
+				HISI_FB_ERR
+				    ("fb%d, dss_core_rate(%llu) is invalid!",
+				     hisifd->index, dss_core_rate);
+				dss_core_rate = DEFAULT_DSS_CORE_CLK_07V_RATE;
+			}
+
+			if ((layer->src_rect.w > layer->dst_rect.w) &&
+			    (layer->src_rect.w > get_panel_xres(hisifd))) {
+				scfd_h =
+				    layer->src_rect.w * 100 /
+				    get_panel_xres(hisifd);
+			} else {
+				scfd_h = 100;
+			}
+
+			if (layer->src_rect.h > layer->dst_rect.h) {
+				scfd_v =
+				    layer->src_rect.h * 100 / layer->dst_rect.h;
+			} else {
+				scfd_v = 100;
+			}
+
+			credit_step =
+			    hisifd->panel_info.pxl_clk_rate * 32 * 150 *
+			    scfd_h * scfd_v / dss_core_rate / (100 * 100 * 100);
+
+			if (g_debug_ovl_online_composer
+			    || g_debug_ovl_credit_step) {
+				HISI_FB_INFO
+				    ("fb%d, layer_idx(%d), chn_idx(%d), src_rect(%d,%d,%d,%d),"
+				     "dst_rect(%d,%d,%d,%d), scfd_h=%d, "
+				     "scfd_v=%d, credit_step=%d.\n",
+				     hisifd->index, layer->layer_idx,
+				     layer->chn_idx, layer->src_rect.x,
+				     layer->src_rect.y, layer->src_rect.w,
+				     layer->src_rect.h, layer->dst_rect.x,
+				     layer->dst_rect.y, layer->dst_rect.w,
+				     layer->dst_rect.h, scfd_h, scfd_v,
+				     credit_step);
+			}
+
+			if (credit_step < 32) {
+				credit_step = 32;
+			}
+
+			if (credit_step > 64) {
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, 0x0, 1, 11);
+			} else {
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, 0x1, 1, 11);
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, credit_step, 7,
+					       16);
+			}
+
+		}
+	} else {
+		if (layer && (layer->need_cap & CAP_AFBCD)) {
+			dss_core_rate = hisifd->dss_clk_rate.dss_pri_clk_rate;
+			if (dss_core_rate == 0) {
+				HISI_FB_ERR
+				    ("fb%d, dss_core_rate(%llu is invalid!",
+				     hisifd->index, dss_core_rate);
+				dss_core_rate = DEFAULT_DSS_CORE_CLK_07V_RATE;
+			}
+
+			credit_step_lower =
+			    g_dss_min_bandwidth_inbusbusy * 1000000UL * 8 /
+			    dss_core_rate;
+
+			if ((layer->src_rect.w > layer->dst_rect.w) &&
+			    (layer->src_rect.w > get_panel_xres(hisifd))) {
+				scfd_h =
+				    layer->src_rect.w * 100 /
+				    get_panel_xres(hisifd);
+			} else {
+				scfd_h = 100;
+			}
+
+			if (layer->src_rect.h > layer->dst_rect.h) {
+				scfd_v =
+				    layer->src_rect.h * 100 / layer->dst_rect.h;
+			} else {
+				scfd_v = 100;
+			}
+
+			credit_step =
+			    hisifd->panel_info.pxl_clk_rate * 32 * scfd_h *
+			    scfd_v / dss_core_rate / (100 * 100);
+
+			if (g_debug_ovl_online_composer
+			    || g_debug_ovl_credit_step) {
+				HISI_FB_INFO
+				    ("fb%d, layer_idx(%d), chn_idx(%d), src_rect(%d,%d,%d,%d),"
+				     "dst_rect(%d,%d,%d,%d), scfd_h=%d, "
+				     "scfd_v=%d, credit_step=%d.\n",
+				     hisifd->index, layer->layer_idx,
+				     layer->chn_idx, layer->src_rect.x,
+				     layer->src_rect.y, layer->src_rect.w,
+				     layer->src_rect.h, layer->dst_rect.x,
+				     layer->dst_rect.y, layer->dst_rect.w,
+				     layer->dst_rect.h, scfd_h, scfd_v,
+				     credit_step);
+			}
+#ifndef CREDIT_STEP_LOWER_ENABLE
+			if (credit_step > 64) {
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, 0x0, 1, 11);
+			} else {
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, 0x1, 1, 11);
+				aif1->aif_ch_ctl =
+				    set_bits32(aif1->aif_ch_ctl, credit_step, 7,
+					       16);
+			}
+#else
+			/* credit en lower */
+			aif1->aif_ch_ctl_add =
+			    set_bits32(aif1->aif_ch_ctl_add, 1, 1, 11);
+			aif1->aif_ch_ctl_add =
+			    set_bits32(aif1->aif_ch_ctl_add, 2, 4, 12);
+			aif1->aif_ch_ctl_add =
+			    set_bits32(aif1->aif_ch_ctl_add, credit_step_lower,
+				       7, 16);
+			aif1->aif_ch_ctl =
+			    set_bits32(aif1->aif_ch_ctl, 0x2, 2, 8);
+			aif1->aif_ch_ctl =
+			    set_bits32(aif1->aif_ch_ctl, 0x0, 1, 11);
+#endif
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS SMMU
+ */
+void hisi_dss_smmu_on(struct hisi_fb_data_type *hisifd)
+{
+	char __iomem *smmu_base = NULL;
+	int idx0 = 0;
+	int idx1 = 0;
+	int idx2 = 0;
+	uint32_t phy_pgd_base = 0;
+	struct iommu_domain_data *domain_data = NULL;
+	uint64_t smmu_rwerraddr_phys = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	smmu_base = hisifd->dss_base + DSS_SMMU_OFFSET;
+
+	set_reg(smmu_base + SMMU_SCR, 0x0, 1, 0);
+	set_reg(smmu_base + SMMU_SCR, 0x1, 8, 20);
+	set_reg(smmu_base + SMMU_SCR, g_dss_smmu_outstanding - 1, 4, 16);
+	set_reg(smmu_base + SMMU_SCR, 0x7, 3, 3);
+	set_reg(smmu_base + SMMU_LP_CTRL, 0x1, 1, 0);
+
+	set_reg(smmu_base + SMMU_CB_TTBCR, 0x1, 1, 0);
+
+	if (g_smmu_rwerraddr_virt) {
+		smmu_rwerraddr_phys = virt_to_phys(g_smmu_rwerraddr_virt);
+		set_reg(smmu_base + SMMU_ERR_RDADDR,
+			(uint32_t) (smmu_rwerraddr_phys & 0xFFFFFFFF), 32, 0);
+		set_reg(smmu_base + SMMU_ERR_WRADDR,
+			(uint32_t) (smmu_rwerraddr_phys & 0xFFFFFFFF), 32, 0);
+	} else {
+		set_reg(smmu_base + SMMU_ERR_RDADDR, 0x7FF00000, 32, 0);
+		set_reg(smmu_base + SMMU_ERR_WRADDR, 0x7FFF0000, 32, 0);
+	}
+
+	set_reg(smmu_base + SMMU_RLD_EN0_NS, DSS_SMMU_RLD_EN0_DEFAULT_VAL, 32,
+		0);
+	set_reg(smmu_base + SMMU_RLD_EN1_NS, DSS_SMMU_RLD_EN1_DEFAULT_VAL, 32,
+		0);
+
+	idx0 = 36;
+	idx1 = 37;
+	idx2 = 38;
+
+	set_reg(smmu_base + SMMU_SMRx_NS + idx0 * 0x4, 0x1, 32, 0);
+	set_reg(smmu_base + SMMU_SMRx_NS + idx1 * 0x4, 0x1, 32, 0);
+	set_reg(smmu_base + SMMU_SMRx_NS + idx2 * 0x4, 0x1, 32, 0);
+
+	domain_data = (struct iommu_domain_data *)(hisifd->hisi_domain->priv);
+	phy_pgd_base = (uint32_t) (domain_data->phy_pgd_base);
+	set_reg(smmu_base + SMMU_CB_TTBR0, phy_pgd_base, 32, 0);
+}
+
+void hisi_dss_smmu_init(char __iomem *smmu_base, dss_smmu_t *s_smmu)
+{
+	BUG_ON(smmu_base == NULL);
+	BUG_ON(s_smmu == NULL);
+
+	memset(s_smmu, 0, sizeof(dss_smmu_t));
+}
+
+void
+hisi_dss_smmu_ch_set_reg(struct hisi_fb_data_type *hisifd,
+			 char __iomem *smmu_base, dss_smmu_t *s_smmu,
+			 int chn_idx)
+{
+	uint32_t idx = 0;
+	uint32_t i = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(smmu_base == NULL);
+	BUG_ON(s_smmu == NULL);
+
+	if (s_smmu->smmu_smrx_ns_used[chn_idx] == 0)
+		return;
+
+	for (i = 0; i < g_dss_chn_sid_num[chn_idx]; i++) {
+		idx = g_dss_smmu_smrx_idx[chn_idx] + i;
+		BUG_ON((idx < 0) || (idx >= SMMU_SID_NUM));
+
+		hisifd->set_reg(hisifd, smmu_base + SMMU_SMRx_NS + idx * 0x4,
+				s_smmu->smmu_smrx_ns[idx], 32, 0);
+	}
+}
+
+int
+hisi_dss_smmu_ch_config(struct hisi_fb_data_type *hisifd,
+			dss_layer_t *layer, dss_wb_layer_t *wb_layer)
+{
+	dss_smmu_t *smmu = NULL;
+	int chn_idx = 0;
+	dss_img_t *img = NULL;
+	uint32_t idx = 0;
+	uint32_t i = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON((layer == NULL) && (wb_layer == NULL));
+
+	if (wb_layer) {
+		img = &(wb_layer->dst);
+		chn_idx = wb_layer->chn_idx;
+	} else {
+		img = &(layer->img);
+		chn_idx = layer->chn_idx;
+	}
+
+	smmu = &(hisifd->dss_module.smmu);
+	hisifd->dss_module.smmu_used = 1;
+
+	smmu->smmu_smrx_ns_used[chn_idx] = 1;
+
+	for (i = 0; i < g_dss_chn_sid_num[chn_idx]; i++) {
+		idx = g_dss_smmu_smrx_idx[chn_idx] + i;
+		BUG_ON((idx < 0) || (idx >= SMMU_SID_NUM));
+
+		if (img->mmu_enable == 0) {
+			smmu->smmu_smrx_ns[idx] =
+			    set_bits32(smmu->smmu_smrx_ns[idx], 0x1, 1, 0);
+		} else {
+			/* stream config */
+			smmu->smmu_smrx_ns[idx] =
+			    set_bits32(smmu->smmu_smrx_ns[idx], 0x0, 1, 0);
+			smmu->smmu_smrx_ns[idx] =
+			    set_bits32(smmu->smmu_smrx_ns[idx], 0x1, 1, 4);
+			smmu->smmu_smrx_ns[idx] =
+			    set_bits32(smmu->smmu_smrx_ns[idx], 0x3, 7, 5);
+		}
+	}
+	return 0;
+}
+
+void
+hisifb_adjust_block_rect(int block_num, dss_rect_t *ov_block_rects[],
+			 dss_wb_layer_t *wb_layer)
+{
+	return;
+}
+
+/*******************************************************************************
+ ** DSS CSC
+ */
+#define CSC_ROW	(3)
+#define CSC_COL	(5)
+
+/* application: mode 2 is used in rgb2yuv, mode 0 is used in yuv2rgb */
+#define CSC_MPREC_MODE_0 (0)
+#define CSC_MPREC_MODE_1 (1)
+#define CSC_MPREC_MODE_2 (2)
+
+#define CSC_MPREC_MODE_RGB2YUV (CSC_MPREC_MODE_2)
+#define CSC_MPREC_MODE_YUV2RGB (CSC_MPREC_MODE_0)
+
+/*
+ ** Rec.601 for Computer
+ ** [ p00 p01 p02 cscidc2 cscodc2 ]
+ ** [ p10 p11 p12 cscidc1 cscodc1 ]
+ ** [ p20 p21 p22 cscidc0 cscodc0 ]
+ */
+static int CSC_COE_YUV2RGB601_NARROW_MPREC0[CSC_ROW][CSC_COL] = {
+	{0x4a8, 0x000, 0x662, 0x7f0, 0x000},
+	{0x4a8, 0x1e6f, 0x1cc0, 0x77f, 0x000},
+	{0x4a8, 0x812, 0x000, 0x77f, 0x000}
+};
+
+static int CSC_COE_RGB2YUV601_NARROW_MPREC2[CSC_ROW][CSC_COL] = {
+	{0x41C, 0x811, 0x191, 0x000, 0x010},
+	{0x1DA1, 0x1B58, 0x707, 0x000, 0x081},
+	{0x707, 0x1A1E, 0x1EDB, 0x000, 0x081}
+};
+
+static int CSC_COE_YUV2RGB709_NARROW_MPREC0[CSC_ROW][CSC_COL] = {
+	{0x4a8, 0x000, 0x72c, 0x7f0, 0x000},
+	{0x4a8, 0x1f26, 0x1dde, 0x77f, 0x000},
+	{0x4a8, 0x873, 0x000, 0x77f, 0x000}
+};
+
+static int CSC_COE_RGB2YUV709_NARROW_MPREC2[CSC_ROW][CSC_COL] = {
+	{0x2EC, 0x9D4, 0x0FE, 0x000, 0x010},
+	{0x1E64, 0x1A95, 0x707, 0x000, 0x081},
+	{0x707, 0x199E, 0x1F5B, 0x000, 0x081}
+};
+
+static int CSC_COE_YUV2RGB601_WIDE_MPREC0[CSC_ROW][CSC_COL] = {
+	{0x400, 0x000, 0x59c, 0x000, 0x000},
+	{0x400, 0x1ea0, 0x1d25, 0x77f, 0x000},
+	{0x400, 0x717, 0x000, 0x77f, 0x000}
+};
+
+static int CSC_COE_RGB2YUV601_WIDE_MPREC2[CSC_ROW][CSC_COL] = {
+	{0x4C9, 0x964, 0x1d3, 0x000, 0x000},
+	{0x1D4D, 0x1AB3, 0x800, 0x000, 0x081},
+	{0x800, 0x194D, 0x1EB3, 0x000, 0x081},
+};
+
+static int CSC_COE_YUV2RGB709_WIDE_MPREC0[CSC_ROW][CSC_COL] = {
+	{0x400, 0x000, 0x64d, 0x000, 0x000},
+	{0x400, 0x1f40, 0x1e21, 0x77f, 0x000},
+	{0x400, 0x76c, 0x000, 0x77f, 0x000}
+};
+
+static int CSC_COE_RGB2YUV709_WIDE_MPREC2[CSC_ROW][CSC_COL] = {
+	{0x367, 0xB71, 0x128, 0x000, 0x000},
+	{0x1E2B, 0x19D5, 0x800, 0x000, 0x081},
+	{0x800, 0x18BC, 0x1F44, 0x000, 0x081},
+};
+
+void hisi_dss_csc_init(char __iomem *csc_base, dss_csc_t *s_csc)
+{
+	BUG_ON(csc_base == NULL);
+	BUG_ON(s_csc == NULL);
+
+	memset(s_csc, 0, sizeof(dss_csc_t));
+
+	s_csc->idc0 = inp32(csc_base + CSC_IDC0);
+	s_csc->idc2 = inp32(csc_base + CSC_IDC2);
+	s_csc->odc0 = inp32(csc_base + CSC_ODC0);
+	s_csc->odc2 = inp32(csc_base + CSC_ODC2);
+	s_csc->p0 = inp32(csc_base + CSC_P0);
+	s_csc->p1 = inp32(csc_base + CSC_P1);
+	s_csc->p2 = inp32(csc_base + CSC_P2);
+	s_csc->p3 = inp32(csc_base + CSC_P3);
+	s_csc->p4 = inp32(csc_base + CSC_P4);
+	s_csc->icg_module = inp32(csc_base + CSC_ICG_MODULE);
+	s_csc->mprec = inp32(csc_base + CSC_MPREC);
+}
+
+void
+hisi_dss_csc_set_reg(struct hisi_fb_data_type *hisifd,
+		     char __iomem *csc_base, dss_csc_t *s_csc)
+{
+	BUG_ON(hisifd == NULL);
+	BUG_ON(csc_base == NULL);
+	BUG_ON(s_csc == NULL);
+
+	hisifd->set_reg(hisifd, csc_base + CSC_IDC0, s_csc->idc0, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_IDC2, s_csc->idc2, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_ODC0, s_csc->odc0, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_ODC2, s_csc->odc2, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_P0, s_csc->p0, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_P1, s_csc->p1, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_P2, s_csc->p2, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_P3, s_csc->p3, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_P4, s_csc->p4, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_ICG_MODULE,
+			s_csc->icg_module, 32, 0);
+	hisifd->set_reg(hisifd, csc_base + CSC_MPREC, s_csc->mprec, 32, 0);
+}
+
+bool is_pcsc_needed(dss_layer_t *layer)
+{
+	if (layer->chn_idx != DSS_RCHN_V0)
+		return false;
+
+	if (layer->need_cap & CAP_2D_SHARPNESS)
+		return true;
+
+	/* horizental shrink is not supported by arsr2p */
+	if ((layer->dst_rect.h != layer->src_rect.h)
+	    || (layer->dst_rect.w > layer->src_rect.w))
+		return true;
+
+	return false;
+}
+
+int
+hisi_dss_csc_config(struct hisi_fb_data_type *hisifd,
+		    dss_layer_t *layer, dss_wb_layer_t *wb_layer)
+{
+	dss_csc_t *csc = NULL;
+	int chn_idx = 0;
+	uint32_t format = 0;
+	uint32_t csc_mode = 0;
+	int (*csc_coe_yuv2rgb)[CSC_COL];
+	int (*csc_coe_rgb2yuv)[CSC_COL];
+
+	BUG_ON(hisifd == NULL);
+
+	if (wb_layer) {
+		chn_idx = wb_layer->chn_idx;
+		format = wb_layer->dst.format;
+		csc_mode = wb_layer->dst.csc_mode;
+	} else {
+		chn_idx = layer->chn_idx;
+		format = layer->img.format;
+		csc_mode = layer->img.csc_mode;
+	}
+
+	if (chn_idx != DSS_RCHN_V0) {
+		if (!isYUV(format))
+			return 0;
+		hisifd->dss_module.csc_used[chn_idx] = 1;
+	} else if ((chn_idx == DSS_RCHN_V0) && (!isYUV(format))) {
+		if (!is_pcsc_needed(layer))
+			return 0;
+
+		hisifd->dss_module.csc_used[DSS_RCHN_V0] = 1;
+		hisifd->dss_module.pcsc_used[DSS_RCHN_V0] = 1;
+	} else {
+		hisifd->dss_module.csc_used[chn_idx] = 1;
+	}
+
+	if (csc_mode == DSS_CSC_601_WIDE) {
+		csc_coe_yuv2rgb = CSC_COE_YUV2RGB601_WIDE_MPREC0;
+		csc_coe_rgb2yuv = CSC_COE_RGB2YUV601_WIDE_MPREC2;
+	} else if (csc_mode == DSS_CSC_601_NARROW) {
+		csc_coe_yuv2rgb = CSC_COE_YUV2RGB601_NARROW_MPREC0;
+		csc_coe_rgb2yuv = CSC_COE_RGB2YUV601_NARROW_MPREC2;
+	} else if (csc_mode == DSS_CSC_709_WIDE) {
+		csc_coe_yuv2rgb = CSC_COE_YUV2RGB709_WIDE_MPREC0;
+		csc_coe_rgb2yuv = CSC_COE_RGB2YUV709_WIDE_MPREC2;
+	} else if (csc_mode == DSS_CSC_709_NARROW) {
+		csc_coe_yuv2rgb = CSC_COE_YUV2RGB709_NARROW_MPREC0;
+		csc_coe_rgb2yuv = CSC_COE_RGB2YUV709_NARROW_MPREC2;
+	} else {
+		/* TBD  add csc mprec mode 1 and mode 2 */
+		HISI_FB_ERR("not support this csc_mode(%d)!\n", csc_mode);
+		csc_coe_yuv2rgb = CSC_COE_YUV2RGB601_WIDE_MPREC0;
+		csc_coe_rgb2yuv = CSC_COE_RGB2YUV601_WIDE_MPREC2;
+	}
+
+	/* config rch csc */
+	if (layer && hisifd->dss_module.csc_used[chn_idx]) {
+		csc = &(hisifd->dss_module.csc[chn_idx]);
+		csc->mprec = CSC_MPREC_MODE_YUV2RGB;
+		csc->icg_module = set_bits32(csc->icg_module, 0x1, 1, 0);
+
+		csc->idc0 = set_bits32(csc->idc0,
+				       (csc_coe_yuv2rgb[2][3]) |
+				       (csc_coe_yuv2rgb[1][3] << 16), 27, 0);
+		csc->idc2 =
+		    set_bits32(csc->idc2, (csc_coe_yuv2rgb[0][3]), 11, 0);
+
+		csc->odc0 = set_bits32(csc->odc0,
+				       (csc_coe_yuv2rgb[2][4]) |
+				       (csc_coe_yuv2rgb[1][4] << 16), 27, 0);
+		csc->odc2 =
+		    set_bits32(csc->odc2, (csc_coe_yuv2rgb[0][4]), 11, 0);
+
+		csc->p0 = set_bits32(csc->p0, csc_coe_yuv2rgb[0][0], 13, 0);
+		csc->p0 = set_bits32(csc->p0, csc_coe_yuv2rgb[0][1], 13, 16);
+
+		csc->p1 = set_bits32(csc->p1, csc_coe_yuv2rgb[0][2], 13, 0);
+		csc->p1 = set_bits32(csc->p1, csc_coe_yuv2rgb[1][0], 13, 16);
+
+		csc->p2 = set_bits32(csc->p2, csc_coe_yuv2rgb[1][1], 13, 0);
+		csc->p2 = set_bits32(csc->p2, csc_coe_yuv2rgb[1][2], 13, 16);
+
+		csc->p3 = set_bits32(csc->p3, csc_coe_yuv2rgb[2][0], 13, 0);
+		csc->p3 = set_bits32(csc->p3, csc_coe_yuv2rgb[2][1], 13, 16);
+
+		csc->p4 = set_bits32(csc->p4, csc_coe_yuv2rgb[2][2], 13, 0);
+	}
+
+	/* config rch pcsc */
+	if (layer && hisifd->dss_module.pcsc_used[chn_idx]) {
+		csc = &(hisifd->dss_module.pcsc[chn_idx]);
+		csc->mprec = CSC_MPREC_MODE_RGB2YUV;
+		csc->icg_module = set_bits32(csc->icg_module, 0x1, 1, 0);
+
+		csc->idc0 = set_bits32(csc->idc0,
+				       (csc_coe_rgb2yuv[2][3]) |
+				       (csc_coe_rgb2yuv[1][3] << 16), 27, 0);
+		csc->idc2 =
+		    set_bits32(csc->idc2, (csc_coe_rgb2yuv[0][3]), 11, 0);
+
+		csc->odc0 = set_bits32(csc->odc0,
+				       (csc_coe_rgb2yuv[2][4]) |
+				       (csc_coe_rgb2yuv[1][4] << 16), 27, 0);
+		csc->odc2 =
+		    set_bits32(csc->odc2, (csc_coe_rgb2yuv[0][4]), 11, 0);
+
+		csc->p0 = set_bits32(csc->p0, csc_coe_rgb2yuv[0][0], 13, 0);
+		csc->p0 = set_bits32(csc->p0, csc_coe_rgb2yuv[0][1], 13, 16);
+
+		csc->p1 = set_bits32(csc->p1, csc_coe_rgb2yuv[0][2], 13, 0);
+		csc->p1 = set_bits32(csc->p1, csc_coe_rgb2yuv[1][0], 13, 16);
+
+		csc->p2 = set_bits32(csc->p2, csc_coe_rgb2yuv[1][1], 13, 0);
+		csc->p2 = set_bits32(csc->p2, csc_coe_rgb2yuv[1][2], 13, 16);
+
+		csc->p3 = set_bits32(csc->p3, csc_coe_rgb2yuv[2][0], 13, 0);
+		csc->p3 = set_bits32(csc->p3, csc_coe_rgb2yuv[2][1], 13, 16);
+
+		csc->p4 = set_bits32(csc->p4, csc_coe_rgb2yuv[2][2], 13, 0);
+	}
+
+	/* config wch csc */
+	if (wb_layer) {
+		csc = &(hisifd->dss_module.csc[chn_idx]);
+		csc->mprec = CSC_MPREC_MODE_RGB2YUV;
+		csc->icg_module = set_bits32(csc->icg_module, 0x1, 1, 0);
+
+		csc->idc0 = set_bits32(csc->idc0,
+				       (csc_coe_rgb2yuv[2][3]) |
+				       (csc_coe_rgb2yuv[1][3] << 16), 27, 0);
+		csc->idc2 =
+		    set_bits32(csc->idc2, (csc_coe_rgb2yuv[0][3]), 11, 0);
+
+		csc->odc0 = set_bits32(csc->odc0,
+				       (csc_coe_rgb2yuv[2][4]) |
+				       (csc_coe_rgb2yuv[1][4] << 16), 27, 0);
+		csc->odc2 =
+		    set_bits32(csc->odc2, (csc_coe_rgb2yuv[0][4]), 11, 0);
+
+		csc->p0 = set_bits32(csc->p0, csc_coe_rgb2yuv[0][0], 13, 0);
+		csc->p0 = set_bits32(csc->p0, csc_coe_rgb2yuv[0][1], 13, 16);
+
+		csc->p1 = set_bits32(csc->p1, csc_coe_rgb2yuv[0][2], 13, 0);
+		csc->p1 = set_bits32(csc->p1, csc_coe_rgb2yuv[1][0], 13, 16);
+
+		csc->p2 = set_bits32(csc->p2, csc_coe_rgb2yuv[1][1], 13, 0);
+		csc->p2 = set_bits32(csc->p2, csc_coe_rgb2yuv[1][2], 13, 16);
+
+		csc->p3 = set_bits32(csc->p3, csc_coe_rgb2yuv[2][0], 13, 0);
+		csc->p3 = set_bits32(csc->p3, csc_coe_rgb2yuv[2][1], 13, 16);
+
+		csc->p4 = set_bits32(csc->p4, csc_coe_rgb2yuv[2][2], 13, 0);
+	}
+
+	return 0;
+}
+
+uint32_t hisi_dss_mif_get_invalid_sel(dss_img_t *img, uint32_t transform,
+			     int v_scaling_factor, uint8_t is_tile,
+			     bool rdma_stretch_enable)
+{
+	uint32_t invalid_sel_val = 0;
+	uint32_t tlb_tag_org = 0;
+
+	if (img == NULL) {
+		HISI_FB_ERR("img is null");
+		return 0;
+	}
+
+	if ((transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H))
+	    || (transform ==
+		(HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V))) {
+		transform = HISI_FB_TRANSFORM_ROT_90;
+	}
+
+	tlb_tag_org = (transform & 0x7) |
+	    ((is_tile ? 1 : 0) << 3) | ((rdma_stretch_enable ? 1 : 0) << 4);
+
+	switch (tlb_tag_org) {
+	case MMU_TLB_TAG_ORG_0x0:
+		invalid_sel_val = 1;
+		break;
+	case MMU_TLB_TAG_ORG_0x1:
+		invalid_sel_val = 1;
+		break;
+	case MMU_TLB_TAG_ORG_0x2:
+		invalid_sel_val = 2;
+		break;
+	case MMU_TLB_TAG_ORG_0x3:
+		invalid_sel_val = 2;
+		break;
+	case MMU_TLB_TAG_ORG_0x4:
+		invalid_sel_val = 0;
+		break;
+	case MMU_TLB_TAG_ORG_0x7:
+		invalid_sel_val = 0;
+		break;
+
+	case MMU_TLB_TAG_ORG_0x8:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0x9:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0xA:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0xB:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0xC:
+		invalid_sel_val = 0;
+		break;
+	case MMU_TLB_TAG_ORG_0xF:
+		invalid_sel_val = 0;
+		break;
+
+	case MMU_TLB_TAG_ORG_0x10:
+		invalid_sel_val = 1;
+		break;
+	case MMU_TLB_TAG_ORG_0x11:
+		invalid_sel_val = 1;
+		break;
+	case MMU_TLB_TAG_ORG_0x12:
+		invalid_sel_val = 2;
+		break;
+	case MMU_TLB_TAG_ORG_0x13:
+		invalid_sel_val = 2;
+		break;
+	case MMU_TLB_TAG_ORG_0x14:
+		invalid_sel_val = 0;
+		break;
+	case MMU_TLB_TAG_ORG_0x17:
+		invalid_sel_val = 0;
+		break;
+
+	case MMU_TLB_TAG_ORG_0x18:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0x19:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0x1A:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0x1B:
+		invalid_sel_val = 3;
+		break;
+	case MMU_TLB_TAG_ORG_0x1C:
+		invalid_sel_val = 0;
+		break;
+	case MMU_TLB_TAG_ORG_0x1F:
+		invalid_sel_val = 0;
+		break;
+
+	default:
+		invalid_sel_val = 0;
+		HISI_FB_ERR("not support this tlb_tag_org(0x%x)!\n",
+			    tlb_tag_org);
+		break;
+	}
+
+	return invalid_sel_val;
+}
+
+/*******************************************************************************
+ ** DSS ARSR2P
+ */
+#define ARSR2P_PHASE_NUM	(9)
+#define ARSR2P_TAP4	(4)
+#define ARSR2P_TAP6	(6)
+#define ARSR2P_MIN_INPUT (16)
+#define ARSR2P_MAX_WIDTH (2560)
+#define ARSR2P_MAX_HEIGHT (8192)
+#define ARSR2P_SCALE_MAX (60)
+
+#define ARSR2P_SCL_UP_OFFSET (0x48)
+#define ARSR2P_COEF_H0_OFFSET (0x100)
+#define ARSR2P_COEF_H1_OFFSET (0x200)
+
+static const int COEF_AUV_SCL_UP_TAP4[ARSR2P_PHASE_NUM][ARSR2P_TAP4] = {
+	{-3, 254, 6, -1},
+	{-9, 255, 13, -3},
+	{-18, 254, 27, -7},
+	{-23, 245, 44, -10},
+	{-27, 233, 64, -14},
+	{-29, 218, 85, -18},
+	{-29, 198, 108, -21},
+	{-29, 177, 132, -24},
+	{-27, 155, 155, -27}
+};
+
+static const int COEF_AUV_SCL_DOWN_TAP4[ARSR2P_PHASE_NUM][ARSR2P_TAP4] = {
+	{31, 194, 31, 0},
+	{23, 206, 44, -17},
+	{14, 203, 57, -18},
+	{6, 198, 70, -18},
+	{0, 190, 85, -19},
+	{-5, 180, 99, -18},
+	{-10, 170, 114, -18},
+	{-13, 157, 129, -17},
+	{-15, 143, 143, -15}
+};
+
+static const int COEF_Y_SCL_UP_TAP6[ARSR2P_PHASE_NUM][ARSR2P_TAP6] = {
+	{0, -3, 254, 6, -1, 0},
+	{4, -12, 252, 15, -5, 2},
+	{7, -22, 245, 31, -9, 4},
+	{10, -29, 234, 49, -14, 6},
+	{12, -34, 221, 68, -19, 8},
+	{13, -37, 206, 88, -24, 10},
+	{14, -38, 189, 108, -29, 12},
+	{14, -38, 170, 130, -33, 13},
+	{14, -36, 150, 150, -36, 14}
+};
+
+static const int COEF_Y_SCL_DOWN_TAP6[ARSR2P_PHASE_NUM][ARSR2P_TAP6] = {
+	{-22, 43, 214, 43, -22, 0},
+	{-18, 29, 205, 53, -23, 10},
+	{-16, 18, 203, 67, -25, 9},
+	{-13, 9, 198, 80, -26, 8},
+	{-10, 0, 191, 95, -27, 7},
+	{-7, -7, 182, 109, -27, 6},
+	{-5, -14, 174, 124, -27, 4},
+	{-2, -18, 162, 137, -25, 2},
+	{0, -22, 150, 150, -22, 0}
+};
+
+/*******************************************************************************
+ ** DSS ARSR2P
+ */
+int
+hisi_dss_arsr1p_write_coefs(struct hisi_fb_data_type *hisifd,
+			    bool enable_cmdlist, char __iomem *addr,
+			    const int **p, int row, int col)
+{
+	int coef_value = 0;
+	int coef_num = 0;
+	int i = 0;
+	int j = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(addr == NULL);
+
+	if ((row != ARSR2P_PHASE_NUM)
+	    || ((col != ARSR2P_TAP4) && (col != ARSR2P_TAP6))) {
+		HISI_FB_ERR
+		    ("arsr1p filter coefficients is err, arsr1p_phase_num = %d, arsr1p_tap_num = %d\n",
+		     row, col);
+		return -EINVAL;
+	}
+
+	coef_num = (col == ARSR2P_TAP4 ? 2 : 3);
+
+	for (j = 0; j < 2; j++) {
+		for (i = 0; i < row; i++) {
+			if (coef_num == 2) {
+				coef_value =
+				    (*((int *)p + i * col + j * coef_num) &
+				     0x1FF) |
+				    ((*((int *)p + i * col + j * coef_num + 1) &
+				      0x1FF) << 9);
+			} else {
+				coef_value =
+				    (*((int *)p + i * col + j * coef_num) &
+				     0x1FF) |
+				    ((*((int *)p + i * col + j * coef_num + 1) &
+				      0x1FF) << 9) | ((*((int *)p + i * col +
+							 j * coef_num +
+							 2) & 0x1FF) << 18);
+			}
+
+			if (enable_cmdlist) {
+				hisifd->set_reg(hisifd,
+						addr + 0x8 * i + j * 0x4,
+						coef_value, 32, 0);
+			} else {
+				set_reg(addr + 0x8 * i + j * 0x4, coef_value,
+					32, 0);
+			}
+		}
+	}
+
+	return 0;
+}
+
+int
+hisi_dss_post_scl_load_filter_coef(struct hisi_fb_data_type *hisifd,
+				   bool enable_cmdlist,
+				   char __iomem *scl_lut_base,
+				   int coef_lut_idx)
+{
+	int ret = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	ret =
+	    hisi_dss_arsr1p_write_coefs(hisifd, enable_cmdlist,
+					scl_lut_base + ARSR1P_COEFF_H_Y0,
+					(const int **)COEF_Y_SCL_UP_TAP6,
+					ARSR2P_PHASE_NUM, ARSR2P_TAP6);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write H_Y0_COEF coefficients.\n");
+	}
+
+	ret =
+	    hisi_dss_arsr1p_write_coefs(hisifd, enable_cmdlist,
+					scl_lut_base + ARSR1P_COEFF_V_Y0,
+					(const int **)COEF_Y_SCL_UP_TAP6,
+					ARSR2P_PHASE_NUM, ARSR2P_TAP6);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write V_Y0_COEF coefficients.\n");
+	}
+
+	ret =
+	    hisi_dss_arsr1p_write_coefs(hisifd, enable_cmdlist,
+					scl_lut_base + ARSR1P_COEFF_H_UV0,
+					(const int **)COEF_AUV_SCL_UP_TAP4,
+					ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write H_UV0_COEF coefficients.\n");
+	}
+
+	ret =
+	    hisi_dss_arsr1p_write_coefs(hisifd, enable_cmdlist,
+					scl_lut_base + ARSR1P_COEFF_V_UV0,
+					(const int **)COEF_AUV_SCL_UP_TAP4,
+					ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write V_UV0_COEF coefficients.\n");
+	}
+
+	return ret;
+}
+
+int
+hisi_dss_arsr2p_write_coefs(struct hisi_fb_data_type *hisifd,
+			    bool enable_cmdlist, char __iomem *addr,
+			    const int **p, int row, int col)
+{
+	int coef_value = 0;
+	int coef_num = 0;
+	int i = 0;
+	int j = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(addr == NULL);
+
+	if ((row != ARSR2P_PHASE_NUM)
+	    || ((col != ARSR2P_TAP4) && (col != ARSR2P_TAP6))) {
+		HISI_FB_ERR
+		    ("arsr2p filter coefficients is err, arsr2p_phase_num = %d, arsr2p_tap_num = %d\n",
+		     row, col);
+		return -EINVAL;
+	}
+
+	coef_num = (col == ARSR2P_TAP4 ? 2 : 3);
+	for (i = 0; i < row; i++) {
+		for (j = 0; j < 2; j++) {
+			if (coef_num == 2) {
+				coef_value =
+				    (*((int *)p + i * col + j * coef_num) &
+				     0x1FF) |
+				    ((*((int *)p + i * col + j * coef_num + 1) &
+				      0x1FF) << 9);
+			} else {
+				coef_value =
+				    (*((int *)p + i * col + j * coef_num) &
+				     0x1FF) |
+				    ((*((int *)p + i * col + j * coef_num + 1) &
+				      0x1FF) << 9) | ((*((int *)p + i * col +
+							 j * coef_num +
+							 2) & 0x1FF) << 18);
+			}
+
+			if (enable_cmdlist) {
+				hisifd->set_reg(hisifd,
+						addr + 0x8 * i + j * 0x4,
+						coef_value, 32, 0);
+			} else {
+				set_reg(addr + 0x8 * i + j * 0x4, coef_value,
+					32, 0);
+			}
+		}
+	}
+
+	return 0;
+}
+
+void
+hisi_dss_arsr2p_write_config_coefs(struct hisi_fb_data_type *hisifd,
+				   bool enable_cmdlist,
+				   char __iomem *addr,
+				   const int **scl_down,
+				   const int **scl_up, int row, int col)
+{
+	int ret = 0;
+
+	ret =
+	    hisi_dss_arsr2p_write_coefs(hisifd, enable_cmdlist, addr,
+					scl_down, row, col);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write COEF_SCL_DOWN coefficients.\n");
+		return;
+	}
+
+	ret =
+	    hisi_dss_arsr2p_write_coefs(hisifd, enable_cmdlist,
+					addr + ARSR2P_SCL_UP_OFFSET, scl_up,
+					row, col);
+	if (ret < 0) {
+		HISI_FB_ERR("Error to write COEF_SCL_UP coefficients.\n");
+		return;
+	}
+
+}
+
+void hisi_dss_arsr2p_init(char __iomem *arsr2p_base, dss_arsr2p_t *s_arsr2p)
+{
+	BUG_ON(arsr2p_base == NULL);
+	BUG_ON(s_arsr2p == NULL);
+
+	memset(s_arsr2p, 0, sizeof(dss_arsr2p_t));
+
+	s_arsr2p->arsr_input_width_height =
+	    inp32(arsr2p_base + ARSR2P_INPUT_WIDTH_HEIGHT);
+	s_arsr2p->arsr_output_width_height =
+	    inp32(arsr2p_base + ARSR2P_OUTPUT_WIDTH_HEIGHT);
+	s_arsr2p->ihleft = inp32(arsr2p_base + ARSR2P_IHLEFT);
+	s_arsr2p->ihright = inp32(arsr2p_base + ARSR2P_IHRIGHT);
+	s_arsr2p->ivtop = inp32(arsr2p_base + ARSR2P_IVTOP);
+	s_arsr2p->ivbottom = inp32(arsr2p_base + ARSR2P_IVBOTTOM);
+	s_arsr2p->ihinc = inp32(arsr2p_base + ARSR2P_IHINC);
+	s_arsr2p->ivinc = inp32(arsr2p_base + ARSR2P_IVINC);
+	s_arsr2p->offset = inp32(arsr2p_base + ARSR2P_UV_OFFSET);
+	s_arsr2p->mode = inp32(arsr2p_base + ARSR2P_MODE);
+	s_arsr2p->arsr2p_effect.skin_thres_y =
+	    inp32(arsr2p_base + ARSR2P_SKIN_THRES_Y);
+	s_arsr2p->arsr2p_effect.skin_thres_u =
+	    inp32(arsr2p_base + ARSR2P_SKIN_THRES_U);
+	s_arsr2p->arsr2p_effect.skin_thres_v =
+	    inp32(arsr2p_base + ARSR2P_SKIN_THRES_V);
+	s_arsr2p->arsr2p_effect.skin_cfg0 =
+	    inp32(arsr2p_base + ARSR2P_SKIN_CFG0);
+	s_arsr2p->arsr2p_effect.skin_cfg1 =
+	    inp32(arsr2p_base + ARSR2P_SKIN_CFG1);
+	s_arsr2p->arsr2p_effect.skin_cfg2 =
+	    inp32(arsr2p_base + ARSR2P_SKIN_CFG2);
+	s_arsr2p->arsr2p_effect.shoot_cfg1 =
+	    inp32(arsr2p_base + ARSR2P_SHOOT_CFG1);
+	s_arsr2p->arsr2p_effect.shoot_cfg2 =
+	    inp32(arsr2p_base + ARSR2P_SHOOT_CFG2);
+	s_arsr2p->arsr2p_effect.sharp_cfg1 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG1);
+	s_arsr2p->arsr2p_effect.sharp_cfg2 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG2);
+	s_arsr2p->arsr2p_effect.sharp_cfg3 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG3);
+	s_arsr2p->arsr2p_effect.sharp_cfg4 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG4);
+	s_arsr2p->arsr2p_effect.sharp_cfg5 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG5);
+	s_arsr2p->arsr2p_effect.sharp_cfg6 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG6);
+	s_arsr2p->arsr2p_effect.sharp_cfg7 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG7);
+	s_arsr2p->arsr2p_effect.sharp_cfg8 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG8);
+	s_arsr2p->arsr2p_effect.sharp_cfg9 =
+	    inp32(arsr2p_base + ARSR2P_SHARP_CFG9);
+	s_arsr2p->arsr2p_effect.texturw_analysts =
+	    inp32(arsr2p_base + ARSR2P_TEXTURW_ANALYSTS);
+	s_arsr2p->arsr2p_effect.intplshootctrl =
+	    inp32(arsr2p_base + ARSR2P_INTPLSHOOTCTRL);
+
+	s_arsr2p->ihleft1 = inp32(arsr2p_base + ARSR2P_IHLEFT1);
+	s_arsr2p->ihright1 = inp32(arsr2p_base + ARSR2P_IHRIGHT1);
+	s_arsr2p->ivbottom1 = inp32(arsr2p_base + ARSR2P_IVBOTTOM1);
+}
+
+void
+hisi_dss_arsr2p_set_reg(struct hisi_fb_data_type *hisifd,
+			char __iomem *arsr2p_base, dss_arsr2p_t *s_arsr2p)
+{
+	BUG_ON(arsr2p_base == NULL);
+	BUG_ON(s_arsr2p == NULL);
+
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_INPUT_WIDTH_HEIGHT,
+			s_arsr2p->arsr_input_width_height, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_OUTPUT_WIDTH_HEIGHT,
+			s_arsr2p->arsr_output_width_height, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IHLEFT,
+			s_arsr2p->ihleft, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IHRIGHT,
+			s_arsr2p->ihright, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IVTOP,
+			s_arsr2p->ivtop, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IVBOTTOM,
+			s_arsr2p->ivbottom, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IHINC,
+			s_arsr2p->ihinc, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IVINC,
+			s_arsr2p->ivinc, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_UV_OFFSET,
+			s_arsr2p->offset, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_MODE,
+			s_arsr2p->mode, 32, 0);
+
+	if (hisifd->dss_module.arsr2p_effect_used[DSS_RCHN_V0]) {
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_Y,
+				s_arsr2p->arsr2p_effect.skin_thres_y, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_U,
+				s_arsr2p->arsr2p_effect.skin_thres_u, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_V,
+				s_arsr2p->arsr2p_effect.skin_thres_v, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG0,
+				s_arsr2p->arsr2p_effect.skin_cfg0, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG1,
+				s_arsr2p->arsr2p_effect.skin_cfg1, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG2,
+				s_arsr2p->arsr2p_effect.skin_cfg2, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHOOT_CFG1,
+				s_arsr2p->arsr2p_effect.shoot_cfg1, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHOOT_CFG2,
+				s_arsr2p->arsr2p_effect.shoot_cfg2, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG1,
+				s_arsr2p->arsr2p_effect.sharp_cfg1, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG2,
+				s_arsr2p->arsr2p_effect.sharp_cfg2, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG3,
+				s_arsr2p->arsr2p_effect.sharp_cfg3, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG4,
+				s_arsr2p->arsr2p_effect.sharp_cfg4, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG5,
+				s_arsr2p->arsr2p_effect.sharp_cfg5, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG6,
+				s_arsr2p->arsr2p_effect.sharp_cfg6, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG7,
+				s_arsr2p->arsr2p_effect.sharp_cfg7, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG8,
+				s_arsr2p->arsr2p_effect.sharp_cfg8, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG9,
+				s_arsr2p->arsr2p_effect.sharp_cfg9, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_TEXTURW_ANALYSTS,
+				s_arsr2p->arsr2p_effect.texturw_analysts, 32, 0);
+		hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_INTPLSHOOTCTRL,
+				s_arsr2p->arsr2p_effect.intplshootctrl, 32, 0);
+	}
+
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IHLEFT1,
+			s_arsr2p->ihleft1, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IHRIGHT1,
+			s_arsr2p->ihright1, 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_IVBOTTOM1,
+			s_arsr2p->ivbottom1, 32, 0);
+}
+
+void
+hisi_dss_arsr2p_coef_on(struct hisi_fb_data_type *hisifd, bool enable_cmdlist)
+{
+	uint32_t module_base = 0;
+	char __iomem *arsr2p_base = 0;
+	char __iomem *coefy_v = NULL;
+	char __iomem *coefa_v = NULL;
+	char __iomem *coefuv_v = NULL;
+
+	BUG_ON(hisifd == NULL);
+
+	module_base = g_dss_module_base[DSS_RCHN_V0][MODULE_ARSR2P_LUT];
+	coefy_v = hisifd->dss_base + module_base + ARSR2P_LUT_COEFY_V_OFFSET;
+	coefa_v = hisifd->dss_base + module_base + ARSR2P_LUT_COEFA_V_OFFSET;
+	coefuv_v = hisifd->dss_base + module_base + ARSR2P_LUT_COEFUV_V_OFFSET;
+	arsr2p_base =
+	    hisifd->dss_base + g_dss_module_base[DSS_RCHN_V0][MODULE_ARSR2P];
+
+	/* COEFY_V COEFY_H */
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist, coefy_v,
+					   (const int **)
+					   COEF_Y_SCL_DOWN_TAP6,
+					   (const int **)COEF_Y_SCL_UP_TAP6,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP6);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefy_v + ARSR2P_COEF_H0_OFFSET,
+					   (const int **)
+					   COEF_Y_SCL_DOWN_TAP6,
+					   (const int **)COEF_Y_SCL_UP_TAP6,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP6);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefy_v + ARSR2P_COEF_H1_OFFSET,
+					   (const int **)
+					   COEF_Y_SCL_DOWN_TAP6,
+					   (const int **)COEF_Y_SCL_UP_TAP6,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP6);
+
+	/* COEFA_V COEFA_H */
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist, coefa_v,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefa_v + ARSR2P_COEF_H0_OFFSET,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefa_v + ARSR2P_COEF_H1_OFFSET,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+
+	/* COEFUV_V COEFUV_H */
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist, coefuv_v,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefuv_v + ARSR2P_COEF_H0_OFFSET,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+	hisi_dss_arsr2p_write_config_coefs(hisifd, enable_cmdlist,
+					   coefuv_v + ARSR2P_COEF_H1_OFFSET,
+					   (const int **)
+					   COEF_AUV_SCL_DOWN_TAP4,
+					   (const int **)
+					   COEF_AUV_SCL_UP_TAP4,
+					   ARSR2P_PHASE_NUM, ARSR2P_TAP4);
+
+	if (enable_cmdlist) {
+		hisifd->set_reg = hisi_cmdlist_set_reg;
+	} else {
+		hisifd->set_reg = hisifb_set_reg;
+	}
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_Y,
+			(75 | (83 << 8) | (145 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_U,
+			(5 | (10 << 8) | (113 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_THRES_V,
+			(6 | (12 << 8) | (152 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG0,
+			(512 | (3 << 12)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG1, (819), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SKIN_CFG2, (682), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHOOT_CFG1,
+			(512 | (20 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHOOT_CFG2,
+			(-16 | (0 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG1,
+			(2 | (6 << 8) | (48 << 16) | (64 << 24)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG2,
+			(8 | (24 << 8) | (24 << 16) | (40 << 24)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG3,
+			(1 | (1 << 8) | (2500 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG4,
+			(10 | (6 << 8) | (9 << 16) | (12 << 24)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG5,
+			(2 | (12 << 8)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG6,
+			(448 | (64 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG7,
+			(1 | (250 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG8,
+			(-48000), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_SHARP_CFG9,
+			(-32000), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_TEXTURW_ANALYSTS,
+			(15 | (20 << 16)), 32, 0);
+	hisifd->set_reg(hisifd, arsr2p_base + ARSR2P_INTPLSHOOTCTRL,
+			(4), 32, 0);
+
+}
+
+void hisi_dss_arsr2p_effect_config(dss_arsr2p_effect_t *arsr2p_effect)
+{
+	arsr2p_effect->skin_thres_y = 75 | (83 << 8) | (145 << 16);
+	arsr2p_effect->skin_thres_u = 5 | (10 << 8) | (113 << 16);
+	arsr2p_effect->skin_thres_v = 6 | (12 << 8) | (152 << 16);
+	arsr2p_effect->skin_cfg0 = 512 | (3 << 12);
+	arsr2p_effect->skin_cfg1 = 819;
+	arsr2p_effect->skin_cfg2 = 682;
+	arsr2p_effect->shoot_cfg1 = 512 | (20 << 16);
+	arsr2p_effect->shoot_cfg2 = -16 | (0 << 16);
+	arsr2p_effect->sharp_cfg1 = 2 | (6 << 8) | (48 << 16) | (64 << 24);
+	arsr2p_effect->sharp_cfg2 = 8 | (24 << 8) | (24 << 16) | (40 << 24);
+	arsr2p_effect->sharp_cfg3 = 1 | (1 << 8) | (2500 << 16);
+	arsr2p_effect->sharp_cfg4 = 10 | (6 << 8) | (9 << 16) | (12 << 24);
+	arsr2p_effect->sharp_cfg5 = 2 | (12 << 8);
+	arsr2p_effect->sharp_cfg6 = 448 | (64 << 16);
+	arsr2p_effect->sharp_cfg7 = 1 | (250 << 16);
+	arsr2p_effect->sharp_cfg8 = -48000;
+	arsr2p_effect->sharp_cfg9 = -32000;
+	arsr2p_effect->texturw_analysts = 15 | (20 << 16);
+	arsr2p_effect->intplshootctrl = 4;
+}
+
+int
+hisi_dss_arsr2p_config(struct hisi_fb_data_type *hisifd,
+		       dss_layer_t *layer, dss_rect_t *aligned_rect,
+		       bool rdma_stretch_enable)
+{
+	dss_arsr2p_t *arsr2p = NULL;
+	dss_rect_t src_rect;
+	dss_rect_t dst_rect;
+	uint32_t need_cap = 0;
+	int chn_idx = 0;
+	dss_block_info_t *pblock_info = NULL;
+	int extraw = 0, extraw_left = 0, extraw_right = 0;
+
+	bool en_hscl = false;
+	bool en_vscl = false;
+
+	/* arsr mode */
+	bool imageintpl_dis = false;
+	bool hscldown_enabled = false;
+	bool nearest_en = false;
+	bool diintpl_en = false;
+	bool textureanalyhsisen_en = false;
+	bool skinctrl_en = false;
+	bool shootdetect_en = false;
+	bool sharpen_en = false;
+	bool arsr2p_bypass = true;
+
+	bool hscldown_flag = false;
+
+	int ih_inc = 0;
+	int iv_inc = 0;
+	int ih_left = 0;
+	int ih_right = 0;
+	int iv_top = 0;
+	int iv_bottom = 0;
+	int uv_offset = 0;
+	int src_width = 0;
+	int dst_whole_width = 0;
+
+	int outph_left = 0;
+	int outph_right = 0;
+	int outpv_bottom = 0;
+
+	BUG_ON(hisifd == NULL);
+	BUG_ON(layer == NULL);
+
+	chn_idx = layer->chn_idx;
+	if (chn_idx != DSS_RCHN_V0) {
+		return 0;
+	}
+
+	need_cap = layer->need_cap;
+
+	src_rect = layer->src_rect;
+	dst_rect = layer->dst_rect;
+	pblock_info = &(layer->block_info);
+
+	if (pblock_info && pblock_info->h_ratio_arsr2p) {
+		src_rect = pblock_info->arsr2p_in_rect;
+	}
+
+	src_rect.h = aligned_rect->h;
+
+	/* horizental scaler compute */
+	do {
+		if (pblock_info && pblock_info->h_ratio_arsr2p) {
+			ih_inc = pblock_info->h_ratio_arsr2p;
+			src_width = src_rect.w;
+			dst_whole_width = pblock_info->arsr2p_dst_w;
+			src_rect.x = src_rect.x - pblock_info->arsr2p_src_x;
+			src_rect.y = src_rect.y - pblock_info->arsr2p_src_y;
+			dst_rect.x = dst_rect.x - pblock_info->arsr2p_dst_x;
+			dst_rect.y = dst_rect.y - pblock_info->arsr2p_dst_y;
+
+			if (pblock_info->both_vscfh_arsr2p_used) {
+				hscldown_flag = true;
+			}
+
+			if (rdma_stretch_enable) {
+				en_hscl = true;
+			}
+
+			if (ih_inc && ih_inc != ARSR2P_INC_FACTOR) {
+				en_hscl = true;
+			}
+		} else {
+			/* horizental scaling down is not supported by arsr2p, set src_rect.w = dst_rect.w */
+			if (src_rect.w > dst_rect.w) {
+				src_width = dst_rect.w;
+				hscldown_flag = true;
+			} else {
+				src_width = src_rect.w;
+			}
+			dst_whole_width = dst_rect.w;
+
+			src_rect.x = 0;
+			src_rect.y = 0;
+			dst_rect.x = 0;
+			dst_rect.y = 0;
+			if (src_width != dst_rect.w)
+				en_hscl = true;
+
+			ih_inc =
+			    (DSS_WIDTH(src_width) * ARSR2P_INC_FACTOR +
+			     ARSR2P_INC_FACTOR - ih_left) / dst_rect.w;
+		}
+
+		outph_left =
+		    dst_rect.x * ih_inc - (src_rect.x * ARSR2P_INC_FACTOR);
+		if (outph_left < 0)
+			outph_left = 0;
+
+		extraw = (8 * ARSR2P_INC_FACTOR) / ih_inc;
+		extraw_left = (extraw % 2) ? (extraw + 1) : (extraw);
+		ih_left = outph_left - extraw_left * ih_inc;
+		if (ih_left < 0)
+			ih_left = 0;
+
+		outph_right =
+		    (dst_rect.x + dst_rect.w - 1) * ih_inc -
+		    (src_rect.x * ARSR2P_INC_FACTOR);
+		if (dst_whole_width == dst_rect.w) {
+			extraw = (2 * ARSR2P_INC_FACTOR) / ih_inc;
+			extraw_right = (extraw % 2) ? (extraw + 1) : (extraw);
+			ih_right = outph_right + extraw_right * ih_inc;
+
+			/*if(ihright+(starti << 16)) >(width - 1)* ihinc);
+			   ihright = endo*ihinc-(starti<<16); */
+			extraw =
+			    (dst_whole_width - 1) * ih_inc -
+			    (src_rect.x * ARSR2P_INC_FACTOR);
+
+			if (ih_right > extraw) {
+				ih_right = extraw;
+			}
+		} else {
+			ih_right = src_width * ARSR2P_INC_FACTOR - 1;
+		}
+	} while(0);
+
+	/* vertical scaler compute */
+	do {
+		if (src_rect.h != dst_rect.h)
+			en_vscl = true;
+
+		if (src_rect.h > dst_rect.h) {
+			iv_inc =
+			    (DSS_HEIGHT(src_rect.h) * ARSR2P_INC_FACTOR +
+			     ARSR2P_INC_FACTOR / 2 -
+			     iv_top) / DSS_HEIGHT(dst_rect.h);
+		} else {
+			iv_inc =
+			    (DSS_HEIGHT(src_rect.h) * ARSR2P_INC_FACTOR +
+			     ARSR2P_INC_FACTOR - iv_top) / dst_rect.h;
+		}
+
+		iv_bottom = DSS_HEIGHT(dst_rect.h) * iv_inc + iv_top;
+		outpv_bottom = iv_bottom;
+	} while(0);
+
+	if (need_cap & CAP_2D_SHARPNESS) {
+		sharpen_en = true;
+	}
+
+	if ((!en_hscl) && (!en_vscl)) {
+		if (!sharpen_en) {
+			/*if both scaler up and sharpness are not needed, just return */
+			return 0;
+		} else if (!hscldown_flag) {
+			/*if only sharpness is needed, disable image interplo, enable textureanalyhsis */
+			imageintpl_dis = true;
+			textureanalyhsisen_en = true;
+		}
+	}
+
+	arsr2p = &(hisifd->dss_module.arsr2p[chn_idx]);
+	hisifd->dss_module.arsr2p_used[chn_idx] = 1;
+
+	/*check arsr2p input and output width */
+	if ((src_width < ARSR2P_MIN_INPUT) || (dst_rect.w < ARSR2P_MIN_INPUT)
+	    || (src_width > ARSR2P_MAX_WIDTH)
+	    || (dst_rect.w > ARSR2P_MAX_WIDTH)) {
+		HISI_FB_ERR
+		    ("src_rect.w(%d) or dst_rect.w(%d) is smaller than 16 "
+		     "or larger than 2560!\n",
+		     src_width, dst_rect.w);
+		return -EINVAL;
+	}
+
+	if ((dst_rect.w > (src_width * ARSR2P_SCALE_MAX))
+	    || (src_width > (dst_rect.w * ARSR2P_SCALE_MAX))) {
+		HISI_FB_ERR
+		    ("width out of range, original_src_rec(%d, %d, %d, %d) "
+		     "new_src_rect(%d, %d, %d, %d), dst_rect(%d, %d, %d, %d)\n",
+		     layer->src_rect.x, layer->src_rect.y, src_width,
+		     layer->src_rect.h, src_rect.x, src_rect.y, src_width,
+		     src_rect.h, dst_rect.x, dst_rect.y, dst_rect.w,
+		     dst_rect.h);
+
+		return -EINVAL;
+	}
+
+	/*check arsr2p input and output height */
+	if ((src_rect.h > ARSR2P_MAX_HEIGHT)
+	    || (dst_rect.h > ARSR2P_MAX_HEIGHT)) {
+		HISI_FB_ERR
+		    ("src_rect.h(%d) or dst_rect.h(%d) is smaller than 16 "
+		     "or larger than 8192!\n",
+		     src_rect.h, dst_rect.h);
+		return -EINVAL;
+	}
+
+	if ((dst_rect.h > (src_rect.h * ARSR2P_SCALE_MAX))
+	    || (src_rect.h > (dst_rect.h * ARSR2P_SCALE_MAX))) {
+		HISI_FB_ERR
+		    ("height out of range, original_src_rec(%d, %d, %d, %d) "
+		     "new_src_rect(%d, %d, %d, %d), dst_rect(%d, %d, %d, %d).\n",
+		     layer->src_rect.x, layer->src_rect.y, layer->src_rect.w,
+		     layer->src_rect.h, src_rect.x, src_rect.y, src_rect.w,
+		     src_rect.h, dst_rect.x, dst_rect.y, dst_rect.w,
+		     dst_rect.h);
+		return -EINVAL;
+	}
+
+	/*if arsr2p is enabled, hbp+hfp+hsw > 20 */
+	/*if (hisifd_primary && (hisifd_primary->panel_info.ldi.h_back_porch + hisifd_primary->panel_info.ldi.h_front_porch
+	   + hisifd_primary->panel_info.ldi.h_pulse_width) <= 20) {
+	   HISI_FB_ERR("ldi hbp+hfp+hsw is not larger than 20, return!\n");
+	   return -EINVAL;
+	   } */
+
+	/*config arsr2p mode , start */
+	arsr2p_bypass = false;
+	do {
+		if (hscldown_flag) {
+			hscldown_enabled = true;
+			break;
+		}
+
+		if (!en_hscl && (iv_inc >= 2 * ARSR2P_INC_FACTOR)
+		    && !pblock_info->h_ratio_arsr2p) {
+			nearest_en = true;
+			sharpen_en = false;
+			break;
+		}
+
+		if ((!en_hscl) && (!en_vscl)) {
+			break;
+		}
+
+		diintpl_en = true;
+		textureanalyhsisen_en = true;
+	} while(0);
+
+	if (sharpen_en) {
+		skinctrl_en = true;
+		shootdetect_en = true;
+	}
+	/*config arsr2p mode , end */
+
+	/*if sharpness 2d is needed, config the arsr2p effect */
+	hisi_dss_arsr2p_effect_config(&(arsr2p->arsr2p_effect));
+	hisifd->dss_module.arsr2p_effect_used[chn_idx] = 1;
+
+	arsr2p->arsr_input_width_height =
+	    set_bits32(arsr2p->arsr_input_width_height,
+		       DSS_HEIGHT(src_rect.h), 13, 0);
+	arsr2p->arsr_input_width_height =
+	    set_bits32(arsr2p->arsr_input_width_height, DSS_WIDTH(src_width),
+		       13, 16);
+	arsr2p->arsr_output_width_height =
+	    set_bits32(arsr2p->arsr_output_width_height,
+		       DSS_HEIGHT(dst_rect.h), 13, 0);
+	arsr2p->arsr_output_width_height =
+	    set_bits32(arsr2p->arsr_output_width_height,
+		       DSS_WIDTH(dst_rect.w), 13, 16);
+	arsr2p->ihleft = set_bits32(arsr2p->ihleft, ih_left, 29, 0);
+	arsr2p->ihright = set_bits32(arsr2p->ihright, ih_right, 29, 0);
+	arsr2p->ivtop = set_bits32(arsr2p->ivtop, iv_top, 29, 0);
+	arsr2p->ivbottom = set_bits32(arsr2p->ivbottom, iv_bottom, 29, 0);
+	arsr2p->ihinc = set_bits32(arsr2p->ihinc, ih_inc, 22, 0);
+	arsr2p->ivinc = set_bits32(arsr2p->ivinc, iv_inc, 22, 0);
+	arsr2p->offset = set_bits32(arsr2p->offset, uv_offset, 22, 0);
+	arsr2p->mode = set_bits32(arsr2p->mode, arsr2p_bypass, 1, 0);
+	arsr2p->mode = set_bits32(arsr2p->mode, sharpen_en, 1, 1);
+	arsr2p->mode = set_bits32(arsr2p->mode, shootdetect_en, 1, 2);
+	arsr2p->mode = set_bits32(arsr2p->mode, skinctrl_en, 1, 3);
+	arsr2p->mode = set_bits32(arsr2p->mode, textureanalyhsisen_en, 1, 4);
+	arsr2p->mode = set_bits32(arsr2p->mode, diintpl_en, 1, 5);
+	arsr2p->mode = set_bits32(arsr2p->mode, nearest_en, 1, 6);
+	arsr2p->mode = set_bits32(arsr2p->mode, hscldown_enabled, 1, 7);
+	arsr2p->mode = set_bits32(arsr2p->mode, imageintpl_dis, 1, 8);
+
+	arsr2p->ihleft1 = set_bits32(arsr2p->ihleft1, outph_left, 29, 0);
+	arsr2p->ihright1 = set_bits32(arsr2p->ihright1, outph_right, 29, 0);
+	arsr2p->ivbottom1 = set_bits32(arsr2p->ivbottom1, outpv_bottom, 29, 0);
+
+	return 0;
+}
+
+/*******************************************************************************
+ ** DSS remove mctl ch&ov mutex for offline
+ */
+void
+hisi_remove_mctl_mutex(struct hisi_fb_data_type *hisifd, int mctl_idx,
+		       uint32_t cmdlist_idxs)
+{
+	dss_module_reg_t *dss_module = NULL;
+	int i = 0;
+	char __iomem *chn_mutex_base = NULL;
+	char __iomem *cmdlist_base = NULL;
+	uint32_t offset = 0;
+	uint32_t cmdlist_idxs_temp = 0;
+
+	BUG_ON(hisifd == NULL);
+
+	dss_module = &(hisifd->dss_module);
+	cmdlist_base = hisifd->dss_base + DSS_CMDLIST_OFFSET;
+
+	for (i = 0; i < DSS_CHN_MAX_DEFINE; i++) {
+		if (dss_module->mctl_ch_used[i] == 1) {
+			chn_mutex_base =
+			    dss_module->mctl_ch_base[i].chn_mutex_base +
+			    g_dss_module_ovl_base[mctl_idx][MODULE_MCTL_BASE];
+			BUG_ON(chn_mutex_base == NULL);
+
+			set_reg(chn_mutex_base, 0, 32, 0);
+		}
+	}
+
+	set_reg(dss_module->mctl_base[mctl_idx] + MCTL_CTL_MUTEX_OV, 0, 32, 0);
+
+	offset = 0x40;
+	cmdlist_idxs_temp = cmdlist_idxs;
+
+	for (i = 0; i < HISI_DSS_CMDLIST_MAX; i++) {
+		if ((cmdlist_idxs_temp & 0x1) == 0x1) {
+			set_reg(cmdlist_base + CMDLIST_CH0_CTRL + i * offset,
+				0x6, 3, 2);
+		}
+		cmdlist_idxs_temp = cmdlist_idxs_temp >> 1;
+	}
+
+}
+
+void
+hisi_dss_mctl_ov_set_ctl_dbg_reg(struct hisi_fb_data_type *hisifd,
+				 char __iomem *mctl_base, bool enable_cmdlist)
+{
+	if (hisifd == NULL) {
+		HISI_FB_ERR("hisifd is null");
+		return;
+	}
+
+	if (enable_cmdlist) {
+		set_reg(mctl_base + MCTL_CTL_DBG, 0xB03A20, 32, 0);
+		set_reg(mctl_base + MCTL_CTL_TOP, 0x1, 32, 0);
+	} else {
+		set_reg(mctl_base + MCTL_CTL_DBG, 0xB13A00, 32, 0);
+		if (hisifd->index == PRIMARY_PANEL_IDX) {
+			set_reg(mctl_base + MCTL_CTL_TOP, 0x2, 32, 0);
+		} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
+			set_reg(mctl_base + MCTL_CTL_TOP, 0x3, 32, 0);
+		} else {
+			;
+		}
+	}
+}
+
+int
+hisi_dss_check_userdata(struct hisi_fb_data_type *hisifd,
+			dss_overlay_t *pov_req,
+			dss_overlay_block_t *pov_h_block_infos)
+{
+	int i = 0;
+	dss_wb_layer_t *wb_layer = NULL;
+
+	if (hisifd == NULL) {
+		HISI_FB_ERR("invalid hisifd!");
+		return -EINVAL;
+	}
+
+	if (pov_req == NULL) {
+		HISI_FB_ERR("fb%d, invalid pov_req!", hisifd->index);
+		return -EINVAL;
+	}
+
+	if (pov_h_block_infos == NULL) {
+		HISI_FB_ERR("fb%d, invalid pov_h_block_infos!", hisifd->index);
+		return -EINVAL;
+	}
+
+	if ((pov_req->ov_block_nums <= 0) ||
+	    (pov_req->ov_block_nums > HISI_DSS_OV_BLOCK_NUMS)) {
+		HISI_FB_ERR("fb%d, invalid ov_block_nums=%d!",
+			    hisifd->index, pov_req->ov_block_nums);
+		return -EINVAL;
+	}
+
+	if ((pov_h_block_infos->layer_nums <= 0)
+	    || (pov_h_block_infos->layer_nums > MAX_DSS_SRC_NUM)) {
+		HISI_FB_ERR("fb%d, invalid layer_nums=%d!",
+			    hisifd->index, pov_h_block_infos->layer_nums);
+		return -EINVAL;
+	}
+
+	if ((pov_req->ovl_idx < 0) || pov_req->ovl_idx >= DSS_OVL_IDX_MAX) {
+		HISI_FB_ERR("fb%d, invalid ovl_idx=%d!",
+			    hisifd->index, pov_req->ovl_idx);
+		return -EINVAL;
+	}
+
+	if (hisifd->index == PRIMARY_PANEL_IDX) {
+		if (hisifd->panel_info.dirty_region_updt_support) {
+			if (pov_req->dirty_rect.x < 0
+			    || pov_req->dirty_rect.y < 0
+			    || pov_req->dirty_rect.w < 0
+			    || pov_req->dirty_rect.h < 0) {
+				HISI_FB_ERR
+				    ("dirty_rect(%d, %d, %d, %d) is out of range!\n",
+				     pov_req->dirty_rect.x,
+				     pov_req->dirty_rect.y,
+				     pov_req->dirty_rect.w,
+				     pov_req->dirty_rect.h);
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		if (pov_req->wb_enable != 1) {
+			HISI_FB_ERR("pov_req->wb_enable=%u is invalid!\n",
+				    pov_req->wb_enable);
+			return -EINVAL;
+		}
+
+		if ((pov_req->wb_layer_nums <= 0) ||
+		    (pov_req->wb_layer_nums > MAX_DSS_DST_NUM)) {
+			HISI_FB_ERR("fb%d, invalid wb_layer_nums=%d!",
+				    hisifd->index, pov_req->wb_layer_nums);
+			return -EINVAL;
+		}
+
+		if (pov_req->wb_ov_rect.x < 0 || pov_req->wb_ov_rect.y < 0) {
+			HISI_FB_ERR("wb_ov_rect(%d, %d) is out of range!\n",
+				    pov_req->wb_ov_rect.x,
+				    pov_req->wb_ov_rect.y);
+			return -EINVAL;
+		}
+
+		if (pov_req->wb_compose_type >= DSS_WB_COMPOSE_TYPE_MAX) {
+			HISI_FB_ERR("wb_compose_type=%u is invalid!\n",
+				    pov_req->wb_compose_type);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < pov_req->wb_layer_nums; i++) {
+			wb_layer = &(pov_req->wb_layer_infos[i]);
+
+			if (wb_layer->chn_idx != DSS_WCHN_W2) {
+				if (wb_layer->chn_idx < DSS_WCHN_W0
+				    || wb_layer->chn_idx > DSS_WCHN_W1) {
+					HISI_FB_ERR
+					    ("fb%d, wchn_idx=%d is invalid!",
+					     hisifd->index, wb_layer->chn_idx);
+					return -EINVAL;
+				}
+			}
+
+			if (wb_layer->dst.format >= HISI_FB_PIXEL_FORMAT_MAX) {
+				HISI_FB_ERR("fb%d, format=%d is invalid!",
+					    hisifd->index,
+					    wb_layer->dst.format);
+				return -EINVAL;
+			}
+
+			if ((wb_layer->dst.bpp == 0)
+			    || (wb_layer->dst.width == 0)
+			    || (wb_layer->dst.height == 0)
+			    || (wb_layer->dst.stride == 0)) {
+				HISI_FB_ERR
+				    ("fb%d, bpp=%d, width=%d, height=%d, stride=%d is invalid!",
+				     hisifd->index, wb_layer->dst.bpp,
+				     wb_layer->dst.width, wb_layer->dst.height,
+				     wb_layer->dst.stride);
+				return -EINVAL;
+			}
+#if 0
+			if (wb_layer->dst.mmu_enable) {
+				if (wb_layer->dst.buf_size == 0) {
+					HISI_FB_ERR
+					    ("fb%d, buf_size=%d is invalid!",
+					     hisifd->index,
+					     wb_layer->dst.buf_size);
+					return -EINVAL;
+				}
+			}
+
+			if (isYUVSemiPlanar(wb_layer->dst.format)
+			    || isYUVPlanar(wb_layer->dst.format)) {
+				if ((wb_layer->dst.stride_plane1 == 0)
+				    || (wb_layer->dst.offset_plane1 == 0)) {
+					HISI_FB_ERR
+					    ("fb%d, stride_plane1=%d, offset_plane1=%d is invalid!",
+					     hisifd->index,
+					     wb_layer->dst.stride_plane1,
+					     wb_layer->dst.offset_plane1);
+					return -EINVAL;
+				}
+			}
+
+			if (isYUVPlanar(wb_layer->dst.format)) {
+				if ((wb_layer->dst.stride_plane2 == 0)
+				    || (wb_layer->dst.offset_plane2 == 0)) {
+					HISI_FB_ERR
+					    ("fb%d, stride_plane2=%d, offset_plane2=%d is invalid!",
+					     hisifd->index,
+					     wb_layer->dst.stride_plane2,
+					     wb_layer->dst.offset_plane2);
+					return -EINVAL;
+				}
+			}
+#endif
+
+			if (wb_layer->need_cap & CAP_AFBCE) {
+				if ((wb_layer->dst.afbc_header_stride == 0)
+				    || (wb_layer->dst.afbc_payload_stride == 0)) {
+					HISI_FB_ERR
+					    ("fb%d, afbc_header_stride=%d, afbc_payload_stride=%d is invalid!",
+					     hisifd->index,
+					     wb_layer->dst.afbc_header_stride,
+					     wb_layer->dst.afbc_payload_stride);
+					return -EINVAL;
+				}
+			}
+
+			if (wb_layer->dst.csc_mode >= DSS_CSC_MOD_MAX) {
+				HISI_FB_ERR("fb%d, csc_mode=%d is invalid!",
+					    hisifd->index,
+					    wb_layer->dst.csc_mode);
+				return -EINVAL;
+			}
+
+			if (wb_layer->dst.afbc_scramble_mode >=
+			    DSS_AFBC_SCRAMBLE_MODE_MAX) {
+				HISI_FB_ERR
+				    ("fb%d, afbc_scramble_mode=%d is invalid!",
+				     hisifd->index,
+				     wb_layer->dst.afbc_scramble_mode);
+				return -EINVAL;
+			}
+
+			if (wb_layer->src_rect.x < 0 || wb_layer->src_rect.y < 0
+			    || wb_layer->src_rect.w <= 0
+			    || wb_layer->src_rect.h <= 0) {
+				HISI_FB_ERR
+				    ("src_rect(%d, %d, %d, %d) is out of range!\n",
+				     wb_layer->src_rect.x, wb_layer->src_rect.y,
+				     wb_layer->src_rect.w,
+				     wb_layer->src_rect.h);
+				return -EINVAL;
+			}
+
+			if (wb_layer->dst_rect.x < 0 || wb_layer->dst_rect.y < 0
+			    || wb_layer->dst_rect.w <= 0
+			    || wb_layer->dst_rect.h <= 0) {
+				HISI_FB_ERR
+				    ("dst_rect(%d, %d, %d, %d) is out of range!\n",
+				     wb_layer->dst_rect.x, wb_layer->dst_rect.y,
+				     wb_layer->dst_rect.w,
+				     wb_layer->dst_rect.h);
+				return -EINVAL;
+			}
+		}
+	} else {
+		;
+	}
+
+	return 0;
+}
+
+int
+hisi_dss_check_layer_par(struct hisi_fb_data_type *hisifd, dss_layer_t *layer)
+{
+	if (hisifd == NULL) {
+		HISI_FB_ERR("hisifd is NULL, return!");
+		return -EINVAL;
+	}
+
+	if (layer == NULL) {
+		HISI_FB_ERR("layer is NULL, return!");
+		return -EINVAL;
+	}
+
+	if (layer->layer_idx < 0 || layer->layer_idx >= MAX_DSS_SRC_NUM) {
+		HISI_FB_ERR("fb%d, layer_idx=%d is invalid!", hisifd->index,
+			    layer->layer_idx);
+		return -EINVAL;
+	}
+
+	if (layer->need_cap & (CAP_BASE | CAP_DIM | CAP_PURE_COLOR))
+		return 0;
+
+	if (hisifd->index == AUXILIARY_PANEL_IDX) {
+		if (layer->chn_idx != DSS_RCHN_V2) {
+			if (layer->chn_idx < 0 || layer->chn_idx >= DSS_WCHN_W0) {
+				HISI_FB_ERR("fb%d, rchn_idx=%d is invalid!",
+					    hisifd->index, layer->chn_idx);
+				return -EINVAL;
+			}
+		}
+
+		if (layer->chn_idx == DSS_RCHN_D2) {
+			HISI_FB_ERR
+			    ("fb%d, chn_idx[%d] does not used by offline play!",
+			     hisifd->index, layer->chn_idx);
+			return -EINVAL;
+		}
+	} else {
+		if (layer->chn_idx < 0 || layer->chn_idx >= DSS_WCHN_W0) {
+			HISI_FB_ERR("fb%d, rchn_idx=%d is invalid!",
+				    hisifd->index, layer->chn_idx);
+			return -EINVAL;
+		}
+	}
+
+	if (layer->blending < 0 || layer->blending >= HISI_FB_BLENDING_MAX) {
+		HISI_FB_ERR("fb%d, blending=%d is invalid!", hisifd->index,
+			    layer->blending);
+		return -EINVAL;
+	}
+
+	if (layer->img.format >= HISI_FB_PIXEL_FORMAT_MAX) {
+		HISI_FB_ERR("fb%d, format=%d is invalid!", hisifd->index,
+			    layer->img.format);
+		return -EINVAL;
+	}
+
+	if ((layer->img.bpp == 0) || (layer->img.width == 0)
+	    || (layer->img.height == 0) || (layer->img.stride == 0)) {
+		HISI_FB_ERR
+		    ("fb%d, bpp=%d, width=%d, height=%d, stride=%d is invalid!",
+		     hisifd->index, layer->img.bpp, layer->img.width,
+		     layer->img.height, layer->img.stride);
+		return -EINVAL;
+	}
+#if 0
+	if (layer->img.mmu_enable) {
+		if (layer->img.buf_size == 0) {
+			HISI_FB_ERR("fb%d, buf_size=%d is invalid!",
+				    hisifd->index, layer->img.buf_size);
+			return -EINVAL;
+		}
+	}
+
+	if (isYUVSemiPlanar(layer->img.format)
+	    || isYUVPlanar(layer->img.format)) {
+		if ((layer->img.stride_plane1 == 0)
+		    || (layer->img.offset_plane1 == 0)) {
+			HISI_FB_ERR
+			    ("fb%d, stride_plane1=%d, offset_plane1=%d is invalid!",
+			     hisifd->index, layer->img.stride_plane1,
+			     layer->img.offset_plane1);
+			return -EINVAL;
+		}
+	}
+
+	if (isYUVPlanar(layer->img.format)) {
+		if ((layer->img.stride_plane2 == 0)
+		    || (layer->img.offset_plane2 == 0)) {
+			HISI_FB_ERR
+			    ("fb%d, stride_plane2=%d, offset_plane2=%d is invalid!",
+			     hisifd->index, layer->img.stride_plane2,
+			     layer->img.offset_plane2);
+			return -EINVAL;
+		}
+	}
+#endif
+
+	if (layer->need_cap & CAP_AFBCD) {
+		if ((layer->img.afbc_header_stride == 0)
+		    || (layer->img.afbc_payload_stride == 0)
+		    || (layer->img.mmbuf_size == 0)) {
+			HISI_FB_ERR
+			    ("fb%d, afbc_header_stride=%d, afbc_payload_stride=%d, "
+			     "mmbuf_size=%d is invalid!",
+			     hisifd->index, layer->img.afbc_header_stride,
+			     layer->img.afbc_payload_stride,
+			     layer->img.mmbuf_size);
+			return -EINVAL;
+		}
+	}
+
+	if (layer->img.csc_mode >= DSS_CSC_MOD_MAX) {
+		HISI_FB_ERR("fb%d, csc_mode=%d is invalid!", hisifd->index,
+			    layer->img.csc_mode);
+		return -EINVAL;
+	}
+
+	if (layer->img.afbc_scramble_mode >= DSS_AFBC_SCRAMBLE_MODE_MAX) {
+		HISI_FB_ERR("fb%d, afbc_scramble_mode=%d is invalid!",
+			    hisifd->index, layer->img.afbc_scramble_mode);
+		return -EINVAL;
+	}
+
+	if ((layer->layer_idx != 0) && (layer->need_cap & CAP_BASE)) {
+		HISI_FB_ERR("fb%d, layer%d is not base!", hisifd->index,
+			    layer->layer_idx);
+		return -EINVAL;
+	}
+
+	if (layer->src_rect.x < 0 || layer->src_rect.y < 0 ||
+	    layer->src_rect.w <= 0 || layer->src_rect.h <= 0) {
+		HISI_FB_ERR("src_rect(%d, %d, %d, %d) is out of range!\n",
+			    layer->src_rect.x, layer->src_rect.y,
+			    layer->src_rect.w, layer->src_rect.h);
+		return -EINVAL;
+	}
+
+	if (layer->src_rect_mask.x < 0 || layer->src_rect_mask.y < 0 ||
+	    layer->src_rect_mask.w < 0 || layer->src_rect_mask.h < 0) {
+		HISI_FB_ERR("src_rect_mask(%d, %d, %d, %d) is out of range!\n",
+			    layer->src_rect_mask.x, layer->src_rect_mask.y,
+			    layer->src_rect_mask.w, layer->src_rect_mask.h);
+		return -EINVAL;
+	}
+
+	if (layer->dst_rect.x < 0 || layer->dst_rect.y < 0 ||
+	    layer->dst_rect.w <= 0 || layer->dst_rect.h <= 0) {
+		HISI_FB_ERR("dst_rect(%d, %d, %d, %d) is out of range!\n",
+			    layer->dst_rect.x, layer->dst_rect.y,
+			    layer->dst_rect.w, layer->dst_rect.h);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void hisifb_disreset_dss(struct hisi_fb_data_type *hisifd)
+{
+}
diff --git a/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.h b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.h
new file mode 100755
index 000000000000..1d5b1fc0cc92
--- /dev/null
+++ b/drivers/video/fbdev/hisi/dss/hisi_overlay_utils_hi3660.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2013-2014, Hisilicon Tech. Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _HISI_OVERLAY_UTILS_PLATFORM_H_
+#define _HISI_OVERLAY_UTILS_PLATFORM_H_
+
+#define HISI_DSS_VERSION_V400
+
+#define GPIO_LCD_POWER_1V2  (54)
+#define GPIO_LCD_STANDBY    (67)
+#define GPIO_LCD_RESETN     (65)
+#define GPIO_LCD_GATING     (60)
+#define GPIO_LCD_PCLK_GATING (58)
+#define GPIO_LCD_REFCLK_GATING (59)
+#define GPIO_LCD_SPICS         (168)
+#define GPIO_LCD_DRV_EN        (73)
+
+#define GPIO_PG_SEL_A (72)
+#define GPIO_TX_RX_A (74)
+#define GPIO_PG_SEL_B (76)
+#define GPIO_TX_RX_B (78)
+
+/*******************************************************************************
+ **
+ */
+#define CRGPERI_PLL0_CLK_RATE	(1600000000UL)
+#define CRGPERI_PLL2_CLK_RATE	(960000000UL)
+#define CRGPERI_PLL3_CLK_RATE	(1600000000UL)
+
+#define DEFAULT_DSS_CORE_CLK_08V_RATE	(535000000UL)
+#define DEFAULT_DSS_CORE_CLK_07V_RATE	(400000000UL)
+#define DEFAULT_PCLK_DSS_RATE	(114000000UL)
+#define DEFAULT_PCLK_PCTRL_RATE	(80000000UL)
+#define DSS_MAX_PXL0_CLK_288M (288000000UL)
+
+#define MMBUF_SIZE_MAX	(288 * 1024)
+#define HISI_DSS_CMDLIST_MAX	(16)
+#define HISI_DSS_CMDLIST_IDXS_MAX (0xFFFF)
+#define HISI_DSS_COPYBIT_CMDLIST_IDXS	 (0xC000)
+#define HISI_DSS_DPP_MAX_SUPPORT_BIT (0x7ff)
+#define HISIFB_DSS_PLATFORM_TYPE  (FB_ACCEL_HI366x | FB_ACCEL_PLATFORM_TYPE_ASIC)
+
+#define DSS_MIF_SMMU_SMRX_IDX_STEP (16)
+#define CRG_PERI_DIS3_DEFAULT_VAL     (0x0002F000)
+#define SCF_LINE_BUF	(2560)
+#define DSS_GLB_MODULE_CLK_SEL_DEFAULT_VAL  (0xF0000008)
+#define DSS_LDI_CLK_SEL_DEFAULT_VAL    (0x00000004)
+#define DSS_DBUF_MEM_CTRL_DEFAULT_VAL  (0x00000008)
+#define DSS_SMMU_RLD_EN0_DEFAULT_VAL    (0xffffffff)
+#define DSS_SMMU_RLD_EN1_DEFAULT_VAL    (0xffffff8f)
+#define DSS_SMMU_OUTSTANDING_VAL		(0xf)
+#define DSS_MIF_CTRL2_INVAL_SEL3_STRIDE_MASK		(0xc)
+#define DSS_AFBCE_ENC_OS_CFG_DEFAULT_VAL			(0x7)
+#define TUI_SEC_RCH			(DSS_RCHN_V0)
+#define DSS_CHN_MAX_DEFINE (DSS_COPYBIT_MAX)
+
+/* perf stat */
+#define DSS_DEVMEM_PERF_BASE						(0xFDF10000)
+#define CRG_PERIPH_APB_PERRSTSTAT0_REG 				(0x68)
+#define CRG_PERIPH_APB_IP_RST_PERF_STAT_BIT 		(18)
+#define PERF_SAMPSTOP_REG 							(0x10)
+#define DEVMEM_PERF_SIZE							(0x100)
+
+#endif
-- 
2.12.0-rc0

  parent reply	other threads:[~2017-02-07  2:37 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20170207024027epcas5p2528e797ee0c34cb60d97f0b659f4acbf@epcas5p2.samsung.com>
2017-02-07  2:35 ` [PATCH 1/8] fb: hisilicon: Add framebuffer driver for hi3660 SoC cailiwei
2017-02-07  2:35   ` cailiwei
2017-02-07  2:35   ` [PATCH 2/8] " cailiwei
2017-02-07  2:35     ` cailiwei
2017-02-07  2:35   ` [PATCH 3/8] " cailiwei
2017-02-07  2:35   ` [PATCH 4/8] " cailiwei
2017-02-07  2:35   ` [PATCH 5/8] " cailiwei
2017-02-07  2:35     ` cailiwei
2017-02-07  2:35   ` [PATCH 6/8] " cailiwei
2017-02-07  2:35     ` cailiwei
2017-02-07  2:35   ` cailiwei [this message]
2017-02-07  2:35   ` [PATCH 8/8] " cailiwei
2017-02-07  2:35     ` cailiwei
2017-02-08 16:07   ` [PATCH 1/8] " Bartlomiej Zolnierkiewicz
2017-02-08 16:07     ` Bartlomiej Zolnierkiewicz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170207023559.79455-7-cailiwei@hisilicon.com \
    --to=cailiwei@hisilicon.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=dengqingshan@hisilicon.com \
    --cc=guodong.xu@linaro.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=shizongxuan@huawei.com \
    --cc=suzhuangluan@hisilicon.com \
    --cc=xuhongtao8@hisilicon.com \
    --cc=zhengwanchun@hisilicon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.