static void am_meson_crtc_enable(struct drm_crtc *crtc)
{
- unsigned long flags;
char *name;
enum vmode_e mode;
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
update_vout_viu();
memcpy(&pipeline->mode, adjusted_mode,
sizeof(struct drm_display_mode));
- spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags);
- amcrtc->vblank_enable = 1;
- spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags);
- enable_irq(amcrtc->vblank_irq);
+ enable_irq(amcrtc->irq);
}
static void am_meson_crtc_disable(struct drm_crtc *crtc)
{
struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
- unsigned long flags;
DRM_INFO("%s\n", __func__);
if (crtc->state->event && !crtc->state->active) {
crtc->state->event = NULL;
}
- spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags);
- amcrtc->vblank_enable = 0;
- spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags);
-
- disable_irq(amcrtc->vblank_irq);
+ disable_irq(amcrtc->irq);
}
static void am_meson_crtc_commit(struct drm_crtc *crtc)
static int am_meson_enable_vblank(struct drm_device *dev, unsigned int crtc)
{
- struct meson_drm *priv = dev->dev_private;
-
- if (crtc >= MESON_MAX_CRTC)
- return -EBADFD;
-
- priv->crtc_funcs[crtc]->enable_vblank(priv->crtc);
return 0;
}
static void am_meson_disable_vblank(struct drm_device *dev, unsigned int crtc)
{
- struct meson_drm *priv = dev->dev_private;
-
- if (crtc >= MESON_MAX_CRTC)
- return;
-
- priv->crtc_funcs[crtc]->disable_vblank(priv->crtc);
}
static void am_meson_load(struct drm_device *dev)
drm->mode_config.funcs = &meson_mode_config_funcs;
drm->mode_config.allow_fb_modifiers = true;
/*
- * irq will init in each crtc, just mark the enable flag here.
+ * enable drm irq mode.
+ * - with irq_enabled = true, we can use the vblank feature.
*/
drm->irq_enabled = true;
DRM_INFO("%s %d\n", __func__, on);
if (on) {
- enable_irq(amcrtc->vblank_irq);
+ enable_irq(amcrtc->irq);
drm_crtc_vblank_on(crtc);
} else {
- disable_irq(amcrtc->vblank_irq);
+ disable_irq(amcrtc->irq);
drm_crtc_vblank_off(crtc);
}
static int am_meson_crtc_enable_vblank(struct drm_crtc *crtc)
{
- unsigned long flags;
- struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
-
- spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags);
- amcrtc->vblank_enable = true;
- spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags);
-
return 0;
}
static void am_meson_crtc_disable_vblank(struct drm_crtc *crtc)
{
- unsigned long flags;
- struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
-
- spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags);
- amcrtc->vblank_enable = false;
- spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags);
}
const struct meson_crtc_funcs meson_private_crtc_funcs = {
void am_meson_crtc_irq(struct meson_drm *priv)
{
- unsigned long flags;
struct am_meson_crtc *amcrtc = to_am_meson_crtc(priv->crtc);
- spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags);
- if (amcrtc->vblank_enable) {
- osd_drm_vsync_isr_handler();
- am_meson_crtc_handle_vsync(amcrtc);
- }
- spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags);
+ am_meson_crtc_handle_vsync(amcrtc);
}
static irqreturn_t am_meson_vpu_irq(int irq, void *arg)
dev_err(dev, "cannot find irq for vpu\n");
return irq;
}
- amcrtc->vblank_irq = (unsigned int)irq;
-
- spin_lock_init(&amcrtc->vblank_irq_lock);
- amcrtc->vblank_enable = false;
+ amcrtc->irq = (unsigned int)irq;
- ret = devm_request_irq(dev, amcrtc->vblank_irq, am_meson_vpu_irq,
+ ret = devm_request_irq(dev, amcrtc->irq, am_meson_vpu_irq,
IRQF_SHARED, dev_name(dev), drm_dev);
if (ret)
return ret;
- disable_irq(amcrtc->vblank_irq);
+ /* IRQ is initially disabled; it gets enabled in crtc_enable */
+ disable_irq(amcrtc->irq);
INIT_DELAYED_WORK(&osd_dwork, mem_free_work);
schedule_delayed_work(&osd_dwork, msecs_to_jiffies(60 * 1000));