/* create extra planes */
int xilinx_drm_plane_create_planes(struct xilinx_drm_plane_manager *manager,
				   unsigned int possible_crtcs)
{
	struct xilinx_drm_plane *plane;
	int i;
	int err_ret;

	xilinx_drm_plane_create_property(manager);

	/* find if there any available plane, and create if available */
	for (i = 0; i < manager->num_planes; i++) {
		if (manager->planes[i])
			continue;

		plane = xilinx_drm_plane_create(manager, possible_crtcs, false);
		if (IS_ERR(plane)) {
			DRM_ERROR("failed to allocate a plane\n");
			err_ret = PTR_ERR(plane);
			goto err_out;
		}

		xilinx_drm_plane_attach_property(&plane->base);

		manager->planes[i] = plane;
	}

	return 0;

err_out:
	xilinx_drm_plane_destroy_planes(manager);
	return err_ret;
}
Beispiel #2
0
struct xilinx_drm_plane_manager *
xilinx_drm_plane_probe_manager(struct drm_device *drm)
{
	struct xilinx_drm_plane_manager *manager;
	struct device *dev = drm->dev;
	struct device_node *sub_node;
	const char *format;
	int ret;

	manager = devm_kzalloc(dev, sizeof(*manager), GFP_KERNEL);
	if (!manager)
		return ERR_PTR(-ENOMEM);

	/* this node is used to create a plane */
	manager->node = of_get_child_by_name(dev->of_node, "planes");
	if (!manager->node) {
		DRM_ERROR("failed to get a planes node\n");
		return ERR_PTR(-EINVAL);
	}

	/* check the base pixel format of plane manager */
	ret = of_property_read_string(manager->node, "xlnx,pixel-format",
				      &format);
	if (ret < 0) {
		DRM_ERROR("failed to get a plane manager format\n");
		return ERR_PTR(ret);
	}

	ret = xilinx_drm_format_by_name(format, &manager->format);
	if (ret < 0) {
		DRM_ERROR("invalid plane manager format\n");
		return ERR_PTR(ret);
	}

	manager->drm = drm;

	/* probe an OSD. proceed even if there's no OSD */
	sub_node = of_parse_phandle(dev->of_node, "xlnx,osd", 0);
	if (sub_node) {
		manager->osd = xilinx_osd_probe(dev, sub_node);
		of_node_put(sub_node);
		if (IS_ERR(manager->osd)) {
			of_node_put(manager->node);
			DRM_ERROR("failed to probe an osd\n");
			return ERR_CAST(manager->osd);
		}
		manager->default_alpha = OSD_MAX_ALPHA;
	}

	manager->dp_sub = xilinx_drm_dp_sub_of_get(drm->dev->of_node);
	if (IS_ERR(manager->dp_sub)) {
		DRM_DEBUG_KMS("failed to get a dp_sub\n");
		return ERR_CAST(manager->dp_sub);
	} else if (manager->dp_sub != NULL) {
		manager->default_alpha = XILINX_DRM_DP_SUB_MAX_ALPHA;
	}

	ret = xilinx_drm_plane_init_manager(manager);
	if (ret) {
		DRM_ERROR("failed to init a plane manager\n");
		return ERR_PTR(ret);
	}

	xilinx_drm_plane_create_property(manager);

	return manager;
}