Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 931b4556 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: Add support for ROI function of AD4"

parents 6464c0fa 1dd9ec41
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ enum ad_property {
	AD_ASSERTIVE,
	AD_BACKLIGHT,
	AD_STRENGTH,
	AD_ROI,
	AD_IPC_SUSPEND,
	AD_IPC_RESUME,
	AD_IPC_RESET,
+19 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ enum {
	SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS,
	SDE_CP_CRTC_DSPP_AD_BACKLIGHT,
	SDE_CP_CRTC_DSPP_AD_STRENGTH,
	SDE_CP_CRTC_DSPP_AD_ROI,
	SDE_CP_CRTC_DSPP_MAX,
	/* DSPP features end */

@@ -826,6 +827,15 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			break;
		case SDE_CP_CRTC_DSPP_AD_ROI:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
				ret = -EINVAL;
				continue;
			}
			ad_cfg.prop = AD_ROI;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			break;
		default:
			ret = -EINVAL;
			break;
@@ -1427,6 +1437,11 @@ static void dspp_ad_install_property(struct drm_crtc *crtc)
				"SDE_DSPP_AD_V4_BACKLIGHT",
			SDE_CP_CRTC_DSPP_AD_BACKLIGHT, 0, (BIT(16) - 1),
			0);

		sde_cp_crtc_install_range_property(crtc, "SDE_DSPP_AD_V4_ROI",
			SDE_CP_CRTC_DSPP_AD_ROI, 0, U64_MAX, 0);
		sde_cp_create_local_blob(crtc, SDE_CP_CRTC_DSPP_AD_ROI,
			sizeof(struct drm_msm_ad4_roi_cfg));
		break;
	default:
		DRM_ERROR("version %d not supported\n", version);
@@ -1590,6 +1605,7 @@ static void sde_cp_update_list(struct sde_cp_node *prop_node,
	case SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS:
	case SDE_CP_CRTC_DSPP_AD_BACKLIGHT:
	case SDE_CP_CRTC_DSPP_AD_STRENGTH:
	case SDE_CP_CRTC_DSPP_AD_ROI:
		if (dirty_list)
			list_add_tail(&prop_node->dirty_list, &crtc->ad_dirty);
		else
@@ -1641,6 +1657,9 @@ static int sde_cp_ad_validate_prop(struct sde_cp_node *prop_node,
		case SDE_CP_CRTC_DSPP_AD_STRENGTH:
			ad_prop = AD_STRENGTH;
			break;
		case SDE_CP_CRTC_DSPP_AD_ROI:
			ad_prop = AD_ROI;
			break;
		default:
			/* Not an AD property */
			return 0;
+250 −34
Original line number Diff line number Diff line
@@ -48,6 +48,15 @@ enum ad4_state {
	ad4_state_max,
};

struct ad4_roi_info {
	u32 h_start;
	u32 h_end;
	u32 v_start;
	u32 v_end;
	u32 f_in;
	u32 f_out;
};

typedef int (*ad4_prop_setup)(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *ad);

@@ -77,6 +86,11 @@ static int ad4_cfg_setup_ipcr(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg);
static int ad4_input_setup(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg);
static int ad4_roi_setup(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg);
static int ad4_roi_setup_ipcr(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg);
static int ad4_roi_coordinate_offset(struct sde_hw_cp_cfg *hw_cfg,
		struct ad4_roi_info *output);
static int ad4_input_setup_idle(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg);
static int ad4_input_setup_ipcr(struct sde_hw_dspp *dspp,
@@ -118,6 +132,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_idle][AD_ASSERTIVE] = ad4_assertive_setup,
	[ad4_state_idle][AD_BACKLIGHT] = ad4_backlight_setup,
	[ad4_state_idle][AD_STRENGTH] = ad4_strength_setup_idle,
	[ad4_state_idle][AD_ROI] = ad4_no_op_setup,
	[ad4_state_idle][AD_IPC_SUSPEND] = ad4_no_op_setup,
	[ad4_state_idle][AD_IPC_RESUME] = ad4_no_op_setup,
	[ad4_state_idle][AD_IPC_RESET] = ad4_no_op_setup,
@@ -131,6 +146,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_startup][AD_BACKLIGHT] = ad4_backlight_setup,
	[ad4_state_startup][AD_IPC_SUSPEND] = ad4_no_op_setup,
	[ad4_state_startup][AD_STRENGTH] = ad4_no_op_setup,
	[ad4_state_startup][AD_ROI] = ad4_roi_setup,
	[ad4_state_startup][AD_IPC_RESUME] = ad4_no_op_setup,
	[ad4_state_startup][AD_IPC_RESET] = ad4_ipc_reset_setup_startup,

@@ -142,6 +158,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_run][AD_ASSERTIVE] = ad4_assertive_setup,
	[ad4_state_run][AD_BACKLIGHT] = ad4_backlight_setup,
	[ad4_state_run][AD_STRENGTH] = ad4_no_op_setup,
	[ad4_state_run][AD_ROI] = ad4_roi_setup,
	[ad4_state_run][AD_IPC_SUSPEND] = ad4_ipc_suspend_setup_run,
	[ad4_state_run][AD_IPC_RESUME] = ad4_no_op_setup,
	[ad4_state_run][AD_IPC_RESET] = ad4_setup_debug,
