Initialize writeback connector initialising the virtual encoder and intel connector. We also allocate memory for drm_writeback_connector but not the drm_connector within it due to a constraint we need all connectors to be an intel_connector. The writeback_format arrays is used to tell the user which drm formats are supported by us.
Bspec: 49275 Signed-off-by: Suraj Kandpal <suraj.kand...@intel.com> --- drivers/gpu/drm/i915/Makefile | 1 + .../gpu/drm/i915/display/intel_writeback.c | 129 ++++++++++++++++++ .../gpu/drm/i915/display/intel_writeback.h | 17 +++ 3 files changed, 147 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_writeback.c create mode 100644 drivers/gpu/drm/i915/display/intel_writeback.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 853543443072..c9201f6111c3 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -295,6 +295,7 @@ i915-y += \ display/intel_vblank.o \ display/intel_vga.o \ display/intel_wm.o \ + display/intel_writeback.o \ display/skl_scaler.o \ display/skl_universal_plane.o \ display/skl_watermark.o \ diff --git a/drivers/gpu/drm/i915/display/intel_writeback.c b/drivers/gpu/drm/i915/display/intel_writeback.c new file mode 100644 index 000000000000..f3843ac9b026 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_writeback.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2025 Intel Corporation + */ + +#include <linux/slab.h> +#include <drm/drm_atomic_state_helper.h> +#include <drm/drm_writeback.h> +#include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_encoder.h> + +#include "i915_drv.h" +#include "intel_atomic.h" +#include "intel_de.h" +#include "intel_display_types.h" +#include "intel_display_driver.h" +#include "intel_connector.h" +#include "intel_writeback.h" + +struct intel_writeback_connector { + struct drm_writeback_connector base; + struct intel_encoder encoder; + struct intel_connector connector; + enum transcoder trans; + int frame_num; +}; + +static const u32 writeback_formats[] = { + DRM_FORMAT_XYUV8888, + DRM_FORMAT_YUYV, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_XVYU2101010, + DRM_FORMAT_VYUY, + DRM_FORMAT_XBGR2101010, +}; + +static int intel_writeback_connector_init(struct intel_connector *connector) +{ + struct intel_digital_connector_state *conn_state; + + conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL); + if (!conn_state) + return -ENOMEM; + + __drm_atomic_helper_connector_reset(&connector->base, + &conn_state->base); + return 0; +} + +static int +intel_writeback_connector_alloc(struct intel_connector *connector) +{ + if (intel_writeback_connector_init(connector) < 0) { + kfree(connector); + return -ENOMEM; + } + + return 0; +} + +static const struct drm_encoder_funcs drm_writeback_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +const struct drm_connector_funcs conn_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_connector_helper_funcs conn_helper_funcs = { +}; + +static const struct drm_writeback_connector_helper_funcs writeback_conn_helper_funcs = { +}; + +int intel_writeback_init(struct intel_display *display) +{ + struct intel_encoder *encoder; + struct intel_writeback_connector *writeback_conn; + struct intel_connector *connector; + int ret; + + writeback_conn = kzalloc(sizeof(*writeback_conn), GFP_KERNEL); + if (!writeback_conn) + return -ENOSPC; + + encoder = &writeback_conn->encoder; + encoder->base.possible_crtcs = 0xf; + ret = drm_encoder_init(display->drm, &encoder->base, + &drm_writeback_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) { + kfree(writeback_conn); + return ret; + } + + encoder->type = INTEL_OUTPUT_WRITEBACK; + encoder->pipe_mask = ~0; + encoder->cloneable = 0; + + connector = &writeback_conn->connector; + intel_writeback_connector_alloc(connector); + + connector->base.interlace_allowed = 0; + drm_connector_helper_add(&connector->base, &conn_helper_funcs); + ret = drm_writeback_connector_init_with_conn(display->drm, &connector->base, + &writeback_conn->base, + &encoder->base, &conn_funcs, + &writeback_conn_helper_funcs, + writeback_formats, + ARRAY_SIZE(writeback_formats)); + if (ret) { + intel_connector_free(connector); + drm_encoder_cleanup(&encoder->base); + kfree(&writeback_conn->encoder); + kfree(writeback_conn); + return ret; + } + + intel_connector_attach_encoder(connector, encoder); + connector->get_hw_state = intel_connector_get_hw_state; + connector->base.status = connector_status_disconnected; + writeback_conn->frame_num = 1; + + return 0; +} diff --git a/drivers/gpu/drm/i915/display/intel_writeback.h b/drivers/gpu/drm/i915/display/intel_writeback.h new file mode 100644 index 000000000000..5911684cb81a --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_writeback.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2025 Intel Corporation + */ + +#ifndef __INTEL_WRITEBACK_H__ +#define __INTEL_WRITEBACK_H__ + +#include <linux/types.h> + +struct intel_display; +struct intel_writeback_connector; + +int intel_writeback_init(struct intel_display *display); + +#endif /* __INTEL_WRITEBACK_H__ */ + -- 2.34.1