Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-20 Thread Maxime Ripard
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote:
> On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> > Hi Daniel,
> > 
> > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > > Create overscan profiles reducing the displayed zone.
> > > > 
> > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced 
> > > > modes
> > > > by steps of 5% that the user will be able to select.
> > > > 
> > > > Signed-off-by: Maxime Ripard 
> > > 
> > > tbh I think if we agree to do this (and that still seems an open question)
> > > I think there should be a generic helper to add these overscan modes with
> > > increased porches. Anything that only depends upon the sink (and
> > > overscanning is something the sink does) should imo be put into a suitable
> > > helper library for everyone to share.
> > > 
> > > Or maybe even stash it into the probe helpers and call it for all TV
> > > connectors. Definitely not a driver-private thing.
> > 
> > Last time we discussed it, my recollection was that you didn't want to
> > have generic code for it, but I'd be happy to implement it.
> > 
> > I'll come up with something like that.
> 
> Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
> Since you called me out, feel free to do whatever you want ...

I also found the generic solution to be a much better solution, so
I'll definitely implement it :)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-20 Thread Maxime Ripard
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote:
> On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> > Hi Daniel,
> > 
> > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > > Create overscan profiles reducing the displayed zone.
> > > > 
> > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced 
> > > > modes
> > > > by steps of 5% that the user will be able to select.
> > > > 
> > > > Signed-off-by: Maxime Ripard 
> > > 
> > > tbh I think if we agree to do this (and that still seems an open question)
> > > I think there should be a generic helper to add these overscan modes with
> > > increased porches. Anything that only depends upon the sink (and
> > > overscanning is something the sink does) should imo be put into a suitable
> > > helper library for everyone to share.
> > > 
> > > Or maybe even stash it into the probe helpers and call it for all TV
> > > connectors. Definitely not a driver-private thing.
> > 
> > Last time we discussed it, my recollection was that you didn't want to
> > have generic code for it, but I'd be happy to implement it.
> > 
> > I'll come up with something like that.
> 
> Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
> Since you called me out, feel free to do whatever you want ...

I also found the generic solution to be a much better solution, so
I'll definitely implement it :)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-11 Thread Daniel Vetter
On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> Hi Daniel,
> 
> On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > Create overscan profiles reducing the displayed zone.
> > > 
> > > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > > by steps of 5% that the user will be able to select.
> > > 
> > > Signed-off-by: Maxime Ripard 
> > 
> > tbh I think if we agree to do this (and that still seems an open question)
> > I think there should be a generic helper to add these overscan modes with
> > increased porches. Anything that only depends upon the sink (and
> > overscanning is something the sink does) should imo be put into a suitable
> > helper library for everyone to share.
> > 
> > Or maybe even stash it into the probe helpers and call it for all TV
> > connectors. Definitely not a driver-private thing.
> 
> Last time we discussed it, my recollection was that you didn't want to
> have generic code for it, but I'd be happy to implement it.
> 
> I'll come up with something like that.

Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
Since you called me out, feel free to do whatever you want ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-11 Thread Daniel Vetter
On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> Hi Daniel,
> 
> On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > Create overscan profiles reducing the displayed zone.
> > > 
> > > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > > by steps of 5% that the user will be able to select.
> > > 
> > > Signed-off-by: Maxime Ripard 
> > 
> > tbh I think if we agree to do this (and that still seems an open question)
> > I think there should be a generic helper to add these overscan modes with
> > increased porches. Anything that only depends upon the sink (and
> > overscanning is something the sink does) should imo be put into a suitable
> > helper library for everyone to share.
> > 
> > Or maybe even stash it into the probe helpers and call it for all TV
> > connectors. Definitely not a driver-private thing.
> 
> Last time we discussed it, my recollection was that you didn't want to
> have generic code for it, but I'd be happy to implement it.
> 
> I'll come up with something like that.

Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
Since you called me out, feel free to do whatever you want ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-10 Thread Maxime Ripard
Hi Daniel,

On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > Create overscan profiles reducing the displayed zone.
> > 
> > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > by steps of 5% that the user will be able to select.
> > 
> > Signed-off-by: Maxime Ripard 
> 
> tbh I think if we agree to do this (and that still seems an open question)
> I think there should be a generic helper to add these overscan modes with
> increased porches. Anything that only depends upon the sink (and
> overscanning is something the sink does) should imo be put into a suitable
> helper library for everyone to share.
> 
> Or maybe even stash it into the probe helpers and call it for all TV
> connectors. Definitely not a driver-private thing.