@@ -154,6 +171,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_ipcs][AD_ASSERTIVE] = ad4_no_op_setup,
	[ad4_state_ipcs][AD_BACKLIGHT] = ad4_no_op_setup,
	[ad4_state_ipcs][AD_STRENGTH] = ad4_no_op_setup,
	[ad4_state_ipcs][AD_ROI] = ad4_no_op_setup,
	[ad4_state_ipcs][AD_IPC_SUSPEND] = ad4_no_op_setup,
	[ad4_state_ipcs][AD_IPC_RESUME] = ad4_ipc_resume_setup_ipcs,
	[ad4_state_ipcs][AD_IPC_RESET] = ad4_no_op_setup,
@@ -166,6 +184,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_ipcr][AD_ASSERTIVE] = ad4_assertive_setup_ipcr,
	[ad4_state_ipcr][AD_BACKLIGHT] = ad4_backlight_setup_ipcr,
	[ad4_state_ipcr][AD_STRENGTH] = ad4_no_op_setup,
	[ad4_state_ipcr][AD_ROI] = ad4_roi_setup_ipcr,
	[ad4_state_ipcr][AD_IPC_SUSPEND] = ad4_ipc_suspend_setup_ipcr,
	[ad4_state_ipcr][AD_IPC_RESUME] = ad4_no_op_setup,
	[ad4_state_ipcr][AD_IPC_RESET] = ad4_ipc_reset_setup_ipcr,
