As part of the cleanup of gud_probe(), this patch splits off format init code from gud_probe into it's own function. This makes the code more compartmentalised and easier to follow, and makes gud_probe() smaller and also easier to read.
Signed-off-by: Ruben Wauters <[email protected]> --- V1 -> V2: - Removed output parameters for gud_get_formats() - Added gud_get_max_buffer_size() helper function Apologies this v2 took so long --- drivers/gpu/drm/gud/gud_drv.c | 193 +++++++++++++++++++++------------- 1 file changed, 119 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 680447f426f3..278cc9bf68d0 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -435,11 +435,123 @@ static void gud_free_buffers_and_mutex(void *data) mutex_destroy(&gdrm->ctrl_lock); } -static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) +static size_t gud_get_max_buffer_size(struct gud_device *gdrm, u32 *formats, u32 num_formats) +{ + struct drm_device *drm = &gdrm->drm; + size_t max_buffer_size = 0; + size_t fmt_buf_size; + int i; + + for (i = 0; i < num_formats; i++) { + const struct drm_format_info *info = drm_format_info(formats[i]); + + fmt_buf_size = drm_format_info_min_pitch(info, 0, drm->mode_config.max_width) * + drm->mode_config.max_height; + max_buffer_size = max(max_buffer_size, fmt_buf_size); + } + + /* GUD_DRM_FORMAT_R1 and GUD_DRM_FORMAT_XRGB1111 are not in the formats array. */ + /* Ensure there is enough space for them. */ + fmt_buf_size = drm_format_info_min_pitch(&gud_drm_format_r1, 0, + drm->mode_config.max_width) * + drm->mode_config.max_height; + max_buffer_size = max(max_buffer_size, fmt_buf_size); + + fmt_buf_size = drm_format_info_min_pitch(&gud_drm_format_xrgb1111, 0, + drm->mode_config.max_width) * + drm->mode_config.max_height; + max_buffer_size = max(max_buffer_size, fmt_buf_size); + + return max_buffer_size; +} + +static int gud_get_formats(struct gud_device *gdrm, u32 *formats) { const struct drm_format_info *xrgb8888_emulation_format = NULL; bool rgb565_supported = false, xrgb8888_supported = false; unsigned int num_formats_dev, num_formats = 0; + u8 *formats_dev; + struct drm_device *drm = &gdrm->drm; + struct device *usb_device = gdrm->drm.dev; + int ret, i; + + formats_dev = devm_kmalloc(usb_device, GUD_FORMATS_MAX_NUM, GFP_KERNEL); + if (!formats_dev) + return -ENOMEM; + + ret = gud_usb_get(gdrm, GUD_REQ_GET_FORMATS, 0, formats_dev, GUD_FORMATS_MAX_NUM); + if (ret < 0) + return ret; + + num_formats_dev = ret; + for (i = 0; i < num_formats_dev; i++) { + const struct drm_format_info *info; + u32 format; + + format = gud_to_fourcc(formats_dev[i]); + if (!format) { + drm_dbg(drm, "Unsupported format: 0x%02x\n", formats_dev[i]); + continue; + } + + if (format == GUD_DRM_FORMAT_R1) + info = &gud_drm_format_r1; + else if (format == GUD_DRM_FORMAT_XRGB1111) + info = &gud_drm_format_xrgb1111; + else + info = drm_format_info(format); + + switch (format) { + case GUD_DRM_FORMAT_R1: + fallthrough; + case DRM_FORMAT_R8: + fallthrough; + case GUD_DRM_FORMAT_XRGB1111: + fallthrough; + case DRM_FORMAT_RGB332: + fallthrough; + case DRM_FORMAT_RGB888: + if (!xrgb8888_emulation_format) + xrgb8888_emulation_format = info; + break; + case DRM_FORMAT_RGB565: + rgb565_supported = true; + if (!xrgb8888_emulation_format) + xrgb8888_emulation_format = info; + break; + case DRM_FORMAT_XRGB8888: + xrgb8888_supported = true; + break; + } + + if (format == GUD_DRM_FORMAT_R1 || format == GUD_DRM_FORMAT_XRGB1111) + continue; /* Internal not for userspace */ + + formats[num_formats++] = format; + } + + if (!num_formats && !xrgb8888_emulation_format) { + dev_err(usb_device, "No supported pixel formats found\n"); + return -EINVAL; + } + + /* Prefer speed over color depth */ + if (rgb565_supported) + drm->mode_config.preferred_depth = 16; + + if (!xrgb8888_supported && xrgb8888_emulation_format) { + gdrm->xrgb8888_emulation_format = xrgb8888_emulation_format; + formats[num_formats++] = DRM_FORMAT_XRGB8888; + } + + devm_kfree(usb_device, formats_dev); + + return num_formats; +} + +static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + unsigned int num_formats = 0; struct usb_endpoint_descriptor *bulk_out; struct gud_display_descriptor_req desc; struct device *dev = &intf->dev; @@ -447,9 +559,8 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) struct gud_device *gdrm; struct drm_device *drm; struct device *dma_dev; - u8 *formats_dev; u32 *formats; - int ret, i; + int ret; ret = usb_find_bulk_out_endpoint(intf->cur_altsetting, &bulk_out); if (ret) @@ -510,81 +621,16 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) drm->mode_config.helper_private = &gud_mode_config_helpers; /* Format init */ - formats_dev = devm_kmalloc(dev, GUD_FORMATS_MAX_NUM, GFP_KERNEL); /* Add room for emulated XRGB8888 */ formats = devm_kmalloc_array(dev, GUD_FORMATS_MAX_NUM + 1, sizeof(*formats), GFP_KERNEL); - if (!formats_dev || !formats) + if (!formats) return -ENOMEM; - ret = gud_usb_get(gdrm, GUD_REQ_GET_FORMATS, 0, formats_dev, GUD_FORMATS_MAX_NUM); - if (ret < 0) - return ret; - - num_formats_dev = ret; - for (i = 0; i < num_formats_dev; i++) { - const struct drm_format_info *info; - size_t fmt_buf_size; - u32 format; - - format = gud_to_fourcc(formats_dev[i]); - if (!format) { - drm_dbg(drm, "Unsupported format: 0x%02x\n", formats_dev[i]); - continue; - } - - if (format == GUD_DRM_FORMAT_R1) - info = &gud_drm_format_r1; - else if (format == GUD_DRM_FORMAT_XRGB1111) - info = &gud_drm_format_xrgb1111; - else - info = drm_format_info(format); - - switch (format) { - case GUD_DRM_FORMAT_R1: - fallthrough; - case DRM_FORMAT_R8: - fallthrough; - case GUD_DRM_FORMAT_XRGB1111: - fallthrough; - case DRM_FORMAT_RGB332: - fallthrough; - case DRM_FORMAT_RGB888: - if (!xrgb8888_emulation_format) - xrgb8888_emulation_format = info; - break; - case DRM_FORMAT_RGB565: - rgb565_supported = true; - if (!xrgb8888_emulation_format) - xrgb8888_emulation_format = info; - break; - case DRM_FORMAT_XRGB8888: - xrgb8888_supported = true; - break; - } - - fmt_buf_size = drm_format_info_min_pitch(info, 0, drm->mode_config.max_width) * - drm->mode_config.max_height; - max_buffer_size = max(max_buffer_size, fmt_buf_size); - - if (format == GUD_DRM_FORMAT_R1 || format == GUD_DRM_FORMAT_XRGB1111) - continue; /* Internal not for userspace */ - - formats[num_formats++] = format; - } + num_formats = gud_get_formats(gdrm, formats); + if (num_formats <= 0) + return num_formats; - if (!num_formats && !xrgb8888_emulation_format) { - dev_err(dev, "No supported pixel formats found\n"); - return -EINVAL; - } - - /* Prefer speed over color depth */ - if (rgb565_supported) - drm->mode_config.preferred_depth = 16; - - if (!xrgb8888_supported && xrgb8888_emulation_format) { - gdrm->xrgb8888_emulation_format = xrgb8888_emulation_format; - formats[num_formats++] = DRM_FORMAT_XRGB8888; - } + max_buffer_size = gud_get_max_buffer_size(gdrm, formats, num_formats); if (desc.max_buffer_size) max_buffer_size = le32_to_cpu(desc.max_buffer_size); @@ -650,7 +696,6 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) return ret; devm_kfree(dev, formats); - devm_kfree(dev, formats_dev); drm_client_setup(drm, NULL); -- 2.55.0