Last time we discussed it, my recollection was that you didn't want to
have generic code for it, but I'd be happy to implement it.

I'll come up with something like that.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-10 Thread Maxime Ripard
Hi Daniel,

On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > Create overscan profiles reducing the displayed zone.
> > 
> > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > by steps of 5% that the user will be able to select.
> > 
> > Signed-off-by: Maxime Ripard 
> 
> tbh I think if we agree to do this (and that still seems an open question)
> I think there should be a generic helper to add these overscan modes with
> increased porches. Anything that only depends upon the sink (and
> overscanning is something the sink does) should imo be put into a suitable
> helper library for everyone to share.
> 
> Or maybe even stash it into the probe helpers and call it for all TV
> connectors. Definitely not a driver-private thing.

Last time we discussed it, my recollection was that you didn't want to
have generic code for it, but I'd be happy to implement it.

I'll come up with something like that.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-08 Thread Daniel Vetter
On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> Create overscan profiles reducing the displayed zone.
> 
> For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> by steps of 5% that the user will be able to select.
> 
> Signed-off-by: Maxime Ripard 

tbh I think if we agree to do this (and that still seems an open question)
I think there should be a generic helper to add these overscan modes with
increased porches. Anything that only depends upon the sink (and
overscanning is something the sink does) should imo be put into a suitable
helper library for everyone to share.

