Beispiel #1
0
static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
			 struct drm_plane *plane)
{
	struct kirin_drm_private *priv = dev->dev_private;
	struct device_node *port;
	int ret;

	/* set crtc port so that
	 * drm_of_find_possible_crtcs call works
	 */
	port = of_get_child_by_name(dev->dev->of_node, "port");
	if (!port) {
		DRM_ERROR("no port node found in %s\n",
			  dev->dev->of_node->full_name);
		return -EINVAL;
	}
	of_node_put(port);
	crtc->port = port;

	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
					&ade_crtc_funcs, NULL);
	if (ret) {
		DRM_ERROR("failed to init crtc.\n");
		return ret;
	}

	drm_crtc_helper_add(crtc, &ade_crtc_helper_funcs);
	priv->crtc[drm_crtc_index(crtc)] = crtc;

	return 0;
}
Beispiel #2
0
static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
{
	struct amdgpu_crtc *amdgpu_crtc;
	int i;

	amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
			      (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
	if (amdgpu_crtc == NULL)
		return -ENOMEM;

	drm_crtc_init(adev->ddev, &amdgpu_crtc->base, &dce_virtual_crtc_funcs);

	drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256);
	amdgpu_crtc->crtc_id = index;
	adev->mode_info.crtcs[index] = amdgpu_crtc;

	for (i = 0; i < 256; i++) {
		amdgpu_crtc->lut_r[i] = i << 2;
		amdgpu_crtc->lut_g[i] = i << 2;
		amdgpu_crtc->lut_b[i] = i << 2;
	}

	amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
	amdgpu_crtc->encoder = NULL;
	amdgpu_crtc->connector = NULL;
	amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
	drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);

	return 0;
}
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
		struct omap_overlay *ovl, int id)
{
	struct drm_crtc *crtc = NULL;
	struct omap_crtc *omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);

	DBG("%s", ovl->name);

	if (!omap_crtc) {
		dev_err(dev->dev, "could not allocate CRTC\n");
		goto fail;
	}

	crtc = &omap_crtc->base;

	omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true);
	omap_crtc->plane->crtc = crtc;
	omap_crtc->name = ovl->name;
	omap_crtc->id = id;

	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);

	return crtc;

fail:
	if (crtc) {
		omap_crtc_destroy(crtc);
	}
	return NULL;
}
Beispiel #4
0
struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm)
{
	struct sun4i_drv *drv = drm->dev_private;
	struct sun4i_crtc *scrtc;
	int ret;

	scrtc = devm_kzalloc(drm->dev, sizeof(*scrtc), GFP_KERNEL);
	if (!scrtc)
		return NULL;
	scrtc->drv = drv;

	ret = drm_crtc_init_with_planes(drm, &scrtc->crtc,
					drv->primary,
					NULL,
					&sun4i_crtc_funcs,
					NULL);
	if (ret) {
		dev_err(drm->dev, "Couldn't init DRM CRTC\n");
		return NULL;
	}

	drm_crtc_helper_add(&scrtc->crtc, &sun4i_crtc_helper_funcs);

	return scrtc;
}
Beispiel #5
0
int vigs_crtc_init(struct vigs_device *vigs_dev)
{
    struct vigs_crtc *vigs_crtc;
    int ret;

    DRM_DEBUG_KMS("enter\n");

    vigs_crtc = kzalloc(sizeof(*vigs_crtc), GFP_KERNEL);

    if (!vigs_crtc) {
        return -ENOMEM;
    }

    ret = drm_crtc_init(vigs_dev->drm_dev,
                        &vigs_crtc->base,
                        &vigs_crtc_funcs);

    if (ret != 0) {
        kfree(vigs_crtc);
        return ret;
    }

    drm_crtc_helper_add(&vigs_crtc->base, &vigs_crtc_helper_funcs);

    return 0;
}
struct pl111_drm_crtc *pl111_crtc_create(struct drm_device *dev)
{
	struct pl111_drm_crtc *pl111_crtc;

	pl111_crtc = kzalloc(sizeof(struct pl111_drm_crtc), GFP_KERNEL);
	if (pl111_crtc == NULL) {
		pr_err("Failed to allocated pl111_drm_crtc\n");
		return NULL;
	}

	drm_crtc_init(dev, &pl111_crtc->crtc, &crtc_funcs);
	drm_crtc_helper_add(&pl111_crtc->crtc, &crtc_helper_funcs);

