Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00f09afd authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'exynos-drm-next' of...

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

This patch set adds iommu support, userptr feature to g2d, minor fixups
and code cleanups.

And the iommu feature has dependency of the below patches related to
dma mapping framework.

This patch is used to allocate fully physically contiguous memory region.
- add sending AVI and AVI info frames.
  . this adds some codes for composing AVI and AUI info frames
    and send them every VSYNC for HDMI Certification.
- bug fix to previous pull request.
- add some code cleanup

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (32 commits)
  drm/exynos: sending AVI and AUI info frames
  drm/exynos: Use devm_clk_get in exynos_drm_fimd.c
  drm/exynos: Use devm_* APIs in exynos_hdmi.c
  drm/exynos: Use devm_clk_get in exynos_mixer.c
  drm/exynos: Fix potential NULL pointer dereference
  drm/exynos: Use devm_clk_get in exynos_drm_g2d.c
  drm/exynos: use sgt instead of pages for framebuffer address
  drm: exynos: fix for loosing display mode header during mode adjustment
  drm/exynos: fix memory leak to EDID block
  drm/exynos: remove 'pages' and 'page_size' elements in exynos gem buffer
  drm/exynos: add exynos drm specific fb_mmap function
  drm/exynos: make sure that overlay data are updated
  drm/exynos: add vm_ops to specific gem mmaper
  drm/exynos: add userptr feature for g2d module
  drm/exynos: remove unnecessary sg_alloc_table call
  drm: exynos: fix for mapping of dma buffers
  drm/exynos: remove EXYNOS_BO_NONCONTIG type checking.
  drm/exynos: add iommu support for g2d
  drm/exynos: add iommu support for hdmi driver
  drm/exynos: add iommu support to fimd driver
  ...
parents 7136470d a144c2e9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -91,3 +91,12 @@ transferred to 'device' domain. This attribute can be also used for
dma_unmap_{single,page,sg} functions family to force buffer to stay in
device domain after releasing a mapping for it. Use this attribute with
care!

DMA_ATTR_FORCE_CONTIGUOUS
-------------------------

By default DMA-mapping subsystem is allowed to assemble the buffer
allocated by dma_alloc_attrs() function from individual pages if it can
be mapped as contiguous chunk into device dma address space. By
specifing this attribute the allocated buffer is forced to be contiguous
also in physical memory.
+33 −8
Original line number Diff line number Diff line
@@ -1036,7 +1036,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
	spin_unlock_irqrestore(&mapping->lock, flags);
}

static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
					  gfp_t gfp, struct dma_attrs *attrs)
{
	struct page **pages;
	int count = size >> PAGE_SHIFT;
@@ -1050,6 +1051,23 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t
	if (!pages)
		return NULL;

	if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs))
	{
		unsigned long order = get_order(size);
		struct page *page;

		page = dma_alloc_from_contiguous(dev, count, order);
		if (!page)
			goto error;

		__dma_clear_buffer(page, size);

		for (i = 0; i < count; i++)
			pages[i] = page + i;

		return pages;
	}

	while (count) {
		int j, order = __fls(count);

@@ -1083,14 +1101,21 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t
	return NULL;
}

static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size)
static int __iommu_free_buffer(struct device *dev, struct page **pages,
			       size_t size, struct dma_attrs *attrs)
{
	int count = size >> PAGE_SHIFT;
	int array_size = count * sizeof(struct page *);
	int i;

	if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) {
		dma_release_from_contiguous(dev, pages[0], count);
	} else {
		for (i = 0; i < count; i++)
			if (pages[i])
				__free_pages(pages[i], 0);
	}

	if (array_size <= PAGE_SIZE)
		kfree(pages);
	else
@@ -1252,7 +1277,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
	if (gfp & GFP_ATOMIC)
		return __iommu_alloc_atomic(dev, size, handle);

	pages = __iommu_alloc_buffer(dev, size, gfp);
	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
	if (!pages)
		return NULL;

@@ -1273,7 +1298,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
err_mapping:
	__iommu_remove_mapping(dev, *handle, size);
err_buffer:
	__iommu_free_buffer(dev, pages, size);
	__iommu_free_buffer(dev, pages, size, attrs);
	return NULL;
}

@@ -1329,7 +1354,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
	}

	__iommu_remove_mapping(dev, handle, size);
	__iommu_free_buffer(dev, pages, size);
	__iommu_free_buffer(dev, pages, size, attrs);
}

static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
+3 −0
Original line number Diff line number Diff line
@@ -1021,6 +1021,8 @@ void drm_vblank_off(struct drm_device *dev, int crtc)

	/* Send any queued vblank events, lest the natives grow disquiet */
	seq = drm_vblank_count_and_time(dev, crtc, &now);

	spin_lock(&dev->event_lock);
	list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
		if (e->pipe != crtc)
			continue;
@@ -1031,6 +1033,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
		drm_vblank_put(dev, e->pipe);
		send_vblank_event(dev, e, seq, &now);
	}
	spin_unlock(&dev->event_lock);

	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
+6 −0
Original line number Diff line number Diff line
@@ -10,6 +10,12 @@ config DRM_EXYNOS
	  Choose this option if you have a Samsung SoC EXYNOS chipset.
	  If M is selected the module will be called exynosdrm.

config DRM_EXYNOS_IOMMU
	bool "EXYNOS DRM IOMMU Support"
	depends on DRM_EXYNOS && EXYNOS_IOMMU && ARM_DMA_USE_IOMMU
	help
	  Choose this option if you want to use IOMMU feature for DRM.

config DRM_EXYNOS_DMABUF
	bool "EXYNOS DRM DMABUF"
	depends on DRM_EXYNOS
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
		exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
		exynos_drm_plane.o

exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)	+= exynos_hdmi.o exynos_mixer.o \
Loading