Or maybe even stash it into the probe helpers and call it for all TV
connectors. Definitely not a driver-private thing.
-Daniel
> ---
>  drivers/gpu/drm/sun4i/sun4i_tv.c | 60 +++--
>  1 file changed, 36 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c 
> b/drivers/gpu/drm/sun4i/sun4i_tv.c
> index f99886462cb8..9ee03ba086b6 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -301,27 +301,33 @@ static const struct tv_mode 
> *sun4i_tv_find_tv_by_mode(const struct drm_display_m
>   DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
>mode->name, tv_mode->name);
>  
> - if (!strcmp(mode->name, tv_mode->name))
> + if (!strncmp(mode->name, tv_mode->name, strlen(tv_mode->name)))
>   return tv_mode;
>   }
>  
>   /* Then by number of lines */
>   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
>   const struct tv_mode *tv_mode = _modes[i];
> + int j;
>  
> - DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
> -  mode->name, tv_mode->name,
> -  mode->vdisplay, tv_mode->vdisplay);
> + for (j = 0; j < 20; j += 5) {
> + u32 vdisplay = tv_mode->vdisplay * (100 - j) / 100;
>  
> - if (mode->vdisplay == tv_mode->vdisplay)
> - return tv_mode;
> + DRM_DEBUG_DRIVER("Comparing mode with %s (%d) (X: %d vs 
> %d)",
> +  tv_mode->name, j,
> +  vdisplay, tv_mode->vdisplay);
> +
> + if (vdisplay == tv_mode->vdisplay)
> + return tv_mode;
> + }
>   }
>  
>   return NULL;
>  }
>  
>  static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
> -   struct drm_display_mode *mode)
> +   struct drm_display_mode *mode,
> +   int overscan)
>  {
>   DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
>  
> @@ -329,12 +335,12 @@ static void sun4i_tv_mode_to_drm_mode(const struct 
> tv_mode *tv_mode,
>   mode->clock = 13500;
>   mode->flags = DRM_MODE_FLAG_INTERLACE;
>  
> - mode->hdisplay = tv_mode->hdisplay;
> + mode->hdisplay = tv_mode->hdisplay * (100 - overscan) / 100;
>   mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
>   mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
>   mode->htotal = mode->hsync_end  + tv_mode->hback_porch;
>  
> - mode->vdisplay = tv_mode->vdisplay;
> + mode->vdisplay = tv_mode->vdisplay * (100 - overscan) / 100;
>   mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch;
>   mode->vsync_end = mode->vsync_start + tv_mode->vsync_len;
>   mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
> @@ -352,10 +358,10 @@ static int sun4i_tv_atomic_check(struct drm_encoder 
> *encoder,
>   return -EINVAL;
>  
>   state->display_x_size = tv_mode->hdisplay;
> - state->plane_x_offset = 0;
> + state->plane_x_offset = (tv_mode->hdisplay - mode->hdisplay) / 2;
>  
>   state->display_y_size = tv_mode->vdisplay;
> - state->plane_y_offset = 0;
> + state->plane_y_offset = (tv_mode->vdisplay - mode->vdisplay) / 2;
>  
>   return 0;
>  }
> @@ -404,7 +410,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
>   struct drm_display_mode tv_drm_mode = { 0 };
>  
>   strcpy(tv_drm_mode.name, "TV");
> - sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode);
> + sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode, 0);
>   drm_mode_set_crtcinfo(_drm_mode, CRTC_INTERLACE_HALVE_V);
>  
>   sun4i_tcon1_mode_set(tcon, _drm_mode);
> @@ -526,22 +532,28 @@ static int sun4i_tv_comp_get_modes(struct drm_connector 
> *connector)
>   int i;
>  
>   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
> - struct drm_display_mode *mode;
>   const struct tv_mode *tv_mode = _modes[i];
> -
> - mode = drm_mode_create(connector->dev);
> - if (!mode) {
> - DRM_ERROR("Failed to create a new display 

Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-11-08 Thread Daniel Vetter
On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> Create overscan profiles reducing the displayed zone.
> 
> For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> by steps of 5% that the user will be able to select.
> 
> Signed-off-by: Maxime Ripard 

tbh I think if we agree to do this (and that still seems an open question)
I think there should be a generic helper to add these overscan modes with
increased porches. Anything that only depends upon the sink (and
overscanning is something the sink does) should imo be put into a suitable
helper library for everyone to share.

Or maybe even stash it into the probe helpers and call it for all TV
connectors. Definitely not a driver-private thing.
-Daniel
> ---
>  drivers/gpu/drm/sun4i/sun4i_tv.c | 60 +++--
>  1 file changed, 36 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c 
> b/drivers/gpu/drm/sun4i/sun4i_tv.c
> index f99886462cb8..9ee03ba086b6 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -301,27 +301,33 @@ static const struct tv_mode 
> *sun4i_tv_find_tv_by_mode(const struct drm_display_m
>   DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
>mode->name, tv_mode->name);
>  
> - if (!strcmp(mode->name, tv_mode->name))
> + if (!strncmp(mode->name, tv_mode->name, strlen(tv_mode->name)))
>   return tv_mode;
>   }
>  
>   /* Then by number of lines */
>   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
>   const struct tv_mode *tv_mode = _modes[i];
> + int j;
>  
> - DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
> -  mode->name, tv_mode->name,
> -  mode->vdisplay, tv_mode->vdisplay);
> + for (j = 0; j < 20; j += 5) {
> + u32 vdisplay = tv_mode->vdisplay * (100 - j) / 100;
>  
> - if (mode->vdisplay == tv_mode->vdisplay)
> - return tv_mode;
> + DRM_DEBUG_DRIVER("Comparing mode with %s (%d) (X: %d vs 
> %d)",
> +  tv_mode->name, j,
> +  vdisplay, tv_mode->vdisplay);
> +
> + if (vdisplay == tv_mode->vdisplay)
> + return tv_mode;
> + }
>   }
>  
>   return NULL;
>  }
>  
>  static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
> -   struct drm_display_mode *mode)
> +   struct drm_display_mode *mode,
> +   int overscan)
>  {
>   DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
>  
> @@ -329,12 +335,12 @@ static void sun4i_tv_mode_to_drm_mode(const struct 
> tv_mode *tv_mode,
>   mode->clock = 13500;
>   mode->flags = DRM_MODE_FLAG_INTERLACE;
>  
> - mode->hdisplay = tv_mode->hdisplay;
> + mode->hdisplay = tv_mode->hdisplay * (100 - overscan) / 100;
>   mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
>   mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
>   mode->htotal = mode->hsync_end  + tv_mode->hback_porch;
>  
> - mode->vdisplay = tv_mode->vdisplay;
> + mode->vdisplay = tv_mode->vdisplay * (100 - overscan) / 100;
>   mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch;
>   mode->vsync_end = mode->vsync_start + tv_mode->vsync_len;
>   mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
> @@ -352,10 +358,10 @@ static int sun4i_tv_atomic_check(struct drm_encoder 
> *encoder,
>   return -EINVAL;
>  
>   state->display_x_size = tv_mode->hdisplay;
> - state->plane_x_offset = 0;
> + state->plane_x_offset = (tv_mode->hdisplay - mode->hdisplay) / 2;
>  
>   state->display_y_size = tv_mode->vdisplay;
> - state->plane_y_offset = 0;
> + state->plane_y_offset = (tv_mode->vdisplay - mode->vdisplay) / 2;
>  
>   return 0;
>  }
> @@ -404,7 +410,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
>   struct drm_display_mode tv_drm_mode = { 0 };
>  
>   strcpy(tv_drm_mode.name, "TV");
> - sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode);
> + sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode, 0);
>   drm_mode_set_crtcinfo(_drm_mode, CRTC_INTERLACE_HALVE_V);
>  
>   sun4i_tcon1_mode_set(tcon, _drm_mode);
> @@ -526,22 +532,28 @@ static int sun4i_tv_comp_get_modes(struct drm_connector 
> *connector)
>   int i;
>  
>   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
> - struct drm_display_mode *mode;
>   const struct tv_mode *tv_mode = _modes[i];
> -
> - mode = drm_mode_create(connector->dev);
> - if (!mode) {
> - DRM_ERROR("Failed to create a new display mode\n");
> - return 

[PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-10-18 Thread Maxime Ripard
Create overscan profiles reducing the displayed zone.

For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
by steps of 5% that the user will be able to select.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_tv.c | 60 +++--
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index f99886462cb8..9ee03ba086b6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -301,27 +301,33 @@ static const struct tv_mode 
*sun4i_tv_find_tv_by_mode(const struct drm_display_m
DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
 mode->name, tv_mode->name);
 
-   if (!strcmp(mode->name, tv_mode->name))
+   if (!strncmp(mode->name, tv_mode->name, strlen(tv_mode->name)))
return tv_mode;
}
 
/* Then by number of lines */
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
const struct tv_mode *tv_mode = _modes[i];
+   int j;
 
-   DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
-mode->name, tv_mode->name,
-mode->vdisplay, tv_mode->vdisplay);
+   for (j = 0; j < 20; j += 5) {
+   u32 vdisplay = tv_mode->vdisplay * (100 - j) / 100;
 
-   if (mode->vdisplay == tv_mode->vdisplay)
-   return tv_mode;
+   DRM_DEBUG_DRIVER("Comparing mode with %s (%d) (X: %d vs 
%d)",
+tv_mode->name, j,
+vdisplay, tv_mode->vdisplay);
+
+   if (vdisplay == tv_mode->vdisplay)
+   return tv_mode;
+   }
}
 