	pl111_crtc->crtc_index = pl111_crtc_num;
	pl111_crtc_num++;
	pl111_crtc->crtc.enabled = 0;
	pl111_crtc->last_bpp = 0;
	pl111_crtc->current_update_res = NULL;
#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
	pl111_crtc->displaying_fb = NULL;
	pl111_crtc->old_kds_res_set = NULL;
	spin_lock_init(&pl111_crtc->current_displaying_lock);
#endif
	pl111_crtc->show_framebuffer_cb = show_framebuffer_on_crtc_cb_internal;
	INIT_LIST_HEAD(&pl111_crtc->update_queue);
	spin_lock_init(&pl111_crtc->base_update_lock);

	return pl111_crtc;
}
Beispiel #7
0
/* CRTC setup */
static void cirrus_crtc_init(struct drm_device *dev)
{
	struct cirrus_device *cdev = dev->dev_private;
	struct cirrus_crtc *cirrus_crtc;
	int i;

	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
			      (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
			      GFP_KERNEL);

	if (cirrus_crtc == NULL)
		return;

	drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs);

	drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
	cdev->mode_info.crtc = cirrus_crtc;

	for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
		cirrus_crtc->lut_r[i] = i;
		cirrus_crtc->lut_g[i] = i;
		cirrus_crtc->lut_b[i] = i;
	}

	drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
}
Beispiel #8
0
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
					struct drm_plane *plane,
					enum exynos_drm_output_type type,
					const struct exynos_drm_crtc_ops *ops,
					void *ctx)
{
	struct exynos_drm_crtc *exynos_crtc;
	struct drm_crtc *crtc;
	int ret;

	exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
	if (!exynos_crtc)
		return ERR_PTR(-ENOMEM);

	exynos_crtc->type = type;
	exynos_crtc->ops = ops;
	exynos_crtc->ctx = ctx;

	crtc = &exynos_crtc->base;

	ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,
					&exynos_crtc_funcs, NULL);
	if (ret < 0)
		goto err_crtc;

	drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs);

	return exynos_crtc;

err_crtc:
	plane->funcs->destroy(plane);
	kfree(exynos_crtc);
	return ERR_PTR(ret);
}
Beispiel #9
0
static void bochs_crtc_init(struct drm_device *dev)
{
	struct bochs_device *bochs = dev->dev_private;
	struct drm_crtc *crtc = &bochs->crtc;

	drm_crtc_init(dev, crtc, &bochs_crtc_funcs);
	drm_crtc_helper_add(crtc, &bochs_helper_funcs);
}
Beispiel #10
0
/* initialize crtc */
struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
		struct drm_plane *plane, int id, int ovlp_id,
		enum mdp4_dma dma_id)
{
	struct drm_crtc *crtc = NULL;
	struct mdp4_crtc *mdp4_crtc;
	int ret;

	mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL);
	if (!mdp4_crtc) {
		ret = -ENOMEM;
		goto fail;
	}

	crtc = &mdp4_crtc->base;

	mdp4_crtc->plane = plane;
	mdp4_crtc->id = id;

	mdp4_crtc->ovlp = ovlp_id;
	mdp4_crtc->dma = dma_id;

	mdp4_crtc->vblank.irqmask = dma2irq(mdp4_crtc->dma);
	mdp4_crtc->vblank.irq = mdp4_crtc_vblank_irq;

	mdp4_crtc->err.irqmask = dma2err(mdp4_crtc->dma);
	mdp4_crtc->err.irq = mdp4_crtc_err_irq;

	snprintf(mdp4_crtc->name, sizeof(mdp4_crtc->name), "%s:%d",
			dma_names[dma_id], ovlp_id);

	spin_lock_init(&mdp4_crtc->cursor.lock);

	ret = drm_flip_work_init(&mdp4_crtc->unref_fb_work, 16,
			"unref fb", unref_fb_worker);
	if (ret)
		goto fail;

	ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64,
			"unref cursor", unref_cursor_worker);

	INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb);

	drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs);
	drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);

	mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base);

	return crtc;

