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

Commit 3ee1c926 authored by jabashque's avatar jabashque Committed by MajorP93
Browse files

techpack: display: Set oplus_dimlayer_hbm when switching power modes

When switching to a power mode that isn't "ON", we want to set
oplus_dimlayer_hbm to 0. When switching back to "ON", we want to restore
the original oplus_dimlayer_hbm value *after* setting everything else
up.

We want to do this because otherwise, if we leave oplus_dimlayer_hbm set
to 1, then there's a possiblity of the dimlayer being set after HBM gets
enabled, resulting in the potential of a brief, bright flash when waking
the device from Always-on Display Mode. In addition, when restoring the
original oplus_dimlayer_hbm value, we want to do that *after* the rest
of the panel setup; otherwise, we still risk having brief flashes.

To do this, we're creating a separate oplus_dimlayer_hbm_saved variable,
which tracks the user-intended state of oplus_dimlayer_hbm. When the
panel is ON, the sysfs attribute and the ioctl for dimlayer_hbm writes
to both oplus_dimlayer_hbm_saved and oplus_dimlayer_hbm; otherwise, they
write only to the former. This gives us free reign to set and restore
oplus_dimlayer_hbm when switching power modes.

Since the sysfs attribute and ioctl get a vblank for 5 frames before
changing the oplus_dimlayer_hbm variable, we'll also do that when
changing oplus_dimlayer_hbm while switching panel power modes.

Change-Id: I73288152f7048d94b3081cfd536df37a17577950
parent 8a0e7d7e
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ ktime_t oplus_backlight_time;
u32 oplus_backlight_delta = 0;

extern int oplus_dimlayer_hbm;
extern int oplus_dimlayer_hbm_saved;
extern int enable_global_hbm_flags;

/*#ifdef OPLUS_BUG_STABILITY*/
@@ -1676,7 +1677,7 @@ static ssize_t oplus_display_set_dimlayer_enable(struct device *dev,
static ssize_t oplus_display_get_dimlayer_hbm(struct device *dev,
                                struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", oplus_dimlayer_hbm);
	return sprintf(buf, "%d\n", oplus_dimlayer_hbm_saved);
}

extern int oplus_dimlayer_hbm_vblank_count;
@@ -1692,8 +1693,9 @@ static ssize_t oplus_display_set_dimlayer_hbm(struct device *dev,

	sscanf(buf, "%d", &value);
	value = !!value;
	if (oplus_dimlayer_hbm == value)
	if (oplus_dimlayer_hbm_saved == value)
		return count;
	if (get_oplus_display_power_status() == OPLUS_DISPLAY_POWER_ON) {
		if (!dsi_connector || !dsi_connector->state || !dsi_connector->state->crtc) {
			pr_err("[%s]: display not ready\n", __func__);
		} else {
@@ -1707,9 +1709,12 @@ static ssize_t oplus_display_set_dimlayer_hbm(struct device *dev,
			}
		}
		oplus_dimlayer_hbm = value;
	}
	oplus_dimlayer_hbm_saved = value;

#ifdef OPLUS_BUG_STABILITY
	pr_err("debug for oplus_display_set_dimlayer_hbm set oplus_dimlayer_hbm = %d\n",oplus_dimlayer_hbm);
	pr_err("debug for oplus_display_set_dimlayer_hbm set oplus_dimlayer_hbm = %d, oplus_dimlayer_hbm_saved = %d\n",
		oplus_dimlayer_hbm, oplus_dimlayer_hbm_saved);
#endif

	return count;
@@ -2303,6 +2308,8 @@ int dsi_display_oplus_set_power(struct drm_connector *connector,
		switch(get_oplus_display_scene()) {
		case OPLUS_DISPLAY_NORMAL_SCENE:
		case OPLUS_DISPLAY_NORMAL_HBM_SCENE:
			oplus_dimlayer_hbm = 0;
			oplus_dimlayer_vblank(connector->state->crtc);
			rc = dsi_panel_set_lp1(display->panel);
			rc = dsi_panel_set_lp2(display->panel);
			set_oplus_display_scene(OPLUS_DISPLAY_AOD_SCENE);
@@ -2359,6 +2366,10 @@ int dsi_display_oplus_set_power(struct drm_connector *connector,
			oplus_dsi_update_spr_mode();
		}
		set_oplus_display_power_status(OPLUS_DISPLAY_POWER_ON);
		if (oplus_dimlayer_hbm != oplus_dimlayer_hbm_saved) {
			oplus_dimlayer_hbm = oplus_dimlayer_hbm_saved;
			oplus_dimlayer_vblank(connector->state->crtc);
		}
		msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK,
					    &notifier_data);
		break;
+29 −13
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ bool oplus_skip_pcc = false;
bool apollo_backlight_enable = false;
struct drm_msm_pcc oplus_save_pcc;
int oplus_dimlayer_hbm = 0;
int oplus_dimlayer_hbm_saved = 0;
int oplus_aod_dim_alpha = CUST_A_NO;

extern int oplus_underbrightness_alpha;
@@ -809,7 +810,7 @@ int oplus_display_panel_get_dimlayer_hbm(void *data)
{
	uint32_t *dimlayer_hbm = data;

	(*dimlayer_hbm) = oplus_dimlayer_hbm;
	(*dimlayer_hbm) = oplus_dimlayer_hbm_saved;

	return 0;
}
@@ -823,8 +824,9 @@ int oplus_display_panel_set_dimlayer_hbm(void *data)
	int value = (*dimlayer_hbm);

	value = !!value;
	if (oplus_dimlayer_hbm == value)
	if (oplus_dimlayer_hbm_saved == value)
		return 0;
	if (get_oplus_display_power_status() == OPLUS_DISPLAY_POWER_ON) {
		if (!dsi_connector || !dsi_connector->state || !dsi_connector->state->crtc) {
			pr_err("[%s]: display not ready\n", __func__);
		} else {
@@ -838,14 +840,28 @@ int oplus_display_panel_set_dimlayer_hbm(void *data)
			}
		}
		oplus_dimlayer_hbm = value;
	}
	oplus_dimlayer_hbm_saved = value;

#ifdef OPLUS_BUG_STABILITY
	pr_err("debug for oplus_display_set_dimlayer_hbm set oplus_dimlayer_hbm = %d\n", oplus_dimlayer_hbm);
	pr_err("debug for oplus_display_set_dimlayer_hbm set oplus_dimlayer_hbm = %d, oplus_dimlayer_hbm_saved = %d\n",
		oplus_dimlayer_hbm, oplus_dimlayer_hbm_saved);
#endif

	return 0;
}

void oplus_dimlayer_vblank(struct drm_crtc *crtc) {
	int err = drm_crtc_vblank_get(crtc);
	if (err) {
		pr_err("failed to get crtc vblank, error=%d\n", err);
	} else {
		/* do vblank put after 5 frames */
		oplus_dimlayer_hbm_vblank_count = 5;
		atomic_inc(&oplus_dimlayer_hbm_vblank_ref);
	}
}

int oplus_display_panel_notify_fp_press(void *data)
{
	struct dsi_display *display = get_main_display();
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ bool _sde_encoder_setup_dither_for_onscreenfingerprint(struct sde_encoder_phys *

int sde_plane_check_fingerprint_layer(const struct drm_plane_state *drm_state);
int oplus_display_panel_set_dimlayer_hbm(void *data);
void oplus_dimlayer_vblank(struct drm_crtc *crtc);
int oplus_display_panel_get_dimlayer_hbm(void *data);
int oplus_display_panel_notify_fp_press(void *data);
#endif /*_OPLUS_ONSCREENFINGERPRINT_H_*/