return NULL;
 }
 
 static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
- struct drm_display_mode *mode)
+ struct drm_display_mode *mode,
+ int overscan)
 {
DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
 
@@ -329,12 +335,12 @@ static void sun4i_tv_mode_to_drm_mode(const struct 
tv_mode *tv_mode,
mode->clock = 13500;
mode->flags = DRM_MODE_FLAG_INTERLACE;
 
-   mode->hdisplay = tv_mode->hdisplay;
+   mode->hdisplay = tv_mode->hdisplay * (100 - overscan) / 100;
mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
mode->htotal = mode->hsync_end  + tv_mode->hback_porch;
 
-   mode->vdisplay = tv_mode->vdisplay;
+   mode->vdisplay = tv_mode->vdisplay * (100 - overscan) / 100;
mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch;
mode->vsync_end = mode->vsync_start + tv_mode->vsync_len;
mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
@@ -352,10 +358,10 @@ static int sun4i_tv_atomic_check(struct drm_encoder 
*encoder,
return -EINVAL;
 
state->display_x_size = tv_mode->hdisplay;
-   state->plane_x_offset = 0;
+   state->plane_x_offset = (tv_mode->hdisplay - mode->hdisplay) / 2;
 
state->display_y_size = tv_mode->vdisplay;
-   state->plane_y_offset = 0;
+   state->plane_y_offset = (tv_mode->vdisplay - mode->vdisplay) / 2;
 
return 0;
 }
@@ -404,7 +410,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode tv_drm_mode = { 0 };
 
strcpy(tv_drm_mode.name, "TV");
-   sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode);
+   sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode, 0);
drm_mode_set_crtcinfo(_drm_mode, CRTC_INTERLACE_HALVE_V);
 