fail:
	if (crtc)
		mdp4_crtc_destroy(crtc);

	return ERR_PTR(ret);
}
Beispiel #11
0
static int qdev_crtc_init(struct drm_device *dev, int crtc_id)
{
	struct qxl_crtc *qxl_crtc;

	qxl_crtc = kzalloc(sizeof(struct qxl_crtc), GFP_KERNEL);
	if (!qxl_crtc)
		return -ENOMEM;

	drm_crtc_init(dev, &qxl_crtc->base, &qxl_crtc_funcs);
	qxl_crtc->index = crtc_id;
	drm_mode_crtc_set_gamma_size(&qxl_crtc->base, 256);
	drm_crtc_helper_add(&qxl_crtc->base, &qxl_crtc_helper_funcs);
	return 0;
}
Beispiel #12
0
int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
{
	struct drm_crtc *crtc = &sdev->crtc.crtc;
	int ret;

	sdev->crtc.dpms = DRM_MODE_DPMS_OFF;

	ret = drm_crtc_init(sdev->ddev, crtc, &crtc_funcs);
	if (ret < 0)
		return ret;

	drm_crtc_helper_add(crtc, &crtc_helper_funcs);

	return 0;
}
Beispiel #13
0
int vbox_crtc_init(struct drm_device *pDev, unsigned i)
{
    struct vbox_crtc *pCrtc;

    LogFunc(("vboxvideo: %d\n", __LINE__));
    pCrtc = kzalloc(sizeof(struct vbox_crtc), GFP_KERNEL);
    if (!pCrtc)
        return -ENOMEM;
    pCrtc->crtc_id = i;

    drm_crtc_init(pDev, &pCrtc->base, &vbox_crtc_funcs);
    drm_mode_crtc_set_gamma_size(&pCrtc->base, 256);
    drm_crtc_helper_add(&pCrtc->base, &vbox_crtc_helper_funcs);
    LogFunc(("vboxvideo: %d: pCrtc=%p\n", __LINE__, pCrtc));

    return 0;
}
/* initialize crtc */
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
		struct drm_plane *plane, enum omap_channel channel, int id)
{
	struct drm_crtc *crtc = NULL;
	struct omap_crtc *omap_crtc;
	int ret;

	DBG("%s", channel_names[channel]);

	omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
	if (!omap_crtc)
		return NULL;

	crtc = &omap_crtc->base;

	init_waitqueue_head(&omap_crtc->pending_wait);

	omap_crtc->channel = channel;
	omap_crtc->name = channel_names[channel];

	omap_crtc->vblank_irq.irqmask = pipe2vbl(crtc);
	omap_crtc->vblank_irq.irq = omap_crtc_vblank_irq;

	omap_crtc->error_irq.irqmask =
			dispc_mgr_get_sync_lost_irq(channel);
	omap_crtc->error_irq.irq = omap_crtc_error_irq;
	omap_irq_register(dev, &omap_crtc->error_irq);

	/* temporary: */
	omap_crtc->mgr = omap_dss_get_overlay_manager(channel);

	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
					&omap_crtc_funcs);
	if (ret < 0) {
		kfree(omap_crtc);
		return NULL;
	}

	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);

	omap_plane_install_properties(crtc->primary, &crtc->base);

	omap_crtcs[channel] = omap_crtc;

	return crtc;
}
int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
{
	struct drm_plane *primary;
	struct drm_crtc *crtc = &fsl_dev->crtc;
	unsigned int i, j, reg_num;
	int ret;

	primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
	ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
					&fsl_dcu_drm_crtc_funcs, NULL);
	if (ret < 0)
		return ret;

	drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs);

	if (!strcmp(fsl_dev->soc->name, "ls1021a"))
		reg_num = LS1021A_LAYER_REG_NUM;
	else
		reg_num = VF610_LAYER_REG_NUM;
	for (i = 0; i <= fsl_dev->soc->total_layer; i++) {
		for (j = 0; j < reg_num; j++) {
			ret = regmap_write(fsl_dev->regmap,
					   DCU_CTRLDESCLN(i, j), 0);
			if (ret)
				goto init_failed;
		}
	}
	ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
				 DCU_MODE_DCU_MODE_MASK,
				 DCU_MODE_DCU_MODE(DCU_MODE_OFF));
	if (ret)
		goto init_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
			   DCU_UPDATE_MODE_READREG);
	if (ret)
		goto init_failed;

	return 0;
