Skip to contentSkip to conversation

drm/fb: handle tile connectors

PATCH In review Rob Clark 4 participants 11 messages Mar 6, 2015 – Mar 11, 2015

Subsystems (6)
lore
Share & tools
lore

Rob Clark

author
#0 lore raw

cover drm/fb: handle tile connectors

Fix fb_width/height to properly take account tiles (for ex, DP MST). Also fixes for fb_width/height vs surface_width/height confusion that I noticed in a handful of drivers.

Rob Clark (5):
drm/cma: use correct fb width/height
drm/exynos: use correct fb width/height
drm/rockchip: use correct fb width/height
drm/fb: small cleanup
drm/fb: handle tiled connectors better

 drivers/gpu/drm/drm_fb_cma_helper.c           |  2 +-
 drivers/gpu/drm/drm_fb_helper.c               | 48 +++++++++++++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c     |  5 +--
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c |  2 +-
 4 files changed, 40 insertions(+), 17 deletions(-)
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#1 lore raw

PATCH 1/5 drm/cma: use correct fb width/height

---
 drivers/gpu/drm/drm_fb_cma_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_fb_cma_helper.c +1 -1
index cc0ae04..5c1aca4 100644
@@ -304,7 +304,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
 	}
 
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
 	offset = fbi->var.xoffset * bytes_per_pixel;
 	offset += fbi->var.yoffset * fb->pitches[0];
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
#2 lore raw

Re: [PATCH 1/5] drm/cma: use correct fb width/height

Hi Rob,

Thank you for the patch.

On Friday 06 March 2015 16:23:06 Rob Clark wrote:

This deserves an explanation, the reason why this fix is needed is far from clear from the code only.

Quoted 18 lines
---
 drivers/gpu/drm/drm_fb_cma_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(quoted diff) +0 -0

b/drivers/gpu/drm/drm_fb_cma_helper.c index cc0ae04..5c1aca4 100644

drivers/gpu/drm/drm_fb_cma_helper.c +1 -1
@@ -304,7 +304,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper
 *helper, }
 
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
 	offset = fbi->var.xoffset * bytes_per_pixel;
 	offset += fbi->var.yoffset * fb->pitches[0];
Signature · 8 lines
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#3 lore raw

Re: [PATCH 1/5] drm/cma: use correct fb width/height

Quoted 9 lines · Laurent Pinchart

Hi Rob,

Thank you for the patch.

On Friday 06 March 2015 16:23:06 Rob Clark wrote:

This deserves an explanation, the reason why this fix is needed is far from clear from the code only.

as discussed on irc, I'll add a patch that kerneldoc's 'struct drm_fb_helper_surface_size' and some commit msgs and re-send the series

BR,
-R

Quoted 16 lines
Quoted 16 lines
---
 drivers/gpu/drm/drm_fb_cma_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(quoted diff) +0 -0

b/drivers/gpu/drm/drm_fb_cma_helper.c index cc0ae04..5c1aca4 100644

drivers/gpu/drm/drm_fb_cma_helper.c +1 -1
@@ -304,7 +304,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper
 *helper, }
 
      drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-     drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+     drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
Quoted 8 lines

drivers/gpu/drm/drm_fb_cma_helper.c static int drm_fbdev_cma_create(struct drm_fb_helper *helper, · line 310

Quoted 2 lines
drivers/gpu/drm/drm_fb_cma_helper.c +0 -0
      offset = fbi->var.xoffset * bytes_per_pixel;
      offset += fbi->var.yoffset * fb->pitches[0];

--
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

author
#4 lore raw

PATCH 2/5 drm/exynos: use correct fb width/height

In reply to Rob Clark
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_fbdev.c +3 -2
index 84f8dfe..e71e331 100644
@@ -76,6 +76,7 @@ static struct fb_ops exynos_drm_fb_ops = {
 };
 
 static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
+				     struct drm_fb_helper_surface_size *sizes,
 				     struct drm_framebuffer *fb)
 {
 	struct fb_info *fbi = helper->fbdev;
@@ -85,7 +86,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
 	unsigned long offset;
 
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
 	/* RGB formats use only one buffer */
 	buffer = exynos_drm_fb_buffer(fb, 0);
@@ -189,7 +190,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 		goto err_destroy_framebuffer;
 	}
 
