diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 9 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 64 |
2 files changed, 65 insertions, 8 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index e4f79718b253..8167c8ceaedd 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -1819,7 +1819,8 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc) tegra_dc_unpowergate_locked(dc); - if (dc->out->enable) + if (!(dc->out->flags & TEGRA_DC_OUT_INITIALIZED_MODE) && + dc->out->enable) dc->out->enable(&dc->ndev->dev); tegra_dc_setup_clk(dc, dc->clk); @@ -2097,6 +2098,12 @@ static void _tegra_dc_disable(struct tegra_dc *dc) if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) mutex_unlock(&dc->one_shot_lock); + + /* + * We will need to reinitialize the display the next time panel + * is enabled. + */ + dc->out->flags &= ~TEGRA_DC_OUT_INITIALIZED_MODE; } void tegra_dc_disable(struct tegra_dc *dc) diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index e95aeef796d9..9ae3491820cd 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c @@ -3215,6 +3215,43 @@ static void tegra_dsi_send_dc_frames(struct tegra_dc *dc, } } +static void tegra_dsi_setup_initialized_panel(struct tegra_dc_dsi_data *dsi) +{ + regulator_enable(dsi->avdd_dsi_csi); + + dsi->status.init = DSI_MODULE_INIT; + dsi->status.lphs = DSI_LPHS_IN_HS_MODE; + dsi->status.driven = DSI_DRIVEN_MODE_DC; + dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_DC; + dsi->status.clk_out = DSI_PHYCLK_OUT_EN; + dsi->status.lp_op = DSI_LP_OP_NOT_INIT; + dsi->status.dc_stream = DSI_DC_STREAM_ENABLE; + + if (dsi->info.video_clock_mode == TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS) + dsi->status.clk_mode = DSI_PHYCLK_CONTINUOUS; + else + dsi->status.clk_mode = DSI_PHYCLK_TX_ONLY; + + if (!(dsi->info.ganged_type)) { + if (dsi->info.video_burst_mode == + TEGRA_DSI_VIDEO_NONE_BURST_MODE || + dsi->info.video_burst_mode == + TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END) + dsi->status.clk_burst = DSI_CLK_BURST_NONE_BURST; + else + dsi->status.clk_burst = DSI_CLK_BURST_BURST_MODE; + } + + if (dsi->info.video_data_type == TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE) + dsi->status.vtype = DSI_VIDEO_TYPE_CMD_MODE; + else + dsi->status.vtype = DSI_VIDEO_TYPE_VIDEO_MODE; + + tegra_dsi_clk_enable(dsi); + + dsi->enabled = true; +} + static void _tegra_dc_dsi_enable(struct tegra_dc *dc) { struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc); @@ -3223,6 +3260,15 @@ static void _tegra_dc_dsi_enable(struct tegra_dc *dc) mutex_lock(&dsi->lock); tegra_dc_io_start(dc); + /* + * Do not program this panel as the bootloader as has already + * initialized it. This avoids periods of blanking during boot. + */ + if (dc->out->flags & TEGRA_DC_OUT_INITIALIZED_MODE) { + tegra_dsi_setup_initialized_panel(dsi); + goto fail; + } + /* Stop DC stream before configuring DSI registers * to avoid visible glitches on panel during transition * from bootloader to kernel driver @@ -4153,6 +4199,16 @@ static long tegra_dc_dsi_setup_clk(struct tegra_dc *dc, struct clk *clk) struct clk *parent_clk; struct clk *base_clk; + /* divide by 1000 to avoid overflow */ + dc->mode.pclk /= 1000; + rate = (dc->mode.pclk * dc->shift_clk_div.mul * 2) + / dc->shift_clk_div.div; + rate *= 1000; + dc->mode.pclk *= 1000; + + if (dc->out->flags & TEGRA_DC_OUT_INITIALIZED_MODE) + goto skip_setup; + if (clk == dc->clk) { parent_clk = clk_get_sys(NULL, dc->out->parent_clk ? : "pll_d_out0"); @@ -4175,19 +4231,13 @@ static long tegra_dc_dsi_setup_clk(struct tegra_dc *dc, struct clk *clk) } } - /* divide by 1000 to avoid overflow */ - dc->mode.pclk /= 1000; - rate = (dc->mode.pclk * dc->shift_clk_div.mul * 2) - / dc->shift_clk_div.div; - rate *= 1000; - dc->mode.pclk *= 1000; - if (rate != clk_get_rate(base_clk)) clk_set_rate(base_clk, rate); if (clk_get_parent(clk) != parent_clk) clk_set_parent(clk, parent_clk); +skip_setup: return tegra_dc_pclk_round_rate(dc, dc->mode.pclk); } |