init_failed:
	dev_err(fsl_dev->dev, "init DCU register failed\n");
	return ret;
}
Beispiel #16
0
int hdlcd_setup_crtc(struct drm_device *drm)
{
	struct hdlcd_drm_private *hdlcd = drm->dev_private;
	struct drm_plane *primary;
	int ret;

	primary = hdlcd_plane_init(drm);
	if (IS_ERR(primary))
		return PTR_ERR(primary);

	ret = drm_crtc_init_with_planes(drm, &hdlcd->crtc, primary, NULL,
					&hdlcd_crtc_funcs, NULL);
	if (ret) {
		hdlcd_plane_destroy(primary);
		return ret;
	}

	drm_crtc_helper_add(&hdlcd->crtc, &hdlcd_crtc_helper_funcs);
	return 0;
}
Beispiel #17
0
int arc_pgu_setup_crtc(struct drm_device *drm)
{
	struct arcpgu_drm_private *arcpgu = drm->dev_private;
	struct drm_plane *primary;
	int ret;

	primary = arc_pgu_plane_init(drm);
	if (IS_ERR(primary))
		return PTR_ERR(primary);

	ret = drm_crtc_init_with_planes(drm, &arcpgu->crtc, primary, NULL,
					&arc_pgu_crtc_funcs, NULL);
	if (ret) {
		arc_pgu_plane_destroy(primary);
		return ret;
	}

	drm_crtc_helper_add(&arcpgu->crtc, &arc_pgu_crtc_helper_funcs);
	return 0;
}
Beispiel #18
0
static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
{
	struct drm_device *dev = vgdev->ddev;
	struct virtio_gpu_output *output = vgdev->outputs + index;
	struct drm_connector *connector = &output->conn;
	struct drm_encoder *encoder = &output->enc;
	struct drm_crtc *crtc = &output->crtc;
	struct drm_plane *primary, *cursor;

	output->index = index;
	if (index == 0) {
		output->info.enabled = cpu_to_le32(true);
		output->info.r.width = cpu_to_le32(XRES_DEF);
		output->info.r.height = cpu_to_le32(YRES_DEF);
	}

	primary = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_PRIMARY, index);
	if (IS_ERR(primary))
		return PTR_ERR(primary);
	cursor = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_CURSOR, index);
	if (IS_ERR(cursor))
		return PTR_ERR(cursor);
	drm_crtc_init_with_planes(dev, crtc, primary, cursor,
				  &virtio_gpu_crtc_funcs, NULL);
	drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);

	drm_connector_init(dev, connector, &virtio_gpu_connector_funcs,
			   DRM_MODE_CONNECTOR_VIRTUAL);
	drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs);
	if (vgdev->has_edid)
		drm_connector_attach_edid_property(connector);

	drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs,
			 DRM_MODE_ENCODER_VIRTUAL, NULL);
	drm_encoder_helper_add(encoder, &virtio_gpu_enc_helper_funcs);
	encoder->possible_crtcs = 1 << index;

	drm_connector_attach_encoder(connector, encoder);
	drm_connector_register(connector);
	return 0;
}
void vboxvideo_crtc_init(struct drm_device *dev, int index)
{
    struct vboxvideo_device *gdev = dev->dev_private;
    struct vboxvideo_crtc *vboxvideo_crtc;
    int i;

    vboxvideo_crtc = kzalloc(  sizeof(struct vboxvideo_crtc)
                             + (VBOXVIDEOFB_CONN_LIMIT
                                * sizeof(struct drm_connector *)),
                             GFP_KERNEL);
    if (vboxvideo_crtc == NULL)
        return;

    drm_crtc_init(dev, &vboxvideo_crtc->base, &vboxvideo_crtc_funcs);

    vboxvideo_crtc->crtc_id = index;
    vboxvideo_crtc->last_dpms = VBOXVIDEO_DPMS_CLEARED;
    gdev->mode_info.crtcs[index] = vboxvideo_crtc;

    drm_crtc_helper_add(&vboxvideo_crtc->base, &vboxvideo_helper_funcs);
}
/**
 * drm_simple_display_pipe_init - Initialize a simple display pipeline
 * @dev: DRM device
 * @pipe: simple display pipe object to initialize
 * @funcs: callbacks for the display pipe (optional)
 * @formats: array of supported formats (DRM_FORMAT\_\*)
 * @format_count: number of elements in @formats
 * @format_modifiers: array of formats modifiers
 * @connector: connector to attach and register (optional)
 *
 * Sets up a display pipeline which consist of a really simple
 * plane-crtc-encoder pipe.
 *
 * If a connector is supplied, the pipe will be coupled with the provided
 * connector. You may supply a NULL connector when using drm bridges, that
 * handle connectors themselves (see drm_simple_display_pipe_attach_bridge()).
 *
 * Teardown of a simple display pipe is all handled automatically by the drm
 * core through calling drm_mode_config_cleanup(). Drivers afterwards need to
 * release the memory for the structure themselves.
 *
 * Returns:
 * Zero on success, negative error code on failure.
 */
int drm_simple_display_pipe_init(struct drm_device *dev,
			struct drm_simple_display_pipe *pipe,
			const struct drm_simple_display_pipe_funcs *funcs,
			const uint32_t *formats, unsigned int format_count,
			const uint64_t *format_modifiers,
			struct drm_connector *connector)
{
	struct drm_encoder *encoder = &pipe->encoder;
	struct drm_plane *plane = &pipe->plane;
	struct drm_crtc *crtc = &pipe->crtc;
	int ret;

