summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.c2
-rw-r--r--drivers/gpu/imx/dpu/dpu-framegen.c45
-rw-r--r--include/video/dpu.h4
3 files changed, 38 insertions, 13 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.c b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
index 4c05b8cd3834..01b0a04ca2b6 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-crtc.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
@@ -455,7 +455,7 @@ static void dpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
crtc->base.id, crtc->name, __func__,
drm_mode_vrefresh(mode));
- framegen_cfg_videomode(dpu_crtc->fg, mode);
+ framegen_cfg_videomode(dpu_crtc->fg, mode, DRM_MODE_ENCODER_NONE);
framegen_displaymode(dpu_crtc->fg, FGDM__SEC_ON_TOP);
framegen_panic_displaymode(dpu_crtc->fg, FGDM__TEST);
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
index 21041fe987a5..a64995a4a1ad 100644
--- a/drivers/gpu/imx/dpu/dpu-framegen.c
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -19,6 +19,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/types.h>
+#include <drm/drm_mode.h>
#include <video/dpu.h>
#include "dpu-prv.h"
@@ -92,10 +93,12 @@
struct dpu_framegen {
void __iomem *base;
struct clk *clk_pll;
+ struct clk *clk_bypass;
struct clk *clk_disp;
struct mutex mutex;
int id;
bool inuse;
+ bool use_bypass_clk;
struct dpu_soc *dpu;
};
@@ -151,8 +154,10 @@ void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode)
}
EXPORT_SYMBOL_GPL(framegen_syncmode);
-void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m)
+void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
+ unsigned int encoder_type)
{
+ struct dpu_soc *dpu = fg->dpu;
u32 hact, htotal, hsync, hsbp;
u32 vact, vtotal, vsync, vsbp;
u32 kick_row, kick_col;
@@ -204,14 +209,28 @@ void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m)
disp_clock_rate = m->clock * 1000;
- /* find an even divisor for PLL */
- do {
- div += 2;
- pll_clock_rate = disp_clock_rate * div;
- } while (pll_clock_rate < PLL_MIN_FREQ_HZ);
+ if (encoder_type == DRM_MODE_ENCODER_TMDS) {
+ dpu_pxlink_set_mst_addr(dpu, fg->id, 1);
+
+ clk_set_parent(fg->clk_disp, fg->clk_bypass);
+
+ fg->use_bypass_clk = true;
+ } else {
+ dpu_pxlink_set_mst_addr(dpu, fg->id, 0);
+
+ clk_set_parent(fg->clk_disp, fg->clk_pll);
- clk_set_rate(fg->clk_pll, pll_clock_rate);
- clk_set_rate(fg->clk_disp, disp_clock_rate);
+ /* find an even divisor for PLL */
+ do {
+ div += 2;
+ pll_clock_rate = disp_clock_rate * div;
+ } while (pll_clock_rate < PLL_MIN_FREQ_HZ);
+
+ clk_set_rate(fg->clk_pll, pll_clock_rate);
+ clk_set_rate(fg->clk_disp, disp_clock_rate);
+
+ fg->use_bypass_clk = false;
+ }
}
EXPORT_SYMBOL_GPL(framegen_cfg_videomode);
@@ -386,14 +405,16 @@ EXPORT_SYMBOL_GPL(framegen_wait_for_secondary_syncup);
void framegen_enable_clock(struct dpu_framegen *fg)
{
- clk_prepare_enable(fg->clk_pll);
+ if (!fg->use_bypass_clk)
+ clk_prepare_enable(fg->clk_pll);
clk_prepare_enable(fg->clk_disp);
}
EXPORT_SYMBOL_GPL(framegen_enable_clock);
void framegen_disable_clock(struct dpu_framegen *fg)
{
- clk_disable_unprepare(fg->clk_pll);
+ if (!fg->use_bypass_clk)
+ clk_disable_unprepare(fg->clk_pll);
clk_disable_unprepare(fg->clk_disp);
}
EXPORT_SYMBOL_GPL(framegen_disable_clock);
@@ -473,6 +494,10 @@ int dpu_fg_init(struct dpu_soc *dpu, unsigned int id,
if (IS_ERR(fg->clk_pll))
return PTR_ERR(fg->clk_pll);
+ fg->clk_bypass = devm_clk_get(dpu->dev, "bypass0");
+ if (IS_ERR(fg->clk_bypass))
+ return PTR_ERR(fg->clk_bypass);
+
fg->clk_disp = devm_clk_get(dpu->dev, id ? "disp1" : "disp0");
if (IS_ERR(fg->clk_disp))
return PTR_ERR(fg->clk_disp);
diff --git a/include/video/dpu.h b/include/video/dpu.h
index fdb74fa57944..ad9d30453a89 100644
--- a/include/video/dpu.h
+++ b/include/video/dpu.h
@@ -473,8 +473,8 @@ void framegen_enable(struct dpu_framegen *fg);
void framegen_disable(struct dpu_framegen *fg);
void framegen_shdtokgen(struct dpu_framegen *fg);
void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode);
-void
-framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m);
+void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
+ unsigned int encoder_type);
void framegen_pkickconfig(struct dpu_framegen *fg, bool enable);
void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y);
void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode);