int hisi_lcd_backlight_off(struct platform_device *pdev)
{
	struct hisi_fb_data_type *hisifd = NULL;
	int ret = 0;

	BUG_ON(pdev == NULL);
	hisifd = platform_get_drvdata(pdev);
	BUG_ON(hisifd == NULL);

	HISI_FB_INFO("fb%d, +!\n", hisifd->index);

	if (hisifd->panel_info.bl_set_type & BL_SET_BY_PWM) {
		ret = hisi_pwm_off(pdev);
		#ifdef CONFIG_BACKLIGHT_10000
		        ret = hisi_blpwm_off(pdev);
		#endif
	} else if (hisifd->panel_info.bl_set_type & BL_SET_BY_BLPWM) {
		ret = hisi_blpwm_off(pdev);
	} else if (hisifd->panel_info.bl_set_type & BL_SET_BY_MIPI) {
		;
	} else {
		HISI_FB_ERR("No such bl_set_type(%d)!\n", hisifd->panel_info.bl_set_type);
	}

	HISI_FB_INFO("fb%d, -!\n", hisifd->index);

	return ret;
}
int hisi_pwm_set_backlight(struct hisi_fb_data_type *hisifd)
{
	char __iomem *pwm_base = NULL;
	uint32_t bl_max = 0;
	uint32_t bl_level = 0;

	BUG_ON(hisifd == NULL);

	pwm_base = hisifd_pwm_base;
	BUG_ON(pwm_base == NULL);

	#ifdef CONFIG_BACKLIGHT_10000
	    g_bl_info.bl_max = hisifd->panel_info.bl_max;
	#endif
	bl_level = hisifd->bl_level;
	bl_max = hisifd->panel_info.bl_max;
	if (bl_level > hisifd->panel_info.bl_max) {
		bl_level = hisifd->panel_info.bl_max;
	}

	if (bl_max < 1) {
		HISI_FB_ERR("bl_max=%d is invalid!\n", bl_max);
		return -EINVAL;
	}

	if ((bl_level > 0) && (bl_level < PWM_BL_LEVEL_MIN)) {
		bl_level = PWM_BL_LEVEL_MIN;
	}

	#ifdef CONFIG_BACKLIGHT_10000
	      if(bl_level > 0){
		    bl_level= bl_level * g_bl_info.current_cabc_pwm / CABC_PWM_DUTY_MAX_LEVEL;
		    bl_level =  bl_level < PWM_BL_LEVEL_MIN ? PWM_BL_LEVEL_MIN : bl_level ;
	      }
	      g_bl_info.ap_brightness = bl_level;
	      HISI_FB_INFO("g_bl_info.ap_brightness= %d\n",bl_level);
	      if(bl_level > 0 && g_bl_info.index_cabc_dimming > 0 &&  g_bl_info.index_cabc_dimming < 33 )
	      {
		    HISI_FB_INFO("cabc is dimming and g_bl_info.index_cabc_dimming = %d\n",g_bl_info.index_cabc_dimming);
		    return;
	      }
	#endif

	bl_level = (bl_level * PWM_OUT_PRECISION) / bl_max;

	outp32(pwm_base + PWM_LOCK_OFFSET, 0x1acce551);
	outp32(pwm_base + PWM_CTL_OFFSET, 0x0);
	outp32(pwm_base + PWM_CFG_OFFSET, 0x2);
	outp32(pwm_base + PWM_PR0_OFFSET, 0x1);
	outp32(pwm_base + PWM_PR1_OFFSET, 0x2);
	outp32(pwm_base + PWM_CTL_OFFSET, 0x1);
	outp32(pwm_base + PWM_C0_MR_OFFSET, (PWM_OUT_PRECISION - 1));
	outp32(pwm_base + PWM_C0_MR0_OFFSET, bl_level);

	return 0;
}
int mipi_dsi_read_compare(struct mipi_dsi_read_compare_data *data, char __iomem *dsi_base)
{
	u32 *read_value = data->read_value;
	u32 *expected_value = data->expected_value;
	u32 *read_mask = data->read_mask;
	char **reg_name = data->reg_name;
	int log_on = data->log_on;
	struct dsi_cmd_desc *cmds = data->cmds;
	int cnt = data->cnt;

	int cnt_not_match = 0;
	int read_ret = 0;
	int i;

	read_ret = mipi_dsi_cmds_rx(read_value, cmds, cnt, dsi_base);

	if(read_ret){
		HISI_FB_ERR("Read error number: %d\n", read_ret);
		return cnt;
	}
	for(i=0; i<cnt; i++) {
		if (log_on) {
			HISI_FB_INFO("Read reg %s: 0x%X, value = 0x%X\n", reg_name[i], cmds[i].payload[0], read_value[i]);
		}
		if(expected_value[i] != (read_value[i] & read_mask[i])){
			cnt_not_match++;
		}
	}

	return cnt_not_match;
}
static int cabc_pwm_thread(void *p)
{
	while(!kthread_should_stop())
	{
		if(g_bl_info.index_cabc_dimming > CABC_DIMMING_STEP_TOTAL_NUM)
		{
			set_current_state(TASK_INTERRUPTIBLE);
			schedule();
			g_bl_info.index_cabc_dimming =1 ;
		}
		else
		{
			if(g_bl_info.cabc_pwm_in != 0)
			{
			    g_bl_info.cabc_pwm = g_bl_info.cabc_pwm_in;
			    g_bl_info.cabc_pwm_in = 0;
			    g_bl_info.index_cabc_dimming = 1;
			    g_bl_info.prev_cabc_pwm = g_bl_info.current_cabc_pwm;
			}
			int32_t delta_cabc_pwm = g_bl_info.cabc_pwm - g_bl_info.prev_cabc_pwm;
			int32_t pwm_duty=delta_cabc_pwm*g_bl_info.index_cabc_dimming/32 + delta_cabc_pwm *g_bl_info.index_cabc_dimming % 32 /16;
			g_bl_info.current_cabc_pwm = g_bl_info.prev_cabc_pwm +   pwm_duty;
			HISI_FB_INFO("g_bl_info.current_cabc_pwm = %d,g_bl_info.index_cabc_dimming= %d,pwm_duty= %d,g_bl_info.index_cabc_dimming= %d!\n",g_bl_info.current_cabc_pwm ,g_bl_info.index_cabc_dimming,pwm_duty,g_bl_info.index_cabc_dimming);
			int32_t backlight = g_bl_info.current_cabc_pwm * g_bl_info.ap_brightness / CABC_PWM_DUTY_MAX_LEVEL;
			if (backlight > 0 && backlight < PWM_BL_LEVEL_MIN) {
			    backlight = PWM_BL_LEVEL_MIN;
			}
			update_backlight(backlight);
			g_bl_info.index_cabc_dimming++;
			msleep(16);
		}
	}
	return 0;
}
void dss_underflow_stop_perf_state(struct hisi_fb_data_type *hisifd)
{
#ifdef DSS_DEVMEM_PERF_BASE
	void __iomem * perf_stat_base;

	if (inp32(hisifd->peri_crg_base + CRG_PERIPH_APB_PERRSTSTAT0_REG) & (1 << CRG_PERIPH_APB_IP_RST_PERF_STAT_BIT)) {
		HISI_FB_INFO("Failed : perf might not be used");
		return ;
	}

	perf_stat_base = ioremap(DSS_DEVMEM_PERF_BASE, DEVMEM_PERF_SIZE);
	outp32(perf_stat_base + PERF_SAMPSTOP_REG, 0x1);
	iounmap(perf_stat_base);
	HISI_FB_INFO("OK : perf state stop succ");
#endif
}
static int hisi_pwm_probe(struct platform_device *pdev)
{
	struct device_node *np = NULL;
	int ret = 0;

	HISI_FB_DEBUG("+.\n");

	BUG_ON(pdev == NULL);

	np = of_find_compatible_node(NULL, NULL, DTS_COMP_PWM_NAME);
	if (!np) {
		HISI_FB_ERR("NOT FOUND device node %s!\n", DTS_COMP_PWM_NAME);
		ret = -ENXIO;
		goto err_return;
	}

	/* get pwm reg base */
	hisifd_pwm_base = of_iomap(np, 0);

#if !defined(CONFIG_ARCH_HI3630FPGA) && !defined(CONFIG_HISI_3635_FPGA) \
	&& !defined(CONFIG_HISI_3650_FPGA)
	/* pwm pinctrl init */
	ret = pinctrl_cmds_tx(pdev, pwm_pinctrl_init_cmds,
		ARRAY_SIZE(pwm_pinctrl_init_cmds));
	if (ret != 0) {
		HISI_FB_ERR("Init pwm pinctrl failed! ret=%d.\n", ret);
		goto err_return;
	}

	/* get blpwm clk resource */
	g_dss_pwm_clk = of_clk_get(np, 0);
	if (IS_ERR(g_dss_pwm_clk)) {
		HISI_FB_ERR("%s clock not found: %d!\n",
			np->name, (int)PTR_ERR(g_dss_pwm_clk));
		ret = -ENXIO;
		goto err_return;
	}

	ret = clk_set_rate(g_dss_pwm_clk, DEFAULT_PWM_CLK_RATE);
	if (ret != 0) {
		HISI_FB_ERR("dss_pwm_clk clk_set_rate(%lu) failed, error=%d!\n",
			DEFAULT_PWM_CLK_RATE, ret);
		ret = -EINVAL;
		goto err_return;
	}

	HISI_FB_INFO("dss_pwm_clk:[%lu]->[%lu].\n",
		DEFAULT_PWM_CLK_RATE, clk_get_rate(g_dss_pwm_clk));
#endif

	hisi_fb_device_set_status0(DTS_PWM_READY);

	HISI_FB_DEBUG("-.\n");

	return 0;

err_return:
	return ret;
}
static int mipi_dsi_clk_irq_setup(struct platform_device *pdev)
{
	struct hisi_fb_data_type *hisifd = NULL;
	int ret = 0;

	BUG_ON(pdev == NULL);
	hisifd = platform_get_drvdata(pdev);
	BUG_ON(hisifd == NULL);

	hisifd->dss_dphy0_clk = devm_clk_get(&pdev->dev, hisifd->dss_dphy0_clk_name);
	if (IS_ERR(hisifd->dss_dphy0_clk)) {
		ret = PTR_ERR(hisifd->dss_dphy0_clk);
		return ret;
	} else {
		ret = clk_set_rate(hisifd->dss_dphy0_clk, DEFAULT_MIPI_CLK_RATE);
		if (ret < 0) {
			HISI_FB_ERR("fb%d dss_dphy0_clk clk_set_rate(%lu) failed, error=%d!\n",
				hisifd->index, DEFAULT_MIPI_CLK_RATE, ret);
			return -EINVAL;
		}

		HISI_FB_INFO("dss_dphy0_clk:[%lu]->[%lu].\n",
			DEFAULT_MIPI_CLK_RATE, clk_get_rate(hisifd->dss_dphy0_clk));
	}

	if (is_dual_mipi_panel(hisifd)) {
		hisifd->dss_dphy1_clk = devm_clk_get(&pdev->dev, hisifd->dss_dphy1_clk_name);
		if (IS_ERR(hisifd->dss_dphy1_clk)) {
			ret = PTR_ERR(hisifd->dss_dphy1_clk);
			return ret;
		} else {
			ret = clk_set_rate(hisifd->dss_dphy1_clk, DEFAULT_MIPI_CLK_RATE);
			if (ret < 0) {
				HISI_FB_ERR("fb%d dss_dphy1_clk clk_set_rate(%lu) failed, error=%d!\n",
					hisifd->index, DEFAULT_MIPI_CLK_RATE, ret);
				return -EINVAL;
			}

			HISI_FB_INFO("dss_dphy1_clk:[%lu]->[%lu].\n",
				DEFAULT_MIPI_CLK_RATE, clk_get_rate(hisifd->dss_dphy1_clk));
		}
	}

	return ret;
}
int hisifb_vsync_ctrl(struct fb_info *info, void __user *argp)
{
	int ret = 0;
	struct hisi_fb_data_type *hisifd = NULL;
	struct hisi_fb_panel_data *pdata = NULL;
	struct hisifb_vsync *vsync_ctrl = NULL;
	int enable = 0;

	BUG_ON(info == NULL);
	hisifd = (struct hisi_fb_data_type *)info->par;
	BUG_ON(hisifd == NULL);
	pdata = dev_get_platdata(&hisifd->pdev->dev);
	BUG_ON(pdata == NULL);
	vsync_ctrl = &(hisifd->vsync_ctrl);
	BUG_ON(vsync_ctrl == NULL);

	ret = copy_from_user(&enable, argp, sizeof(enable));
	if (ret) {
		HISI_FB_ERR("hisifb_vsync_ctrl ioctl failed!\n");
		return ret;
	}

	enable = (enable) ? 1 : 0;

	mutex_lock(&(vsync_ctrl->vsync_lock));

	if (vsync_ctrl->vsync_enabled == enable) {
		mutex_unlock(&(vsync_ctrl->vsync_lock));
		return 0;
	}

	if (g_debug_online_vsync)
		HISI_FB_INFO("fb%d, enable=%d!\n", hisifd->index, enable);

	vsync_ctrl->vsync_enabled = enable;

	mutex_unlock(&(vsync_ctrl->vsync_lock));

	down(&hisifd->blank_sem);

	if (!hisifd->panel_power_on) {
		HISI_FB_DEBUG("fb%d, panel is power off!", hisifd->index);
		up(&hisifd->blank_sem);
		return 0;
	}

	if (enable) {
		hisifb_activate_vsync(hisifd);
	} else {
		hisifb_deactivate_vsync(hisifd);
	}

	up(&hisifd->blank_sem);

	return 0;
}
void hisifb_adjust_block_rect(int block_num, dss_rect_t *ov_block_rects[], dss_wb_layer_t *wb_layer)
{
	int i = 0;
	dss_rect_t block_rect;
	bool need_adjust_block = false;

	BUG_ON(ov_block_rects == NULL);
	BUG_ON(wb_layer == NULL);

	if ((block_num > 1) && (ov_block_rects[block_num - 1]->w < HISI_DSS_MIN_ROT_AFBCE_BLOCK_SIZE)) {
		if ((wb_layer->transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V))
			&& (wb_layer->need_cap == CAP_AFBCE)) {
			if (g_debug_ovl_block_composer) {
				HISI_FB_INFO("before_adjust:ov_block_rects[%d]:[%d:%d:%d:%d]\n",
					block_num - 1, ov_block_rects[block_num-1]->x, ov_block_rects[block_num-1]->y, ov_block_rects[block_num-1]->w,
					ov_block_rects[block_num-1]->h);
			}

			block_rect = *ov_block_rects[block_num - 1];
			ov_block_rects[block_num - 1]->w += HISI_DSS_MIN_ROT_AFBCE_BLOCK_SIZE;
			if (ov_block_rects[block_num - 1]->w > HISI_DSS_MAX_ROT_AFBCE_BLOCK_SIZE) {
				ov_block_rects[block_num - 1]->w = HISI_DSS_MAX_ROT_AFBCE_BLOCK_SIZE;
			}

			block_rect.x -= ov_block_rects[block_num - 1]->w - block_rect.w;
			ov_block_rects[block_num - 1]->x = ALIGN_UP(block_rect.x, AFBC_BLOCK_ALIGN);
			ov_block_rects[block_num - 1]->w -= ov_block_rects[block_num - 1]->x - block_rect.x;

			need_adjust_block = true;
		}
	}

	if (need_adjust_block && g_debug_ovl_block_composer) {
		for (i = 0; i < block_num; i++) {
			HISI_FB_INFO("after_adjust:ov_block_rects[%d]:[%d:%d:%d:%d]\n",
				i, ov_block_rects[i]->x, ov_block_rects[i]->y, ov_block_rects[i]->w,
				ov_block_rects[i]->h);
		}
	}
}
static void update_backlight(uint32_t backlight)
{
	uint32_t bl_level = (backlight * PWM_OUT_PRECISION) / g_bl_info.bl_max;
	HISI_FB_INFO("update_backlight: backlight = %d!\n", backlight);
	BUG_ON(hisifd_pwm_base == NULL);
	outp32(hisifd_pwm_base + PWM_LOCK_OFFSET, 0x1acce551);
	outp32(hisifd_pwm_base + PWM_CTL_OFFSET, 0x0);
	outp32(hisifd_pwm_base + PWM_CFG_OFFSET, 0x2);
	outp32(hisifd_pwm_base + PWM_PR0_OFFSET, 0x1);
	outp32(hisifd_pwm_base + PWM_PR1_OFFSET, 0x2);
	outp32(hisifd_pwm_base + PWM_CTL_OFFSET, 0x1);
	outp32(hisifd_pwm_base + PWM_C0_MR_OFFSET, (PWM_OUT_PRECISION - 1));
	outp32(hisifd_pwm_base + PWM_C0_MR0_OFFSET, bl_level);
}
void hisifb_vsync_isr_handler(struct hisi_fb_data_type *hisifd)
{
	struct hisifb_vsync *vsync_ctrl = NULL;
	int buffer_updated = 0;
	ktime_t pre_vsync_timestamp;

	BUG_ON(hisifd == NULL);
	vsync_ctrl = &(hisifd->vsync_ctrl);
	BUG_ON(vsync_ctrl == NULL);

	pre_vsync_timestamp = vsync_ctrl->vsync_timestamp;
	vsync_ctrl->vsync_timestamp = ktime_get();
	wake_up_interruptible_all(&(vsync_ctrl->vsync_wait));

	if (hisifd->panel_info.vsync_ctrl_type != VSYNC_CTRL_NONE) {
		spin_lock(&vsync_ctrl->spin_lock);
		if (vsync_ctrl->vsync_ctrl_expire_count) {
			vsync_ctrl->vsync_ctrl_expire_count--;
			if (vsync_ctrl->vsync_ctrl_expire_count == 0)
				schedule_work(&vsync_ctrl->vsync_ctrl_work);
		}
		spin_unlock(&vsync_ctrl->spin_lock);
	}

	if (vsync_ctrl->vsync_report_fnc) {
		if (hisifd->vsync_ctrl.vsync_enabled) {
			buffer_updated = atomic_dec_return(&(vsync_ctrl->buffer_updated));
		} else {
			buffer_updated = 1;
		}

		if (buffer_updated < 0) {
			atomic_cmpxchg(&(vsync_ctrl->buffer_updated), buffer_updated, 1);
		} else {
			vsync_ctrl->vsync_report_fnc(buffer_updated);
		}
	}

	if (g_debug_online_vsync) {
		HISI_FB_INFO("fb%d, VSYNC=%llu, time_diff=%llu.\n", hisifd->index,
			ktime_to_ns(hisifd->vsync_ctrl.vsync_timestamp),
			(ktime_to_ns(hisifd->vsync_ctrl.vsync_timestamp) - ktime_to_ns(pre_vsync_timestamp)));
	}
}
static void hisifb_vsync_ctrl_workqueue_handler(struct work_struct *work)
{
	struct hisi_fb_data_type *hisifd = NULL;
	struct hisifb_vsync *vsync_ctrl = NULL;
	struct hisi_fb_panel_data *pdata = NULL;
	unsigned long flags = 0;

	vsync_ctrl = container_of(work, typeof(*vsync_ctrl), vsync_ctrl_work);
	BUG_ON(vsync_ctrl == NULL);
	hisifd = vsync_ctrl->hisifd;
	BUG_ON(hisifd == NULL);
	pdata = dev_get_platdata(&hisifd->pdev->dev);
	BUG_ON(pdata == NULL);

	down(&(hisifd->blank_sem));

	if (!hisifd->panel_power_on) {
		HISI_FB_INFO("fb%d, panel is power off!", hisifd->index);
		up(&(hisifd->blank_sem));
		return;
	}

	mutex_lock(&(vsync_ctrl->vsync_lock));
	if (vsync_ctrl->vsync_ctrl_disabled_set &&
		(vsync_ctrl->vsync_ctrl_expire_count == 0) &&
		vsync_ctrl->vsync_ctrl_enabled &&
		!vsync_ctrl->vsync_enabled && !vsync_ctrl->vsync_ctrl_offline_enabled) {
		HISI_FB_DEBUG("fb%d, dss clk off!\n", hisifd->index);

		spin_lock_irqsave(&(vsync_ctrl->spin_lock), flags);
		if (pdata->vsync_ctrl) {
			pdata->vsync_ctrl(hisifd->pdev, 0);
		} else {
			HISI_FB_ERR("fb%d, vsync_ctrl not supported!\n", hisifd->index);
		}
		vsync_ctrl->vsync_ctrl_enabled = 0;
		vsync_ctrl->vsync_ctrl_disabled_set = 0;
		spin_unlock_irqrestore(&(vsync_ctrl->spin_lock), flags);

		if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) {
			mipi_dsi_ulps_cfg(hisifd, 0);
		}

		if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) {
			if (hisifd->lp_fnc)
				hisifd->lp_fnc(hisifd, true);
		}

		if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) {
			dpe_inner_clk_disable(hisifd);
			dpe_common_clk_disable(hisifd);
			mipi_dsi_clk_disable(hisifd);
		}

		if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) {
			dpe_regulator_disable(hisifd);
		}
	}
	mutex_unlock(&(vsync_ctrl->vsync_lock));

	if (vsync_ctrl->vsync_report_fnc) {
		vsync_ctrl->vsync_report_fnc(1);
	}

	up(&(hisifd->blank_sem));
}
static ssize_t vsync_show_event(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	ssize_t ret = 0;
	int vsync_flag = 0;
	int secure_flag = 0;
	struct fb_info *fbi = NULL;
	struct hisi_fb_data_type *hisifd = NULL;
	struct hisifb_secure *secure_ctrl = NULL;
	ktime_t prev_timestamp;

	if (NULL == dev) {
		HISI_FB_ERR("NULL Pointer.\n");
		return 0;
	}

	fbi = dev_get_drvdata(dev);
	if (NULL == fbi) {
		HISI_FB_ERR("NULL Pointer.\n");
		return 0;
	}

	hisifd = (struct hisi_fb_data_type *)fbi->par;
	if (NULL == hisifd) {
		HISI_FB_ERR("NULL Pointer.\n");
		return 0;
	}

	secure_ctrl = &(hisifd->secure_ctrl);
	if (NULL == secure_ctrl) {
		HISI_FB_ERR("NULL Pointer.\n");
		return 0;
	}

	if (NULL == buf) {
		HISI_FB_ERR("NULL Pointer.\n");
		return 0;
	}

	prev_timestamp = hisifd->vsync_ctrl.vsync_timestamp;

	/*lint -e666*/
	ret = wait_event_interruptible(hisifd->vsync_ctrl.vsync_wait,
		(vsync_timestamp_changed(hisifd, prev_timestamp) && hisifd->vsync_ctrl.vsync_enabled)
		|| (secure_ctrl->tui_need_switch));
	/*lint +e666*/

	vsync_flag = (vsync_timestamp_changed(hisifd, prev_timestamp) &&
						hisifd->vsync_ctrl.vsync_enabled);

	secure_flag = secure_ctrl->tui_need_switch;
	if (vsync_flag && secure_flag) {
		HISI_FB_INFO("report (secure_event = %d) to hwc with vsync at (frame_no = %d).\n", \
						secure_ctrl->secure_event, hisifd->ov_req.frame_no);

		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu, SecureEvent=%d \n",
			ktime_to_ns(hisifd->vsync_ctrl.vsync_timestamp), secure_ctrl->secure_event);
		buf[strlen(buf) + 1] = '\0';
		if (secure_ctrl->secure_event == DSS_SEC_DISABLE) {
			secure_ctrl->tui_need_switch = 0;
		}

	} else if (vsync_flag) {
		ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu, xxxxxxevent=x \n",
			ktime_to_ns(hisifd->vsync_ctrl.vsync_timestamp));
		buf[strlen(buf) + 1] = '\0';
		secure_ctrl->tui_need_skip_report = 0;

	} else if (secure_flag && !secure_ctrl->tui_need_skip_report) {
		HISI_FB_INFO("report (secure_event = %d) to hwc at (frame_no = %d).\n", \
						secure_ctrl->secure_event, hisifd->ov_req.frame_no);

		ret = snprintf(buf, PAGE_SIZE, "xxxxx=%llu, SecureEvent=%d \n",
			ktime_to_ns(hisifd->vsync_ctrl.vsync_timestamp), secure_ctrl->secure_event);
		buf[strlen(buf) + 1] = '\0';
		secure_ctrl->tui_need_skip_report = 1;
		if (secure_ctrl->secure_event == DSS_SEC_DISABLE) {
			secure_ctrl->tui_need_switch = 0;
		}

	} else {
		;//do nothing
	}

	return ret;
}
void panel_check_status_and_report_by_dsm(struct lcd_reg_read_t *lcd_status_reg, int cnt, char __iomem *mipi_dsi0_base)
{
	u32 read_value = 0, expected_value = 0, read_mask = 0;
	u8 reg_addr = 0;
	char *reg_name = NULL;
	int dsm_error_found = 0, dsm_client_ready = 0;
	u32 pkg_status = 0, try_times = 100, i = 0;
	struct dsi_cmd_desc packet_size_set_cmd = {DTYPE_MAX_PKTSIZE, 0, 10, WAIT_TYPE_US, 1, NULL};

	if (!dsm_client_ocuppy(lcd_dclient)) {
		dsm_client_ready = 1;
	}

	mipi_dsi_max_return_packet_size(&packet_size_set_cmd, mipi_dsi0_base);

	for (i = 0; i < cnt; i++) {
		/*Each iteration read a registers*/
		reg_addr = lcd_status_reg[i].reg_addr;
		reg_name = lcd_status_reg[i].reg_name;
		expected_value = lcd_status_reg[i].expected_value;
		read_mask = lcd_status_reg[i].read_mask;

		/*Send MIPI read command, and wait the return value no longer than 100*30us*/
		try_times = 100;
		outp32(mipi_dsi0_base + MIPIDSI_GEN_HDR_OFFSET, reg_addr << 8 | 0x06);
		udelay(20);
		do {
			pkg_status = inp32(mipi_dsi0_base + MIPIDSI_CMD_PKT_STATUS_OFFSET);
			if (!(pkg_status & 0x10))
				break;
			udelay(30);
		} while (--try_times);

		/*Read the return value, report error if read timeout or read value is not expected*/
		read_value = inp32(mipi_dsi0_base + MIPIDSI_GEN_PLD_DATA_OFFSET);
		if (read_mask != 0)
			read_value &= read_mask;
		if (!try_times) {
			HISI_FB_ERR("Read %s timeout!\n", reg_name);
			if (dsm_client_ready) {
				dsm_client_record(lcd_dclient, "Read %s timeout!\n", reg_name);
				dsm_error_found++;
			}
			break;
		} else if (read_value != expected_value && read_mask != 0) {
			HISI_FB_ERR("ERROR: read %s = 0x%X, but expect: 0x%X\n", reg_name, read_value, expected_value);
			if (dsm_client_ready) {
				dsm_client_record(lcd_dclient, "ERROR: read %s = 0x%X, but expect: 0x%X\n", reg_name, read_value, expected_value);
				dsm_error_found++;
			}
			break;
		} else if (read_value == expected_value && read_mask == 0) {
			/*In this case read_mask == 0, read value equal to expected_value is a LCD error*/
			HISI_FB_ERR("ERROR: read %s = 0x%X, but expect NOT equal to: 0x%X\n", reg_name, read_value, expected_value);
			if (dsm_client_ready) {
				dsm_client_record(lcd_dclient, "ERROR: read %s = 0x%X, but expect NOT equal to: 0x%X\n", reg_name, read_value, expected_value);
				dsm_error_found++;
			}
			break;
		} else {
			HISI_FB_INFO("Read %s = 0x%x\n", reg_name, read_value);
		}
	}

	/*Report error to Device Status Monitor*/
	if (dsm_error_found > 0) {
		dsm_client_notify(lcd_dclient, DSM_LCD_STATUS_ERROR_NO);
	} else if (dsm_client_ready) {
		dsm_client_unocuppy(lcd_dclient);
	} else {
		HISI_FB_INFO("dsm lcd_dclient ocuppy failed!\n");
	}
}
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;
	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 = 0x9 - chn_idx;
	BUG_ON(mid < 0);

	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 (g_fpga_flag == 0) {
		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_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;
				}

				//after stretch
				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 = pix_f*128/(core_f*16/4)*1.25*scfd_h*scfd_v
				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_offline_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) {
					credit_step = 0;
				}

				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_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;
				}

				//after stretch
				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 = pix_f*128/(core_f*16/4)*scfd_h*scfd_v
				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_offline_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) {
					credit_step = 0;
				}

				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 ((ovl_idx == DSS_OVL2) || (ovl_idx == DSS_OVL3)) {
			aif1->aif_ch_ctl = set_bits32(aif1->aif_ch_ctl, 0x1, 1, 11);
			aif1->aif_ch_ctl = set_bits32(aif1->aif_ch_ctl, 0x10, 7, 16);
		}
	}

	return 0;
}
static void mipi_init(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base)
{
	uint32_t hline_time = 0;
	uint32_t hsa_time = 0;
	uint32_t hbp_time = 0;
	uint32_t pixel_clk = 0;
	unsigned long dw_jiffies = 0;
	struct mipi_dsi_phy_ctrl phy_ctrl = {0};
	uint32_t tmp = 0;
	bool is_ready = false;
	struct hisi_panel_info *pinfo = NULL;

	BUG_ON(hisifd == NULL);
	BUG_ON(mipi_dsi_base == NULL);

	pinfo = &(hisifd->panel_info);
	get_dsi_phy_ctrl(pinfo->mipi.dsi_bit_clk, &phy_ctrl);

	/* config TE */
	if (is_mipi_cmd_panel(hisifd)) {
		/* config to command mode */
		set_reg(mipi_dsi_base + MIPIDSI_MODE_CFG_OFFSET, 0x1, 1, 0);
		/* ALLOWED_CMD_SIZE */
		set_reg(mipi_dsi_base + MIPIDSI_EDPI_CMD_SIZE_OFFSET, pinfo->xres, 16, 0);
		/* cnt=2 in update-patial scene, cnt nees to be checked for different panels*/
		set_reg(mipi_dsi_base + MIPIDSI_HS_WR_TO_CNT_OFFSET, 0x1000002, 25, 0);

		/* phy_stop_wait_time */
		set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, 0x30, 8, 8);

		/* FIXME: test tearing effect, if use gpio, no need */
		/*set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x1, 1, 0);*/
	}

	/*--------------configuring the DPI packet transmission----------------*/
	/*
	** 1. Global configuration
	** Configure Register PHY_IF_CFG with the correct number of lanes
	** to be used by the controller.
	*/
	set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, pinfo->mipi.lane_nums, 2, 0);

	/*
	** 2. Configure the DPI Interface:
	** This defines how the DPI interface interacts with the controller.
	*/
	set_reg(mipi_dsi_base + MIPIDSI_DPI_VCID_OFFSET, pinfo->mipi.vc, 2, 0);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, pinfo->mipi.color_mode, 4, 0);

	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.data_en_plr, 1, 0);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.vsync_plr, 1, 1);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.hsync_plr, 1, 2);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 3);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 4);

	if (pinfo->bpp == LCD_RGB666) {
		set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, 0x1, 1, 8);
	}

	/*
	** 3. Select the Video Transmission Mode:
	** This defines how the processor requires the video line to be
	** transported through the DSI link.
	*/

	/* video mode: low power mode */
	set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x3f, 6, 8);
	/* set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x0, 1, 14); */

	/* burst mode */
	set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, phy_ctrl.burst_mode, 2, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_PKT_SIZE_OFFSET, pinfo->xres, 14, 0);

	/* for dsi read, BTA enable*/
	set_reg(mipi_dsi_base + MIPIDSI_PCKHDL_CFG_OFFSET, 0x1, 1, 2);

	/*
	** 4. Define the DPI Horizontal timing configuration:
	**
	** Hsa_time = HSA*(PCLK period/Clk Lane Byte Period);
	** Hbp_time = HBP*(PCLK period/Clk Lane Byte Period);
	** Hline_time = (HSA+HBP+HACT+HFP)*(PCLK period/Clk Lane Byte Period);
	*/
	pixel_clk = pinfo->pxl_clk_rate / 1000000;
	hsa_time = pinfo->ldi.h_pulse_width * phy_ctrl.lane_byte_clk / pixel_clk;
	hbp_time = pinfo->ldi.h_back_porch * phy_ctrl.lane_byte_clk / pixel_clk;
	hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch +
		pinfo->xres + pinfo->ldi.h_front_porch) *
		phy_ctrl.lane_byte_clk / pixel_clk;
	set_reg(mipi_dsi_base + MIPIDSI_VID_HSA_TIME_OFFSET, hsa_time, 12, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_HBP_TIME_OFFSET, hbp_time, 12, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time, 15, 0);

	/*
	** 5. Define the Vertical line configuration:
	*/
	set_reg(mipi_dsi_base + MIPIDSI_VID_VSA_LINES_OFFSET, pinfo->ldi.v_pulse_width, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VBP_LINES_OFFSET, pinfo->ldi.v_back_porch, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VFP_LINES_OFFSET, pinfo->ldi.v_front_porch, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VACTIVE_LINES_OFFSET, pinfo->yres, 14, 0);
	set_reg(mipi_dsi_base + MIPIDSI_TO_CNT_CFG_OFFSET, 0x7FF, 16, 0);

	/* Configure core's phy parameters */
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, 4095, 15, 0);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_lp2hs_time, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_hs2lp_time, 10, 16);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_lp2hs_time, 8, 16);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_hs2lp_time, 8, 24);

	/*------------DSI and D-PHY Initialization-----------------*/
	/* 1. Waking up Core */
	set_reg(mipi_dsi_base + MIPIDSI_PWR_UP_OFFSET, 0x1, 1, 0);

	/*
	** 3. Configure the TX_ESC clock frequency to a frequency lower than 20 MHz
	** that is the maximum allowed frequency for D-PHY ESCAPE mode.
	*/

	set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 0);
	set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 8);


	/*
	** 4. Configure the DPHY PLL clock frequency through the TEST Interface to
	** operate at XX Hz,
	*/

	/* Write CP current */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010011);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.cp_current);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write LPF Control */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010012);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.lpf_ctrl);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/*Configured N and M factors effective*/
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010019);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.factors_effective);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write N Pll */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010017);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.n_pll-1);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write M Pll part 1 */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_1);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write M Pll part 2 */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_2);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Set hsfreqrange */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010044);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.hsfreqrange);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Set PLL unlocking filter */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010016);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.pll_unlocking_filter);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

#if 0
	/* Set the phy direction*/
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x000100b0);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00000001);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
#endif

	outp32(mipi_dsi_base + MIPIDSI_PHY_RSTZ_OFFSET, 0x0000000F);

	is_ready = false;
	dw_jiffies = jiffies + HZ / 2;
	do {
		tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET);
		if ((tmp & 0x00000001) == 0x00000001) {
			is_ready = true;
			break;
		}
	} while (time_after(dw_jiffies, jiffies));

	if (!is_ready) {
		HISI_FB_INFO("fb%d, phylock is not ready!MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n",
			hisifd->index, tmp);
	}

	is_ready = false;
	dw_jiffies = jiffies + HZ / 2;
	do {
		tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET);
		if ((tmp & 0x00000004) == 0x00000004) {
			is_ready = true;
			break;
		}
	} while (time_after(dw_jiffies, jiffies));

	if (!is_ready) {
		HISI_FB_INFO("fb%d, phystopstateclklane is not ready! MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n",
			hisifd->index, tmp);
	}
}