sun4i_tcon1_mode_set(tcon, _drm_mode);
@@ -526,22 +532,28 @@ static int sun4i_tv_comp_get_modes(struct drm_connector 
*connector)
int i;
 
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
-   struct drm_display_mode *mode;
const struct tv_mode *tv_mode = _modes[i];
-
-   mode = drm_mode_create(connector->dev);
-   if (!mode) {
-   DRM_ERROR("Failed to create a new display mode\n");
-   return 0;
+   int j;
+
+   for (j = 0; j < 20; j += 5) {
+   struct drm_display_mode *mode = 
drm_mode_create(connector->dev);
+   if (!mode) {
+   DRM_ERROR("Failed to create a new display 
mode\n");
+   return 0;
+   }
+
+   if (j)
+   sprintf(mode->name, "%s%d", tv_mode->name,
+   j);
+   else
+   

[PATCH 5/5] drm/sun4i: Add support for the overscan profiles

2016-10-18 Thread Maxime Ripard
Create overscan profiles reducing the displayed zone.

For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
by steps of 5% that the user will be able to select.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_tv.c | 60 +++--
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index f99886462cb8..9ee03ba086b6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -301,27 +301,33 @@ static const struct tv_mode 
*sun4i_tv_find_tv_by_mode(const struct drm_display_m
DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
 mode->name, tv_mode->name);
 
-   if (!strcmp(mode->name, tv_mode->name))
+   if (!strncmp(mode->name, tv_mode->name, strlen(tv_mode->name)))
return tv_mode;
}
 
/* Then by number of lines */
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
const struct tv_mode *tv_mode = _modes[i];
+   int j;
 
-   DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
-mode->name, tv_mode->name,
-mode->vdisplay, tv_mode->vdisplay);
+   for (j = 0; j < 20; j += 5) {
+   u32 vdisplay = tv_mode->vdisplay * (100 - j) / 100;
 
-   if (mode->vdisplay == tv_mode->vdisplay)
-   return tv_mode;
+   DRM_DEBUG_DRIVER("Comparing mode with %s (%d) (X: %d vs 
%d)",
+tv_mode->name, j,
+vdisplay, tv_mode->vdisplay);
+
+   if (vdisplay == tv_mode->vdisplay)
+   return tv_mode;
+   }
}
 
return NULL;
 }
 
 static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
- struct drm_display_mode *mode)
+ struct drm_display_mode *mode,
+ int overscan)
 {
DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
 
@@ -329,12 +335,12 @@ static void sun4i_tv_mode_to_drm_mode(const struct 
tv_mode *tv_mode,
mode->clock = 13500;
mode->flags = DRM_MODE_FLAG_INTERLACE;
 
-   mode->hdisplay = tv_mode->hdisplay;
+   mode->hdisplay = tv_mode->hdisplay * (100 - overscan) / 100;
mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
mode->htotal = mode->hsync_end  + tv_mode->hback_porch;
 
-   mode->vdisplay = tv_mode->vdisplay;
+   mode->vdisplay = tv_mode->vdisplay * (100 - overscan) / 100;
mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch;
mode->vsync_end = mode->vsync_start + tv_mode->vsync_len;
mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
@@ -352,10 +358,10 @@ static int sun4i_tv_atomic_check(struct drm_encoder 
*encoder,
return -EINVAL;
 
state->display_x_size = tv_mode->hdisplay;
-   state->plane_x_offset = 0;
+   state->plane_x_offset = (tv_mode->hdisplay - mode->hdisplay) / 2;
 
state->display_y_size = tv_mode->vdisplay;
-   state->plane_y_offset = 0;
+   state->plane_y_offset = (tv_mode->vdisplay - mode->vdisplay) / 2;
 
return 0;
 }
@@ -404,7 +410,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode tv_drm_mode = { 0 };
 
strcpy(tv_drm_mode.name, "TV");
-   sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode);
+   sun4i_tv_mode_to_drm_mode(tv_mode, _drm_mode, 0);
drm_mode_set_crtcinfo(_drm_mode, CRTC_INTERLACE_HALVE_V);
 
sun4i_tcon1_mode_set(tcon, _drm_mode);
@@ -526,22 +532,28 @@ static int sun4i_tv_comp_get_modes(struct drm_connector 
*connector)
int i;
 
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
-   struct drm_display_mode *mode;
const struct tv_mode *tv_mode = _modes[i];
-
-   mode = drm_mode_create(connector->dev);
-   if (!mode) {
-   DRM_ERROR("Failed to create a new display mode\n");
-   return 0;
+   int j;
+
+   for (j = 0; j < 20; j += 5) {
+   struct drm_display_mode *mode = 
drm_mode_create(connector->dev);
+   if (!mode) {
+   DRM_ERROR("Failed to create a new display 
mode\n");
+   return 0;
+   }
+
+   if (j)
+   sprintf(mode->name, "%s%d", tv_mode->name,
+   j);
+   else
+   strcpy(mode->name, tv_mode->name);
+
+