int irq;
struct drm_property *alpha;
+ struct drm_property *use_global;
struct completion disable_completion;
};
return -ENOMEM;
}
+ crtc->use_global = drm_property_create_range(drm, 0,
+ "use_global_alpha", 0, 1);
+ if (!crtc->use_global) {
+ dev_err(crtc->dev, "cannot create use_global property\n");
+ return -ENOMEM;
+ }
+
/* attach alpha property to channel 0 */
drm_object_attach_property(&crtc->plane[0]->base.base,
crtc->alpha, 255);
crtc->plane[0]->alpha_prop = crtc->alpha;
+ drm_object_attach_property(&crtc->plane[0]->base.base,
+ crtc->use_global, 0);
+ crtc->plane[0]->use_global_prop = crtc->use_global;
+
crtc->irq = dcss_vblank_irq_get(dcss);
if (crtc->irq < 0) {
dev_err(crtc->dev, "unable to get vblank interrupt\n");
if (property == dcss_plane->alpha_prop)
dcss_plane->alpha_val = val;
+ else if (property == dcss_plane->use_global_prop)
+ dcss_plane->use_global_val = val;
else
return -EINVAL;
if (property == dcss_plane->alpha_prop)
*val = dcss_plane->alpha_val;
+ else if (property == dcss_plane->use_global_prop)
+ *val = dcss_plane->use_global_val;
else
return -EINVAL;
if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state) &&
!dcss_plane_needs_setup(state, old_state) &&
!dcss_dtg_global_alpha_changed(dcss_plane->dcss, dcss_plane->ch_num,
- pixel_format,
- dcss_plane->alpha_val)) {
+ pixel_format, dcss_plane->alpha_val,
+ dcss_plane->use_global_val)) {
dcss_plane_atomic_set_base(dcss_plane);
return;
}
state->crtc_x, state->crtc_y,
state->crtc_w, state->crtc_h);
dcss_dtg_plane_alpha_set(dcss_plane->dcss, dcss_plane->ch_num,
- pixel_format, dcss_plane->alpha_val);
+ pixel_format, dcss_plane->alpha_val,
+ dcss_plane->use_global_val);
dcss_dpr_enable(dcss_plane->dcss, dcss_plane->ch_num, true);
dcss_scaler_enable(dcss_plane->dcss, dcss_plane->ch_num, true);
int alpha_val;
struct drm_property *alpha_prop;
+ int use_global_val;
+ struct drm_property *use_global_prop;
+
int ch_num;
};
u32 control_status;
u32 alpha;
+ u32 use_global;
/*
* This will be passed on by DRM CRTC so that we can signal when DTG has
#endif
dtg->alpha = 255;
+ dtg->use_global = 0;
dtg->control_status |= OVL_DATA_MODE | BLENDER_VIDEO_ALPHA_SEL |
((0x5 << CSS_PIX_COMP_SWAP_POS) & CSS_PIX_COMP_SWAP_MASK) |
}
bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
- u32 pix_format, int alpha)
+ u32 pix_format, int alpha,
+ int use_global_alpha)
{
struct dcss_dtg_priv *dtg = dcss->dtg_priv;
if (ch_num)
return false;
- return dcss_dtg_global_alpha_needed(pix_format) && alpha != dtg->alpha;
+ return dcss_dtg_global_alpha_needed(pix_format) &&
+ (alpha != dtg->alpha || use_global_alpha != dtg->use_global);
}
EXPORT_SYMBOL(dcss_dtg_global_alpha_changed);
void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
- u32 pix_format, int alpha)
+ u32 pix_format, int alpha, bool use_global_alpha)
{
struct dcss_dtg_priv *dtg = dcss->dtg_priv;
u32 alpha_val;
alpha_val = (alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK;
- if (dcss_dtg_global_alpha_needed(pix_format)) {
+ /*
+ * Use global alpha if pixel format does not have alpha channel or the
+ * user explicitly chose to use global alpha.
+ */
+ if (dcss_dtg_global_alpha_needed(pix_format) || use_global_alpha) {
dtg->control_status &= ~(CH1_ALPHA_SEL | DEFAULT_FG_ALPHA_MASK);
dtg->control_status |= alpha_val;
} else {
}
dtg->alpha = alpha;
+ dtg->use_global = use_global_alpha;
}
EXPORT_SYMBOL(dcss_dtg_plane_alpha_set);
bool dcss_dtg_is_enabled(struct dcss_soc *dcss);
void dcss_dtg_ch_enable(struct dcss_soc *dcss, int ch_num, bool en);
void dcss_dtg_plane_alpha_set(struct dcss_soc *dcss, int ch_num,
- u32 pix_format, int alpha);
+ u32 pix_format, int alpha, bool use_global_alpha);
bool dcss_dtg_global_alpha_changed(struct dcss_soc *dcss, int ch_num,
- u32 pix_format, int alpha);
+ u32 pix_format, int alpha,
+ int use_global_alpha);
/* SUBSAM */
void dcss_ss_sync_set(struct dcss_soc *dcss, struct videomode *vm,