-	ret = exynos_drm_fbdev_update(helper, helper->fb);
+	ret = exynos_drm_fbdev_update(helper, sizes, helper->fb);
 	if (ret < 0)
 		goto err_dealloc_cmap;
 
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
maintainer
#5 lore raw

Re: [PATCH 2/5] drm/exynos: use correct fb width/height

Quoted 1 line · Rob Clark

Thanks,
Inki Dae

Quoted 27 lines
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_fbdev.c +2 -1
index 84f8dfe..e71e331 100644
@@ -76,6 +76,7 @@ static struct fb_ops exynos_drm_fb_ops = {
 };
 
 static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
+				     struct drm_fb_helper_surface_size *sizes,
 				     struct drm_framebuffer *fb)
 {
 	struct fb_info *fbi = helper->fbdev;
@@ -85,7 +86,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
 	unsigned long offset;
 
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
 	/* RGB formats use only one buffer */
 	buffer = exynos_drm_fb_buffer(fb, 0);

drivers/gpu/drm/exynos/exynos_drm_fbdev.c static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, · line 196

Quoted 8 lines
drivers/gpu/drm/exynos/exynos_drm_fbdev.c +1 -1
@@ -189,7 +190,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 		goto err_destroy_framebuffer;
 	}
 
-	ret = exynos_drm_fbdev_update(helper, helper->fb);
+	ret = exynos_drm_fbdev_update(helper, sizes, helper->fb);
 	if (ret < 0)
 		goto err_dealloc_cmap;
 

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

author
#6 lore raw

PATCH 3/5 drm/rockchip: use correct fb width/height

In reply to Rob Clark
---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +1 -1
index a5d889a8..ff04877 100644
@@ -106,7 +106,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
 
 	fb = helper->fb;
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
 	offset = fbi->var.xoffset * bytes_per_pixel;
 	offset += fbi->var.yoffset * fb->pitches[0];
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#7 lore raw

PATCH 4/5 drm/fb: small cleanup

In reply to Rob Clark

Flip conditional to reduce indentation level of rest of fxn, and use min/max to make the code clearer.

---
 drivers/gpu/drm/drm_fb_helper.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +15 -13
index 1e6a0c7..5ec3849 100644
@@ -1035,22 +1035,24 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_display_mode *desired_mode;
 		int x, y;
+
 		desired_mode = fb_helper->crtc_info[i].desired_mode;
+
+		if (!desired_mode)
+			continue;
+
+		crtc_count++;
+
 		x = fb_helper->crtc_info[i].x;
 		y = fb_helper->crtc_info[i].y;
-		if (desired_mode) {
-			if (gamma_size == 0)
-				gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
-			if (desired_mode->hdisplay + x < sizes.fb_width)
-				sizes.fb_width = desired_mode->hdisplay + x;
-			if (desired_mode->vdisplay + y < sizes.fb_height)
-				sizes.fb_height = desired_mode->vdisplay + y;
-			if (desired_mode->hdisplay + x > sizes.surface_width)
-				sizes.surface_width = desired_mode->hdisplay + x;
-			if (desired_mode->vdisplay + y > sizes.surface_height)
-				sizes.surface_height = desired_mode->vdisplay + y;
-			crtc_count++;
-		}
+
+		if (gamma_size == 0)
+			gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
+
+		sizes.surface_width  = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
+		sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_width);
+		sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
+		sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
 	}
 
 	if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Reviewed-by on v1 4/5
#8 lore raw

Re: [PATCH 4/5] drm/fb: small cleanup

Quoted 35 lines · Rob Clark

Flip conditional to reduce indentation level of rest of fxn, and use min/max to make the code clearer.

---
 drivers/gpu/drm/drm_fb_helper.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +7 -9
index 1e6a0c7..5ec3849 100644
@@ -1035,22 +1035,24 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
        for (i = 0; i < fb_helper->crtc_count; i++) {
                struct drm_display_mode *desired_mode;
                int x, y;
+
                desired_mode = fb_helper->crtc_info[i].desired_mode;
+
+               if (!desired_mode)
+                       continue;
+
+               crtc_count++;
+
                x = fb_helper->crtc_info[i].x;
                y = fb_helper->crtc_info[i].y;
-               if (desired_mode) {
-                       if (gamma_size == 0)
-                               gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
-                       if (desired_mode->hdisplay + x < sizes.fb_width)
-                               sizes.fb_width = desired_mode->hdisplay + x;
-                       if (desired_mode->vdisplay + y < sizes.fb_height)
-                               sizes.fb_height = desired_mode->vdisplay + y;
-                       if (desired_mode->hdisplay + x > sizes.surface_width)
-                               sizes.surface_width = desired_mode->hdisplay + x;

drivers/gpu/drm/drm_fb_helper.c static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, · line 1053

Quoted 10 lines
drivers/gpu/drm/drm_fb_helper.c +6 -4
-                       if (desired_mode->vdisplay + y > sizes.surface_height)
-                               sizes.surface_height = desired_mode->vdisplay + y;
-                       crtc_count++;
-               }
+
+               if (gamma_size == 0)
+                       gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
+
+               sizes.surface_width  = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
+               sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_width);

