static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc) { bool ret = true; if (dc->out->enable) dc->out->enable(); tegra_dc_setup_clk(dc, dc->clk); tegra_dc_clk_enable(dc); if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { mutex_lock(&tegra_dcs[1]->lock); disable_irq(tegra_dcs[1]->irq); } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { mutex_lock(&tegra_dcs[0]->lock); disable_irq(tegra_dcs[0]->irq); } msleep(5); tegra_periph_reset_assert(dc->clk); msleep(2); #ifdef CONFIG_TEGRA_SILICON_PLATFORM tegra_periph_reset_deassert(dc->clk); msleep(1); #endif if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { enable_dc_irq(tegra_dcs[1]->irq); mutex_unlock(&tegra_dcs[1]->lock); } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { enable_dc_irq(tegra_dcs[0]->irq); mutex_unlock(&tegra_dcs[0]->lock); } enable_dc_irq(dc->irq); if (tegra_dc_init(dc)) { dev_err(&dc->ndev->dev, "cannot initialize\n"); ret = false; } if (dc->out_ops && dc->out_ops->enable) dc->out_ops->enable(dc); if (dc->out->postpoweron) dc->out->postpoweron(); /* force a full blending update */ dc->blend.z[0] = -1; tegra_dc_ext_enable(dc->ext); if (!ret) { dev_err(&dc->ndev->dev, "initialization failed,disabling"); _tegra_dc_controller_disable(dc); } trace_printk("%s:reset enable\n", dc->ndev->name); return ret; }
static void tegra_dc_reset_worker(struct work_struct *work) { struct tegra_dc *dc = container_of(work, struct tegra_dc, reset_work); unsigned long val = 0; mutex_lock(&shared_lock); dev_warn(&dc->ndev->dev, "overlay stuck in underflow state. resetting.\n"); tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); if (dc->enabled == false) goto unlock; dc->enabled = false; /* * off host read bus */ val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC); val &= ~(0x00000100); tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC); /* * set DC to STOP mode */ tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND); msleep(10); _tegra_dc_controller_disable(dc); /* _tegra_dc_controller_reset_enable deasserts reset */ _tegra_dc_controller_reset_enable(dc); dc->enabled = true; /* reopen host read bus */ val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC); val &= ~(0x00000100); val |= 0x100; tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC); unlock: mutex_unlock(&dc->lock); mutex_unlock(&shared_lock); trace_printk("%s:reset complete\n", dc->ndev->name); }
static void _tegra_dc_disable(struct tegra_dc *dc) { if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) { mutex_lock(&dc->one_shot_lock); cancel_delayed_work_sync(&dc->one_shot_work); } tegra_dc_hold_dc_out(dc); _tegra_dc_controller_disable(dc); tegra_dc_io_end(dc); tegra_dc_release_dc_out(dc); if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) mutex_unlock(&dc->one_shot_lock); }
static bool _tegra_dc_controller_enable(struct tegra_dc *dc) { int failed_init = 0; if (dc->out->enable) dc->out->enable(); tegra_dc_setup_clk(dc, dc->clk); tegra_dc_clk_enable(dc); /* do not accept interrupts during initialization */ tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE); tegra_dc_writel(dc, 0, DC_CMD_INT_MASK); enable_dc_irq(dc->irq); failed_init = tegra_dc_init(dc); if (failed_init) { _tegra_dc_controller_disable(dc); return false; } if (dc->out_ops && dc->out_ops->enable) dc->out_ops->enable(dc); /* force a full blending update */ dc->blend.z[0] = -1; tegra_dc_ext_enable(dc->ext); trace_printk("%s:enable\n", dc->ndev->name); tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL); tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); if (dc->out->postpoweron) dc->out->postpoweron(); return true; }
static void _tegra_dc_disable(struct tegra_dc *dc) { _tegra_dc_controller_disable(dc); tegra_dc_io_end(dc); }