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); }
OMAP_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) { #if !defined (CONFIG_OMAP2_DSS) if (omap_dispc_request_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain) != 0) #else pOMAPLFBVSyncISRHandle = omap_dispc_register_isr( (omap_dispc_isr_t)OMAPLFBVSyncISR, psSwapChain, DISPC_IRQ_VSYNC); if (pOMAPLFBVSyncISRHandle != NULL) #endif return PVRSRV_ERROR_OUT_OF_MEMORY; /* not worth a proper mapping */ return OMAP_OK; }
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) { int r; if (dssdev->manager == NULL) { DSSERR("failed to enable display: no manager\n"); return -ENODEV; } r = rfbi_runtime_get(); if (r) return r; r = omap_dss_start_device(dssdev); if (r) { DSSERR("failed to start device\n"); goto err0; } r = omap_dispc_register_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); if (r) { DSSERR("can't get FRAMEDONE irq\n"); goto err1; } dispc_mgr_set_lcd_display_type(dssdev->manager->id, OMAP_DSS_LCD_DISPLAY_TFT); dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI); dispc_mgr_enable_stallmode(dssdev->manager->id, true); dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size); rfbi_configure(dssdev->phy.rfbi.channel, dssdev->ctrl.pixel_size, dssdev->phy.rfbi.data_lines); rfbi_set_timings(dssdev->phy.rfbi.channel, &dssdev->ctrl.rfbi_timings); return 0; err1: omap_dss_stop_device(dssdev); err0: rfbi_runtime_put(); return r; }
static int rfbi_display_enable(struct omap_dss_device *dssdev) { int r; dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; r = omap_dss_start_device(dssdev); if (r) { DSSERR("failed to start device\n"); goto err0; } r = omap_dispc_register_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); if (r) { DSSERR("can't get FRAMEDONE irq\n"); goto err1; } dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI); dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); rfbi_configure(dssdev->phy.rfbi.channel, dssdev->ctrl.pixel_size, dssdev->phy.rfbi.data_lines); rfbi_set_timings(dssdev->phy.rfbi.channel, &dssdev->ctrl.rfbi_timings); if (dssdev->driver->enable) { r = dssdev->driver->enable(dssdev); if (r) goto err2; } return 0; err2: omap_dispc_unregister_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); err1: omap_dss_stop_device(dssdev); err0: return r; }
static int omapfb_wait_for_vsync(struct fb_info *fbi) { wait_queue_t wqt; unsigned long cnt, timeout = HZ/5; int ret; void *handle = NULL; u32 mask = 0; struct omapfb_info *ofbi = FB2OFB(fbi); struct omap_display *display = fb2display(fbi); mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD; handle = omap_dispc_register_isr(omapfb_isr, fbi, mask); if (!handle) return -EINVAL; init_waitqueue_entry(&wqt, current); cnt = ofbi->vsync_cnt; ret = wait_event_interruptible_timeout(ofbi->vsync_wait, cnt != ofbi->vsync_cnt, timeout); /* * If the GFX is on TV, then wait for another VSYNC * to compensate for Interlaced scan */ if (display->type == OMAP_DISPLAY_TYPE_VENC) { if (ret > 0) { cnt = ofbi->vsync_cnt; ret = wait_event_interruptible_timeout( ofbi->vsync_wait, cnt != ofbi->vsync_cnt, timeout); } } omap_dispc_unregister_isr(handle); if (ret < 0) return ret; if (ret == 0) return -ETIMEDOUT; return 0; }
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 inline int OMAPLFBRegisterVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) { return omap_dispc_register_isr(OMAPLFBVSyncISR, psSwapChain, DISPC_IRQ_VSYNC); }
else WARN_ON(1); } int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, unsigned long timeout) { void dispc_irq_wait_handler(void *data, u32 mask) { complete((struct completion *)data); } int r; DECLARE_COMPLETION_ONSTACK(completion); r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion, irqmask); if (r) return r; timeout = wait_for_completion_interruptible_timeout(&completion, timeout); omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask); if (timeout == 0) return -ETIMEDOUT; if (timeout == -ERESTARTSYS) return -ERESTARTSYS;
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) { int r; struct dispc_clock_info dispc_cinfo; struct omap_video_timings timings = { .hsw = 1, .hfp = 1, .hbp = 1, .vsw = 1, .vfp = 0, .vbp = 0, }; r = omap_dss_start_device(dssdev); if (r) { DSSERR("RFBI: failed to start device\n"); return r; } r = rfbi_runtime_get(); if (r) { DSSERR("RFBI: failed to get runtime\n"); goto err0; } r = omap_dispc_register_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); if (r) { DSSERR("RFBI: can't get FRAMEDONE irq\n"); goto err1; } dispc_set_parallel_interface_mode(dssdev->manager->id, OMAP_DSS_PARALLELMODE_RFBI); dispc_enable_fifohandcheck(dssdev->manager->id, 1); dispc_set_lcd_display_type(dssdev->manager->id, OMAP_DSS_LCD_DISPLAY_TFT); dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size); dispc_set_lcd_timings(dssdev->manager->id, &timings); r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); if (r) { DSSERR("RFBI: Failed to set dispc clocks\n"); goto err1; } rfbi_configure(dssdev->phy.rfbi.channel, dssdev->ctrl.pixel_size, dssdev->phy.rfbi.data_lines); rfbi_set_timings(dssdev->phy.rfbi.channel, &dssdev->ctrl.rfbi_timings); return 0; err1: rfbi_runtime_put(); err0: omap_dss_stop_device(dssdev); return r; } EXPORT_SYMBOL(omapdss_rfbi_display_enable); void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) { omap_dispc_unregister_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); omap_dss_stop_device(dssdev); rfbi_runtime_put(); }