Commit b7fa0cde authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm/tegra/for-5.5-rc1-fixes' of git://anongit.freedesktop.org/tegra/linux into drm-next



drm/tegra: Fixes for v5.5-rc1

This is a set of small fixes, mostly for regressions introduced with the
DMA API and DisplayPort support in the main pull request for v5.5-rc1.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thierry Reding <thierry.reding@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191204124316.3534855-1-thierry.reding@gmail.com
parents 4673402e d66dfcf8
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -837,16 +837,15 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane,
static void tegra_cursor_atomic_update(struct drm_plane *plane,
				       struct drm_plane_state *old_state)
{
	struct tegra_bo *bo = tegra_fb_get_plane(plane->state->fb, 0);
	struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
	struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
	struct drm_plane_state *state = plane->state;
	u32 value = CURSOR_CLIP_DISPLAY;

	/* rien ne va plus */
	if (!plane->state->crtc || !plane->state->fb)
		return;

	switch (state->crtc_w) {
	switch (plane->state->crtc_w) {
	case 32:
		value |= CURSOR_SIZE_32x32;
		break;
@@ -864,16 +863,16 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
		break;

	default:
		WARN(1, "cursor size %ux%u not supported\n", state->crtc_w,
		     state->crtc_h);
		WARN(1, "cursor size %ux%u not supported\n",
		     plane->state->crtc_w, plane->state->crtc_h);
		return;
	}

	value |= (bo->iova >> 10) & 0x3fffff;
	value |= (state->iova[0] >> 10) & 0x3fffff;
	tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR);

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	value = (bo->iova >> 32) & 0x3;
	value = (state->iova[0] >> 32) & 0x3;
	tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI);
#endif

@@ -892,7 +891,8 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
	tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);

	/* position the cursor */
	value = (state->crtc_y & 0x3fff) << 16 | (state->crtc_x & 0x3fff);
	value = (plane->state->crtc_y & 0x3fff) << 16 |
		(plane->state->crtc_x & 0x3fff);
	tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
}

@@ -2017,7 +2017,7 @@ static int tegra_dc_init(struct host1x_client *client)
		dev_warn(dc->dev, "failed to allocate syncpoint\n");

	err = host1x_client_iommu_attach(client);
	if (err < 0) {
	if (err < 0 && err != -ENODEV) {
		dev_err(client->dev, "failed to attach to domain: %d\n", err);
		return err;
	}
+4 −3
Original line number Diff line number Diff line
@@ -920,10 +920,8 @@ int host1x_client_iommu_attach(struct host1x_client *client)

	if (tegra->domain) {
		group = iommu_group_get(client->dev);
		if (!group) {
			dev_err(client->dev, "failed to get IOMMU group\n");
		if (!group)
			return -ENODEV;
		}

		if (domain != tegra->domain) {
			err = iommu_attach_group(tegra->domain, group);
@@ -1243,6 +1241,9 @@ static int host1x_drm_remove(struct host1x_device *dev)
	drm_atomic_helper_shutdown(drm);
	drm_mode_config_cleanup(drm);

	if (tegra->hub)
		tegra_display_hub_cleanup(tegra->hub);

	err = host1x_device_exit(dev);
	if (err < 0)
		dev_err(&dev->dev, "host1x device cleanup failed: %d\n", err);
+43 −7
Original line number Diff line number Diff line
@@ -27,6 +27,29 @@ static void tegra_bo_put(struct host1x_bo *bo)
	drm_gem_object_put_unlocked(&obj->gem);
}

/* XXX move this into lib/scatterlist.c? */
static int sg_alloc_table_from_sg(struct sg_table *sgt, struct scatterlist *sg,
				  unsigned int nents, gfp_t gfp_mask)
{
	struct scatterlist *dst;
	unsigned int i;
	int err;

	err = sg_alloc_table(sgt, nents, gfp_mask);
	if (err < 0)
		return err;

	dst = sgt->sgl;

	for (i = 0; i < nents; i++) {
		sg_set_page(dst, sg_page(sg), sg->length, 0);
		dst = sg_next(dst);
		sg = sg_next(sg);
	}

	return 0;
}

static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
				     dma_addr_t *phys)
{
@@ -52,11 +75,31 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
		return ERR_PTR(-ENOMEM);

	if (obj->pages) {
		/*
		 * If the buffer object was allocated from the explicit IOMMU
		 * API code paths, construct an SG table from the pages.
		 */
		err = sg_alloc_table_from_pages(sgt, obj->pages, obj->num_pages,
						0, obj->gem.size, GFP_KERNEL);
		if (err < 0)
			goto free;
	} else if (obj->sgt) {
		/*
		 * If the buffer object already has an SG table but no pages
		 * were allocated for it, it means the buffer was imported and
		 * the SG table needs to be copied to avoid overwriting any
		 * other potential users of the original SG table.
		 */
		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
					     GFP_KERNEL);
		if (err < 0)
			goto free;
	} else {
		/*
		 * If the buffer object had no pages allocated and if it was
		 * not imported, it had to be allocated with the DMA API, so
		 * the DMA API helper can be used.
		 */
		err = dma_get_sgtable(dev, sgt, obj->vaddr, obj->iova,
				      obj->gem.size);
		if (err < 0)
@@ -397,13 +440,6 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
		err = tegra_bo_iommu_map(tegra, bo);
		if (err < 0)
			goto detach;
	} else {
		if (bo->sgt->nents > 1) {
			err = -EINVAL;
			goto detach;
		}

		bo->iova = sg_dma_address(bo->sgt->sgl);
	}

	bo->gem.import_attach = attach;
+0 −3
Original line number Diff line number Diff line
@@ -605,11 +605,8 @@ static struct tegra_display_hub_state *
tegra_display_hub_get_state(struct tegra_display_hub *hub,
			    struct drm_atomic_state *state)
{
	struct drm_device *drm = dev_get_drvdata(hub->client.parent);
	struct drm_private_state *priv;

	WARN_ON(!drm_modeset_is_locked(&drm->mode_config.connection_mutex));

	priv = drm_atomic_get_private_obj_state(state, &hub->base);
	if (IS_ERR(priv))
		return ERR_CAST(priv);
+11 −0
Original line number Diff line number Diff line
@@ -129,6 +129,17 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
				goto unpin;
			}

			/*
			 * The display controller needs contiguous memory, so
			 * fail if the buffer is discontiguous and we fail to
			 * map its SG table to a single contiguous chunk of
			 * I/O virtual memory.
			 */
			if (err > 1) {
				err = -EINVAL;
				goto unpin;
			}

			state->iova[i] = sg_dma_address(sgt->sgl);
			state->sgt[i] = sgt;
		} else {
Loading