@@ -178,6 +197,7 @@ static ad4_prop_setup prop_set_func[ad4_state_max][AD_PROPMAX] = {
	[ad4_state_manual][AD_ASSERTIVE] = ad4_no_op_setup,
	[ad4_state_manual][AD_BACKLIGHT] = ad4_no_op_setup,
	[ad4_state_manual][AD_STRENGTH] = ad4_strength_setup,
	[ad4_state_manual][AD_ROI] = ad4_no_op_setup,
	[ad4_state_manual][AD_IPC_SUSPEND] = ad4_no_op_setup,
	[ad4_state_manual][AD_IPC_RESUME] = ad4_no_op_setup,
	[ad4_state_manual][AD_IPC_RESET] = ad4_setup_debug_manual,
@@ -191,16 +211,19 @@ struct ad4_info {
	bool is_master;
	u32 last_assertive;
	u32 cached_assertive;
	u32 last_str_inroi;
	u32 last_str_outroi;
	u64 last_als;
	u64 cached_als;
	u64 last_bl;
	u64 cached_bl;
	u32 last_str;
	u32 frame_count;
	u32 frmt_mode;
	u32 irdx_control_0;
	u32 tf_ctrl;
	u32 vc_control_0;
	struct ad4_roi_info last_roi_cfg;
	struct ad4_roi_info cached_roi_cfg;
};

static struct ad4_info info[DSPP_MAX] = {
@@ -319,7 +342,7 @@ static int ad4_no_op_setup(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)

static int ad4_setup_debug(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)
{
	u32 strength = 0;
	u32 in_str = 0, out_str = 0;
	struct sde_hw_mixer *hw_lm;

	hw_lm = cfg->hw_cfg->mixer_info;
@@ -327,9 +350,10 @@ static int ad4_setup_debug(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)
		/* this AD core is the salve core */
		return 0;

	strength = SDE_REG_READ(&dspp->hw, dspp->cap->sblk->ad.base + 0x4c);
	pr_debug("%s(): AD strength = %d\n", __func__, strength);

	in_str = SDE_REG_READ(&dspp->hw, dspp->cap->sblk->ad.base + 0x4c);
	out_str = SDE_REG_READ(&dspp->hw, dspp->cap->sblk->ad.base + 0x50);
	pr_debug("%s(): AD in strength %d, out strength %d\n", __func__,
				    in_str, out_str);
	return 0;
}

@@ -368,6 +392,18 @@ static int ad4_mode_setup(struct sde_hw_dspp *dspp, enum ad4_modes mode)
		info[dspp->idx].cached_bl = U64_MAX;
		info[dspp->idx].last_als = 0x0;
		info[dspp->idx].cached_als = U64_MAX;
		info[dspp->idx].last_roi_cfg.h_start = 0x0;
		info[dspp->idx].last_roi_cfg.h_end = 0xffff;
		info[dspp->idx].last_roi_cfg.v_start = 0x0;
		info[dspp->idx].last_roi_cfg.v_end = 0xffff;
		info[dspp->idx].last_roi_cfg.f_in = 0x400;
		info[dspp->idx].last_roi_cfg.f_out = 0x400;
		info[dspp->idx].cached_roi_cfg.h_start = U32_MAX;
		info[dspp->idx].cached_roi_cfg.h_end = U32_MAX;
		info[dspp->idx].cached_roi_cfg.v_start = U32_MAX;
		info[dspp->idx].cached_roi_cfg.v_end = U32_MAX;
		info[dspp->idx].cached_roi_cfg.f_in = U32_MAX;
		info[dspp->idx].cached_roi_cfg.f_out = U32_MAX;
	} else {
		if (mode == AD4_MANUAL) {
			/*vc_control_0 */
@@ -768,15 +804,6 @@ static int ad4_cfg_setup(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)
	}
	ad_cfg = cfg->hw_cfg->payload;

	blk_offset = 0x18;
	val = (ad_cfg->cfg_param_002 & (BIT(16) - 1));
	val |= ((ad_cfg->cfg_param_001 & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
	blk_offset += 4;
	val = (ad_cfg->cfg_param_004 & (BIT(16) - 1));
	val |= ((ad_cfg->cfg_param_003 & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	blk_offset = 0x20;
	val = (ad_cfg->cfg_param_005 & (BIT(8) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
@@ -793,10 +820,6 @@ static int ad4_cfg_setup(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)
	blk_offset = 0x3c;
	val = (ad_cfg->cfg_param_010 & (BIT(12) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
	blk_offset += 4;
	val = ((ad_cfg->cfg_param_011 & (BIT(16) - 1)) << 16);
	val |= (ad_cfg->cfg_param_012 & (BIT(16) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	blk_offset = 0x88;
	val = (ad_cfg->cfg_param_013 & (BIT(8) - 1));
@@ -891,10 +914,6 @@ static int ad4_cfg_setup(struct sde_hw_dspp *dspp, struct sde_ad_hw_cfg *cfg)

	info[dspp->idx].vc_control_0 = (ad_cfg->cfg_param_041 & (BIT(7) - 1));

	blk_offset = 0x160;
	val = (ad_cfg->cfg_param_043 & (BIT(10) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	blk_offset = 0x16c;
	val = (ad_cfg->cfg_param_044 & (BIT(8) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
@@ -934,6 +953,145 @@ static int ad4_input_setup(struct sde_hw_dspp *dspp,
	return 0;
}

static int ad4_roi_setup(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
	int ret = 0;
	u32 blk_offset = 0, val = 0;
	struct ad4_roi_info roi_cfg = {};

	ret = ad4_roi_coordinate_offset(cfg->hw_cfg, &roi_cfg);
	if (ret) {
		DRM_ERROR("params invalid\n");
		return -EINVAL;
	}
	info[dspp->idx].last_roi_cfg = roi_cfg;

	/*roi h start and end*/
	blk_offset = 0x18;
	val = (info[dspp->idx].last_roi_cfg.h_end & (BIT(16) - 1));
	val |= ((info[dspp->idx].last_roi_cfg.h_start & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	/*roi v start and end*/
	blk_offset += 4;
	val = (info[dspp->idx].last_roi_cfg.v_end & (BIT(16) - 1));
	val |= ((info[dspp->idx].last_roi_cfg.v_start & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	/*roi factor in and out*/
	blk_offset = 0x40;
	val = ((info[dspp->idx].last_roi_cfg.f_in & (BIT(16) - 1)) << 16);
	val |= (info[dspp->idx].last_roi_cfg.f_out & (BIT(16) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	return ret;
}

static int ad4_roi_setup_ipcr(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
	int ret = 0;
	struct ad4_roi_info roi_cfg = {};

	ret = ad4_roi_coordinate_offset(cfg->hw_cfg, &roi_cfg);
	if (ret) {
		DRM_ERROR("params invalid\n");
		return -EINVAL;
	}

	info[dspp->idx].cached_roi_cfg = roi_cfg;

	return 0;
}

static int ad4_roi_coordinate_offset(struct sde_hw_cp_cfg *hw_cfg,
						struct ad4_roi_info *output)
{
	struct sde_hw_mixer *hw_lm = hw_cfg->mixer_info;
	struct drm_msm_ad4_roi_cfg *roi = NULL;

	if (!hw_cfg->payload) {
		output->h_start = 0x0;
		output->h_end = hw_cfg->displayh;
		output->v_start = 0x0;
		output->v_end = hw_cfg->displayv;
		output->f_in = 0x400;
		output->f_out = 0x400;
		return 0;
	}

	if (hw_cfg->len != sizeof(struct drm_msm_ad4_roi_cfg)) {
		DRM_ERROR("invalid sz param exp %zd given %d cfg %pK\n",
			sizeof(struct drm_msm_ad4_roi_cfg), hw_cfg->len,
			hw_cfg->payload);
		return -EINVAL;
	}
	roi = (struct drm_msm_ad4_roi_cfg *)hw_cfg->payload;

	if (roi->h_x >= hw_cfg->displayh || roi->v_x >= hw_cfg->displayv) {
		DRM_ERROR("invalid roi=[%u,%u,%u,%u], display=[%u,%u]\n",
			roi->h_x, roi->h_y, roi->v_x, roi->v_y,
			hw_cfg->displayh, hw_cfg->displayv);
		return -EINVAL;
	}

	if (roi->h_x >= roi->h_y || roi->v_x >= roi->v_y) {
		DRM_ERROR("invalid roi=[%u,%u,%u,%u], display=[%u,%u]\n",
			roi->h_x, roi->h_y, roi->v_x, roi->v_y,
			hw_cfg->displayh, hw_cfg->displayv);
		return -EINVAL;
	}

	if (roi->h_y > hw_cfg->displayh)
		roi->h_y = hw_cfg->displayh;

	if (roi->v_y > hw_cfg->displayv)
		roi->v_y = hw_cfg->displayv;

	/* single dspp cfg */
	output->h_start = roi->h_x;
	output->h_end = roi->h_y;
	output->v_start = roi->v_x;
	output->v_end = roi->v_y;
	output->f_in = roi->factor_in;
	output->f_out = roi->factor_out;

	/* check whether dual dspp */
	if (hw_cfg->num_of_mixers != 2)
		return 0;

	if (roi->h_y <= hw_lm->cfg.out_width) {
		if (hw_lm->cfg.right_mixer) {
			/* the region on the left of screen, clear right info */
			output->h_start = 0;
			output->h_end = 0;
			output->v_start = 0;
			output->v_end = 0;
		}
	} else if (roi->h_x < hw_lm->cfg.out_width) {
		/* the region occupy both sides of screen: left and right */
		if (hw_lm->cfg.right_mixer) {
			output->h_start = 0;
			output->h_end -= hw_lm->cfg.out_width;
		} else {
			output->h_end = hw_lm->cfg.out_width;
		}
	} else {
		/* the region on the right of the screen*/
		if (hw_lm->cfg.right_mixer) {
			output->h_start -= hw_lm->cfg.out_width;
			output->h_end -= hw_lm->cfg.out_width;
		} else {
			output->h_start = 0;
			output->h_end = 0;
			output->v_start = 0;
			output->v_end = 0;
		}
	}
	return 0;
}

static int ad4_suspend_setup(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
@@ -1335,7 +1493,7 @@ void sde_read_intr_resp_ad4(struct sde_hw_dspp *dspp, u32 event,
static int ad4_ipc_suspend_setup_run(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
	u32 strength = 0, i = 0;
	u32 in_str = 0, out_str = 0, i = 0;
	struct sde_hw_mixer *hw_lm;

	hw_lm = cfg->hw_cfg->mixer_info;
@@ -1343,16 +1501,21 @@ static int ad4_ipc_suspend_setup_run(struct sde_hw_dspp *dspp,
		/* this AD core is the salve core */
		for (i = DSPP_0; i < DSPP_MAX; i++) {
			if (info[i].is_master) {
				strength = info[i].last_str;
				in_str = info[i].last_str_inroi;
				out_str = info[i].last_str_outroi;
				break;
			}
		}
	} else {
		strength = SDE_REG_READ(&dspp->hw,
		in_str = SDE_REG_READ(&dspp->hw,
				dspp->cap->sblk->ad.base + 0x4c);
		pr_debug("%s(): AD strength = %d\n", __func__, strength);
		out_str = SDE_REG_READ(&dspp->hw,
				dspp->cap->sblk->ad.base + 0x50);
		pr_debug("%s(): AD in strength %d, out %d\n", __func__,
				in_str, out_str);
	}
	info[dspp->idx].last_str = strength;
	info[dspp->idx].last_str_inroi = in_str;
	info[dspp->idx].last_str_outroi = out_str;
	info[dspp->idx].state = ad4_state_ipcs;
	pr_debug("%s(): AD state move to ipcs\n", __func__);

@@ -1378,10 +1541,29 @@ static int ad4_ipc_resume_setup_ipcs(struct sde_hw_dspp *dspp,
	blk_offset = 0x34;
	val = (0x55 & (BIT(8) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	/* set roi config */
	blk_offset = 0x18;
	val = (info[dspp->idx].last_roi_cfg.h_end & (BIT(16) - 1));
	val |= ((info[dspp->idx].last_roi_cfg.h_start & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
	blk_offset += 4;
	val = (info[dspp->idx].last_roi_cfg.v_end & (BIT(16) - 1));
	val |= ((info[dspp->idx].last_roi_cfg.v_start & (BIT(16) - 1)) << 16);
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
	blk_offset = 0x40;
	val = ((info[dspp->idx].last_roi_cfg.f_in & (BIT(16) - 1)) << 16);
	val |= (info[dspp->idx].last_roi_cfg.f_out & (BIT(16) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	/* set manual strength */
	blk_offset = 0x15c;
	val = (info[dspp->idx].last_str & (BIT(10) - 1));
	val = (info[dspp->idx].last_str_inroi & (BIT(10) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);
	blk_offset = 0x160;
	val = (info[dspp->idx].last_str_outroi & (BIT(10) - 1));
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, val);

	/* enable manual mode */
	blk_offset = 0x138;
	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->ad.base + blk_offset, 0);
@@ -1401,7 +1583,7 @@ static int ad4_ipc_reset_setup_ipcr(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
	int ret;
	u32 strength = 0, i = 0;
	u32 in_str = 0, out_str = 0, i = 0;
	struct sde_hw_mixer *hw_lm;

	/* Read AD calculator strength output during the 2 frames of manual
@@ -1414,20 +1596,25 @@ static int ad4_ipc_reset_setup_ipcr(struct sde_hw_dspp *dspp,
		/* this AD core is the salve core */
		for (i = DSPP_0; i < DSPP_MAX; i++) {
			if (info[i].is_master) {
				strength = info[i].last_str;
				in_str = info[i].last_str_inroi;
				out_str = info[i].last_str_outroi;
				break;
			}
		}
	} else {
		strength = SDE_REG_READ(&dspp->hw,
		in_str = SDE_REG_READ(&dspp->hw,
				dspp->cap->sblk->ad.base + 0x4c);
		pr_debug("%s(): AD strength = %d\n", __func__, strength);
		out_str = SDE_REG_READ(&dspp->hw,
				dspp->cap->sblk->ad.base + 0x50);
		pr_debug("%s(): AD in strength %d, out %d\n", __func__,
				in_str, out_str);
	}

	if (info[dspp->idx].frame_count == AD_IPC_FRAME_COUNT) {
		info[dspp->idx].state = ad4_state_run;
		pr_debug("%s(): AD state move to run\n", __func__);
		info[dspp->idx].last_str = strength;
		info[dspp->idx].last_str_inroi = in_str;
		info[dspp->idx].last_str_outroi = out_str;
		ret = ad4_cfg_ipc_reset(dspp, cfg);
		if (ret)
			return ret;
@@ -1441,7 +1628,7 @@ static int ad4_ipc_reset_setup_ipcr(struct sde_hw_dspp *dspp,
static int ad4_cfg_ipc_reset(struct sde_hw_dspp *dspp,
		struct sde_ad_hw_cfg *cfg)
{
	u32 blk_offset;
	u32 blk_offset, val = 0;

	/* revert manual strength */
	/* tf control */
@@ -1477,6 +1664,35 @@ static int ad4_cfg_ipc_reset(struct sde_hw_dspp *dspp,
		info[dspp->idx].cached_assertive = U8_MAX;
	}

	/*reset cached roi config*/
	if (info[dspp->idx].cached_roi_cfg.h_start != U32_MAX) {
		blk_offset = 0x18;
		val = (info[dspp->idx].cached_roi_cfg.h_end & (BIT(16) - 1));
		val |= ((info[dspp->idx].cached_roi_cfg.h_start &
			(BIT(16) - 1)) << 16);
		SDE_REG_WRITE(&dspp->hw,
			dspp->cap->sblk->ad.base + blk_offset, val);
		blk_offset += 4;
		val = (info[dspp->idx].cached_roi_cfg.v_end & (BIT(16) - 1));
		val |= ((info[dspp->idx].cached_roi_cfg.v_start &
			(BIT(16) - 1)) << 16);
		SDE_REG_WRITE(&dspp->hw,
			dspp->cap->sblk->ad.base + blk_offset, val);
		blk_offset = 0x40;
		val = ((info[dspp->idx].cached_roi_cfg.f_in &
			(BIT(16) - 1)) << 16);
		val |= (info[dspp->idx].cached_roi_cfg.f_out & (BIT(16) - 1));
		SDE_REG_WRITE(&dspp->hw,
			dspp->cap->sblk->ad.base + blk_offset, val);

		info[dspp->idx].last_roi_cfg = info[dspp->idx].cached_roi_cfg;
		info[dspp->idx].cached_roi_cfg.h_start = U32_MAX;
		info[dspp->idx].cached_roi_cfg.h_end = U32_MAX;
		info[dspp->idx].cached_roi_cfg.v_start = U32_MAX;
		info[dspp->idx].cached_roi_cfg.v_end = U32_MAX;
		info[dspp->idx].cached_roi_cfg.f_in = U32_MAX;
		info[dspp->idx].cached_roi_cfg.f_out = U32_MAX;
	}
	return 0;
}

+19 −0
Original line number Diff line number Diff line
@@ -436,4 +436,23 @@ struct drm_msm_pa_dither {
	__u32 matrix[DITHER_MATRIX_SZ];
};

/**
 * struct drm_msm_ad4_roi_cfg - ad4 roi params config set
 * by user-space client.
 * @h_x - hotizontal direction start
 * @h_y - hotizontal direction end
 * @v_x - vertical direction start
 * @v_y - vertical direction end
 * @factor_in - the alpha value for inside roi region
 * @factor_out - the alpha value for outside roi region
 */
#define DRM_MSM_AD4_ROI
struct drm_msm_ad4_roi_cfg {
	__u32 h_x;
	__u32 h_y;
	__u32 v_x;
	__u32 v_y;
	__u32 factor_in;
	__u32 factor_out;
};
#endif /* _MSM_DRM_PP_H_ */