	pipe->connector = connector;
	pipe->funcs = funcs;

	drm_plane_helper_add(plane, &drm_simple_kms_plane_helper_funcs);
	ret = drm_universal_plane_init(dev, plane, 0,
				       &drm_simple_kms_plane_funcs,
				       formats, format_count,
				       format_modifiers,
				       DRM_PLANE_TYPE_PRIMARY, NULL);
	if (ret)
		return ret;

	drm_crtc_helper_add(crtc, &drm_simple_kms_crtc_helper_funcs);
	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
					&drm_simple_kms_crtc_funcs, NULL);
	if (ret)
		return ret;

	encoder->possible_crtcs = drm_crtc_mask(crtc);
	ret = drm_encoder_init(dev, encoder, &drm_simple_kms_encoder_funcs,
			       DRM_MODE_ENCODER_NONE, NULL);
	if (ret || !connector)
		return ret;

	return drm_connector_attach_encoder(connector, encoder);
}
Beispiel #21
0
static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
{
	struct drm_device *dev = vgdev->ddev;
	struct virtio_gpu_output *output = vgdev->outputs + index;
	struct drm_connector *connector = &output->conn;
	struct drm_encoder *encoder = &output->enc;
	struct drm_crtc *crtc = &output->crtc;
	struct drm_plane *plane;

	output->index = index;
	if (index == 0) {
		output->info.enabled = cpu_to_le32(true);
		output->info.r.width = cpu_to_le32(XRES_DEF);
		output->info.r.height = cpu_to_le32(YRES_DEF);
	}

	plane = virtio_gpu_plane_init(vgdev, index);
	if (IS_ERR(plane))
		return PTR_ERR(plane);
	drm_crtc_init_with_planes(dev, crtc, plane, NULL,
				  &virtio_gpu_crtc_funcs, NULL);
	drm_mode_crtc_set_gamma_size(crtc, 256);
	drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);
	plane->crtc = crtc;

	drm_connector_init(dev, connector, &virtio_gpu_connector_funcs,
			   DRM_MODE_CONNECTOR_VIRTUAL);
	drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs);

	drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs,
			 DRM_MODE_ENCODER_VIRTUAL, NULL);
	drm_encoder_helper_add(encoder, &virtio_gpu_enc_helper_funcs);
	encoder->possible_crtcs = 1 << index;

	drm_mode_connector_attach_encoder(connector, encoder);
	drm_connector_register(connector);
	return 0;
}
Beispiel #22
0
int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
{
	struct drm_plane *primary;
	struct drm_crtc *crtc = &fsl_dev->crtc;
	int ret;

	fsl_dcu_drm_init_planes(fsl_dev->drm);

	primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
	if (!primary)
		return -ENOMEM;

	ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
					&fsl_dcu_drm_crtc_funcs, NULL);
	if (ret) {
		primary->funcs->destroy(primary);
		return ret;
	}

	drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs);

	return 0;
}
Beispiel #23
0
int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
{
	static const unsigned int mmio_offsets[] = {
		DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET
	};

	struct rcar_du_device *rcdu = rgrp->dev;
	struct platform_device *pdev = to_platform_device(rcdu->dev);
	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
	struct drm_crtc *crtc = &rcrtc->crtc;
	unsigned int irqflags;
	struct clk *clk;
	char clk_name[9];
	char *name;
	int irq;
	int ret;

	/* Get the CRTC clock and the optional external clock. */
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
		sprintf(clk_name, "du.%u", index);
		name = clk_name;
	} else {
		name = NULL;
	}

	rcrtc->clock = devm_clk_get(rcdu->dev, name);
	if (IS_ERR(rcrtc->clock)) {
		dev_err(rcdu->dev, "no clock for CRTC %u\n", index);
		return PTR_ERR(rcrtc->clock);
	}

	sprintf(clk_name, "dclkin.%u", index);
	clk = devm_clk_get(rcdu->dev, clk_name);
	if (!IS_ERR(clk)) {
		rcrtc->extclock = clk;
	} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
		dev_info(rcdu->dev, "can't get external clock %u\n", index);
		return -EPROBE_DEFER;
	}

	init_waitqueue_head(&rcrtc->flip_wait);

	rcrtc->group = rgrp;
	rcrtc->mmio_offset = mmio_offsets[index];
	rcrtc->index = index;
	rcrtc->enabled = false;

	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
					&rgrp->planes[index % 2].plane,
					NULL, &crtc_funcs);
	if (ret < 0)
		return ret;

	drm_crtc_helper_add(crtc, &crtc_helper_funcs);

	/* Start with vertical blanking interrupt reporting disabled. */
	drm_crtc_vblank_off(crtc);

	/* Register the interrupt handler. */
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
		irq = platform_get_irq(pdev, index);
		irqflags = 0;
	} else {
		irq = platform_get_irq(pdev, 0);
		irqflags = IRQF_SHARED;
	}

	if (irq < 0) {
		dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index);
		return irq;
	}

	ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
			       dev_name(rcdu->dev), rcrtc);
	if (ret < 0) {
		dev_err(rcdu->dev,
			"failed to register IRQ for CRTC %u\n", index);
		return ret;
	}

	return 0;
}
Beispiel #24
0
static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
{
	struct vmw_screen_object_unit *sou;
	struct drm_device *dev = dev_priv->dev;
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	struct drm_plane *primary, *cursor;
	struct drm_crtc *crtc;
	int ret;

	sou = kzalloc(sizeof(*sou), GFP_KERNEL);
	if (!sou)
		return -ENOMEM;

	sou->base.unit = unit;
	crtc = &sou->base.crtc;
	encoder = &sou->base.encoder;
	connector = &sou->base.connector;
	primary = &sou->base.primary;
	cursor = &sou->base.cursor;

	sou->base.active_implicit = false;
	sou->base.pref_active = (unit == 0);
	sou->base.pref_width = dev_priv->initial_width;
	sou->base.pref_height = dev_priv->initial_height;
	sou->base.pref_mode = NULL;

	/*
	 * Remove this after enabling atomic because property values can
	 * only exist in a state object
	 */
	sou->base.is_implicit = false;

	/* Initialize primary plane */
	vmw_du_plane_reset(primary);

	ret = drm_universal_plane_init(dev, &sou->base.primary,
				       0, &vmw_sou_plane_funcs,
				       vmw_primary_plane_formats,
				       ARRAY_SIZE(vmw_primary_plane_formats),
				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
	if (ret) {
		DRM_ERROR("Failed to initialize primary plane");
		goto err_free;
	}

	drm_plane_helper_add(primary, &vmw_sou_primary_plane_helper_funcs);

	/* Initialize cursor plane */
	vmw_du_plane_reset(cursor);

	ret = drm_universal_plane_init(dev, &sou->base.cursor,
			0, &vmw_sou_cursor_funcs,
			vmw_cursor_plane_formats,
			ARRAY_SIZE(vmw_cursor_plane_formats),
			NULL, DRM_PLANE_TYPE_CURSOR, NULL);
	if (ret) {
		DRM_ERROR("Failed to initialize cursor plane");
		drm_plane_cleanup(&sou->base.primary);
		goto err_free;
	}

	drm_plane_helper_add(cursor, &vmw_sou_cursor_plane_helper_funcs);

	vmw_du_connector_reset(connector);
	ret = drm_connector_init(dev, connector, &vmw_sou_connector_funcs,
				 DRM_MODE_CONNECTOR_VIRTUAL);
	if (ret) {
		DRM_ERROR("Failed to initialize connector\n");
		goto err_free;
	}

	drm_connector_helper_add(connector, &vmw_sou_connector_helper_funcs);
	connector->status = vmw_du_connector_detect(connector, true);
	vmw_connector_state_to_vcs(connector->state)->is_implicit = false;


	ret = drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs,
			       DRM_MODE_ENCODER_VIRTUAL, NULL);
	if (ret) {
		DRM_ERROR("Failed to initialize encoder\n");
		goto err_free_connector;
	}

	(void) drm_connector_attach_encoder(connector, encoder);
	encoder->possible_crtcs = (1 << unit);
	encoder->possible_clones = 0;

	ret = drm_connector_register(connector);
	if (ret) {
		DRM_ERROR("Failed to register connector\n");
		goto err_free_encoder;
	}


	vmw_du_crtc_reset(crtc);
	ret = drm_crtc_init_with_planes(dev, crtc, &sou->base.primary,
					&sou->base.cursor,
					&vmw_screen_object_crtc_funcs, NULL);
	if (ret) {
		DRM_ERROR("Failed to initialize CRTC\n");
		goto err_free_unregister;
	}

	drm_crtc_helper_add(crtc, &vmw_sou_crtc_helper_funcs);

	drm_mode_crtc_set_gamma_size(crtc, 256);

	drm_object_attach_property(&connector->base,
				   dev_priv->hotplug_mode_update_property, 1);
	drm_object_attach_property(&connector->base,
				   dev->mode_config.suggested_x_property, 0);
	drm_object_attach_property(&connector->base,
				   dev->mode_config.suggested_y_property, 0);
	if (dev_priv->implicit_placement_property)
		drm_object_attach_property
			(&connector->base,
			 dev_priv->implicit_placement_property,
			 sou->base.is_implicit);

	return 0;

err_free_unregister:
	drm_connector_unregister(connector);
err_free_encoder:
	drm_encoder_cleanup(encoder);
err_free_connector:
	drm_connector_cleanup(connector);
err_free:
	kfree(sou);
	return ret;
}
struct drm_crtc *xylon_drm_crtc_create(struct drm_device *dev)
{
	struct device_node *sub_node;
	struct drm_plane *primary;
	struct xylon_drm_crtc *crtc;
	int ret;

