static int rfbi_transfer_area(struct omap_dss_device *dssdev, void (*callback)(void *data), void *data) { u32 l; int r; struct omap_overlay_manager *mgr = rfbi.output.manager; u16 width = rfbi.timings.x_res; u16 height = rfbi.timings.y_res; /*BUG_ON(callback == 0);*/ BUG_ON(rfbi.framedone_callback != NULL); DSSDBG("rfbi_transfer_area %dx%d\n", width, height); dss_mgr_set_timings(mgr, &rfbi.timings); r = dss_mgr_enable(mgr); if (r) return r; 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); return 0; }
static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, u16 height, void (*callback)(void *data), void *data) { u32 l; int r; struct omap_video_timings timings = { .hsw = 1, .hfp = 1, .hbp = 1, .vsw = 1, .vfp = 0, .vbp = 0, .x_res = width, .y_res = height, }; /*BUG_ON(callback == 0);*/ BUG_ON(rfbi.framedone_callback != NULL); DSSDBG("rfbi_transfer_area %dx%d\n", width, height); dss_mgr_set_timings(dssdev->manager, &timings); r = dss_mgr_enable(dssdev->manager); if (r) return r; 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); return 0; } static void framedone_callback(void *data, u32 mask) { void (*callback)(void *data); DSSDBG("FRAMEDONE\n"); REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); callback = rfbi.framedone_callback; rfbi.framedone_callback = NULL; if (callback != NULL) callback(rfbi.framedone_callback_data); }
static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = hdmi.output.manager; struct dss_pll_clock_info hdmi_cinfo = { 0 }; r = hdmi_power_on_core(dssdev); if (r) return r; p = &hdmi.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); /* disable and clear irqs */ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); hdmi_wp_set_irqstatus(&hdmi.wp, hdmi_wp_get_irqstatus(&hdmi.wp)); r = dss_pll_enable(&hdmi.pll.pll); if (r) { DSSERR("Failed to enable PLL\n"); goto err_pll_enable; } r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); if (r) { DSSERR("Failed to configure PLL\n"); goto err_pll_cfg; } r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, hdmi_cinfo.clkout[0]); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_cfg; } r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); if (r) goto err_phy_pwr; hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi_wp_video_start(&hdmi.wp); if (r) goto err_vid_enable; r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; hdmi_wp_set_irqenable(&hdmi.wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; err_mgr_enable: hdmi_wp_video_stop(&hdmi.wp); err_vid_enable: hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); err_phy_pwr: err_phy_cfg: err_pll_cfg: dss_pll_disable(&hdmi.pll.pll); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }
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; }
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; }
static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = dssdev->output->manager; unsigned long phy; r = hdmi_power_on_core(dssdev); if (r) return r; dss_mgr_disable(mgr); p = &hdmi.ip_data.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); phy = p->pixel_clock; hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); hdmi.ip_data.ops->video_disable(&hdmi.ip_data); /* config the PLL and PHY hdmi_set_pll_pwrfirst */ r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to lock PLL\n"); goto err_pll_enable; } r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_enable; } hdmi.ip_data.ops->video_configure(&hdmi.ip_data); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); if (r) goto err_vid_enable; r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; return 0; err_mgr_enable: hdmi.ip_data.ops->video_disable(&hdmi.ip_data); err_vid_enable: hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); err_phy_enable: hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }
static int hdmi_power_on(struct omap_dss_device *dssdev) { int r, code = 0; struct omap_video_timings *p; unsigned long phy; r = hdmi_runtime_get(); if (r) return r; dss_mgr_disable(dssdev->manager); p = &dssdev->panel.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", dssdev->panel.timings.x_res, dssdev->panel.timings.y_res); code = get_timings_index(); update_hdmi_timings(&hdmi.ip_data.cfg, p, code); phy = p->pixel_clock; hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); /* config the PLL and PHY hdmi_set_pll_pwrfirst */ r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to lock PLL\n"); goto err; } r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to start PHY\n"); goto err; } hdmi.ip_data.cfg.cm.mode = hdmi.mode; hdmi.ip_data.cfg.cm.code = hdmi.code; hdmi.ip_data.ops->video_configure(&hdmi.ip_data); /* Make selection of HDMI in DSS */ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); /* Select the dispc clock source as PRCM clock, to ensure that it is not * DSI PLL source as the clock selected by DSI PLL might not be * sufficient for the resolution selected / that can be changed * dynamically by user. This can be moved to single location , say * Boardfile. */ dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dispc_set_digit_size(dssdev->panel.timings.x_res, dssdev->panel.timings.y_res); hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); r = dss_mgr_enable(dssdev->manager); if (r) goto err_mgr_enable; return 0; err_mgr_enable: hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); err: hdmi_runtime_put(); return -EIO; }
static int hdmi_power_on(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = dssdev->output->manager; unsigned long phy; gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); gpio_set_value(hdmi.ls_oe_gpio, 1); /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ udelay(300); r = regulator_enable(hdmi.vdda_hdmi_dac_reg); if (r) goto err_vdac_enable; r = hdmi_runtime_get(); if (r) goto err_runtime_get; dss_mgr_disable(mgr); p = &hdmi.ip_data.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); phy = p->pixel_clock; hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); hdmi.ip_data.ops->video_disable(&hdmi.ip_data); /* config the PLL and PHY hdmi_set_pll_pwrfirst */ r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to lock PLL\n"); goto err_pll_enable; } r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_enable; } hdmi.ip_data.ops->video_configure(&hdmi.ip_data); /* Make selection of HDMI in DSS */ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); /* Select the dispc clock source as PRCM clock, to ensure that it is not * DSI PLL source as the clock selected by DSI PLL might not be * sufficient for the resolution selected / that can be changed * dynamically by user. This can be moved to single location , say * Boardfile. */ dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); if (r) goto err_vid_enable; r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; return 0; err_mgr_enable: hdmi.ip_data.ops->video_disable(&hdmi.ip_data); err_vid_enable: hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); err_phy_enable: hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); err_pll_enable: hdmi_runtime_put(); err_runtime_get: regulator_disable(hdmi.vdda_hdmi_dac_reg); err_vdac_enable: gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); gpio_set_value(hdmi.ls_oe_gpio, 0); return -EIO; }
static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; enum omap_channel channel = dssdev->dispc_channel; struct hdmi_wp_data *wp = &hdmi.wp; struct dss_pll_clock_info hdmi_cinfo = { 0 }; unsigned pc; r = hdmi_power_on_core(dssdev); if (r) return r; /* disable and clear irqs */ hdmi_wp_clear_irqenable(wp, 0xffffffff); hdmi_wp_set_irqstatus(wp, 0xffffffff); p = &hdmi.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); pc = p->pixelclock; if (p->double_pixel) pc *= 2; hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); r = dss_pll_enable(&hdmi.pll.pll); if (r) { DSSERR("Failed to enable PLL\n"); goto err_pll_enable; } r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); if (r) { DSSERR("Failed to configure PLL\n"); goto err_pll_cfg; } r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, hdmi_cinfo.clkout[0]); if (r) { DSSDBG("Failed to configure PHY\n"); goto err_phy_cfg; } r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); if (r) goto err_phy_pwr; hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(channel, p); r = dss_mgr_enable(channel); if (r) goto err_mgr_enable; r = hdmi_wp_video_start(&hdmi.wp); if (r) goto err_vid_enable; hdmi_wp_set_irqenable(wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; err_vid_enable: dss_mgr_disable(channel); err_mgr_enable: hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); err_phy_pwr: err_phy_cfg: err_pll_cfg: dss_pll_disable(&hdmi.pll.pll); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }
static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = hdmi.output.manager; struct dss_pll_clock_info hdmi_cinfo = { 0 }; r = hdmi_power_on_core(dssdev); if (r) return r; p = &hdmi.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); /* disable and clear irqs */ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); hdmi_wp_set_irqstatus(&hdmi.wp, hdmi_wp_get_irqstatus(&hdmi.wp)); r = dss_pll_enable(&hdmi.pll.pll); if (r) { DSSERR("Failed to enable PLL\n"); goto err_pll_enable; } r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); if (r) { DSSERR("Failed to configure PLL\n"); goto err_pll_cfg; } r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, hdmi_cinfo.clkout[0]); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_cfg; } r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); if (r) goto err_phy_pwr; hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi_wp_video_start(&hdmi.wp); if (r) goto err_vid_enable; /* * XXX Seems that on we easily get a flood of sync-lost errors when * enabling the output. This seems to be related to the time between * HDMI VSYNC and enabling the DISPC output. * * Testing shows that the sync-lost errors do not happen if we enable * the DISPC output very soon after HDMI VBLANK. So wait here for * VBLANK to reduce the chances of sync-losts. */ hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); while (true) { u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); if (v & HDMI_IRQ_VIDEO_VSYNC) break; usleep_range(500, 1000); } r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; hdmi_wp_set_irqenable(&hdmi.wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; err_mgr_enable: hdmi_wp_video_stop(&hdmi.wp); err_vid_enable: hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); err_phy_pwr: err_phy_cfg: err_pll_cfg: dss_pll_disable(&hdmi.pll.pll); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }