static int rfbi_runtime_get(void) { int r; DSSDBG("rfbi_runtime_get\n"); r = dss_runtime_get(); if (r) goto err_get_dss; r = dispc_runtime_get(); if (r) goto err_get_dispc; r = pm_runtime_get_sync(&rfbi.pdev->dev); WARN_ON(r); if (r < 0) goto err_runtime_get; return 0; err_runtime_get: dispc_runtime_put(); err_get_dispc: dss_runtime_put(); err_get_dss: return r; }
void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { int r; DSSDBG("dpi_set_timings\n"); dssdev->panel.timings = *timings; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { r = dss_runtime_get(); if (r) return; r = dispc_runtime_get(); if (r) { dss_runtime_put(); return; } dpi_set_mode(dssdev); dispc_go(dssdev->manager->id); dispc_runtime_put(); dss_runtime_put(); } }
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) { dispc_runtime_get(); __omap_irq_unregister(dev, irq); dispc_runtime_put(); }
/* connect overlays to the new device, if not already connected. if force * selected, connect always. */ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) { int i; struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *lcd2_mgr = NULL; struct omap_overlay_manager *mgr = NULL; lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); if (dss_has_feature(FEAT_MGR_LCD2)) lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { if (!lcd2_mgr->device || force) { if (lcd2_mgr->device) lcd2_mgr->unset_device(lcd2_mgr); lcd2_mgr->set_device(lcd2_mgr, dssdev); mgr = lcd2_mgr; } } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { if (!lcd_mgr->device || force) { if (lcd_mgr->device) lcd_mgr->unset_device(lcd_mgr); lcd_mgr->set_device(lcd_mgr, dssdev); mgr = lcd_mgr; } } if (dssdev->type == OMAP_DISPLAY_TYPE_VENC || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { if (!tv_mgr->device || force) { if (tv_mgr->device) tv_mgr->unset_device(tv_mgr); tv_mgr->set_device(tv_mgr, dssdev); mgr = tv_mgr; } } if (mgr) { dispc_runtime_get(); for (i = 0; i < dss_feat_get_num_ovls(); i++) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (!ovl->manager || force) { if (ovl->manager) ovl->unset_manager(ovl); ovl->set_manager(ovl, mgr); } } dispc_runtime_put(); } }
static int hdmi_runtime_resume(struct device *dev) { int r; r = dispc_runtime_get(); if (r < 0) return r; return 0; }
static int hdmi_runtime_resume(struct device *dev) { int r; r = dispc_runtime_get(); if (r < 0) return r; clk_prepare_enable(hdmi.sys_clk); return 0; }
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) { unsigned long flags; dispc_runtime_get(); spin_lock_irqsave(&list_lock, flags); if (!WARN_ON(!irq->registered)) { irq->registered = false; list_del(&irq->node); omap_irq_update(dev); } spin_unlock_irqrestore(&list_lock, flags); dispc_runtime_put(); }
void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) { struct omap_drm_private *priv = dev->dev_private; unsigned long flags; dispc_runtime_get(); spin_lock_irqsave(&list_lock, flags); if (!WARN_ON(irq->registered)) { irq->registered = true; list_add(&irq->node, &priv->irq_list); omap_irq_update(dev); } spin_unlock_irqrestore(&list_lock, flags); dispc_runtime_put(); }
static int rfbi_runtime_resume(struct device *dev) { int r; r = dss_runtime_get(); if (r < 0) goto err_get_dss; r = dispc_runtime_get(); if (r < 0) goto err_get_dispc; return 0; err_get_dispc: dss_runtime_put(); err_get_dss: return r; }
static int hdmi_runtime_resume(struct device *dev) { int r; r = dss_runtime_get(); if (r < 0) goto err_get_dss; r = dispc_runtime_get(); if (r < 0) goto err_get_dispc; clk_enable(hdmi.sys_clk); return 0; err_get_dispc: dss_runtime_put(); err_get_dss: return r; }
static int dpi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &dpi.output; int r; mutex_lock(&dpi.lock); if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) { DSSERR("no VDSS_DSI regulator\n"); r = -ENODEV; goto err_no_reg; } if (out == NULL || out->manager == NULL) { DSSERR("failed to enable display: no output/manager\n"); r = -ENODEV; goto err_no_out_mgr; } if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) goto err_reg_enable; } r = dispc_runtime_get(); if (r) goto err_get_dispc; r = dss_dpi_select_source(out->manager->id); if (r) goto err_src_sel; if (dpi.dsidev) { r = dsi_runtime_get(dpi.dsidev); if (r) goto err_get_dsi; r = dsi_pll_init(dpi.dsidev, 0, 1); if (r) goto err_dsi_pll_init; } r = dpi_set_mode(out->manager); if (r) goto err_set_mode; dpi_config_lcd_manager(out->manager); mdelay(2); r = dss_mgr_enable(out->manager); if (r) goto err_mgr_enable; mutex_unlock(&dpi.lock); return 0; err_mgr_enable: err_set_mode: if (dpi.dsidev) dsi_pll_uninit(dpi.dsidev, true); err_dsi_pll_init: if (dpi.dsidev) dsi_runtime_put(dpi.dsidev); err_get_dsi: err_src_sel: dispc_runtime_put(); err_get_dispc: if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) regulator_disable(dpi.vdds_dsi_reg); err_reg_enable: err_no_out_mgr: err_no_reg: mutex_unlock(&dpi.lock); return r; }
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_video_timings *t = &dssdev->panel.timings; struct dss_clock_info dss_cinfo; struct dispc_clock_info dispc_cinfo; u16 lck_div, pck_div; unsigned long fck; unsigned long pck; int r; if (dssdev->manager == NULL) { DSSERR("failed to enable display: no manager\n"); return -ENODEV; } r = omap_dss_start_device(dssdev); if (r) { DSSERR("failed to start device\n"); goto err_start_dev; } r = regulator_enable(sdi.vdds_sdi_reg); if (r) goto err_reg_enable; r = dss_runtime_get(); if (r) goto err_get_dss; r = dispc_runtime_get(); if (r) goto err_get_dispc; sdi_basic_init(dssdev); /* */ dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config, dssdev->panel.acbi, dssdev->panel.acb); r = dss_calc_clock_div(1, t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); if (r) goto err_calc_clock_div; fck = dss_cinfo.fck; lck_div = dispc_cinfo.lck_div; pck_div = dispc_cinfo.pck_div; pck = fck / lck_div / pck_div / 1000; if (pck != t->pixel_clock) { DSSWARN("Could not find exact pixel clock. Requested %d kHz, " "got %lu kHz\n", t->pixel_clock, pck); t->pixel_clock = pck; } dispc_mgr_set_lcd_timings(dssdev->manager->id, t); r = dss_set_clock_div(&dss_cinfo); if (r) goto err_set_dss_clock_div; r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); if (r) goto err_set_dispc_clock_div; dss_sdi_init(dssdev->phy.sdi.datapairs); r = dss_sdi_enable(); if (r) goto err_sdi_enable; mdelay(2); r = dss_mgr_enable(dssdev->manager); if (r) goto err_mgr_enable; return 0; err_mgr_enable: dss_sdi_disable(); err_sdi_enable: err_set_dispc_clock_div: err_set_dss_clock_div: err_calc_clock_div: dispc_runtime_put(); err_get_dispc: dss_runtime_put(); err_get_dss: regulator_disable(sdi.vdds_sdi_reg); err_reg_enable: omap_dss_stop_device(dssdev); err_start_dev: return r; }
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { int r; r = omap_dss_start_device(dssdev); if (r) { DSSERR("failed to start device\n"); goto err_start_dev; } if (cpu_is_omap34xx()) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) goto err_reg_enable; } r = dss_runtime_get(); if (r) goto err_get_dss; if (!dssdev->skip_init) { r = dispc_runtime_get(); if (r) goto err_get_dispc; } dpi_basic_init(dssdev); if (dpi_use_dsi_pll(dssdev)) { r = dsi_runtime_get(dpi.dsidev); if (r) goto err_get_dsi; if (!dssdev->skip_init) { r = dsi_pll_init(dpi.dsidev, 0, 1); if (r) goto err_dsi_pll_init; } } r = dpi_set_mode(dssdev); if (r) goto err_set_mode; mdelay(2); dssdev->manager->enable(dssdev->manager); if (dssdev->skip_init) dssdev->skip_init = false; return 0; err_set_mode: if (dpi_use_dsi_pll(dssdev)) dsi_pll_uninit(dpi.dsidev, true); err_dsi_pll_init: if (dpi_use_dsi_pll(dssdev)) dsi_runtime_put(dpi.dsidev); err_get_dsi: dispc_runtime_put(); err_get_dispc: dss_runtime_put(); err_get_dss: if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); err_reg_enable: omap_dss_stop_device(dssdev); err_start_dev: return r; }
static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, size_t size) { int i, r; struct omap_overlay_manager *mgr = NULL; struct omap_overlay_manager *old_mgr; int len = size; if (buf[size-1] == '\n') --len; if (len > 0) { for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { mgr = omap_dss_get_overlay_manager(i); if (sysfs_streq(buf, mgr->name)) break; mgr = NULL; } } if (len > 0 && mgr == NULL) return -EINVAL; if (mgr) DSSDBG("manager %s found\n", mgr->name); if (mgr == ovl->manager) return size; old_mgr = ovl->manager; r = dispc_runtime_get(); if (r) return r; /* detach old manager */ if (old_mgr) { r = ovl->unset_manager(ovl); if (r) { DSSERR("detach failed\n"); goto err; } r = old_mgr->apply(old_mgr); if (r) goto err; } if (mgr) { r = ovl->set_manager(ovl, mgr); if (r) { DSSERR("Failed to attach overlay\n"); goto err; } r = mgr->apply(mgr); if (r) goto err; } dispc_runtime_put(); return size; err: dispc_runtime_put(); return r; }
static int sdi_display_enable(struct omap_dss_device *dssdev) { struct sdi_device *sdi = dssdev_to_sdi(dssdev); struct videomode *vm = &sdi->vm; unsigned long fck; struct dispc_clock_info dispc_cinfo; unsigned long pck; int r; if (!sdi->output.dispc_channel_connected) { DSSERR("failed to enable display: no output/manager\n"); return -ENODEV; } r = regulator_enable(sdi->vdds_sdi_reg); if (r) goto err_reg_enable; r = dispc_runtime_get(sdi->dss->dispc); if (r) goto err_get_dispc; /* 15.5.9.1.2 */ vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE; r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo); if (r) goto err_calc_clock_div; sdi->mgr_config.clock_info = dispc_cinfo; pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; if (pck != vm->pixelclock) { DSSWARN("Could not find exact pixel clock. Requested %lu Hz, got %lu Hz\n", vm->pixelclock, pck); vm->pixelclock = pck; } dss_mgr_set_timings(&sdi->output, vm); r = dss_set_fck_rate(sdi->dss, fck); if (r) goto err_set_dss_clock_div; sdi_config_lcd_manager(sdi); /* * LCLK and PCLK divisors are located in shadow registers, and we * normally write them to DISPC registers when enabling the output. * However, SDI uses pck-free as source clock for its PLL, and pck-free * is affected by the divisors. And as we need the PLL before enabling * the output, we need to write the divisors early. * * It seems just writing to the DISPC register is enough, and we don't * need to care about the shadow register mechanism for pck-free. The * exact reason for this is unknown. */ dispc_mgr_set_clock_div(sdi->dss->dispc, sdi->output.dispc_channel, &sdi->mgr_config.clock_info); dss_sdi_init(sdi->dss, sdi->datapairs); r = dss_sdi_enable(sdi->dss); if (r) goto err_sdi_enable; mdelay(2); r = dss_mgr_enable(&sdi->output); if (r) goto err_mgr_enable; return 0; err_mgr_enable: dss_sdi_disable(sdi->dss); err_sdi_enable: err_set_dss_clock_div: err_calc_clock_div: dispc_runtime_put(sdi->dss->dispc); err_get_dispc: regulator_disable(sdi->vdds_sdi_reg); err_reg_enable: return r; }
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { int r; if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) { DSSERR("no VDSS_DSI regulator\n"); return -ENODEV; } if (dssdev->manager == NULL) { DSSERR("failed to enable display: no manager\n"); return -ENODEV; } r = omap_dss_start_device(dssdev); if (r) { DSSERR("failed to start device\n"); goto err_start_dev; } if (cpu_is_omap34xx()) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) goto err_reg_enable; } r = dispc_runtime_get(); if (r) goto err_get_dispc; dpi_basic_init(dssdev); if (dpi_use_dsi_pll(dssdev)) { r = dsi_runtime_get(dpi.dsidev); if (r) goto err_get_dsi; r = dsi_pll_init(dpi.dsidev, 0, 1); if (r) goto err_dsi_pll_init; } r = dpi_set_mode(dssdev); if (r) goto err_set_mode; mdelay(2); r = dss_mgr_enable(dssdev->manager); if (r) goto err_mgr_enable; return 0; err_mgr_enable: err_set_mode: if (dpi_use_dsi_pll(dssdev)) dsi_pll_uninit(dpi.dsidev, true); err_dsi_pll_init: if (dpi_use_dsi_pll(dssdev)) dsi_runtime_put(dpi.dsidev); err_get_dsi: dispc_runtime_put(); err_get_dispc: if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); err_reg_enable: omap_dss_stop_device(dssdev); err_start_dev: return r; }
static void dispc_error_worker(struct work_struct *work) { int i; u32 errors; unsigned long flags; static const unsigned fifo_underflow_bits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW, DISPC_IRQ_VID1_FIFO_UNDERFLOW, DISPC_IRQ_VID2_FIFO_UNDERFLOW, DISPC_IRQ_VID3_FIFO_UNDERFLOW, }; spin_lock_irqsave(&dispc_compat.irq_lock, flags); errors = dispc_compat.error_irqs; dispc_compat.error_irqs = 0; spin_unlock_irqrestore(&dispc_compat.irq_lock, flags); dispc_runtime_get(); for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; unsigned bit; ovl = omap_dss_get_overlay(i); bit = fifo_underflow_bits[i]; if (bit & errors) { DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n", ovl->name); dispc_ovl_enable(ovl->id, false); dispc_mgr_go(ovl->manager->id); msleep(50); } } for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { struct omap_overlay_manager *mgr; unsigned bit; mgr = omap_dss_get_overlay_manager(i); bit = dispc_mgr_get_sync_lost_irq(i); if (bit & errors) { int j; DSSERR("SYNC_LOST on channel %s, restarting the output " "with video overlays disabled\n", mgr->name); dss_mgr_disable(mgr); for (j = 0; j < omap_dss_get_num_overlays(); ++j) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(j); if (ovl->id != OMAP_DSS_GFX && ovl->manager == mgr) ovl->disable(ovl); } dss_mgr_enable(mgr); } } if (errors & DISPC_IRQ_OCP_ERR) { DSSERR("OCP_ERR\n"); for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { struct omap_overlay_manager *mgr; mgr = omap_dss_get_overlay_manager(i); dss_mgr_disable(mgr); } } spin_lock_irqsave(&dispc_compat.irq_lock, flags); dispc_compat.irq_error_mask |= errors; _omap_dispc_set_irqs(); spin_unlock_irqrestore(&dispc_compat.irq_lock, flags); dispc_runtime_put(); }
static int sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &sdi.output; struct omap_video_timings *t = &sdi.timings; unsigned long fck; struct dispc_clock_info dispc_cinfo; unsigned long pck; int r; if (out == NULL || out->manager == NULL) { DSSERR("failed to enable display: no output/manager\n"); return -ENODEV; } r = regulator_enable(sdi.vdds_sdi_reg); if (r) goto err_reg_enable; r = dispc_runtime_get(); if (r) goto err_get_dispc; /* 15.5.9.1.2 */ t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo); if (r) goto err_calc_clock_div; sdi.mgr_config.clock_info = dispc_cinfo; pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; if (pck != t->pixel_clock) { DSSWARN("Could not find exact pixel clock. Requested %d kHz, " "got %lu kHz\n", t->pixel_clock, pck); t->pixel_clock = pck; } dss_mgr_set_timings(out->manager, t); r = dss_set_fck_rate(fck); if (r) goto err_set_dss_clock_div; sdi_config_lcd_manager(dssdev); /* * LCLK and PCLK divisors are located in shadow registers, and we * normally write them to DISPC registers when enabling the output. * However, SDI uses pck-free as source clock for its PLL, and pck-free * is affected by the divisors. And as we need the PLL before enabling * the output, we need to write the divisors early. * * It seems just writing to the DISPC register is enough, and we don't * need to care about the shadow register mechanism for pck-free. The * exact reason for this is unknown. */ dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info); dss_sdi_init(sdi.datapairs); r = dss_sdi_enable(); if (r) goto err_sdi_enable; mdelay(2); r = dss_mgr_enable(out->manager); if (r) goto err_mgr_enable; return 0; err_mgr_enable: dss_sdi_disable(); err_sdi_enable: err_set_dss_clock_div: err_calc_clock_div: dispc_runtime_put(); err_get_dispc: regulator_disable(sdi.vdds_sdi_reg); err_reg_enable: return r; }