	sub_node = of_parse_phandle(dev->dev->of_node, "device", 0);
	if (!sub_node) {
		DRM_ERROR("failed get logicvc\n");
		return ERR_PTR(-ENODEV);
	}

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

	crtc->cvc = xylon_cvc_probe(dev->dev, sub_node);
	of_node_put(sub_node);
	if (IS_ERR(crtc->cvc)) {
		DRM_ERROR("failed probe logicvc\n");
		return ERR_CAST(crtc->cvc);
	}

	crtc->manager = xylon_drm_plane_probe_manager(dev, crtc->cvc);
	if (IS_ERR(crtc->manager)) {
		DRM_ERROR("failed probe plane manager\n");
		return ERR_CAST(crtc->manager);
	}

	ret = of_property_read_u32(dev->dev->of_node, "primary-plane",
				   &crtc->primary_id);
	if (ret)
		DRM_INFO("no private-plane property\n");

	ret = xylon_drm_plane_create_all(crtc->manager, 1, crtc->primary_id);
	if (ret) {
		DRM_ERROR("failed create planes\n");
		goto err_out;
	}

	crtc->pixel_clock = devm_clk_get(dev->dev, NULL);
	if (IS_ERR(crtc->pixel_clock)) {
		DRM_ERROR("failed get pixel clock\n");
		ret = -EPROBE_DEFER;
		goto err_out;
	}

