Commit 6541d710 authored by Jiada Wang's avatar Jiada Wang Committed by Philipp Zabel

gpu: ipu-di: Add ipu_di_adjust_videomode()

On some monitors, high resolution modes are not working, exhibiting
pixel column truncation problems (for example, 1280x1024 displays as
1280x1022).

The function ipu_di_adjust_videomode() aims to fix these issues by
adjusting a passed videomode to IPU restrictions. The function can
be called from the drm_crtc_helper_funcs->mode_fixup() methods.
Signed-off-by: default avatarJiada Wang <jiada_wang@mentor.com>
Signed-off-by: default avatarDeepak Das <deepak_das@mentor.com>
Signed-off-by: default avatarSteve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent f66a1627
...@@ -511,6 +511,35 @@ static void ipu_di_config_clock(struct ipu_di *di, ...@@ -511,6 +511,35 @@ static void ipu_di_config_clock(struct ipu_di *di,
clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4)); clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4));
} }
/*
* This function is called to adjust a video mode to IPU restrictions.
* It is meant to be called from drm crtc mode_fixup() methods.
*/
int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
{
u32 diff;
if (mode->vfront_porch >= 2)
return 0;
diff = 2 - mode->vfront_porch;
if (mode->vback_porch >= diff) {
mode->vfront_porch = 2;
mode->vback_porch -= diff;
} else if (mode->vsync_len > diff) {
mode->vfront_porch = 2;
mode->vsync_len = mode->vsync_len - diff;
} else {
dev_warn(di->ipu->dev, "failed to adjust videomode\n");
return -EINVAL;
}
dev_warn(di->ipu->dev, "videomode adapted for IPU restrictions\n");
return 0;
}
EXPORT_SYMBOL_GPL(ipu_di_adjust_videomode);
int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
{ {
u32 reg; u32 reg;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <media/v4l2-mediabus.h> #include <media/v4l2-mediabus.h>
#include <video/videomode.h>
struct ipu_soc; struct ipu_soc;
...@@ -236,6 +237,7 @@ void ipu_di_put(struct ipu_di *); ...@@ -236,6 +237,7 @@ void ipu_di_put(struct ipu_di *);
int ipu_di_disable(struct ipu_di *); int ipu_di_disable(struct ipu_di *);
int ipu_di_enable(struct ipu_di *); int ipu_di_enable(struct ipu_di *);
int ipu_di_get_num(struct ipu_di *); int ipu_di_get_num(struct ipu_di *);
int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode);
int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig); int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment