hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
- if (wait) {
+ if (wait && hdlcd->dpms == DRM_MODE_DPMS_ON) {
drm_vblank_get(fb->dev, 0);
- reinit_completion(&hdlcd->vsync_completion);
+ reinit_completion(&hdlcd->frame_completion);
do {
- ret = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
- msecs_to_jiffies(1000));
+ ret = wait_for_completion_interruptible_timeout(&hdlcd->frame_completion,
+ msecs_to_jiffies(50));
} while (ret <= 0);
drm_vblank_put(fb->dev, 0);
+ } else {
+ dev_info(fb->dev->dev, "%s: wait called with DPMS set to %d\n",
+ __func__, hdlcd->dpms);
}
}
crtc->primary->fb = fb;
- if (hdlcd->dpms != DRM_MODE_DPMS_ON) {
+ if (hdlcd->dpms == DRM_MODE_DPMS_ON) {
+ hdlcd_set_scanout(hdlcd, true);
+ } else {
unsigned long flags;
/* not active, update registers immediately */
if (event)
drm_send_vblank_event(crtc->dev, 0, event);
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- } else {
- hdlcd_set_scanout(hdlcd, true);
}
return 0;
goto fail;
}
- init_completion(&hdlcd->vsync_completion);
+ init_completion(&hdlcd->frame_completion);
ret = drm_vblank_init(dev, 1);
if (ret < 0) {
dev_err(dev->dev, "failed to initialise vblank\n");
drm_vblank_put(dev, 0);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
- complete_all(&hdlcd->vsync_completion);
+ }
+ if (irq_status & HDLCD_INTERRUPT_DMA_END) {
+ // send completion when reading the frame has finished
+ complete_all(&hdlcd->frame_completion);
}
/* acknowledge interrupt(s) */
static int hdlcd_irq_postinstall(struct drm_device *dev)
{
-#ifdef CONFIG_DEBUG_FS
struct hdlcd_drm_private *hdlcd = dev->dev_private;
- unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+ unsigned int irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+#ifdef CONFIG_DEBUG_FS
/* enable debug interrupts */
irq_mask |= HDLCD_DEBUG_INT_MASK;
+#endif
+ /* enable DMA completion interrupts */
+ irq_mask |= HDLCD_INTERRUPT_DMA_END;
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-#endif
+
return 0;
}
{
struct hdlcd_drm_private *hdlcd = dev->dev_private;
/* disable all the interrupts that we might have enabled */
- unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+ unsigned int irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
#ifdef CONFIG_DEBUG_FS
/* disable debug interrupts */
irq_mask &= ~HDLCD_DEBUG_INT_MASK;
#endif
- /* disable vsync interrupts */
- irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
+ /* disable vsync and dma interrupts */
+ irq_mask &= ~(HDLCD_INTERRUPT_VSYNC | HDLCD_INTERRUPT_DMA_END);
hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
}
struct drm_pending_vblank_event *event;
struct drm_crtc crtc;
struct device_node *slave_node;
- struct completion vsync_completion;
+ struct completion frame_completion;
#ifdef CONFIG_DEBUG_FS
atomic_t buffer_underrun_count;
atomic_t bus_error_count;
int ret;
drm_vblank_get(helper->dev, 0);
- reinit_completion(&hdlcd->vsync_completion);
+ reinit_completion(&hdlcd->frame_completion);
do {
- ret = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
- msecs_to_jiffies(1000));
+ ret = wait_for_completion_interruptible_timeout(&hdlcd->frame_completion,
+ msecs_to_jiffies(50));
} while (ret == -ERESTARTSYS);
drm_vblank_put(helper->dev, 0);
if (!ret)
{
struct drm_encoder_slave *slave;
if (!connector->encoder)
- return connector_status_unknown;
+ connector->encoder = hdlcd_connector_best_encoder(connector);
slave = hdlcd_get_slave_encoder(connector);
if (!slave || !slave->slave_funcs)
.destroy = drm_i2c_encoder_destroy,
};
+static void hdlcd_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+ drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
static struct drm_encoder_helper_funcs hdlcd_encoder_helper_funcs = {
.dpms = drm_i2c_encoder_dpms,
.save = drm_i2c_encoder_save,
.commit = drm_i2c_encoder_commit,
.mode_set = drm_i2c_encoder_mode_set,
.detect = drm_i2c_encoder_detect,
+ .disable = hdlcd_hdmi_encoder_disable,
};
static struct tda998x_encoder_params tda998x_params = {