File Index
Files and directories
Sign in
FILE

vkms_output.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/vkms/vkms_output.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2
  3#include "vkms_config.h"
  4#include "vkms_connector.h"
  5#include "vkms_drv.h"
  6#include <drm/drm_managed.h>
  7#include <drm/drm_print.h>
  8
  9int vkms_output_init(struct vkms_device *vkmsdev)
 10{
 11	struct drm_device *dev = &vkmsdev->drm;
 12	struct vkms_config_plane *plane_cfg;
 13	struct vkms_config_crtc *crtc_cfg;
 14	struct vkms_config_encoder *encoder_cfg;
 15	struct vkms_config_connector *connector_cfg;
 16	int ret;
 17	int writeback;
 18
 19	if (!vkms_config_is_valid(vkmsdev->config))
 20		return -EINVAL;
 21
 22	vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
 23		plane_cfg->plane = vkms_plane_init(vkmsdev, plane_cfg);
 24		if (IS_ERR(plane_cfg->plane)) {
 25			DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n");
 26			return PTR_ERR(plane_cfg->plane);
 27		}
 28	}
 29
 30	vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
 31		struct vkms_config_plane *primary, *cursor;
 32
 33		primary = vkms_config_crtc_primary_plane(vkmsdev->config, crtc_cfg);
 34		cursor = vkms_config_crtc_cursor_plane(vkmsdev->config, crtc_cfg);
 35
 36		crtc_cfg->crtc = vkms_crtc_init(dev, &primary->plane->base,
 37						cursor ? &cursor->plane->base : NULL);
 38		if (IS_ERR(crtc_cfg->crtc)) {
 39			DRM_ERROR("Failed to allocate CRTC\n");
 40			return PTR_ERR(crtc_cfg->crtc);
 41		}
 42
 43		/* Initialize the writeback component */
 44		if (vkms_config_crtc_get_writeback(crtc_cfg)) {
 45			writeback = vkms_enable_writeback_connector(vkmsdev, crtc_cfg->crtc);
 46			if (writeback)
 47				DRM_ERROR("Failed to init writeback connector\n");
 48		}
 49	}
 50
 51	vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
 52		struct vkms_config_crtc *possible_crtc;
 53		unsigned long idx = 0;
 54
 55		vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) {
 56			plane_cfg->plane->base.possible_crtcs |=
 57				drm_crtc_mask(&possible_crtc->crtc->crtc);
 58		}
 59	}
 60
 61	vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) {
 62		struct vkms_config_crtc *possible_crtc;
 63		unsigned long idx = 0;
 64
 65		encoder_cfg->encoder = drmm_kzalloc(dev, sizeof(*encoder_cfg->encoder), GFP_KERNEL);
 66		if (!encoder_cfg->encoder) {
 67			DRM_ERROR("Failed to allocate encoder\n");
 68			return -ENOMEM;
 69		}
 70		ret = drmm_encoder_init(dev, encoder_cfg->encoder, NULL,
 71					DRM_MODE_ENCODER_VIRTUAL, NULL);
 72		if (ret) {
 73			DRM_ERROR("Failed to init encoder\n");
 74			return ret;
 75		}
 76
 77		encoder_cfg->encoder->possible_clones |=
 78			drm_encoder_mask(encoder_cfg->encoder);
 79
 80		vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) {
 81			encoder_cfg->encoder->possible_crtcs |=
 82				drm_crtc_mask(&possible_crtc->crtc->crtc);
 83
 84			if (vkms_config_crtc_get_writeback(possible_crtc)) {
 85				struct drm_encoder *wb_encoder =
 86					&possible_crtc->crtc->wb_encoder;
 87
 88				encoder_cfg->encoder->possible_clones |=
 89					drm_encoder_mask(wb_encoder);
 90				wb_encoder->possible_clones |=
 91					drm_encoder_mask(encoder_cfg->encoder);
 92			}
 93		}
 94	}
 95
 96	vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
 97		struct vkms_config_encoder *possible_encoder;
 98		unsigned long idx = 0;
 99
100		connector_cfg->connector = vkms_connector_init(vkmsdev);
101		if (IS_ERR(connector_cfg->connector)) {
102			DRM_ERROR("Failed to init connector\n");
103			return PTR_ERR(connector_cfg->connector);
104		}
105
106		vkms_config_connector_for_each_possible_encoder(connector_cfg,
107								idx,
108								possible_encoder) {
109			ret = drm_connector_attach_encoder(&connector_cfg->connector->base,
110							   possible_encoder->encoder);
111			if (ret) {
112				DRM_ERROR("Failed to attach connector to encoder\n");
113				return ret;
114			}
115		}
116	}
117
118	drm_mode_config_reset(dev);
119
120	return 0;
121}
~/ Read-only file preview.