diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2014-11-26 07:59:11 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2015-03-31 06:44:49 -0400 |
commit | 3973aff06585309f6215c66ed9d11d74656a9fa6 (patch) | |
tree | b013e824edd43b334302de2deb133cf2d20a253c | |
parent | 751e2676ee9272a0fbde6566afde33c1106d7da1 (diff) |
drm/imx: imx-ldb: reset display clock input when disabling LVDS
The LDB driver changes the attached display interface's input clock mux
to the LDB_DI clock reference. Change it back again when disabling the
LVDS display. Changing back to the PLL5 for example allows to configure
the same DI for HDMI output later.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r-- | drivers/gpu/drm/imx/imx-ldb.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 4286399590c3..544282bd4f7f 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
@@ -77,6 +77,7 @@ struct imx_ldb { | |||
77 | struct imx_ldb_channel channel[2]; | 77 | struct imx_ldb_channel channel[2]; |
78 | struct clk *clk[2]; /* our own clock */ | 78 | struct clk *clk[2]; /* our own clock */ |
79 | struct clk *clk_sel[4]; /* parent of display clock */ | 79 | struct clk *clk_sel[4]; /* parent of display clock */ |
80 | struct clk *clk_parent[4]; /* original parent of clk_sel */ | ||
80 | struct clk *clk_pll[2]; /* upstream clock we can adjust */ | 81 | struct clk *clk_pll[2]; /* upstream clock we can adjust */ |
81 | u32 ldb_ctrl; | 82 | u32 ldb_ctrl; |
82 | const struct bus_mux *lvds_mux; | 83 | const struct bus_mux *lvds_mux; |
@@ -287,6 +288,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) | |||
287 | { | 288 | { |
288 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); | 289 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); |
289 | struct imx_ldb *ldb = imx_ldb_ch->ldb; | 290 | struct imx_ldb *ldb = imx_ldb_ch->ldb; |
291 | int mux, ret; | ||
290 | 292 | ||
291 | /* | 293 | /* |
292 | * imx_ldb_encoder_disable is called by | 294 | * imx_ldb_encoder_disable is called by |
@@ -314,6 +316,28 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) | |||
314 | clk_disable_unprepare(ldb->clk[1]); | 316 | clk_disable_unprepare(ldb->clk[1]); |
315 | } | 317 | } |
316 | 318 | ||
319 | if (ldb->lvds_mux) { | ||
320 | const struct bus_mux *lvds_mux = NULL; | ||
321 | |||
322 | if (imx_ldb_ch == &ldb->channel[0]) | ||
323 | lvds_mux = &ldb->lvds_mux[0]; | ||
324 | else if (imx_ldb_ch == &ldb->channel[1]) | ||
325 | lvds_mux = &ldb->lvds_mux[1]; | ||
326 | |||
327 | regmap_read(ldb->regmap, lvds_mux->reg, &mux); | ||
328 | mux &= lvds_mux->mask; | ||
329 | mux >>= lvds_mux->shift; | ||
330 | } else { | ||
331 | mux = (imx_ldb_ch == &ldb->channel[0]) ? 0 : 1; | ||
332 | } | ||
333 | |||
334 | /* set display clock mux back to original input clock */ | ||
335 | ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk_parent[mux]); | ||
336 | if (ret) | ||
337 | dev_err(ldb->dev, | ||
338 | "unable to set di%d parent clock to original parent\n", | ||
339 | mux); | ||
340 | |||
317 | drm_panel_unprepare(imx_ldb_ch->panel); | 341 | drm_panel_unprepare(imx_ldb_ch->panel); |
318 | } | 342 | } |
319 | 343 | ||
@@ -499,6 +523,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
499 | imx_ldb->clk_sel[i] = NULL; | 523 | imx_ldb->clk_sel[i] = NULL; |
500 | break; | 524 | break; |
501 | } | 525 | } |
526 | |||
527 | imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]); | ||
502 | } | 528 | } |
503 | if (i == 0) | 529 | if (i == 0) |
504 | return ret; | 530 | return ret; |