	ret = clk_prepare_enable(crtc->pixel_clock);
	if (ret) {
		DRM_ERROR("failed prepare/enable clock\n");
		goto err_out;
	}

	primary = xylon_drm_plane_get_base(crtc->manager, crtc->primary_id);
	ret = drm_crtc_init_with_planes(dev, &crtc->base, primary, NULL,
					&xylon_drm_crtc_funcs);
	if (ret) {
		DRM_ERROR("failed initialize crtc\n");
		goto err_out;
	}
	drm_crtc_helper_add(&crtc->base, &xylon_drm_crtc_helper_funcs);

	ret = xylon_drm_crtc_create_properties(&crtc->base);
	if (ret) {
		DRM_ERROR("failed initialize crtc properties\n");
		goto err_out;
	}

	xylon_drm_crtc_properties_initial_value(&crtc->base);

	return &crtc->base;

err_out:
	return ERR_PTR(ret);
}
Beispiel #26
0
/* create crtc */
struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
{
	struct xilinx_drm_crtc *crtc;
	struct device_node *sub_node;
	int possible_crtcs = 1;
	int ret;

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

	/* probe chroma resampler and enable */
	sub_node = of_parse_phandle(drm->dev->of_node, "cresample", 0);
	if (sub_node) {
		crtc->cresample = xilinx_cresample_probe(drm->dev, sub_node);
		of_node_put(sub_node);
		if (IS_ERR(crtc->cresample)) {
			DRM_ERROR("failed to probe a cresample\n");
			return ERR_CAST(crtc->cresample);
		}
	}

	/* probe color space converter and enable */
	sub_node = of_parse_phandle(drm->dev->of_node, "rgb2yuv", 0);
	if (sub_node) {
		crtc->rgb2yuv = xilinx_rgb2yuv_probe(drm->dev, sub_node);
		of_node_put(sub_node);
		if (IS_ERR(crtc->rgb2yuv)) {
			DRM_ERROR("failed to probe a rgb2yuv\n");
			return ERR_CAST(crtc->rgb2yuv);
		}
	}

	/* probe a plane manager */
	crtc->plane_manager = xilinx_drm_plane_probe_manager(drm);
	if (IS_ERR(crtc->plane_manager)) {
		DRM_ERROR("failed to probe a plane manager\n");
		return ERR_CAST(crtc->plane_manager);
	}

	/* create a private plane. there's only one crtc now */
	crtc->priv_plane = xilinx_drm_plane_create_private(crtc->plane_manager,
							   possible_crtcs);
	if (IS_ERR(crtc->priv_plane)) {
		DRM_ERROR("failed to create a private plane for crtc\n");
		ret = PTR_ERR(crtc->priv_plane);
		goto err_plane;
	}

	/* create extra planes */
	xilinx_drm_plane_create_planes(crtc->plane_manager, possible_crtcs);

	crtc->pixel_clock = devm_clk_get(drm->dev, NULL);
	if (IS_ERR(crtc->pixel_clock)) {
		DRM_DEBUG_KMS("failed to get pixel clock\n");
		ret = -EPROBE_DEFER;
		goto err_out;
	}

	ret = clk_prepare_enable(crtc->pixel_clock);
	if (ret) {
		DRM_DEBUG_KMS("failed to prepare/enable clock\n");
		goto err_out;
	}

	sub_node = of_parse_phandle(drm->dev->of_node, "vtc", 0);
	if (!sub_node) {
		DRM_ERROR("failed to get a video timing controller node\n");
		ret = -ENODEV;
		goto err_out;
	}

	crtc->vtc = xilinx_vtc_probe(drm->dev, sub_node);
	of_node_put(sub_node);
	if (IS_ERR(crtc->vtc)) {
		DRM_ERROR("failed to probe video timing controller\n");
		ret = PTR_ERR(crtc->vtc);
		goto err_out;
	}

	crtc->dpms = DRM_MODE_DPMS_OFF;

	/* initialize drm crtc */
	ret = drm_crtc_init(drm, &crtc->base, &xilinx_drm_crtc_funcs);
	if (ret) {
		DRM_ERROR("failed to initialize crtc\n");
		goto err_out;
	}
	drm_crtc_helper_add(&crtc->base, &xilinx_drm_crtc_helper_funcs);

	xilinx_drm_crtc_attach_property(&crtc->base);

	return &crtc->base;

err_out:
	xilinx_drm_plane_destroy_planes(crtc->plane_manager);
	xilinx_drm_plane_destroy_private(crtc->plane_manager, crtc->priv_plane);
err_plane:
	xilinx_drm_plane_remove_manager(crtc->plane_manager);
	return ERR_PTR(ret);
}
Beispiel #27
0
int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
{
	static const unsigned int mmio_offsets[] = {
		DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET
	};

	struct rcar_du_device *rcdu = rgrp->dev;
	struct platform_device *pdev = to_platform_device(rcdu->dev);
	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
	struct drm_crtc *crtc = &rcrtc->crtc;
	unsigned int irqflags;
	char clk_name[5];
	char *name;
	int irq;
	int ret;

	/* Get the CRTC clock. */
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
		sprintf(clk_name, "du.%u", index);
		name = clk_name;
	} else {
		name = NULL;
	}

	rcrtc->clock = devm_clk_get(rcdu->dev, name);
	if (IS_ERR(rcrtc->clock)) {
		dev_err(rcdu->dev, "no clock for CRTC %u\n", index);
		return PTR_ERR(rcrtc->clock);
	}

	rcrtc->group = rgrp;
	rcrtc->mmio_offset = mmio_offsets[index];
	rcrtc->index = index;
	rcrtc->dpms = DRM_MODE_DPMS_OFF;
	rcrtc->plane = &rgrp->planes.planes[index % 2];
	rcrtc->lvds_ch = -1;

	rcrtc->plane->crtc = crtc;
	rcrtc->plane->fb_plane = true;

	ret = drm_crtc_init(rcdu->ddev, crtc, &crtc_funcs);
	if (ret < 0)
		return ret;

	rcdu->crtcs_connect_id[index] = rcrtc->plane->crtc->base.id;

	drm_crtc_helper_add(crtc, &crtc_helper_funcs);

	/* Register the interrupt handler. */
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
		irq = platform_get_irq(pdev, index);
		irqflags = 0;
	} else {
		irq = platform_get_irq(pdev, 0);
		irqflags = IRQF_SHARED;
	}

	if (irq < 0) {
		dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index);
		return ret;
	}

	rcdu->ddev->irq_enabled = true;

	ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
			       dev_name(rcdu->dev), rcrtc);
	if (ret < 0) {
		dev_err(rcdu->dev,
			"failed to register IRQ for CRTC %u\n", index);
		return ret;
	}

	return 0;
}