lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170207023559.79455-7-cailiwei@hisilicon.com>
Date:   Tue, 7 Feb 2017 10:35:58 +0800
From:   cailiwei <cailiwei@...ilicon.com>
To:     <linux-fbdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <b.zolnierkie@...sung.com>, <guodong.xu@...aro.org>
CC:     <suzhuangluan@...ilicon.com>, <dengqingshan@...ilicon.com>,
        <xuhongtao8@...ilicon.com>, <zhengwanchun@...ilicon.com>,
        <shizongxuan@...wei.com>, <cailiwei@...ilicon.com>
Subject: [PATCH 7/8] fb: hisilicon: Add framebuffer driver for hi3660 SoC

From: Levy-Cai <cailiwei@...ilicon.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@...ilicon.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