This should be:

sizes.surface_height = max_t(u32, desired_mode->vdisplay + y,
sizes.surface_height);

Other than that, this one is:

Quoted 8 lines
drivers/gpu/drm/drm_fb_helper.c +2 -1
+               sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
+               sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
        }
 
        if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
--

2.1.0

Quoted 4 lines

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

author
#9 lore raw

PATCH 5/5 drm/fb: handle tiled connectors better

In reply to Rob Clark

We don't want tile 0,0 to artificially constrain the size of the legacy fbdev device. Instead when reducing fb_size to be the minimum of all displays, only consider the rightmost and bottommost tiles.

---
 drivers/gpu/drm/drm_fb_helper.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +23 -3
index 5ec3849..182f04a 100644
@@ -1034,9 +1034,16 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 	crtc_count = 0;
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_display_mode *desired_mode;
-		int x, y;
+		struct drm_mode_set *mode_set;
+		int x, y, j;
+		/* in case of tile group, are we the last tile vert or horiz?
+		 * If no tile group you are always the last one both vertically
+		 * and horizontally
+		 */
+		bool lastv = true, lasth = true;
 
 		desired_mode = fb_helper->crtc_info[i].desired_mode;
+		mode_set = &fb_helper->crtc_info[i].mode_set;
 
 		if (!desired_mode)
 			continue;
@@ -1051,8 +1058,21 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 
 		sizes.surface_width  = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
 		sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_width);
-		sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
-		sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
+
+		for (j = 0; j < mode_set->num_connectors; j++) {
+			struct drm_connector *connector = mode_set->connectors[j];
+			if (connector->has_tile) {
+				lasth = (connector->tile_h_loc == (connector->num_h_tile - 1));
+				lastv = (connector->tile_v_loc == (connector->num_v_tile - 1));
+				/* cloning to multiple tiles is just crazy-talk, so: */
+				break;
+			}
+		}
+
+		if (lasth)
+			sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
+		if (lastv)
+			sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
 	}
 
 	if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#10 lore raw

PATCH 5/5 drm/fb: handle tiled connectors better

We don't want tile 0,0 to artificially constrain the size of the legacy fbdev device. Instead when reducing fb_size to be the minimum of all displays, only consider the rightmost and bottommost tiles.

---
 drivers/gpu/drm/drm_fb_helper.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +23 -3
index dca98a4..1a20db7 100644
@@ -1034,9 +1034,16 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 	crtc_count = 0;
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_display_mode *desired_mode;
-		int x, y;
+		struct drm_mode_set *mode_set;
+		int x, y, j;
+		/* in case of tile group, are we the last tile vert or horiz?
+		 * If no tile group you are always the last one both vertically
+		 * and horizontally
+		 */
+		bool lastv = true, lasth = true;
 
 		desired_mode = fb_helper->crtc_info[i].desired_mode;
+		mode_set = &fb_helper->crtc_info[i].mode_set;
 
 		if (!desired_mode)
 			continue;
@@ -1051,8 +1058,21 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 
 		sizes.surface_width  = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
 		sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height);
-		sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
-		sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
+
+		for (j = 0; j < mode_set->num_connectors; j++) {
+			struct drm_connector *connector = mode_set->connectors[j];
+			if (connector->has_tile) {
+				lasth = (connector->tile_h_loc == (connector->num_h_tile - 1));
+				lastv = (connector->tile_v_loc == (connector->num_v_tile - 1));
+				/* cloning to multiple tiles is just crazy-talk, so: */
+				break;
+			}
+		}
+
+		if (lasth)
+			sizes.fb_width  = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
+		if (lastv)
+			sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
 	}
 
 	if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
Signature · 6 lines
2.1.0

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel