diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index 33a3c98a962d..057af96dafeb 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +196,77 @@ int drm_writeback_connector_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_writeback_connector_init); +/** + * drm_writeback_connector_init_with_encoder - Initialize a writeback connector with + * a custom encoder + * + * @dev: DRM device + * @wb_connector: Writeback connector to initialize + * @enc: handle to the already initialized drm encoder + * @formats: Array of supported pixel formats for the writeback engine + * @n_formats: Length of the formats array + * + * This function creates the writeback-connector-specific properties if they + * have not been already created, initializes the connector as + * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property + * values. + * + * This function assumes that the drm_writeback_connector's encoder has already been + * created and initialized before invoking this function. + * + * In addition, this function also assumes that callers of this API will manage + * assigning the encoder helper functions, possible_crtcs and any other encoder + * specific operation. + * + * Returns: 0 on success, or a negative error code + */ +static int __drm_writeback_connector_init(struct drm_device *dev, + struct drm_writeback_connector *wb_connector, + struct drm_encoder *enc, const u32 *formats, + int n_formats) +{ + struct drm_connector *connector = &wb_connector->base; + struct drm_mode_config *config = &dev->mode_config; + struct drm_property_blob *blob; + int ret = create_writeback_properties(dev); + + if (ret != 0) + return ret; + + connector->interlace_allowed = 0; + + ret = drm_connector_attach_encoder(connector, enc); + if (ret) + return ret; + + blob = drm_property_create_blob(dev, n_formats * sizeof(*formats), + formats); + if (IS_ERR(blob)) + return PTR_ERR(blob); + + INIT_LIST_HEAD(&wb_connector->job_queue); + spin_lock_init(&wb_connector->job_lock); + + wb_connector->fence_context = dma_fence_context_alloc(1); + spin_lock_init(&wb_connector->fence_lock); + snprintf(wb_connector->timeline_name, + sizeof(wb_connector->timeline_name), + "CONNECTOR:%d-%s", connector->base.id, connector->name); + + drm_object_attach_property(&connector->base, + config->writeback_out_fence_ptr_property, 0); + + drm_object_attach_property(&connector->base, + config->writeback_fb_id_property, 0); + + drm_object_attach_property(&connector->base, + config->writeback_pixel_formats_property, + blob->base.id); + wb_connector->pixel_formats_blob_ptr = blob; + + return 0; +} + /** * drm_writeback_connector_init_with_encoder - Initialize a writeback connector with * a custom encoder @@ -225,61 +297,24 @@ EXPORT_SYMBOL(drm_writeback_connector_init); * Returns: 0 on success, or a negative error code */ int drm_writeback_connector_init_with_encoder(struct drm_device *dev, - struct drm_writeback_connector *wb_connector, struct drm_encoder *enc, - const struct drm_connector_funcs *con_funcs, const u32 *formats, - int n_formats) + struct drm_writeback_connector *wb_connector, + struct drm_encoder *enc, + const struct drm_connector_funcs *con_funcs, + const u32 *formats, int n_formats) { - struct drm_property_blob *blob; struct drm_connector *connector = &wb_connector->base; - struct drm_mode_config *config = &dev->mode_config; - int ret = create_writeback_properties(dev); - - if (ret != 0) - return ret; - - blob = drm_property_create_blob(dev, n_formats * sizeof(*formats), - formats); - if (IS_ERR(blob)) - return PTR_ERR(blob); - - - connector->interlace_allowed = 0; + int ret; ret = drm_connector_init(dev, connector, con_funcs, DRM_MODE_CONNECTOR_WRITEBACK); if (ret) - goto connector_fail; + return ret; - ret = drm_connector_attach_encoder(connector, enc); + ret = __drm_writeback_connector_init(dev, wb_connector, enc, formats, + n_formats); if (ret) - goto attach_fail; + drm_connector_cleanup(connector); - INIT_LIST_HEAD(&wb_connector->job_queue); - spin_lock_init(&wb_connector->job_lock); - - wb_connector->fence_context = dma_fence_context_alloc(1); - spin_lock_init(&wb_connector->fence_lock); - snprintf(wb_connector->timeline_name, - sizeof(wb_connector->timeline_name), - "CONNECTOR:%d-%s", connector->base.id, connector->name); - - drm_object_attach_property(&connector->base, - config->writeback_out_fence_ptr_property, 0); - - drm_object_attach_property(&connector->base, - config->writeback_fb_id_property, 0); - - drm_object_attach_property(&connector->base, - config->writeback_pixel_formats_property, - blob->base.id); - wb_connector->pixel_formats_blob_ptr = blob; - - return 0; - -attach_fail: - drm_connector_cleanup(connector); -connector_fail: - drm_property_blob_put(blob); return ret; } EXPORT_SYMBOL(drm_writeback_connector_init_with_encoder);