static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, u16 height, void (*callback)(void *data), void *data) { u32 l; /*BUG_ON(callback == 0);*/ BUG_ON(rfbi.framedone_callback != NULL); DSSDBG("rfbi_transfer_area %dx%d\n", width, height); dispc_mgr_set_lcd_size(dssdev->manager->id, width, height); dispc_mgr_enable(dssdev->manager->id, true); rfbi.framedone_callback = callback; rfbi.framedone_callback_data = data; rfbi_write_reg(RFBI_PIXEL_CNT, width * height); l = rfbi_read_reg(RFBI_CONTROL); l = FLD_MOD(l, 1, 0, 0); /* enable */ if (!rfbi.te_enabled) l = FLD_MOD(l, 1, 4, 4); /* ITE */ rfbi_write_reg(RFBI_CONTROL, l); }
static void dispc_mgr_disable_digit_out(void) { DECLARE_COMPLETION_ONSTACK(framedone_compl); int r, i; u32 irq_mask; int num_irqs; if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false) return; /* * When we disable the digit output, we need to wait for FRAMEDONE to * know that DISPC has finished with the output. */ irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT); num_irqs = 1; if (!irq_mask) { /* * omap 2/3 don't have framedone irq for TV, so we need to use * vsyncs for this. */ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT); /* * We need to wait for both even and odd vsyncs. Note that this * is not totally reliable, as we could get a vsync interrupt * before we disable the output, which leads to timeout in the * wait_for_completion. */ num_irqs = 2; } r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl, irq_mask); if (r) DSSERR("failed to register %x isr\n", irq_mask); dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false); /* if we couldn't register the irq, just sleep and exit */ if (r) { msleep(100); return; } for (i = 0; i < num_irqs; ++i) { if (!wait_for_completion_timeout(&framedone_compl, msecs_to_jiffies(100))) DSSERR("timeout waiting for digit out to stop\n"); } r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl, irq_mask); if (r) DSSERR("failed to unregister %x isr\n", irq_mask); }
/* Called only from the encoder enable/disable and suspend/resume handlers. */ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) { struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); enum omap_channel channel = omap_crtc->channel; struct omap_irq_wait *wait; u32 framedone_irq, vsync_irq; int ret; if (dispc_mgr_is_enabled(channel) == enable) return; if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) { /* * Digit output produces some sync lost interrupts during the * first frame when enabling, so we need to ignore those. */ omap_crtc->ignore_digit_sync_lost = true; } framedone_irq = dispc_mgr_get_framedone_irq(channel); vsync_irq = dispc_mgr_get_vsync_irq(channel); if (enable) { wait = omap_irq_wait_init(dev, vsync_irq, 1); } else { /* * When we disable the digit output, we need to wait for * FRAMEDONE to know that DISPC has finished with the output. * * OMAP2/3 does not have FRAMEDONE irq for digit output, and in * that case we need to use vsync interrupt, and wait for both * even and odd frames. */ if (framedone_irq) wait = omap_irq_wait_init(dev, framedone_irq, 1); else wait = omap_irq_wait_init(dev, vsync_irq, 2); } dispc_mgr_enable(channel, enable); ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); if (ret) { dev_err(dev->dev, "%s: timeout waiting for %s\n", omap_crtc->name, enable ? "enable" : "disable"); } if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) { omap_crtc->ignore_digit_sync_lost = false; /* make sure the irq handler sees the value above */ mb(); } }
static void dispc_mgr_disable_lcd_out(enum omap_channel channel) { DECLARE_COMPLETION_ONSTACK(framedone_compl); int r; u32 irq; if (dispc_mgr_is_enabled(channel) == false) return; /* * When we disable LCD output, we need to wait for FRAMEDONE to know * that DISPC has finished with the LCD output. */ irq = dispc_mgr_get_framedone_irq(channel); r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl, irq); if (r) DSSERR("failed to register FRAMEDONE isr\n"); dispc_mgr_enable(channel, false); /* if we couldn't register for framedone, just sleep and exit */ if (r) { msleep(100); return; } if (!wait_for_completion_timeout(&framedone_compl, msecs_to_jiffies(100))) DSSERR("timeout waiting for FRAME DONE\n"); r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl, irq); if (r) DSSERR("failed to unregister FRAMEDONE isr\n"); }
static void dispc_mgr_enable_digit_out(void) { DECLARE_COMPLETION_ONSTACK(vsync_compl); int r; u32 irq_mask; if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true) return; /* * Digit output produces some sync lost interrupts during the first * frame when enabling. Those need to be ignored, so we register for the * sync lost irq to prevent the error handler from triggering. */ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) | dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT); r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl, irq_mask); if (r) { DSSERR("failed to register %x isr\n", irq_mask); return; } dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true); /* wait for the first evsync */ if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100))) DSSERR("timeout waiting for digit out to start\n"); r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl, irq_mask); if (r) DSSERR("failed to unregister %x isr\n", irq_mask); }
static void dispc_mgr_enable_lcd_out(enum omap_channel channel) { dispc_mgr_enable(channel, true); }