Skip to content

Commit f4bd542

Browse files
committed
drm/fb-helper: Scale back depth to supported maximum
The following happened when migrating an old fbdev driver to DRM: The Integrator/CP PL111 supports 16BPP but only ARGB1555/ABGR1555 or XRGB1555/XBGR1555 i.e. the maximum depth is 15. This makes the initialization of the framebuffer fail since the code in drm_fb_helper_single_fb_probe() assigns the same value to sizes.surface_bpp and sizes.surface_depth. I.e. it simply assumes a 1-to-1 mapping between BPP and depth, which is true in most cases but not for this hardware that only support odd formats. To support the odd case of a driver supporting 16BPP with only 15 bits of depth, this patch will make the code loop over the formats supported on the primary plane on each CRTC managed by the FB helper and cap the depth to the maximum supported on any primary plane. On the PL110 Integrator, this makes drm_mode_legacy_fb_format() select DRM_FORMAT_XRGB1555 which is acceptable for this driver, and thus we get framebuffer, penguin and console on the Integrator/CP. Cc: Noralf Trønnes <noralf@tronnes.org> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190110114049.10618-1-linus.walleij@linaro.org
1 parent 1581b2d commit f4bd542

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1797,14 +1797,18 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
17971797
int i;
17981798
struct drm_fb_helper_surface_size sizes;
17991799
int gamma_size = 0;
1800+
int best_depth = 0;
18001801

18011802
memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
18021803
sizes.surface_depth = 24;
18031804
sizes.surface_bpp = 32;
18041805
sizes.fb_width = (u32)-1;
18051806
sizes.fb_height = (u32)-1;
18061807

1807-
/* if driver picks 8 or 16 by default use that for both depth/bpp */
1808+
/*
1809+
* If driver picks 8 or 16 by default use that for both depth/bpp
1810+
* to begin with
1811+
*/
18081812
if (preferred_bpp != sizes.surface_bpp)
18091813
sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
18101814

@@ -1839,6 +1843,55 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
18391843
}
18401844
}
18411845

1846+
/*
1847+
* If we run into a situation where, for example, the primary plane
1848+
* supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth
1849+
* 16) we need to scale down the depth of the sizes we request.
1850+
*/
1851+
for (i = 0; i < fb_helper->crtc_count; i++) {
1852+
struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
1853+
struct drm_crtc *crtc = mode_set->crtc;
1854+
struct drm_plane *plane = crtc->primary;
1855+
int j;
1856+
1857+
DRM_DEBUG("test CRTC %d primary plane\n", i);
1858+
1859+
for (j = 0; j < plane->format_count; j++) {
1860+
const struct drm_format_info *fmt;
1861+
1862+
fmt = drm_format_info(plane->format_types[j]);
1863+
1864+
/*
1865+
* Do not consider YUV or other complicated formats
1866+
* for framebuffers. This means only legacy formats
1867+
* are supported (fmt->depth is a legacy field) but
1868+
* the framebuffer emulation can only deal with such
1869+
* formats, specifically RGB/BGA formats.
1870+
*/
1871+
if (fmt->depth == 0)
1872+
continue;
1873+
1874+
/* We found a perfect fit, great */
1875+
if (fmt->depth == sizes.surface_depth) {
1876+
best_depth = fmt->depth;
1877+
break;
1878+
}
1879+
1880+
/* Skip depths above what we're looking for */
1881+
if (fmt->depth > sizes.surface_depth)
1882+
continue;
1883+
1884+
/* Best depth found so far */
1885+
if (fmt->depth > best_depth)
1886+
best_depth = fmt->depth;
1887+
}
1888+
}
1889+
if (sizes.surface_depth != best_depth) {
1890+
DRM_INFO("requested bpp %d, scaled depth down to %d",
1891+
sizes.surface_bpp, best_depth);
1892+
sizes.surface_depth = best_depth;
1893+
}
1894+
18421895
crtc_count = 0;
18431896
for (i = 0; i < fb_helper->crtc_count; i++) {
18441897
struct drm_display_mode *desired_mode;

0 commit comments

Comments
 (0)